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