Title: [222306] trunk
Revision
222306
Author
[email protected]
Date
2017-09-20 18:15:23 -0700 (Wed, 20 Sep 2017)

Log Message

Add infrastructure for adding custom headers to requests per website
https://bugs.webkit.org/show_bug.cgi?id=177255

Reviewed by Geoffrey Garen.

Source/WebCore:

Covered by API tests.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
* loader/DocumentLoader.cpp:
* loader/DocumentLoader.h:
(WebCore::DocumentLoader::setCustomHeaderFields):
* loader/HTTPHeaderField.cpp: Added.
(WebCore::RFC7230::isTokenCharacter):
(WebCore::RFC7230::isDelimiter):
(WebCore::RFC7230::isVisibleCharacter):
(WebCore::RFC7230::isWhitespace):
(WebCore::RFC7230::isInRange):
(WebCore::RFC7230::isOBSText):
(WebCore::RFC7230::isQuotedTextCharacter):
(WebCore::RFC7230::isQuotedPairSecondOctet):
(WebCore::RFC7230::isCommentText):
(WebCore::RFC7230::isValidName):
(WebCore::RFC7230::isValidValue):
(WebCore::HTTPHeaderField::HTTPHeaderField):
* loader/HTTPHeaderField.h: Added.
(WebCore::HTTPHeaderField::encode const):
(WebCore::HTTPHeaderField::decode):

Source/WebKit:

* Shared/WebsitePolicies.cpp: Added.
* Shared/WebsitePolicies.h:
(WebKit::WebsitePolicies::encode const):
(WebKit::WebsitePolicies::decode):
* UIProcess/API/APIWebsitePolicies.h:
* UIProcess/API/C/WKWebsitePolicies.cpp:
(WKWebsitePoliciesCopyCustomHeaderFields):
(WKWebsitePoliciesSetCustomHeaderFields):
* UIProcess/API/C/WKWebsitePolicies.h:
* UIProcess/API/Cocoa/_WKWebsitePolicies.h:
* UIProcess/API/Cocoa/_WKWebsitePolicies.mm:
(-[_WKWebsitePolicies customHeaderFields]):
(-[_WKWebsitePolicies setCustomHeaderFields:]):
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/HTTPHeaderField.cpp: Added.
(shouldRemainUnchanged):
(shouldBeInvalid):
(shouldBecome):
(TEST):
* TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm:
(TEST):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/CMakeLists.txt (222305 => 222306)


--- trunk/Source/WebCore/CMakeLists.txt	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebCore/CMakeLists.txt	2017-09-21 01:15:23 UTC (rev 222306)
@@ -2102,6 +2102,7 @@
     loader/FrameLoadRequest.cpp
     loader/FrameLoader.cpp
     loader/FrameLoaderStateMachine.cpp
+    loader/HTTPHeaderField.cpp
     loader/HistoryController.cpp
     loader/ImageLoader.cpp
     loader/LinkHeader.cpp

Modified: trunk/Source/WebCore/ChangeLog (222305 => 222306)


--- trunk/Source/WebCore/ChangeLog	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebCore/ChangeLog	2017-09-21 01:15:23 UTC (rev 222306)
@@ -1,3 +1,34 @@
+2017-09-20  Alex Christensen  <[email protected]>
+
+        Add infrastructure for adding custom headers to requests per website
+        https://bugs.webkit.org/show_bug.cgi?id=177255
+
+        Reviewed by Geoffrey Garen.
+
+        Covered by API tests.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * loader/DocumentLoader.cpp:
+        * loader/DocumentLoader.h:
+        (WebCore::DocumentLoader::setCustomHeaderFields):
+        * loader/HTTPHeaderField.cpp: Added.
+        (WebCore::RFC7230::isTokenCharacter):
+        (WebCore::RFC7230::isDelimiter):
+        (WebCore::RFC7230::isVisibleCharacter):
+        (WebCore::RFC7230::isWhitespace):
+        (WebCore::RFC7230::isInRange):
+        (WebCore::RFC7230::isOBSText):
+        (WebCore::RFC7230::isQuotedTextCharacter):
+        (WebCore::RFC7230::isQuotedPairSecondOctet):
+        (WebCore::RFC7230::isCommentText):
+        (WebCore::RFC7230::isValidName):
+        (WebCore::RFC7230::isValidValue):
+        (WebCore::HTTPHeaderField::HTTPHeaderField):
+        * loader/HTTPHeaderField.h: Added.
+        (WebCore::HTTPHeaderField::encode const):
+        (WebCore::HTTPHeaderField::decode):
+
 2017-09-20  Said Abou-Hallawa  <[email protected]>
 
         REGRESSION(r191731): SVGPatternElement can only reference another SVGPatternElement in the same SVG document

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (222305 => 222306)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-09-21 01:15:23 UTC (rev 222306)
@@ -2739,6 +2739,8 @@
 		5C9A7A761AA0F6ED00958ACF /* DFABytecodeInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C3930601AA0F6A90029C816 /* DFABytecodeInterpreter.cpp */; };
 		5C9B860C1C21E3C900110F36 /* NetworkLoadMetrics.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C9B860B1C21E3C600110F36 /* NetworkLoadMetrics.mm */; };
 		5C9EF1711DFF71CC00A452E3 /* XPathGrammar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C9EF16F1DFF719900A452E3 /* XPathGrammar.cpp */; };
+		5CA1DEC51F71EF9900E71BD3 /* HTTPHeaderField.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CA1DEC21F71E68600E71BD3 /* HTTPHeaderField.cpp */; };
+		5CA1DEC61F71F1C700E71BD3 /* HTTPHeaderField.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CA1DEC41F71E68700E71BD3 /* HTTPHeaderField.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		5CB37FFE1C62D28C00F20188 /* ScrollAnimatorMock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CB37FFC1C62D27800F20188 /* ScrollAnimatorMock.cpp */; };
 		5CB37FFF1C62D2A100F20188 /* ScrollAnimatorMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CB37FFD1C62D27800F20188 /* ScrollAnimatorMock.h */; };
 		5CBC8DAC1AAA302200E1C803 /* MediaAccessibilitySoftLink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CBC8DAA1AAA302200E1C803 /* MediaAccessibilitySoftLink.cpp */; };
@@ -10687,6 +10689,8 @@
 		5C9B860B1C21E3C600110F36 /* NetworkLoadMetrics.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NetworkLoadMetrics.mm; sourceTree = "<group>"; };
 		5C9EF16F1DFF719900A452E3 /* XPathGrammar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XPathGrammar.cpp; sourceTree = "<group>"; };
 		5C9EF1701DFF719900A452E3 /* XPathGrammar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPathGrammar.h; sourceTree = "<group>"; };
+		5CA1DEC21F71E68600E71BD3 /* HTTPHeaderField.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPHeaderField.cpp; sourceTree = "<group>"; };
+		5CA1DEC41F71E68700E71BD3 /* HTTPHeaderField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPHeaderField.h; sourceTree = "<group>"; };
 		5CB37FFC1C62D27800F20188 /* ScrollAnimatorMock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollAnimatorMock.cpp; sourceTree = "<group>"; };
 		5CB37FFD1C62D27800F20188 /* ScrollAnimatorMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimatorMock.h; sourceTree = "<group>"; };
 		5CBC8DAA1AAA302200E1C803 /* MediaAccessibilitySoftLink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaAccessibilitySoftLink.cpp; sourceTree = "<group>"; };
@@ -24439,6 +24443,8 @@
 				51C81B880C4422F70019ECE3 /* FTPDirectoryParser.h */,
 				97DCE1FF10807C750057D394 /* HistoryController.cpp */,
 				97DCE20010807C750057D394 /* HistoryController.h */,
+				5CA1DEC21F71E68600E71BD3 /* HTTPHeaderField.cpp */,
+				5CA1DEC41F71E68700E71BD3 /* HTTPHeaderField.h */,
 				089582530E857A7E00F82C83 /* ImageLoader.cpp */,
 				089582540E857A7E00F82C83 /* ImageLoader.h */,
 				CBA9DC081DF44DC40005675C /* LinkHeader.cpp */,
@@ -28145,6 +28151,7 @@
 				AD49914318F0815100BF0092 /* HTMLUnknownElement.h in Headers */,
 				E44613AB0CD6331000FADA75 /* HTMLVideoElement.h in Headers */,
 				839AAFED1A0C0C8D00605F99 /* HTMLWBRElement.h in Headers */,
+				5CA1DEC61F71F1C700E71BD3 /* HTTPHeaderField.h in Headers */,
 				514C76710CE923A1007EF3CD /* HTTPHeaderMap.h in Headers */,
 				1AB5EBD2194A50F30059AC70 /* HTTPHeaderNames.h in Headers */,
 				41614A791DA64241004AD06F /* HTTPHeaderValues.h in Headers */,
@@ -29202,8 +29209,8 @@
 				932AD70617EFA2C40038F8FF /* MainFrame.h in Headers */,
 				7AE6C93C1BE0C60100E19E03 /* MainThreadSharedTimer.h in Headers */,
 				1A8F6BC60DB55CDC001DB794 /* ManifestParser.h in Headers */,
+				CE1866451F72E5B400A0CAB6 /* MarkerSubrange.h in Headers */,
 				93309DF8099E64920056E581 /* markup.h in Headers */,
-				CE1866451F72E5B400A0CAB6 /* MarkerSubrange.h in Headers */,
 				9728C3141268E4390041E89B /* MarkupAccumulator.h in Headers */,
 				00C60E3F13D76D7E0092A275 /* MarkupTokenizerInlines.h in Headers */,
 				FABE72F51059C1EB00D888CC /* MathMLAnnotationElement.h in Headers */,
@@ -32189,6 +32196,7 @@
 				A8EA79F30A1916DF00A8EF5F /* HTMLUListElement.cpp in Sources */,
 				E44613AA0CD6331000FADA75 /* HTMLVideoElement.cpp in Sources */,
 				839AAFEC1A0C0C8D00605F99 /* HTMLWBRElement.cpp in Sources */,
+				5CA1DEC51F71EF9900E71BD3 /* HTTPHeaderField.cpp in Sources */,
 				0B8C56D40F28627F000502E1 /* HTTPHeaderMap.cpp in Sources */,
 				1AC900C31943C0FC008625B5 /* HTTPHeaderNames.cpp in Sources */,
 				41614A781DA6423B004AD06F /* HTTPHeaderValues.cpp in Sources */,
@@ -33276,8 +33284,8 @@
 				7AE6C93B1BE0C60100E19E03 /* MainThreadSharedTimer.cpp in Sources */,
 				7AE6C9381BE0C5C800E19E03 /* MainThreadSharedTimerCF.cpp in Sources */,
 				1A8F6BC50DB55CDC001DB794 /* ManifestParser.cpp in Sources */,
+				CE1866441F72E5B400A0CAB6 /* MarkerSubrange.cpp in Sources */,
 				93309DF7099E64920056E581 /* markup.cpp in Sources */,
-				CE1866441F72E5B400A0CAB6 /* MarkerSubrange.cpp in Sources */,
 				9728C3131268E4390041E89B /* MarkupAccumulator.cpp in Sources */,
 				FABE72F41059C1EB00D888CC /* MathMLAnnotationElement.cpp in Sources */,
 				FABE72F41059C1EB00D999DD /* MathMLElement.cpp in Sources */,

Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (222305 => 222306)


--- trunk/Source/WebCore/loader/DocumentLoader.cpp	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp	2017-09-21 01:15:23 UTC (rev 222306)
@@ -52,6 +52,7 @@
 #include "FrameTree.h"
 #include "HTMLFormElement.h"
 #include "HTMLFrameOwnerElement.h"
+#include "HTTPHeaderField.h"
 #include "HTTPHeaderNames.h"
 #include "HistoryItem.h"
 #include "IconLoader.h"

Modified: trunk/Source/WebCore/loader/DocumentLoader.h (222305 => 222306)


--- trunk/Source/WebCore/loader/DocumentLoader.h	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebCore/loader/DocumentLoader.h	2017-09-21 01:15:23 UTC (rev 222306)
@@ -69,6 +69,7 @@
 class FormState;
 class Frame;
 class FrameLoader;
+class HTTPHeaderField;
 class IconLoader;
 class Page;
 class PreviewConverter;
@@ -295,6 +296,8 @@
 
     const Vector<LinkIcon>& linkIcons() const { return m_linkIcons; }
 
+    void setCustomHeaderFields(Vector<HTTPHeaderField>&& fields) { m_customHeaderFields = WTFMove(fields); }
+    
 protected:
     WEBCORE_EXPORT DocumentLoader(const ResourceRequest&, const SubstituteData&);
 
@@ -452,6 +455,8 @@
     HashMap<std::unique_ptr<IconLoader>, uint64_t> m_iconLoaders;
     Vector<LinkIcon> m_linkIcons;
 
+    Vector<HTTPHeaderField> m_customHeaderFields;
+    
     bool m_subresourceLoadersArePageCacheAcceptable { false };
     ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy { ShouldOpenExternalURLsPolicy::ShouldNotAllow };
 

Added: trunk/Source/WebCore/loader/HTTPHeaderField.cpp (0 => 222306)


--- trunk/Source/WebCore/loader/HTTPHeaderField.cpp	                        (rev 0)
+++ trunk/Source/WebCore/loader/HTTPHeaderField.cpp	2017-09-21 01:15:23 UTC (rev 222306)
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTTPHeaderField.h"
+
+namespace WebCore {
+
+namespace RFC7230 {
+    
+static bool isTokenCharacter(UChar c)
+{
+    return isASCIIAlpha(c) || isASCIIDigit(c)
+        || c == '!' || c == '#' || c == '$'
+        || c == '%' || c == '&' || c == '\''
+        || c == '*' || c == '+' || c == '-'
+        || c == '.' || c == '^' || c == '_'
+        || c == '`' || c == '|' || c == '~';
+}
+
+static bool isDelimiter(UChar c)
+{
+    return c == '(' || c == ')' || c == ','
+        || c == '/' || c == ':' || c == ';'
+        || c == '<' || c == '=' || c == '>'
+        || c == '?' || c == '@' || c == '['
+        || c == '\\' || c == ']' || c == '{'
+        || c == '}' || c == '"';
+}
+
+static bool isVisibleCharacter(UChar c)
+{
+    return isTokenCharacter(c) || isDelimiter(c);
+}
+
+static bool isWhitespace(UChar c)
+{
+    return c == ' ' || c == '\t';
+}
+
+template<size_t min, size_t max>
+static bool isInRange(UChar c)
+{
+    return c >= min && c <= max;
+}
+
+static bool isOBSText(UChar c)
+{
+    return isInRange<0x80, 0xFF>(c);
+}
+
+static bool isQuotedTextCharacter(UChar c)
+{
+    return isWhitespace(c)
+        || c == 0x21
+        || isInRange<0x23, 0x5B>(c)
+        || isInRange<0x5D, 0x7E>(c)
+        || isOBSText(c);
+}
+
+static bool isQuotedPairSecondOctet(UChar c)
+{
+    return isWhitespace(c)
+        || isVisibleCharacter(c)
+        || isOBSText(c);
+}
+
+static bool isCommentText(UChar c)
+{
+    return isWhitespace(c)
+        || isInRange<0x21, 0x27>(c)
+        || isInRange<0x2A, 0x5B>(c)
+        || isInRange<0x5D, 0x7E>(c)
+        || isOBSText(c);
+}
+
+static bool isValidName(StringView name)
+{
+    if (!name.length())
+        return false;
+    for (size_t i = 0; i < name.length(); ++i) {
+        if (!isTokenCharacter(name[i]))
+            return false;
+    }
+    return true;
+}
+
+static bool isValidValue(StringView value)
+{
+    enum class State {
+        OptionalWhitespace,
+        Token,
+        QuotedString,
+        Comment,
+    };
+    State state = State::OptionalWhitespace;
+    size_t commentDepth = 0;
+    bool hadNonWhitespace = false;
+    
+    for (size_t i = 0; i < value.length(); ++i) {
+        UChar c = value[i];
+        switch (state) {
+        case State::OptionalWhitespace:
+            if (isWhitespace(c))
+                continue;
+            hadNonWhitespace = true;
+            if (isTokenCharacter(c)) {
+                state = State::Token;
+                continue;
+            }
+            if (c == '"') {
+                state = State::QuotedString;
+                continue;
+            }
+            if (c == '(') {
+                ASSERT(!commentDepth);
+                ++commentDepth;
+                state = State::Comment;
+                continue;
+            }
+            return false;
+            
+        case State::Token:
+            if (isTokenCharacter(c))
+                continue;
+            state = State::OptionalWhitespace;
+            continue;
+        case State::QuotedString:
+            if (c == '"') {
+                state = State::OptionalWhitespace;
+                continue;
+            }
+            if (c == '\\') {
+                ++i;
+                if (i == value.length())
+                    return false;
+                if (!isQuotedPairSecondOctet(value[i]))
+                    return false;
+                continue;
+            }
+            if (!isQuotedTextCharacter(c))
+                return false;
+            continue;
+        case State::Comment:
+            if (c == '(') {
+                ++commentDepth;
+                continue;
+            }
+            if (c == ')') {
+                --commentDepth;
+                if (!commentDepth)
+                    state = State::OptionalWhitespace;
+                continue;
+            }
+            if (c == '\\') {
+                ++i;
+                if (i == value.length())
+                    return false;
+                if (!isQuotedPairSecondOctet(value[i]))
+                    return false;
+                continue;
+            }
+            if (!isCommentText(c))
+                return false;
+            continue;
+        }
+    }
+    
+    switch (state) {
+    case State::OptionalWhitespace:
+    case State::Token:
+        return hadNonWhitespace;
+    case State::QuotedString:
+    case State::Comment:
+        // Unclosed comments or quotes are invalid values.
+        break;
+    }
+    return false;
+}
+
+} // namespace RFC7230
+
+HTTPHeaderField::HTTPHeaderField(const String& field)
+{
+    size_t colonLocation = field.find(':');
+    if (colonLocation == notFound)
+        return;
+
+    StringView name = StringView(field).substring(0, colonLocation).stripLeadingAndTrailingMatchedCharacters(RFC7230::isWhitespace);
+    StringView value = StringView(field).substring(colonLocation + 1).stripLeadingAndTrailingMatchedCharacters(RFC7230::isWhitespace);
+    if (!RFC7230::isValidName(name) || !RFC7230::isValidValue(value))
+        return;
+
+    m_field = makeString(name, ':', ' ',  value);
+}
+
+}

Added: trunk/Source/WebCore/loader/HTTPHeaderField.h (0 => 222306)


--- trunk/Source/WebCore/loader/HTTPHeaderField.h	                        (rev 0)
+++ trunk/Source/WebCore/loader/HTTPHeaderField.h	2017-09-21 01:15:23 UTC (rev 222306)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class WEBCORE_EXPORT HTTPHeaderField {
+public:
+    HTTPHeaderField(const String&);
+    
+    const String& field() const { return m_field; }
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<HTTPHeaderField> decode(Decoder&);
+
+private:
+    String m_field;
+};
+
+template<class Encoder>
+void HTTPHeaderField::encode(Encoder& encoder) const
+{
+    encoder << m_field;
+}
+
+template<class Decoder>
+std::optional<HTTPHeaderField> HTTPHeaderField::decode(Decoder& decoder)
+{
+    std::optional<String> field;
+    decoder >> field;
+    if (!field)
+        return std::nullopt;
+
+    return {{ WTFMove(*field) }};
+}
+
+} // namespace WebCore

Modified: trunk/Source/WebKit/ChangeLog (222305 => 222306)


--- trunk/Source/WebKit/ChangeLog	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebKit/ChangeLog	2017-09-21 01:15:23 UTC (rev 222306)
@@ -1,3 +1,26 @@
+2017-09-20  Alex Christensen  <[email protected]>
+
+        Add infrastructure for adding custom headers to requests per website
+        https://bugs.webkit.org/show_bug.cgi?id=177255
+
+        Reviewed by Geoffrey Garen.
+
+        * Shared/WebsitePolicies.cpp: Added.
+        * Shared/WebsitePolicies.h:
+        (WebKit::WebsitePolicies::encode const):
+        (WebKit::WebsitePolicies::decode):
+        * UIProcess/API/APIWebsitePolicies.h:
+        * UIProcess/API/C/WKWebsitePolicies.cpp:
+        (WKWebsitePoliciesCopyCustomHeaderFields):
+        (WKWebsitePoliciesSetCustomHeaderFields):
+        * UIProcess/API/C/WKWebsitePolicies.h:
+        * UIProcess/API/Cocoa/_WKWebsitePolicies.h:
+        * UIProcess/API/Cocoa/_WKWebsitePolicies.mm:
+        (-[_WKWebsitePolicies customHeaderFields]):
+        (-[_WKWebsitePolicies setCustomHeaderFields:]):
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
+
 2017-09-20  Michael Catanzaro  <[email protected]>
 
         REGRESSION(r222194) [WPE] Library and executable output names broken

Modified: trunk/Source/WebKit/Shared/WebsitePolicies.h (222305 => 222306)


--- trunk/Source/WebKit/Shared/WebsitePolicies.h	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebKit/Shared/WebsitePolicies.h	2017-09-21 01:15:23 UTC (rev 222306)
@@ -25,9 +25,11 @@
 
 #pragma once
 
+#include <WebCore/HTTPHeaderField.h>
 #include <wtf/EnumTraits.h>
 #include <wtf/OptionSet.h>
 #include <wtf/Optional.h>
+#include <wtf/Vector.h>
 
 namespace WebKit {
 
@@ -48,6 +50,7 @@
     bool contentBlockersEnabled { true };
     OptionSet<WebsiteAutoplayQuirk> allowedAutoplayQuirks;
     WebsiteAutoplayPolicy autoplayPolicy { WebsiteAutoplayPolicy::Default };
+    Vector<WebCore::HTTPHeaderField> customHeaderFields;
 
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static std::optional<WebsitePolicies> decode(Decoder&);
@@ -76,6 +79,7 @@
     encoder << contentBlockersEnabled;
     encoder << autoplayPolicy;
     encoder << allowedAutoplayQuirks;
+    encoder << customHeaderFields;
 }
 
 template<class Decoder> std::optional<WebsitePolicies> WebsitePolicies::decode(Decoder& decoder)
@@ -94,11 +98,17 @@
     decoder >> allowedAutoplayQuirks;
     if (!allowedAutoplayQuirks)
         return std::nullopt;
+    
+    std::optional<Vector<WebCore::HTTPHeaderField>> customHeaderFields;
+    decoder >> customHeaderFields;
+    if (!customHeaderFields)
+        return std::nullopt;
 
     return { {
         WTFMove(*contentBlockersEnabled),
         WTFMove(*allowedAutoplayQuirks),
         WTFMove(*autoplayPolicy),
+        WTFMove(*customHeaderFields),
     } };
 }
 

Modified: trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.h (222305 => 222306)


--- trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.h	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.h	2017-09-21 01:15:23 UTC (rev 222306)
@@ -46,6 +46,9 @@
     WebKit::WebsiteAutoplayPolicy autoplayPolicy() const { return m_websitePolicies.autoplayPolicy; }
     void setAutoplayPolicy(WebKit::WebsiteAutoplayPolicy policy) { m_websitePolicies.autoplayPolicy = policy; }
 
+    void setCustomHeaderFields(Vector<WebCore::HTTPHeaderField>&& customHeaderFields) { m_websitePolicies.customHeaderFields = WTFMove(customHeaderFields); };
+    const Vector<WebCore::HTTPHeaderField> customHeaderFields() { return m_websitePolicies.customHeaderFields; }
+
     const WebKit::WebsitePolicies& websitePolicies() { return m_websitePolicies; }
     
 private:

Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsitePolicies.cpp (222305 => 222306)


--- trunk/Source/WebKit/UIProcess/API/C/WKWebsitePolicies.cpp	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsitePolicies.cpp	2017-09-21 01:15:23 UTC (rev 222306)
@@ -26,8 +26,10 @@
 #include "config.h"
 #include "WKWebsitePolicies.h"
 
+#include "APIArray.h"
 #include "APIWebsitePolicies.h"
 #include "WKAPICast.h"
+#include "WKArray.h"
 #include "WebsitePolicies.h"
 
 using namespace WebKit;
@@ -52,6 +54,30 @@
     return toImpl(websitePolicies)->contentBlockersEnabled();
 }
 
+WK_EXPORT WKArrayRef WKWebsitePoliciesCopyCustomHeaderFields(WKWebsitePoliciesRef websitePolicies)
+{
+    const auto& fields = toImpl(websitePolicies)->customHeaderFields();
+    Vector<RefPtr<API::Object>> strings;
+    strings.reserveInitialCapacity(fields.size());
+    for (const auto& field : fields)
+        strings.uncheckedAppend(API::String::create(field.field()));
+    return toAPI(API::Array::create(WTFMove(strings)).ptr());
+}
+
+WK_EXPORT void WKWebsitePoliciesSetCustomHeaderFields(WKWebsitePoliciesRef websitePolicies, WKArrayRef array)
+{
+    size_t length = WKArrayGetSize(array);
+    Vector<WebCore::HTTPHeaderField> fields;
+    fields.reserveInitialCapacity(length);
+    for (size_t i = 0; i < length; ++i) {
+        WebCore::HTTPHeaderField parsedField(toImpl(static_cast<WKStringRef>(WKArrayGetItemAtIndex(array, i)))->string());
+        if (!parsedField.field().isNull()
+            && parsedField.field().startsWithIgnoringASCIICase("X-")) // Let's just pretend RFC6648 never happened.
+            fields.uncheckedAppend(WTFMove(parsedField));
+    }
+    toImpl(websitePolicies)->setCustomHeaderFields(WTFMove(fields));
+}
+
 void WKWebsitePoliciesSetAllowedAutoplayQuirks(WKWebsitePoliciesRef websitePolicies, WKWebsiteAutoplayQuirk allowedQuirks)
 {
     OptionSet<WebsiteAutoplayQuirk> quirks;

Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsitePolicies.h (222305 => 222306)


--- trunk/Source/WebKit/UIProcess/API/C/WKWebsitePolicies.h	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsitePolicies.h	2017-09-21 01:15:23 UTC (rev 222306)
@@ -51,6 +51,9 @@
 WK_EXPORT bool WKWebsitePoliciesGetContentBlockersEnabled(WKWebsitePoliciesRef);
 WK_EXPORT void WKWebsitePoliciesSetContentBlockersEnabled(WKWebsitePoliciesRef, bool);
 
+WK_EXPORT WKArrayRef WKWebsitePoliciesCopyCustomHeaderFields(WKWebsitePoliciesRef);
+WK_EXPORT void WKWebsitePoliciesSetCustomHeaderFields(WKWebsitePoliciesRef, WKArrayRef);
+
 WK_EXPORT WKWebsiteAutoplayQuirk WKWebsitePoliciesGetAllowedAutoplayQuirks(WKWebsitePoliciesRef);
 WK_EXPORT void WKWebsitePoliciesSetAllowedAutoplayQuirks(WKWebsitePoliciesRef, WKWebsiteAutoplayQuirk);
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.h (222305 => 222306)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.h	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.h	2017-09-21 01:15:23 UTC (rev 222306)
@@ -45,6 +45,7 @@
 @property (nonatomic) BOOL contentBlockersEnabled;
 @property (nonatomic) _WKWebsiteAutoplayQuirk allowedAutoplayQuirks WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 @property (nonatomic) _WKWebsiteAutoplayPolicy autoplayPolicy WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+@property (nonatomic, copy, setter=setCustomHeaderFields:) NSArray<NSString *> *customHeaderFields WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 @end
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.mm (222305 => 222306)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.mm	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.mm	2017-09-21 01:15:23 UTC (rev 222306)
@@ -116,6 +116,28 @@
     }
 }
 
+- (NSArray<NSString *> *)customHeaderFields
+{
+    const auto& fields = _websitePolicies->customHeaderFields();
+    NSMutableArray *array = [[[NSMutableArray alloc] initWithCapacity:fields.size()] autorelease];
+    for (const auto& field : fields)
+        [array addObject:field.field()];
+    return array;
+}
+
+- (void)setCustomHeaderFields:(NSArray<NSString *> *)fields
+{
+    Vector<WebCore::HTTPHeaderField> parsedFields;
+    parsedFields.reserveInitialCapacity(fields.count);
+    for (NSString *string in fields) {
+        WebCore::HTTPHeaderField parsedField(string);
+        if (!parsedField.field().isNull()
+            && parsedField.field().startsWithIgnoringASCIICase("X-")) // Let's just pretend RFC6648 never happened.
+            parsedFields.uncheckedAppend(WTFMove(parsedField));
+    }
+    _websitePolicies->setCustomHeaderFields(WTFMove(parsedFields));
+}
+
 - (NSString *)description
 {
     return [NSString stringWithFormat:@"<%@: %p; contentBlockersEnabled = %d>", NSStringFromClass(self.class), self, self.contentBlockersEnabled];

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (222305 => 222306)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp	2017-09-21 01:15:23 UTC (rev 222306)
@@ -821,6 +821,8 @@
         return;
     }
 
+    documentLoader->setCustomHeaderFields(WTFMove(websitePolicies.customHeaderFields));
+    
     // Only setUserContentExtensionsEnabled if it hasn't already been disabled by reloading without content blockers.
     if (documentLoader->userContentExtensionsEnabled())
         documentLoader->setUserContentExtensionsEnabled(websitePolicies.contentBlockersEnabled);

Modified: trunk/Tools/ChangeLog (222305 => 222306)


--- trunk/Tools/ChangeLog	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Tools/ChangeLog	2017-09-21 01:15:23 UTC (rev 222306)
@@ -1,3 +1,19 @@
+2017-09-20  Alex Christensen  <[email protected]>
+
+        Add infrastructure for adding custom headers to requests per website
+        https://bugs.webkit.org/show_bug.cgi?id=177255
+
+        Reviewed by Geoffrey Garen.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/HTTPHeaderField.cpp: Added.
+        (shouldRemainUnchanged):
+        (shouldBeInvalid):
+        (shouldBecome):
+        (TEST):
+        * TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm:
+        (TEST):
+
 2017-09-20  Daniel Bates  <[email protected]>
 
         Spelling and grammar dots should not overlap

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (222305 => 222306)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2017-09-21 01:15:23 UTC (rev 222306)
@@ -235,6 +235,7 @@
 		5C9E59411D3EB5AC00E3C62E /* ApplicationCache.db in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5C9E593E1D3EB1DE00E3C62E /* ApplicationCache.db */; };
 		5C9E59421D3EB5AC00E3C62E /* ApplicationCache.db-shm in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5C9E593F1D3EB1DE00E3C62E /* ApplicationCache.db-shm */; };
 		5C9E59431D3EB5AC00E3C62E /* ApplicationCache.db-wal in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5C9E59401D3EB1DE00E3C62E /* ApplicationCache.db-wal */; };
+		5CA1DEC81F71F70100E71BD3 /* HTTPHeaderField.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CA1DEC71F71F40700E71BD3 /* HTTPHeaderField.cpp */; };
 		5CB18BA81F5645E300EE23C4 /* ClickAutoFillButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5CB18BA71F5645B200EE23C4 /* ClickAutoFillButton.mm */; };
 		5CB40B4E1F4B98D3007DC7B9 /* UIDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5CB40B4D1F4B98BE007DC7B9 /* UIDelegate.mm */; };
 		5CE354D91E70DA5C00BEFE3B /* WKContentExtensionStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5CE354D81E70D9C300BEFE3B /* WKContentExtensionStore.mm */; };
@@ -1331,6 +1332,7 @@
 		5C9E593E1D3EB1DE00E3C62E /* ApplicationCache.db */ = {isa = PBXFileReference; lastKnownFileType = file; path = ApplicationCache.db; sourceTree = "<group>"; };
 		5C9E593F1D3EB1DE00E3C62E /* ApplicationCache.db-shm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ApplicationCache.db-shm"; sourceTree = "<group>"; };
 		5C9E59401D3EB1DE00E3C62E /* ApplicationCache.db-wal */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ApplicationCache.db-wal"; sourceTree = "<group>"; };
+		5CA1DEC71F71F40700E71BD3 /* HTTPHeaderField.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPHeaderField.cpp; sourceTree = "<group>"; };
 		5CB18BA71F5645B200EE23C4 /* ClickAutoFillButton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ClickAutoFillButton.mm; sourceTree = "<group>"; };
 		5CB40B4D1F4B98BE007DC7B9 /* UIDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UIDelegate.mm; sourceTree = "<group>"; };
 		5CE354D81E70D9C300BEFE3B /* WKContentExtensionStore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKContentExtensionStore.mm; sourceTree = "<group>"; };
@@ -2082,6 +2084,7 @@
 				1CAD1F851E5CE7DA00AF2C2C /* FontCache.cpp */,
 				8E4A85361E1D1AA100F53B0F /* GridPosition.cpp */,
 				83B88A331C80056D00BB2418 /* HTMLParserIdioms.cpp */,
+				5CA1DEC71F71F40700E71BD3 /* HTTPHeaderField.cpp */,
 				7A909A731D877475007E10F8 /* IntPoint.cpp */,
 				7A909A741D877475007E10F8 /* IntRect.cpp */,
 				7A909A751D877475007E10F8 /* IntSize.cpp */,
@@ -3241,6 +3244,7 @@
 				7CCE7EC11A411A7E00447C4C /* HTMLCollectionNamedItem.mm in Sources */,
 				7CCE7EC21A411A7E00447C4C /* HTMLFormCollectionNamedItem.mm in Sources */,
 				7C83E0501D0A641800FEBCF3 /* HTMLParserIdioms.cpp in Sources */,
+				5CA1DEC81F71F70100E71BD3 /* HTTPHeaderField.cpp in Sources */,
 				51AF23DF1EF1A3730072F281 /* IconLoadingDelegate.mm in Sources */,
 				510477781D29923B009747EB /* IDBDeleteRecovery.mm in Sources */,
 				5110FCFA1E01CDB8006F8D0B /* IDBIndexUpgradeToV2.mm in Sources */,
@@ -3282,6 +3286,7 @@
 				46C519DA1D355AB200DAA51A /* LocalStorageNullEntries.mm in Sources */,
 				7A6A2C701DCCFA8C00C0D085 /* LocalStorageQuirkTest.mm in Sources */,
 				076E507F1F4513D6006E9F5A /* Logging.cpp in Sources */,
+				CE1866491F72E8F100A0CAB6 /* MarkerSubrange.cpp in Sources */,
 				CDA315981ED53651009F60D3 /* MediaPlaybackSleepAssertion.mm in Sources */,
 				CDC9442E1EF1FC080059C3C4 /* MediaStreamTrackDetached.mm in Sources */,
 				7CCE7EB21A411A5100447C4C /* MemoryCacheAddImageToCacheIOS.mm in Sources */,
@@ -3372,7 +3377,6 @@
 				7CCE7ED11A411A7E00447C4C /* StringTruncator.mm in Sources */,
 				ECA680CE1E68CC0900731D20 /* StringUtilities.mm in Sources */,
 				CE4D5DE71F6743BA0072CFC6 /* StringWithDirection.cpp in Sources */,
-				CE1866491F72E8F100A0CAB6 /* MarkerSubrange.cpp in Sources */,
 				7CCE7ED21A411A7E00447C4C /* SubresourceErrorCrash.mm in Sources */,
 				7CCE7EA81A411A1900447C4C /* SyntheticBackingScaleFactorWindow.m in Sources */,
 				7CCE7F161A411AE600447C4C /* TerminateTwice.cpp in Sources */,

Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/HTTPHeaderField.cpp (0 => 222306)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/HTTPHeaderField.cpp	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/HTTPHeaderField.cpp	2017-09-21 01:15:23 UTC (rev 222306)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "Test.h"
+#include <WebCore/HTTPHeaderField.h>
+
+static void shouldRemainUnchanged(Vector<String>&& strings)
+{
+    for (const auto& string : strings)
+        EXPECT_TRUE(WebCore::HTTPHeaderField(string).field() == string);
+}
+
+static void shouldBeInvalid(Vector<String>&& strings)
+{
+    for (const auto& string : strings)
+        EXPECT_TRUE(WebCore::HTTPHeaderField(string).field() == String());
+}
+
+static void shouldBecome(Vector<std::pair<String, String>>&& pairs)
+{
+    for (const auto& pair : pairs)
+        EXPECT_TRUE(WebCore::HTTPHeaderField(pair.first).field() == pair.second);
+}
+
+TEST(HTTPHeaderField, Parser)
+{
+    static const char nonASCIIComment[8] = {'a', ':', ' ', '(', 0x21, static_cast<char>(0xFF), ')', '\0'};
+    static const char nonASCIIQuotedPairInComment[8] = {'a', ':', ' ', '(', '\\', static_cast<char>(0xFF), ')', '\0'};
+    static const char nonASCIIQuotedPairInQuote[8] = {'a', ':', ' ', '"', '\\', static_cast<char>(0xFF), '"', '\0'};
+    static const char delInQuote[7] = {'a', ':', ' ', '"', static_cast<char>(0x7F), '"', '\0'};
+
+    shouldRemainUnchanged({
+        "a: b",
+        "a: b c",
+        "!: b",
+        "a: ()",
+        "a: (\\ )",
+        "a: (())",
+        "a: \"\"",
+        "a: \"aA?\t \"",
+        "a: \"a\" (b) ((c))",
+        nonASCIIComment,
+        nonASCIIQuotedPairInComment,
+        nonASCIIQuotedPairInQuote,
+    });
+    
+    shouldBeInvalid({
+        "a:",
+        "a: ",
+        "a: \rb",
+        "a: \nb",
+        "a: \vb",
+        "\a: b",
+        "?: b",
+        "a: \ab",
+        "a: (\\\a)",
+        "a: (\\\a)",
+        "a: (",
+        "a: (()",
+        "a: (\a)",
+        "a: \"\a\"",
+        "a: \"a\" (b)}((c))",
+        delInQuote,
+    });
+    
+    shouldBecome({
+        { "a: b ", "a: b" },
+        { " a: b", "a: b" },
+        { "a: \tb", "a: b" },
+        { " a: b c ", "a: b c" },
+        { "a:  b ", "a: b" },
+        { "a:\tb", "a: b" },
+        { "\ta:\t b\t", "a: b" },
+        { "a: \"a\" (b) ", "a: \"a\" (b)" },
+    });
+}

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm (222305 => 222306)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm	2017-09-21 01:10:47 UTC (rev 222305)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm	2017-09-21 01:15:23 UTC (rev 222306)
@@ -622,6 +622,18 @@
     [webView stringByEvaluatingJavaScript:@"play()"];
     [webView waitForMessage:@"playing"];
 }
-#endif
+#endif // PLATFORM(MAC)
 
-#endif
+TEST(WebKit, InvalidCustomHeaders)
+{
+    auto websitePolicies = adoptNS([[_WKWebsitePolicies alloc] init]);
+    [websitePolicies setCustomHeaderFields:@[@"invalidheader:", @"noncustom: header", @"X-custom: header", @"    x-Custom :  Needs Canonicalization\t "]];
+    NSArray<NSString *> *canonicalized = [websitePolicies customHeaderFields];
+    EXPECT_EQ(canonicalized.count, 2u);
+    EXPECT_STREQ([canonicalized objectAtIndex:0].UTF8String, "X-custom: header");
+    EXPECT_STREQ([canonicalized objectAtIndex:1].UTF8String, "x-Custom: Needs Canonicalization");
+}
+
+// FIXME: Apply the custom headers from the DocumentLoader to each request and test that they are sent on main resource and subresources.
+
+#endif // WK_API_ENABLED
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to