Title: [277336] trunk
Revision
277336
Author
[email protected]
Date
2021-05-11 12:47:50 -0700 (Tue, 11 May 2021)

Log Message

Add SPI to restrict networking to a set of hosts
https://bugs.webkit.org/show_bug.cgi?id=225426
<rdar://77571521>

Patch by Alex Christensen <[email protected]> on 2021-05-11
Reviewed by Tim Horton.

Source/WebCore:

In r259392 I added SPI to turn network access on and off, but a client needs finer grained control.
This uses the same infrastructure to add a set of hosts to allow.  Setting it to nil (the default) allows all hosts,
but setting it to an empty set allows no network access.  This accomplishes the same ability as the old SPI, so I'm deprecating it
with this as a replacement.  The new ability to specify a finite number of hosts to allow creates a limited WKWebView.

* Modules/websockets/ThreadableWebSocketChannel.cpp:
(WebCore::ThreadableWebSocketChannel::validateURL):
* loader/ResourceLoadNotifier.cpp:
(WebCore::ResourceLoadNotifier::dispatchWillSendRequest):
* page/Page.cpp:
(WebCore::Page::allowsLoadFromURL const):
* page/Page.h:
(WebCore::Page::loadsFromNetwork const): Deleted.
* page/PageConfiguration.h:

Source/WebKit:

* Shared/WebPageCreationParameters.cpp:
(WebKit::WebPageCreationParameters::encode const):
(WebKit::WebPageCreationParameters::decode):
* Shared/WebPageCreationParameters.h:
* UIProcess/API/APIPageConfiguration.cpp:
(API::PageConfiguration::copy const):
* UIProcess/API/APIPageConfiguration.h:
(API::PageConfiguration::allowedNetworkHosts const):
(API::PageConfiguration::setAllowedNetworkHosts):
(API::PageConfiguration::loadsFromNetwork const): Deleted.
(API::PageConfiguration::setLoadsFromNetwork): Deleted.
* UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
(-[WKWebViewConfiguration _setLoadsFromNetwork:]):
(-[WKWebViewConfiguration _loadsFromNetwork]):
(-[WKWebViewConfiguration _setAllowedNetworkHosts:]):
(-[WKWebViewConfiguration _allowedNetworkHosts]):
* UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::creationParameters):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::m_lastNavigationWasAppBound):

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm:
(TEST):
(webSocketAcceptValue): Deleted.
* TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm:
* TestWebKitAPI/cocoa/HTTPServer.h:
(TestWebKitAPI::Connection::webSocketHandshake):
* TestWebKitAPI/cocoa/HTTPServer.mm:
(TestWebKitAPI::Connection::webSocketHandshake):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (277335 => 277336)


--- trunk/Source/WebCore/ChangeLog	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebCore/ChangeLog	2021-05-11 19:47:50 UTC (rev 277336)
@@ -1,3 +1,26 @@
+2021-05-11  Alex Christensen  <[email protected]>
+
+        Add SPI to restrict networking to a set of hosts
+        https://bugs.webkit.org/show_bug.cgi?id=225426
+        <rdar://77571521>
+
+        Reviewed by Tim Horton.
+
+        In r259392 I added SPI to turn network access on and off, but a client needs finer grained control.
+        This uses the same infrastructure to add a set of hosts to allow.  Setting it to nil (the default) allows all hosts,
+        but setting it to an empty set allows no network access.  This accomplishes the same ability as the old SPI, so I'm deprecating it
+        with this as a replacement.  The new ability to specify a finite number of hosts to allow creates a limited WKWebView.
+
+        * Modules/websockets/ThreadableWebSocketChannel.cpp:
+        (WebCore::ThreadableWebSocketChannel::validateURL):
+        * loader/ResourceLoadNotifier.cpp:
+        (WebCore::ResourceLoadNotifier::dispatchWillSendRequest):
+        * page/Page.cpp:
+        (WebCore::Page::allowsLoadFromURL const):
+        * page/Page.h:
+        (WebCore::Page::loadsFromNetwork const): Deleted.
+        * page/PageConfiguration.h:
+
 2021-05-11  Megan Gardner  <[email protected]>
 
         Factor out find bounce layer

Modified: trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp (277335 => 277336)


--- trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp	2021-05-11 19:47:50 UTC (rev 277336)
@@ -89,7 +89,7 @@
 {
     ValidatedURL validatedURL { requestedURL, true };
     if (auto* page = document.page()) {
-        if (!page->loadsFromNetwork())
+        if (!page->allowsLoadFromURL(requestedURL))
             return { };
 #if ENABLE(CONTENT_EXTENSIONS)
         if (auto* documentLoader = document.loader()) {

Modified: trunk/Source/WebCore/loader/ResourceLoadNotifier.cpp (277335 => 277336)


--- trunk/Source/WebCore/loader/ResourceLoadNotifier.cpp	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebCore/loader/ResourceLoadNotifier.cpp	2021-05-11 19:47:50 UTC (rev 277336)
@@ -137,7 +137,7 @@
         if (!page->loadsSubresources()) {
             if (!m_frame.isMainFrame() || (m_initialRequestIdentifier && *m_initialRequestIdentifier != identifier))
                 request = { };
-        } else if (!page->loadsFromNetwork() && request.url().protocolIsInHTTPFamily())
+        } else if (!page->allowsLoadFromURL(request.url()))
             request = { };
     }
     

Modified: trunk/Source/WebCore/page/Page.cpp (277335 => 277336)


--- trunk/Source/WebCore/page/Page.cpp	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebCore/page/Page.cpp	2021-05-11 19:47:50 UTC (rev 277336)
@@ -305,8 +305,8 @@
     , m_deviceOrientationUpdateProvider(WTFMove(pageConfiguration.deviceOrientationUpdateProvider))
 #endif
     , m_corsDisablingPatterns(WTFMove(pageConfiguration.corsDisablingPatterns))
+    , m_allowedNetworkHosts(WTFMove(pageConfiguration.allowedNetworkHosts))
     , m_loadsSubresources(pageConfiguration.loadsSubresources)
-    , m_loadsFromNetwork(pageConfiguration.loadsFromNetwork)
     , m_shouldRelaxThirdPartyCookieBlocking(pageConfiguration.shouldRelaxThirdPartyCookieBlocking)
     , m_httpsUpgradeEnabled(pageConfiguration.httpsUpgradeEnabled)
 {
@@ -3299,6 +3299,15 @@
 #endif
 }
 
+bool Page::allowsLoadFromURL(const URL& url) const
+{
+    if (!m_allowedNetworkHosts)
+        return true;
+    if (!url.protocolIsInHTTPFamily() && !url.protocolIs("ws") && !url.protocolIs("wss"))
+        return true;
+    return m_allowedNetworkHosts->contains(url.host().toStringWithoutCopying());
+}
+
 void Page::applicationWillResignActive()
 {
 #if ENABLE(VIDEO)

Modified: trunk/Source/WebCore/page/Page.h (277335 => 277336)


--- trunk/Source/WebCore/page/Page.h	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebCore/page/Page.h	2021-05-11 19:47:50 UTC (rev 277336)
@@ -794,7 +794,7 @@
     bool isUtilityPage() const { return m_isUtilityPage; }
 
     bool loadsSubresources() const { return m_loadsSubresources; }
-    bool loadsFromNetwork() const { return m_loadsFromNetwork; }
+    bool allowsLoadFromURL(const URL&) const;
     ShouldRelaxThirdPartyCookieBlocking shouldRelaxThirdPartyCookieBlocking() const { return m_shouldRelaxThirdPartyCookieBlocking; }
 
     bool isLowPowerModeEnabled() const { return m_throttlingReasons.contains(ThrottlingReason::LowPowerMode); }
@@ -1142,9 +1142,9 @@
 
     Vector<UserContentURLPattern> m_corsDisablingPatterns;
     Vector<UserStyleSheet> m_userStyleSheetsPendingInjection;
+    Optional<HashSet<String>> m_allowedNetworkHosts;
     bool m_isTakingSnapshotsForApplicationSuspension { false };
     bool m_loadsSubresources { true };
-    bool m_loadsFromNetwork { true };
     bool m_canUseCredentialStorage { true };
     ShouldRelaxThirdPartyCookieBlocking m_shouldRelaxThirdPartyCookieBlocking { ShouldRelaxThirdPartyCookieBlocking::No };
     LoadSchedulingMode m_loadSchedulingMode { LoadSchedulingMode::Direct };

Modified: trunk/Source/WebCore/page/PageConfiguration.h (277335 => 277336)


--- trunk/Source/WebCore/page/PageConfiguration.h	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebCore/page/PageConfiguration.h	2021-05-11 19:47:50 UTC (rev 277336)
@@ -132,7 +132,7 @@
 
     // FIXME: These should be all be Settings.
     bool loadsSubresources { true };
-    bool loadsFromNetwork { true };
+    Optional<HashSet<String>> allowedNetworkHosts;
     bool userScriptsShouldWaitUntilNotification { true };
     ShouldRelaxThirdPartyCookieBlocking shouldRelaxThirdPartyCookieBlocking { ShouldRelaxThirdPartyCookieBlocking::No };
     bool httpsUpgradeEnabled { true };

Modified: trunk/Source/WebKit/ChangeLog (277335 => 277336)


--- trunk/Source/WebKit/ChangeLog	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebKit/ChangeLog	2021-05-11 19:47:50 UTC (rev 277336)
@@ -1,3 +1,33 @@
+2021-05-11  Alex Christensen  <[email protected]>
+
+        Add SPI to restrict networking to a set of hosts
+        https://bugs.webkit.org/show_bug.cgi?id=225426
+        <rdar://77571521>
+
+        Reviewed by Tim Horton.
+
+        * Shared/WebPageCreationParameters.cpp:
+        (WebKit::WebPageCreationParameters::encode const):
+        (WebKit::WebPageCreationParameters::decode):
+        * Shared/WebPageCreationParameters.h:
+        * UIProcess/API/APIPageConfiguration.cpp:
+        (API::PageConfiguration::copy const):
+        * UIProcess/API/APIPageConfiguration.h:
+        (API::PageConfiguration::allowedNetworkHosts const):
+        (API::PageConfiguration::setAllowedNetworkHosts):
+        (API::PageConfiguration::loadsFromNetwork const): Deleted.
+        (API::PageConfiguration::setLoadsFromNetwork): Deleted.
+        * UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
+        (-[WKWebViewConfiguration _setLoadsFromNetwork:]):
+        (-[WKWebViewConfiguration _loadsFromNetwork]):
+        (-[WKWebViewConfiguration _setAllowedNetworkHosts:]):
+        (-[WKWebViewConfiguration _allowedNetworkHosts]):
+        * UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::creationParameters):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::m_lastNavigationWasAppBound):
+
 2021-05-11  Brent Fulgham  <[email protected]>
 
         [macOS] Extend access to 'com.apple.print.normalizerd' when canvas drawing is done in the WebContent process

Modified: trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp (277335 => 277336)


--- trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp	2021-05-11 19:47:50 UTC (rev 277336)
@@ -151,7 +151,7 @@
     encoder << overriddenMediaType;
     encoder << corsDisablingPatterns;
     encoder << loadsSubresources;
-    encoder << loadsFromNetwork;
+    encoder << allowedNetworkHosts;
     encoder << userScriptsShouldWaitUntilNotification;
     encoder << crossOriginAccessControlCheckEnabled;
     encoder << processDisplayName;
@@ -509,11 +509,11 @@
         return WTF::nullopt;
     parameters.loadsSubresources = *loadsSubresources;
 
-    Optional<bool> loadsFromNetwork;
-    decoder >> loadsFromNetwork;
-    if (!loadsFromNetwork)
+    Optional<Optional<HashSet<String>>> allowedNetworkHosts;
+    decoder >> allowedNetworkHosts;
+    if (!allowedNetworkHosts)
         return WTF::nullopt;
-    parameters.loadsFromNetwork = *loadsFromNetwork;
+    parameters.allowedNetworkHosts = *allowedNetworkHosts;
 
     Optional<bool> userScriptsShouldWaitUntilNotification;
     decoder >> userScriptsShouldWaitUntilNotification;

Modified: trunk/Source/WebKit/Shared/WebPageCreationParameters.h (277335 => 277336)


--- trunk/Source/WebKit/Shared/WebPageCreationParameters.h	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebKit/Shared/WebPageCreationParameters.h	2021-05-11 19:47:50 UTC (rev 277336)
@@ -222,7 +222,7 @@
     Vector<String> corsDisablingPatterns;
     bool userScriptsShouldWaitUntilNotification { true };
     bool loadsSubresources { true };
-    bool loadsFromNetwork { true };
+    Optional<HashSet<String>> allowedNetworkHosts;
 
     bool crossOriginAccessControlCheckEnabled { true };
     String processDisplayName;

Modified: trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp (277335 => 277336)


--- trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp	2021-05-11 19:47:50 UTC (rev 277336)
@@ -87,7 +87,7 @@
 
     copy->m_processDisplayName = this->m_processDisplayName;
     copy->m_loadsSubresources = this->m_loadsSubresources;
-    copy->m_loadsFromNetwork = this->m_loadsFromNetwork;
+    copy->m_allowedNetworkHosts = this->m_allowedNetworkHosts;
 #if ENABLE(APP_BOUND_DOMAINS)
     copy->m_ignoresAppBoundDomains = this->m_ignoresAppBoundDomains;
     copy->m_limitsNavigationsToAppBoundDomains = this->m_limitsNavigationsToAppBoundDomains;

Modified: trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h (277335 => 277336)


--- trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h	2021-05-11 19:47:50 UTC (rev 277336)
@@ -30,6 +30,7 @@
 #include <wtf/Forward.h>
 #include <wtf/GetPtr.h>
 #include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
 #include <wtf/text/WTFString.h>
 
 #if PLATFORM(IOS_FAMILY)
@@ -146,8 +147,8 @@
     bool loadsSubresources() const { return m_loadsSubresources; }
     void setLoadsSubresources(bool loads) { m_loadsSubresources = loads; }
 
-    bool loadsFromNetwork() const { return m_loadsFromNetwork; }
-    void setLoadsFromNetwork(bool loads) { m_loadsFromNetwork = loads; }
+    const Optional<HashSet<WTF::String>>& allowedNetworkHosts() const { return m_allowedNetworkHosts; }
+    void setAllowedNetworkHosts(Optional<HashSet<WTF::String>>&& hosts) { m_allowedNetworkHosts = WTFMove(hosts); }
 
 #if ENABLE(APP_BOUND_DOMAINS)
     bool ignoresAppBoundDomains() const { return m_ignoresAppBoundDomains; }
@@ -205,7 +206,7 @@
     bool m_crossOriginAccessControlCheckEnabled { true };
     WTF::String m_processDisplayName;
     bool m_loadsSubresources { true };
-    bool m_loadsFromNetwork { true };
+    Optional<HashSet<WTF::String>> m_allowedNetworkHosts;
     
 #if ENABLE(APP_BOUND_DOMAINS)
     bool m_ignoresAppBoundDomains { false };

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm (277335 => 277336)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm	2021-05-11 19:47:50 UTC (rev 277336)
@@ -952,14 +952,35 @@
 
 - (void)_setLoadsFromNetwork:(BOOL)loads
 {
-    _pageConfiguration->setLoadsFromNetwork(loads);
+    _pageConfiguration->setAllowedNetworkHosts(loads ? WTF::nullopt : Optional<HashSet<String>> { HashSet<String> { } });
 }
 
 - (BOOL)_loadsFromNetwork
 {
-    return _pageConfiguration->loadsFromNetwork();
+    return _pageConfiguration->allowedNetworkHosts() == WTF::nullopt;
 }
 
+- (void)_setAllowedNetworkHosts:(NSSet<NSString *> *)hosts
+{
+    if (!hosts)
+        return _pageConfiguration->setAllowedNetworkHosts(WTF::nullopt);
+    HashSet<String> set;
+    for (NSString *host in hosts)
+        set.add(host);
+    _pageConfiguration->setAllowedNetworkHosts(WTFMove(set));
+}
+
+- (NSSet<NSString *> *)_allowedNetworkHosts
+{
+    const auto& hosts = _pageConfiguration->allowedNetworkHosts();
+    if (!hosts)
+        return nil;
+    NSMutableSet<NSString *> *set = [NSMutableSet setWithCapacity:hosts->size()];
+    for (const auto& host : *hosts)
+        [set addObject:host];
+    return set;
+}
+
 - (void)_setLoadsSubresources:(BOOL)loads
 {
     _pageConfiguration->setLoadsSubresources(loads);

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h (277335 => 277336)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h	2021-05-11 19:47:50 UTC (rev 277336)
@@ -79,7 +79,8 @@
 @property (nonatomic, setter=_setDeferrableUserScriptsShouldWaitUntilNotification:) BOOL _deferrableUserScriptsShouldWaitUntilNotification WK_API_AVAILABLE(macos(11.0), ios(14.0));
 @property (nonatomic, setter=_setCrossOriginAccessControlCheckEnabled:) BOOL _crossOriginAccessControlCheckEnabled WK_API_AVAILABLE(macos(11.0), ios(14.0));
 
-@property (nonatomic, setter=_setLoadsFromNetwork:) BOOL _loadsFromNetwork WK_API_AVAILABLE(macos(11.0), ios(14.0));
+@property (nonatomic, setter=_setLoadsFromNetwork:) BOOL _loadsFromNetwork WK_API_DEPRECATED_WITH_REPLACEMENT("_allowedNetworkHosts", macos(11.0, WK_MAC_TBA), ios(14.0, WK_IOS_TBA));
+@property (nonatomic, copy, setter=_setAllowedNetworkHosts:) NSSet<NSString *> *_allowedNetworkHosts WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 @property (nonatomic, setter=_setLoadsSubresources:) BOOL _loadsSubresources WK_API_AVAILABLE(macos(11.0), ios(14.0));
 @property (nonatomic, setter=_setIgnoresAppBoundDomains:) BOOL _ignoresAppBoundDomains WK_API_AVAILABLE(macos(11.0), ios(14.0));
 

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (277335 => 277336)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-05-11 19:47:50 UTC (rev 277336)
@@ -8033,7 +8033,7 @@
     parameters.overriddenMediaType = m_overriddenMediaType;
     parameters.corsDisablingPatterns = corsDisablingPatterns();
     parameters.userScriptsShouldWaitUntilNotification = m_configuration->userScriptsShouldWaitUntilNotification();
-    parameters.loadsFromNetwork = m_configuration->loadsFromNetwork();
+    parameters.allowedNetworkHosts = m_configuration->allowedNetworkHosts();
     parameters.loadsSubresources = m_configuration->loadsSubresources();
     parameters.crossOriginAccessControlCheckEnabled = m_configuration->crossOriginAccessControlCheckEnabled();
     parameters.hasResourceLoadClient = !!m_resourceLoadClient;

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (277335 => 277336)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-05-11 19:47:50 UTC (rev 277336)
@@ -605,7 +605,7 @@
 
     pageConfiguration.userScriptsShouldWaitUntilNotification = parameters.userScriptsShouldWaitUntilNotification;
     pageConfiguration.loadsSubresources = parameters.loadsSubresources;
-    pageConfiguration.loadsFromNetwork = parameters.loadsFromNetwork;
+    pageConfiguration.allowedNetworkHosts = parameters.allowedNetworkHosts;
     pageConfiguration.shouldRelaxThirdPartyCookieBlocking = parameters.shouldRelaxThirdPartyCookieBlocking;
     pageConfiguration.httpsUpgradeEnabled = parameters.httpsUpgradeEnabled;
 

Modified: trunk/Tools/ChangeLog (277335 => 277336)


--- trunk/Tools/ChangeLog	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Tools/ChangeLog	2021-05-11 19:47:50 UTC (rev 277336)
@@ -1,3 +1,20 @@
+2021-05-11  Alex Christensen  <[email protected]>
+
+        Add SPI to restrict networking to a set of hosts
+        https://bugs.webkit.org/show_bug.cgi?id=225426
+        <rdar://77571521>
+
+        Reviewed by Tim Horton.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm:
+        (TEST):
+        (webSocketAcceptValue): Deleted.
+        * TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm:
+        * TestWebKitAPI/cocoa/HTTPServer.h:
+        (TestWebKitAPI::Connection::webSocketHandshake):
+        * TestWebKitAPI/cocoa/HTTPServer.mm:
+        (TestWebKitAPI::Connection::webSocketHandshake):
+
 2021-05-11  Diego Pino Garcia  <[email protected]>
 
         [GTK] compositing/overflow/dynamic-composited-scrolling-status.html is failing

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm (277335 => 277336)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm	2021-05-11 19:47:50 UTC (rev 277336)
@@ -43,10 +43,8 @@
 #import <WebKit/_WKContentRuleListAction.h>
 #import <WebKit/_WKWebsiteDataStoreConfiguration.h>
 #import <wtf/RetainPtr.h>
-#import <wtf/SHA1.h>
 #import <wtf/URL.h>
 #import <wtf/cocoa/VectorCocoa.h>
-#import <wtf/text/Base64.h>
 #import <wtf/text/WTFString.h>
 
 static bool receivedNotification;
@@ -221,34 +219,11 @@
     EXPECT_TRUE(expectedNotifications == notificationList);
 }
 
-static String webSocketAcceptValue(const Vector<char>& request)
-{
-    constexpr auto* keyHeaderField = "Sec-WebSocket-Key: ";
-    const char* keyBegin = strnstr(request.data(), keyHeaderField, request.size()) + strlen(keyHeaderField);
-    EXPECT_NOT_NULL(keyBegin);
-    const char* keyEnd = strnstr(keyBegin, "\r\n", request.size() + (keyBegin - request.data()));
-    EXPECT_NOT_NULL(keyEnd);
-
-    constexpr auto* webSocketKeyGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
-    SHA1 sha1;
-    sha1.addBytes(reinterpret_cast<const uint8_t*>(keyBegin), keyEnd - keyBegin);
-    sha1.addBytes(reinterpret_cast<const uint8_t*>(webSocketKeyGUID), strlen(webSocketKeyGUID));
-    SHA1::Digest hash;
-    sha1.computeHash(hash);
-    return base64Encode(hash.data(), SHA1::hashSize);
-}
-
 TEST(ContentRuleList, ResourceTypes)
 {
     using namespace TestWebKitAPI;
     HTTPServer webSocketServer([](Connection connection) {
-        connection.receiveHTTPRequest([=](Vector<char>&& request) {
-            connection.send(HTTPResponse(101, {
-                { "Upgrade", "websocket" },
-                { "Connection", "Upgrade" },
-                { "Sec-WebSocket-Accept", webSocketAcceptValue(request) }
-            }).serialize(HTTPResponse::IncludeContentLength::No));
-        });
+        connection.webSocketHandshake();
     });
     auto serverPort = webSocketServer.port();
 

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm (277335 => 277336)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm	2021-05-11 19:47:50 UTC (rev 277336)
@@ -48,6 +48,7 @@
 #import <wtf/Threading.h>
 #import <wtf/Vector.h>
 #import <wtf/WeakObjCPtr.h>
+#import <wtf/text/StringConcatenateNumbers.h>
 #import <wtf/text/StringHash.h>
 #import <wtf/text/WTFString.h>
 
@@ -1100,12 +1101,17 @@
 
 TEST(URLSchemeHandler, LoadsFromNetwork)
 {
-    TestWebKitAPI::HTTPServer server({
+    using namespace TestWebKitAPI;
+    HTTPServer server({
         { "/", { {{ "Access-Control-Allow-Origin", "*" }}, "test content" } }
     });
 
-    bool loadSuccess = false;
-    bool loadFail = false;
+    HTTPServer webSocketServer([](Connection connection) {
+        connection.webSocketHandshake();
+    });
+
+    Optional<bool> loadSuccess;
+    Optional<bool> webSocketSuccess;
     bool done = false;
 
     auto handler = adoptNS([TestURLSchemeHandler new]);
@@ -1114,50 +1120,139 @@
     [configuration setURLSchemeHandler:handler.get() forURLScheme:@"test"];
 
     [handler setStartURLSchemeTaskHandler:[&](WKWebView *, id<WKURLSchemeTask> task) {
-        if ([task.request.URL.path isEqualToString:@"/main.html"]) {
-            NSData *data = "" stringWithFormat:@"<script>"
-                "fetch('http://127.0.0.1:%d/').then(()=>{"
-                    "fetch('/loadSuccess')"
+        NSString *path = task.request.URL.path;
+        if ([path isEqualToString:@"/main.html"]) {
+            respond(task, [NSString stringWithFormat:@"<script>"
+                "function checkWebSockets() {"
+                    "var ws = new WebSocket('ws://127.0.0.1:%d');"
+                    "ws._onerror_ = function() { fetch('/webSocketFail') };"
+                    "ws._onopen_ = function() { fetch('/webSocketSuccess') };"
+                "}"
+                "fetch('http://localhost:%d/').then(()=>{"
+                    "fetch('/loadSuccess').then(()=>{ checkWebSockets() })"
                 "}).catch(()=>{"
-                    "var ws = new WebSocket('ws://127.0.0.1:%d');"
-                    "ws._onerror_ = function() { fetch('/loadFail') };"
+                    "fetch('/loadFail').then(()=>{ checkWebSockets() })"
                 "})"
-                "</script>", server.port(), server.port()] dataUsingEncoding:NSUTF8StringEncoding];
-            [task didReceiveResponse:adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:data.length textEncodingName:nil]).get()];
-            [task didReceiveData:data];
-            [task didFinish];
-        } else if ([task.request.URL.path isEqualToString:@"/loadSuccess"]) {
+                "</script>", webSocketServer.port(), server.port()].UTF8String);
+        } else if ([path isEqualToString:@"/loadSuccess"]) {
+            respond(task, "hi");
             loadSuccess = true;
+        } else if ([path isEqualToString:@"/loadFail"]) {
+            respond(task, "hi");
+            loadSuccess = false;
+        } else if ([path isEqualToString:@"/webSocketSuccess"]) {
+            webSocketSuccess = true;
             done = true;
-        } else if ([task.request.URL.path isEqualToString:@"/loadFail"]) {
-            loadFail = true;
+        } else if ([path isEqualToString:@"/webSocketFail"]) {
+            webSocketSuccess = false;
             done = true;
         } else
             ASSERT_NOT_REACHED();
     }];
     
-    {
+    auto runTest = [&] {
+        loadSuccess = WTF::nullopt;
+        webSocketSuccess = WTF::nullopt;
+        done = false;
         auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
         [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"test://host1/main.html"]]];
         TestWebKitAPI::Util::run(&done);
-    }
-    EXPECT_TRUE(loadSuccess);
-    EXPECT_FALSE(loadFail);
+    };
+
+    runTest();
+    EXPECT_TRUE(*loadSuccess);
+    EXPECT_TRUE(*webSocketSuccess);
     EXPECT_EQ(server.totalRequests(), 1u);
+
+    configuration.get()._loadsFromNetwork = NO;
+    runTest();
+    EXPECT_FALSE(*loadSuccess);
+    EXPECT_FALSE(*webSocketSuccess);
+    EXPECT_EQ(server.totalRequests(), 1u);
     
-    loadSuccess = false;
-    loadFail = false;
-    done = false;
+    configuration.get()._allowedNetworkHosts = [NSSet set];
+    runTest();
+    EXPECT_FALSE(*loadSuccess);
+    EXPECT_FALSE(*webSocketSuccess);
+    EXPECT_EQ(server.totalRequests(), 1u);
 
-    configuration.get()._loadsFromNetwork = NO;
-    {
+    configuration.get()._allowedNetworkHosts = nil;
+    runTest();
+    EXPECT_TRUE(*loadSuccess);
+    EXPECT_TRUE(*webSocketSuccess);
+    EXPECT_EQ(server.totalRequests(), 2u);
+
+    configuration.get()._allowedNetworkHosts = [NSSet setWithObject:@"localhost"];
+    runTest();
+    EXPECT_TRUE(*loadSuccess);
+    EXPECT_FALSE(*webSocketSuccess);
+    EXPECT_EQ(server.totalRequests(), 3u);
+}
+
+TEST(URLSchemeHandler, AllowedNetworkHostsRedirect)
+{
+    TestWebKitAPI::HTTPServer serverLocalhost({
+        { "/redirectTarget", { {{ "Access-Control-Allow-Origin", "*" }}, "test content" } }
+    });
+    TestWebKitAPI::HTTPServer server127001({
+        { "/", { 301, {
+            { "Access-Control-Allow-Origin", "*" },
+            { "Location", makeString("http://localhost:", serverLocalhost.port(), "/redirectTarget") }
+        }}},
+    });
+
+    Optional<bool> loadSuccess;
+    bool done = false;
+
+    auto handler = adoptNS([TestURLSchemeHandler new]);
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [configuration setURLSchemeHandler:handler.get() forURLScheme:@"test"];
+
+    [handler setStartURLSchemeTaskHandler:[&](WKWebView *, id<WKURLSchemeTask> task) {
+        NSString *path = task.request.URL.path;
+        if ([path isEqualToString:@"/main.html"]) {
+            respond(task, [NSString stringWithFormat:@"<script>"
+                "fetch('http://127.0.0.1:%d/').then(()=>{"
+                    "fetch('/loadSuccess')"
+                "}).catch(()=>{"
+                    "fetch('/loadFail')"
+                "})"
+                "</script>", server127001.port()].UTF8String);
+        } else if ([path isEqualToString:@"/loadSuccess"]) {
+            loadSuccess = true;
+            done = true;
+        } else if ([path isEqualToString:@"/loadFail"]) {
+            loadSuccess = false;
+            done = true;
+        }
+    }];
+
+    auto runTest = [&] {
+        loadSuccess = WTF::nullopt;
+        done = false;
+        configuration.get().websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
         auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
         [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"test://host1/main.html"]]];
         TestWebKitAPI::Util::run(&done);
-    }
-    EXPECT_FALSE(loadSuccess);
-    EXPECT_TRUE(loadFail);
-    EXPECT_EQ(server.totalRequests(), 1u);
+    };
+
+    runTest();
+    EXPECT_TRUE(*loadSuccess);
+    EXPECT_EQ(serverLocalhost.totalRequests(), 1u);
+    EXPECT_EQ(server127001.totalRequests(), 1u);
+    
+    configuration.get()._allowedNetworkHosts = [NSSet set];
+    runTest();
+    EXPECT_FALSE(*loadSuccess);
+    EXPECT_EQ(serverLocalhost.totalRequests(), 1u);
+    EXPECT_EQ(server127001.totalRequests(), 1u);
+
+    configuration.get()._allowedNetworkHosts = [NSSet setWithObject:@"127.0.0.1"];
+    runTest();
+    EXPECT_FALSE(*loadSuccess);
+    EXPECT_EQ(serverLocalhost.totalRequests(), 1u);
+    EXPECT_EQ(server127001.totalRequests(), 2u);
 }
 
 TEST(URLSchemeHandler, LoadsSubresources)

Modified: trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h (277335 => 277336)


--- trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h	2021-05-11 19:47:50 UTC (rev 277336)
@@ -71,6 +71,7 @@
     void send(RetainPtr<dispatch_data_t>&&, CompletionHandler<void()>&& = nullptr) const;
     void receiveBytes(CompletionHandler<void(Vector<uint8_t>&&)>&&) const;
     void receiveHTTPRequest(CompletionHandler<void(Vector<char>&&)>&&, Vector<char>&& buffer = { }) const;
+    void webSocketHandshake(CompletionHandler<void()>&& = { });
     void terminate();
     void cancel();
 

Modified: trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm (277335 => 277336)


--- trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm	2021-05-11 19:02:56 UTC (rev 277335)
+++ trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm	2021-05-11 19:47:50 UTC (rev 277336)
@@ -30,7 +30,9 @@
 #import <wtf/BlockPtr.h>
 #import <wtf/CompletionHandler.h>
 #import <wtf/RetainPtr.h>
+#import <wtf/SHA1.h>
 #import <wtf/ThreadSafeRefCounted.h>
+#import <wtf/text/Base64.h>
 #import <wtf/text/StringBuilder.h>
 #import <wtf/text/WTFString.h>
 
@@ -325,6 +327,34 @@
     }).get());
 }
 
+void Connection::webSocketHandshake(CompletionHandler<void()>&& connectionHandler)
+{
+    receiveHTTPRequest([connection = Connection(*this), connectionHandler = WTFMove(connectionHandler)] (Vector<char>&& request) mutable {
+
+        auto webSocketAcceptValue = [] (const Vector<char>& request) {
+            constexpr auto* keyHeaderField = "Sec-WebSocket-Key: ";
+            const char* keyBegin = strnstr(request.data(), keyHeaderField, request.size()) + strlen(keyHeaderField);
+            ASSERT(keyBegin);
+            const char* keyEnd = strnstr(keyBegin, "\r\n", request.size() + (keyBegin - request.data()));
+            ASSERT(keyEnd);
+
+            constexpr auto* webSocketKeyGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+            SHA1 sha1;
+            sha1.addBytes(reinterpret_cast<const uint8_t*>(keyBegin), keyEnd - keyBegin);
+            sha1.addBytes(reinterpret_cast<const uint8_t*>(webSocketKeyGUID), strlen(webSocketKeyGUID));
+            SHA1::Digest hash;
+            sha1.computeHash(hash);
+            return base64Encode(hash.data(), SHA1::hashSize);
+        };
+
+        connection.send(HTTPResponse(101, {
+            { "Upgrade", "websocket" },
+            { "Connection", "Upgrade" },
+            { "Sec-WebSocket-Accept", webSocketAcceptValue(request) }
+        }).serialize(HTTPResponse::IncludeContentLength::No), WTFMove(connectionHandler));
+    });
+}
+
 void Connection::terminate()
 {
     nw_connection_cancel(m_connection.get());
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to