Changeset 258866 in webkit


Ignore:
Timestamp:
Mar 23, 2020 12:31:36 PM (4 years ago)
Author:
commit-queue@webkit.org
Message:

XMLHttpRequest: getAllResponseHeaders() sorting
https://bugs.webkit.org/show_bug.cgi?id=200565

Patch by Rob Buis <rbuis@igalia.com> on 2020-03-23
Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Update improved test result.

  • web-platform-tests/xhr/getallresponseheaders-expected.txt:

Source/WebCore:

Sort headers using the ASCII-uppercase header name as key but use ASCII-lowercase header
names in the string result.

Nehavior matches Firefox and Chrome.

Test: imported/web-platform-tests/xhr/getallresponseheaders.htm

[1] https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getallresponseheaders

  • xml/XMLHttpRequest.cpp:

(WebCore::XMLHttpRequest::getAllResponseHeaders const):

Source/WTF:

Add a new manipulator that can efficiently convert
Strings to lower or upper ASCII.

  • wtf/text/StringConcatenate.h:

(WTF::lowercase):
(WTF::uppercase):

  • wtf/text/StringView.cpp:

(WTF::getCharactersWithASCIICaseInternal):
(WTF::StringView::getCharactersWithASCIICase const):

  • wtf/text/StringView.h:

LayoutTests:

Update improved test results.

  • platform/ios/imported/w3c/web-platform-tests/xhr/getallresponseheaders-expected.txt:
  • platform/mac-highsierra/imported/w3c/web-platform-tests/xhr/getallresponseheaders-expected.txt:
  • platform/mac-mojave/imported/w3c/web-platform-tests/xhr/getallresponseheaders-expected.txt:
Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r258859 r258866  
     12020-03-23  Rob Buis  <rbuis@igalia.com>
     2
     3        XMLHttpRequest: getAllResponseHeaders() sorting
     4        https://bugs.webkit.org/show_bug.cgi?id=200565
     5
     6        Reviewed by Darin Adler.
     7
     8        Update improved test results.
     9
     10        * platform/ios/imported/w3c/web-platform-tests/xhr/getallresponseheaders-expected.txt:
     11        * platform/mac-highsierra/imported/w3c/web-platform-tests/xhr/getallresponseheaders-expected.txt:
     12        * platform/mac-mojave/imported/w3c/web-platform-tests/xhr/getallresponseheaders-expected.txt:
     13
    1142020-03-23  Jacob Uphoff  <jacob_uphoff@apple.com>
    215
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r258850 r258866  
     12020-03-23  Rob Buis  <rbuis@igalia.com>
     2
     3        XMLHttpRequest: getAllResponseHeaders() sorting
     4        https://bugs.webkit.org/show_bug.cgi?id=200565
     5
     6        Reviewed by Darin Adler.
     7
     8        Update improved test result.
     9
     10        * web-platform-tests/xhr/getallresponseheaders-expected.txt:
     11
    1122020-03-23  Chris Dumez  <cdumez@apple.com>
    213
  • trunk/LayoutTests/imported/w3c/web-platform-tests/xhr/getallresponseheaders-expected.txt

    r254285 r258866  
    11
    2 FAIL XMLHttpRequest: getAllResponseHeaders() assert_equals: expected "also-here: Mr. PB\r\newok: lego\r\nfoo-test: 1, 2\r\n__custom: token\r\n" but got "__custom: token\r\nalso-here: Mr. PB\r\newok: lego\r\nfoo-test: 1, 2\r\n"
     2PASS XMLHttpRequest: getAllResponseHeaders()
    33PASS XMLHttpRequest: getAllResponseHeaders() 1
    44PASS XMLHttpRequest: getAllResponseHeaders() 2
  • trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/xhr/getallresponseheaders-expected.txt

    r254154 r258866  
    11
    2 FAIL XMLHttpRequest: getAllResponseHeaders() assert_equals: expected "also-here: Mr. PB\r\newok: lego\r\nfoo-test: 1, 2\r\n__custom: token\r\n" but got "__custom: token\r\nalso-here: Mr. PB\r\newok: lego\r\nfoo-test: 1, 2\r\n"
     2PASS XMLHttpRequest: getAllResponseHeaders()
    33PASS XMLHttpRequest: getAllResponseHeaders() 1
    44PASS XMLHttpRequest: getAllResponseHeaders() 2
  • trunk/LayoutTests/platform/mac-highsierra/imported/w3c/web-platform-tests/xhr/getallresponseheaders-expected.txt

    r254285 r258866  
    11
    2 FAIL XMLHttpRequest: getAllResponseHeaders() assert_equals: expected "also-here: Mr. PB\r\newok: lego\r\nfoo-test: 1, 2\r\n__custom: token\r\n" but got "__custom: token\r\nalso-here: Mr. PB\r\newok: lego\r\nfoo-test: 1, 2\r\n"
     2PASS XMLHttpRequest: getAllResponseHeaders()
    33PASS XMLHttpRequest: getAllResponseHeaders() 1
    44PASS XMLHttpRequest: getAllResponseHeaders() 2
  • trunk/LayoutTests/platform/mac-mojave/imported/w3c/web-platform-tests/xhr/getallresponseheaders-expected.txt

    r254285 r258866  
    11
    2 FAIL XMLHttpRequest: getAllResponseHeaders() assert_equals: expected "also-here: Mr. PB\r\newok: lego\r\nfoo-test: 1, 2\r\n__custom: token\r\n" but got "__custom: token\r\nalso-here: Mr. PB\r\newok: lego\r\nfoo-test: 1, 2\r\n"
     2PASS XMLHttpRequest: getAllResponseHeaders()
    33PASS XMLHttpRequest: getAllResponseHeaders() 1
    44PASS XMLHttpRequest: getAllResponseHeaders() 2
  • trunk/Source/WTF/ChangeLog

    r258858 r258866  
     12020-03-23  Rob Buis  <rbuis@igalia.com>
     2
     3        XMLHttpRequest: getAllResponseHeaders() sorting
     4        https://bugs.webkit.org/show_bug.cgi?id=200565
     5
     6        Reviewed by Darin Adler.
     7
     8        Add a new manipulator that can efficiently convert
     9        Strings to lower or upper ASCII.
     10
     11        * wtf/text/StringConcatenate.h:
     12        (WTF::lowercase):
     13        (WTF::uppercase):
     14        * wtf/text/StringView.cpp:
     15        (WTF::getCharactersWithASCIICaseInternal):
     16        (WTF::StringView::getCharactersWithASCIICase const):
     17        * wtf/text/StringView.h:
     18
    1192020-03-23  Antoine Quint  <graouts@apple.com>
    220
  • trunk/Source/WTF/wtf/text/StringConcatenate.h

    r248892 r258866  
    288288};
    289289
     290struct ASCIICaseConverter {
     291    StringView::CaseConvertType type;
     292    StringView string;
     293};
     294
     295inline ASCIICaseConverter lowercase(const StringView& stringView)
     296{
     297    return { StringView::CaseConvertType::Lower, stringView };
     298}
     299
     300inline ASCIICaseConverter uppercase(const StringView& stringView)
     301{
     302    return { StringView::CaseConvertType::Upper, stringView };
     303}
     304
     305template<> class StringTypeAdapter<ASCIICaseConverter, void> {
     306public:
     307    StringTypeAdapter(const ASCIICaseConverter& converter)
     308        : m_converter { converter }
     309    {
     310    }
     311
     312    unsigned length() const { return m_converter.string.length(); }
     313    bool is8Bit() const { return m_converter.string.is8Bit(); }
     314    template<typename CharacterType> void writeTo(CharacterType* destination) const
     315    {
     316        m_converter.string.getCharactersWithASCIICase(m_converter.type, destination);
     317    }
     318
     319private:
     320    const ASCIICaseConverter& m_converter;
     321};
     322
    290323template<typename Adapter>
    291324inline bool are8Bit(Adapter adapter)
     
    365398using WTF::makeString;
    366399using WTF::pad;
     400using WTF::lowercase;
    367401using WTF::tryMakeString;
     402using WTF::uppercase;
    368403
    369404#include <wtf/text/StringOperators.h>
  • trunk/Source/WTF/wtf/text/StringView.cpp

    r257688 r258866  
    3131#include <unicode/ubrk.h>
    3232#include <unicode/unorm2.h>
     33#include <wtf/ASCIICType.h>
    3334#include <wtf/HashMap.h>
    3435#include <wtf/Lock.h>
     
    241242        return convertASCIICase<ASCIICase::Upper>(static_cast<const LChar*>(m_characters), m_length);
    242243    return convertASCIICase<ASCIICase::Upper>(static_cast<const UChar*>(m_characters), m_length);
     244}
     245
     246template<typename DestinationCharacterType, typename SourceCharacterType>
     247void getCharactersWithASCIICaseInternal(StringView::CaseConvertType type, DestinationCharacterType* destination, const SourceCharacterType* source, unsigned length)
     248{
     249    static_assert(std::is_same<SourceCharacterType, LChar>::value || std::is_same<SourceCharacterType, UChar>::value);
     250    static_assert(std::is_same<DestinationCharacterType, LChar>::value || std::is_same<DestinationCharacterType, UChar>::value);
     251    static_assert(sizeof(DestinationCharacterType) >= sizeof(SourceCharacterType));
     252    auto caseConvert = (type == StringView::CaseConvertType::Lower) ? toASCIILower<SourceCharacterType> : toASCIIUpper<SourceCharacterType>;
     253    for (unsigned i = 0; i < length; ++i)
     254        destination[i] = caseConvert(source[i]);
     255}
     256
     257void StringView::getCharactersWithASCIICase(CaseConvertType type, LChar* destination) const
     258{
     259    ASSERT(is8Bit());
     260    getCharactersWithASCIICaseInternal(type, destination, characters8(), m_length);
     261}
     262
     263void StringView::getCharactersWithASCIICase(CaseConvertType type, UChar* destination) const
     264{
     265    if (is8Bit()) {
     266        getCharactersWithASCIICaseInternal(type, destination, characters8(), m_length);
     267        return;
     268    }
     269    getCharactersWithASCIICaseInternal(type, destination, characters16(), m_length);
    243270}
    244271
  • trunk/Source/WTF/wtf/text/StringView.h

    r258685 r258866  
    121121    void getCharactersWithUpconvert(UChar*) const;
    122122
     123    enum class CaseConvertType { Upper, Lower };
     124    WTF_EXPORT_PRIVATE void getCharactersWithASCIICase(CaseConvertType, LChar*) const;
     125    WTF_EXPORT_PRIVATE void getCharactersWithASCIICase(CaseConvertType, UChar*) const;
     126
    123127    StringView substring(unsigned start, unsigned length = std::numeric_limits<unsigned>::max()) const;
    124128    StringView left(unsigned length) const { return substring(0, length); }
  • trunk/Source/WebCore/ChangeLog

    r258864 r258866  
     12020-03-23  Rob Buis  <rbuis@igalia.com>
     2
     3        XMLHttpRequest: getAllResponseHeaders() sorting
     4        https://bugs.webkit.org/show_bug.cgi?id=200565
     5
     6        Reviewed by Darin Adler.
     7
     8        Sort headers using the ASCII-uppercase header name as key but use ASCII-lowercase header
     9        names in the string result.
     10
     11        Nehavior matches Firefox and Chrome.
     12
     13        Test: imported/web-platform-tests/xhr/getallresponseheaders.htm
     14
     15        [1] https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getallresponseheaders
     16
     17        * xml/XMLHttpRequest.cpp:
     18        (WebCore::XMLHttpRequest::getAllResponseHeaders const):
     19
    1202020-03-23  Truitt Savell  <tsavell@apple.com>
    221
  • trunk/Source/WebCore/xml/XMLHttpRequest.cpp

    r258159 r258866  
    812812
    813813    if (!m_allResponseHeaders) {
    814         Vector<String> headers;
     814        Vector<std::pair<String, String>> headers;
    815815        headers.reserveInitialCapacity(m_response.httpHeaderFields().size());
    816816
    817         for (auto& header : m_response.httpHeaderFields()) {
    818             StringBuilder stringBuilder;
    819             stringBuilder.append(header.key.convertToASCIILowercase());
    820             stringBuilder.appendLiteral(": ");
    821             stringBuilder.append(header.value);
    822             stringBuilder.appendLiteral("\r\n");
    823             headers.uncheckedAppend(stringBuilder.toString());
    824         }
    825         std::sort(headers.begin(), headers.end(), WTF::codePointCompareLessThan);
     817        for (auto& header : m_response.httpHeaderFields())
     818            headers.uncheckedAppend(std::make_pair(header.key, header.value));
     819
     820        std::sort(headers.begin(), headers.end(), [] (const std::pair<String, String>& x, const std::pair<String, String>& y) {
     821            unsigned xLength = x.first.length();
     822            unsigned yLength = y.first.length();
     823            unsigned commonLength = std::min(xLength, yLength);
     824            for (unsigned i = 0; i < commonLength; ++i) {
     825                auto xCharacter = toASCIIUpper(x.first[i]);
     826                auto yCharacter = toASCIIUpper(y.first[i]);
     827                if (xCharacter != yCharacter)
     828                    return xCharacter < yCharacter;
     829            }
     830            return xLength < yLength;
     831        });
    826832
    827833        StringBuilder stringBuilder;
    828834        for (auto& header : headers)
    829             stringBuilder.append(header);
     835            stringBuilder.append(lowercase(header.first), ": ", header.second, "\r\n");
     836
    830837        m_allResponseHeaders = stringBuilder.toString();
    831838    }
Note: See TracChangeset for help on using the changeset viewer.