Diff
Modified: trunk/Source/WebCore/ChangeLog (273896 => 273897)
--- trunk/Source/WebCore/ChangeLog 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Source/WebCore/ChangeLog 2021-03-04 18:00:49 UTC (rev 273897)
@@ -1,3 +1,40 @@
+2021-03-04 Alex Christensen <achristen...@webkit.org>
+
+ Introduce "websocket", "fetch", and "other" resource types to WKContentRuleList
+ https://bugs.webkit.org/show_bug.cgi?id=222709
+ <rdar://problem/71552078>
+
+ Reviewed by Youenn Fablet.
+
+ "raw" didn't give the desired granularity. This keeps support for "raw", but splits it into 3 subcategories:
+ "websocket" which only applies to WebSocket requests,
+ "fetch" which applies to XMLHTTPRequest and fetch API requests.
+ "other" which applies to other "raw" requests, such as beacons.
+
+ Covered by API tests.
+
+ * Modules/websockets/ThreadableWebSocketChannel.cpp:
+ (WebCore::ThreadableWebSocketChannel::validateURL):
+ * contentextensions/ContentExtensionParser.cpp:
+ (WebCore::ContentExtensions::getTypeFlags):
+ * css/StyleSheetContents.cpp:
+ (WebCore::StyleSheetContents::subresourcesAllowReuse const):
+ * loader/NetscapePlugInStreamLoader.cpp:
+ (WebCore::NetscapePlugInStreamLoader::NetscapePlugInStreamLoader):
+ * loader/ResourceLoadInfo.cpp:
+ (WebCore::ContentExtensions::toResourceType):
+ (WebCore::ContentExtensions::readResourceType):
+ (WebCore::ContentExtensions::readLoadType):
+ (WebCore::ContentExtensions::ResourceLoadInfo::getResourceFlags const):
+ * loader/ResourceLoadInfo.h:
+ * loader/ResourceLoader.cpp:
+ (WebCore::ResourceLoader::willSendRequestInternal):
+ * loader/ResourceLoader.h:
+ * loader/SubresourceLoader.cpp:
+ (WebCore::SubresourceLoader::SubresourceLoader):
+ * loader/cache/CachedResourceLoader.cpp:
+ (WebCore::CachedResourceLoader::requestResource):
+
2021-03-04 Antoine Quint <grao...@webkit.org>
Adjust progress parameter before calling blend() for discrete interpolations
Modified: trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp (273896 => 273897)
--- trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp 2021-03-04 18:00:49 UTC (rev 273897)
@@ -93,7 +93,7 @@
return { };
#if ENABLE(CONTENT_EXTENSIONS)
if (auto* documentLoader = document.loader()) {
- auto results = page->userContentProvider().processContentRuleListsForLoad(*page, validatedURL.url, ContentExtensions::ResourceType::Raw, *documentLoader);
+ auto results = page->userContentProvider().processContentRuleListsForLoad(*page, validatedURL.url, { ContentExtensions::ResourceType::Raw, ContentExtensions::ResourceType::WebSocket }, *documentLoader);
if (results.summary.blockedLoad)
return { };
if (results.summary.madeHTTPS) {
Modified: trunk/Source/WebCore/contentextensions/ContentExtensionParser.cpp (273896 => 273897)
--- trunk/Source/WebCore/contentextensions/ContentExtensionParser.cpp 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionParser.cpp 2021-03-04 18:00:49 UTC (rev 273897)
@@ -94,7 +94,8 @@
return strings;
}
-static std::error_code getTypeFlags(JSGlobalObject& lexicalGlobalObject, const JSValue& typeValue, ResourceFlags& flags, uint16_t (*stringToType)(const String&))
+template<typename T>
+static std::error_code getTypeFlags(JSGlobalObject& lexicalGlobalObject, const JSValue& typeValue, ResourceFlags& flags, Optional<OptionSet<T>> (*stringToType)(const String&))
{
VM& vm = lexicalGlobalObject.vm();
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -116,11 +117,11 @@
return ContentExtensionError::JSONInvalidObjectInTriggerFlagsArray;
String name = value.toWTFString(&lexicalGlobalObject);
- uint16_t type = stringToType(name);
+ auto type = stringToType(name);
if (!type)
return ContentExtensionError::JSONInvalidStringInTriggerFlagsArray;
- flags |= type;
+ flags |= static_cast<ResourceFlags>(type->toRaw());
}
return { };
Modified: trunk/Source/WebCore/css/StyleSheetContents.cpp (273896 => 273897)
--- trunk/Source/WebCore/css/StyleSheetContents.cpp 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Source/WebCore/css/StyleSheetContents.cpp 2021-03-04 18:00:49 UTC (rev 273897)
@@ -508,7 +508,7 @@
auto* documentLoader = loader.documentLoader();
if (page && documentLoader) {
const auto& request = resource.resourceRequest();
- auto results = page->userContentProvider().processContentRuleListsForLoad(*page, request.url(), ContentExtensions::toResourceType(resource.type()), *documentLoader);
+ auto results = page->userContentProvider().processContentRuleListsForLoad(*page, request.url(), ContentExtensions::toResourceType(resource.type(), resource.resourceRequest().requester()), *documentLoader);
if (results.summary.blockedLoad || results.summary.madeHTTPS)
return true;
}
Modified: trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.cpp (273896 => 273897)
--- trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.cpp 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.cpp 2021-03-04 18:00:49 UTC (rev 273897)
@@ -60,7 +60,7 @@
, m_client(makeWeakPtr(client))
{
#if ENABLE(CONTENT_EXTENSIONS)
- m_resourceType = ContentExtensions::ResourceType::PlugInStream;
+ m_resourceType = { ContentExtensions::ResourceType::PlugInStream };
#endif
}
Modified: trunk/Source/WebCore/loader/ResourceLoadInfo.cpp (273896 => 273897)
--- trunk/Source/WebCore/loader/ResourceLoadInfo.cpp 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Source/WebCore/loader/ResourceLoadInfo.cpp 2021-03-04 18:00:49 UTC (rev 273897)
@@ -34,84 +34,94 @@
namespace WebCore {
namespace ContentExtensions {
-ResourceType toResourceType(CachedResource::Type type)
+OptionSet<ResourceType> toResourceType(CachedResource::Type type, ResourceRequestBase::Requester requester)
{
switch (type) {
case CachedResource::Type::LinkPrefetch:
case CachedResource::Type::MainResource:
- return ResourceType::Document;
+ return { ResourceType::Document };
case CachedResource::Type::SVGDocumentResource:
- return ResourceType::SVGDocument;
+ return { ResourceType::SVGDocument };
case CachedResource::Type::ImageResource:
- return ResourceType::Image;
+ return { ResourceType::Image };
case CachedResource::Type::CSSStyleSheet:
#if ENABLE(XSLT)
case CachedResource::Type::XSLStyleSheet:
#endif
- return ResourceType::StyleSheet;
+ return { ResourceType::StyleSheet };
case CachedResource::Type::Script:
- return ResourceType::Script;
+ return { ResourceType::Script };
case CachedResource::Type::FontResource:
case CachedResource::Type::SVGFontResource:
- return ResourceType::Font;
+ return { ResourceType::Font };
case CachedResource::Type::MediaResource:
- return ResourceType::Media;
+ return { ResourceType::Media };
+ case CachedResource::Type::RawResource:
+ if (requester == ResourceRequestBase::Requester::XHR
+ || requester == ResourceRequestBase::Requester::Fetch)
+ return {{ ResourceType::Raw, ResourceType::Fetch }};
+ FALLTHROUGH;
case CachedResource::Type::Beacon:
case CachedResource::Type::Ping:
case CachedResource::Type::Icon:
- case CachedResource::Type::RawResource:
#if ENABLE(MODEL_ELEMENT)
case CachedResource::Type::ModelResource:
#endif
- return ResourceType::Raw;
+#if ENABLE(APPLICATION_MANIFEST)
+ case CachedResource::Type::ApplicationManifest:
+#endif
+ return {{ ResourceType::Raw, ResourceType::Other }};
case CachedResource::Type::TextTrackResource:
- return ResourceType::Media;
+ return { ResourceType::Media };
-#if ENABLE(APPLICATION_MANIFEST)
- case CachedResource::Type::ApplicationManifest:
- return ResourceType::Raw;
-#endif
};
- return ResourceType::Raw;
+ ASSERT_NOT_REACHED();
+ return { };
}
-uint16_t readResourceType(const String& name)
+Optional<OptionSet<ResourceType>> readResourceType(const String& name)
{
if (name == "document")
- return static_cast<uint16_t>(ResourceType::Document);
+ return { ResourceType::Document };
if (name == "image")
- return static_cast<uint16_t>(ResourceType::Image);
+ return { ResourceType::Image };
if (name == "style-sheet")
- return static_cast<uint16_t>(ResourceType::StyleSheet);
+ return { ResourceType::StyleSheet };
if (name == "script")
- return static_cast<uint16_t>(ResourceType::Script);
+ return { ResourceType::Script };
if (name == "font")
- return static_cast<uint16_t>(ResourceType::Font);
+ return { ResourceType::Font };
if (name == "raw")
- return static_cast<uint16_t>(ResourceType::Raw);
+ return { ResourceType::Raw };
+ if (name == "websocket")
+ return { ResourceType::WebSocket };
+ if (name == "fetch")
+ return { ResourceType::Fetch };
+ if (name == "other")
+ return { ResourceType::Other };
if (name == "svg-document")
- return static_cast<uint16_t>(ResourceType::SVGDocument);
+ return { ResourceType::SVGDocument };
if (name == "media")
- return static_cast<uint16_t>(ResourceType::Media);
+ return { ResourceType::Media };
if (name == "popup")
- return static_cast<uint16_t>(ResourceType::Popup);
+ return { ResourceType::Popup };
if (name == "ping")
- return static_cast<uint16_t>(ResourceType::Ping);
- return static_cast<uint16_t>(ResourceType::Invalid);
+ return { ResourceType::Ping };
+ return WTF::nullopt;
}
-uint16_t readLoadType(const String& name)
+Optional<OptionSet<LoadType>> readLoadType(const String& name)
{
if (name == "first-party")
- return static_cast<uint16_t>(LoadType::FirstParty);
+ return { LoadType::FirstParty };
if (name == "third-party")
- return static_cast<uint16_t>(LoadType::ThirdParty);
- return static_cast<uint16_t>(LoadType::Invalid);
+ return { LoadType::ThirdParty };
+ return WTF::nullopt;
}
bool ResourceLoadInfo::isThirdParty() const
@@ -125,7 +135,7 @@
ResourceFlags ResourceLoadInfo::getResourceFlags() const
{
ResourceFlags flags = 0;
- ASSERT(type != ResourceType::Invalid);
+ ASSERT(!type.isEmpty());
flags |= type.toRaw();
flags |= isThirdParty() ? static_cast<ResourceFlags>(LoadType::ThirdParty) : static_cast<ResourceFlags>(LoadType::FirstParty);
return flags;
Modified: trunk/Source/WebCore/loader/ResourceLoadInfo.h (273896 => 273897)
--- trunk/Source/WebCore/loader/ResourceLoadInfo.h 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Source/WebCore/loader/ResourceLoadInfo.h 2021-03-04 18:00:49 UTC (rev 273897)
@@ -35,13 +35,12 @@
namespace ContentExtensions {
enum class ResourceType : uint16_t {
- Invalid = 0x0000,
Document = 0x0001,
Image = 0x0002,
StyleSheet = 0x0004,
Script = 0x0008,
Font = 0x0010,
- Raw = 0x0020,
+ Raw = 0x0020, // This bit can be reused next time we increment CurrentContentRuleListFileVersion. It is equivalent to using Fetch | WebSocket | Other.
SVGDocument = 0x0040,
Media = 0x0080,
PlugInStream = 0x0100,
@@ -48,11 +47,13 @@
Popup = 0x0200,
// 0x0400 and 0x0800 are used by LoadType.
Ping = 0x1000,
+ Fetch = 0x2000,
+ WebSocket = 0x4000,
+ Other = 0x8000,
};
-const uint16_t ResourceTypeMask = 0x13FF;
+const uint16_t ResourceTypeMask = 0xF3FF;
enum class LoadType : uint16_t {
- Invalid = 0x0000,
FirstParty = 0x0400,
ThirdParty = 0x0800,
};
@@ -72,9 +73,9 @@
const uint64_t ActionFlagMask = 0x0000FFFF00000000;
const uint64_t IfConditionFlag = 0x0001000000000000;
-ResourceType toResourceType(CachedResource::Type);
-uint16_t readResourceType(const String&);
-uint16_t readLoadType(const String&);
+OptionSet<ResourceType> toResourceType(CachedResource::Type, ResourceRequestBase::Requester);
+Optional<OptionSet<ResourceType>> readResourceType(const String&);
+Optional<OptionSet<LoadType>> readLoadType(const String&);
struct ResourceLoadInfo {
URL resourceURL;
Modified: trunk/Source/WebCore/loader/ResourceLoader.cpp (273896 => 273897)
--- trunk/Source/WebCore/loader/ResourceLoader.cpp 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Source/WebCore/loader/ResourceLoader.cpp 2021-03-04 18:00:49 UTC (rev 273897)
@@ -341,7 +341,7 @@
ASSERT(!m_reachedTerminalState);
#if ENABLE(CONTENT_EXTENSIONS)
- ASSERT(m_resourceType != ContentExtensions::ResourceType::Invalid);
+ ASSERT(!m_resourceType.isEmpty());
#endif
// We need a resource identifier for all requests, even if FrameLoader is never going to see it (such as with CORS preflight requests).
Modified: trunk/Source/WebCore/loader/ResourceLoader.h (273896 => 273897)
--- trunk/Source/WebCore/loader/ResourceLoader.h 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Source/WebCore/loader/ResourceLoader.h 2021-03-04 18:00:49 UTC (rev 273897)
@@ -246,7 +246,7 @@
#if ENABLE(CONTENT_EXTENSIONS)
protected:
- ContentExtensions::ResourceType m_resourceType { ContentExtensions::ResourceType::Invalid };
+ OptionSet<ContentExtensions::ResourceType> m_resourceType;
#endif
};
Modified: trunk/Source/WebCore/loader/SubresourceLoader.cpp (273896 => 273897)
--- trunk/Source/WebCore/loader/SubresourceLoader.cpp 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Source/WebCore/loader/SubresourceLoader.cpp 2021-03-04 18:00:49 UTC (rev 273897)
@@ -100,7 +100,7 @@
subresourceLoaderCounter.increment();
#endif
#if ENABLE(CONTENT_EXTENSIONS)
- m_resourceType = ContentExtensions::toResourceType(resource.type());
+ m_resourceType = ContentExtensions::toResourceType(resource.type(), resource.resourceRequest().requester());
#endif
m_canCrossOriginRequestsAskUserForCredentials = resource.type() == CachedResource::Type::MainResource || frame.settings().allowCrossOriginSubresourcesToAskForCredentials();
}
Modified: trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp (273896 => 273897)
--- trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp 2021-03-04 18:00:49 UTC (rev 273897)
@@ -907,7 +907,7 @@
#if ENABLE(CONTENT_EXTENSIONS)
if (m_documentLoader) {
const auto& resourceRequest = request.resourceRequest();
- auto results = page.userContentProvider().processContentRuleListsForLoad(page, resourceRequest.url(), ContentExtensions::toResourceType(type), *m_documentLoader);
+ auto results = page.userContentProvider().processContentRuleListsForLoad(page, resourceRequest.url(), ContentExtensions::toResourceType(type, request.resourceRequest().requester()), *m_documentLoader);
bool blockedLoad = results.summary.blockedLoad;
bool madeHTTPS = results.summary.madeHTTPS;
request.applyResults(WTFMove(results), &page);
Modified: trunk/Tools/ChangeLog (273896 => 273897)
--- trunk/Tools/ChangeLog 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Tools/ChangeLog 2021-03-04 18:00:49 UTC (rev 273897)
@@ -1,3 +1,17 @@
+2021-03-04 Alex Christensen <achristen...@webkit.org>
+
+ Introduce "websocket", "fetch", and "other" resource types to WKContentRuleList
+ https://bugs.webkit.org/show_bug.cgi?id=222709
+ <rdar://problem/71552078>
+
+ Reviewed by Youenn Fablet.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm:
+ (TEST):
+ (webSocketAcceptValue):
+ * TestWebKitAPI/cocoa/HTTPServer.mm:
+ (TestWebKitAPI::statusText):
+
2021-03-04 Youenn Fablet <you...@apple.com>
Update camera and microphone capture state control WKWebView API
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm (273896 => 273897)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm 2021-03-04 18:00:49 UTC (rev 273897)
@@ -25,7 +25,11 @@
#import "config.h"
+#import "HTTPServer.h"
#import "PlatformUtilities.h"
+#import "Test.h"
+#import "TestUIDelegate.h"
+#import "TestURLSchemeHandler.h"
#import <WebKit/WKContentRuleListPrivate.h>
#import <WebKit/WKContentRuleListStore.h>
#import <WebKit/WKNavigationDelegatePrivate.h>
@@ -34,8 +38,10 @@
#import <WebKit/WKWebView.h>
#import <WebKit/_WKContentRuleListAction.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;
@@ -117,7 +123,7 @@
return contentRuleList;
}
-TEST(WebKit, ContentRuleListNotificationMainResource)
+TEST(ContentRuleList, NotificationMainResource)
{
auto delegate = adoptNS([[ContentRuleListNotificationDelegate alloc] init]);
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
@@ -131,7 +137,7 @@
EXPECT_STREQ([notificationIdentifier UTF8String], "testidentifier");
}
-TEST(WebKit, ContentRuleListNotificationSubresource)
+TEST(ContentRuleList, NotificationSubresource)
{
auto delegate = adoptNS([[ContentRuleListNotificationDelegate alloc] init]);
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
@@ -147,7 +153,7 @@
EXPECT_STREQ([notificationIdentifier UTF8String], "testidentifier");
}
-TEST(WebKit, PerformedActionForURL)
+TEST(ContentRuleList, PerformedActionForURL)
{
NSString *firstList = @"[{\"action\":{\"type\":\"notify\",\"notification\":\"testnotification\"},\"trigger\":{\"url-filter\":\"notify\"}}]";
NSString *secondList = @"[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"block\"}}]";
@@ -171,6 +177,101 @@
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));
+ });
+ });
+ auto serverPort = webSocketServer.port();
+
+ auto handler = [[TestURLSchemeHandler new] autorelease];
+ handler.startURLSchemeTaskHandler = ^(WKWebView *, id<WKURLSchemeTask> task) {
+ auto respond = [task] (const char* html) {
+ NSURLResponse *response = [[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:strlen(html) textEncodingName:nil] autorelease];
+ [task didReceiveResponse:response];
+ [task didReceiveData:[NSData dataWithBytes:html length:strlen(html)]];
+ [task didFinish];
+ };
+ NSString *path = task.request.URL.path;
+ if ([path isEqualToString:@"/checkWebSocket.html"])
+ return respond([NSString stringWithFormat:@"<script>var ws = new WebSocket('ws://localhost:%d/test');ws._onopen_=()=>{alert('onopen')};ws._onerror_=()=>{alert('onerror')}</script>", serverPort].UTF8String);
+ if ([path isEqualToString:@"/checkFetch.html"])
+ return respond("<script>fetch('test:///fetchContent').then(()=>{alert('fetched')}).catch(()=>{alert('did not fetch')})</script>");
+ if ([path isEqualToString:@"/fetchContent"])
+ return respond("hello");
+ if ([path isEqualToString:@"/checkXHR.html"])
+ return respond("<script>var xhr = new XMLHttpRequest();xhr.open('GET', 'test:///fetchContent');xhr._onreadystatechange_=()=>{if(xhr.readyState==4){setTimeout(()=>{alert('xhr finished')}, 0)}};xhr._onerror_=()=>{alert('xhr error')};xhr.send()</script>");
+
+ ASSERT_NOT_REACHED();
+ };
+ auto configuration = [[WKWebViewConfiguration new] autorelease];
+ [configuration setURLSchemeHandler:handler forURLScheme:@"test"];
+ configuration.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
+ auto webView = [[[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration] autorelease];
+
+ auto listWithResourceType = [] (const char* type) {
+ return makeContentRuleList([NSString stringWithFormat:@"[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\".*test\",\"resource-type\":[\"%s\"]}}]", type]);
+ };
+
+ WKUserContentController *userContentController = webView.configuration.userContentController;
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"test:///checkWebSocket.html"]]];
+ EXPECT_WK_STREQ([webView _test_waitForAlert], "onopen");
+ [userContentController addContentRuleList:listWithResourceType("websocket").get()];
+ [webView reload];
+ EXPECT_WK_STREQ([webView _test_waitForAlert], "onerror");
+
+ [userContentController removeAllContentRuleLists];
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"test:///checkFetch.html"]]];
+ EXPECT_WK_STREQ([webView _test_waitForAlert], "fetched");
+ [userContentController addContentRuleList:listWithResourceType("fetch").get()];
+ [webView reload];
+ EXPECT_WK_STREQ([webView _test_waitForAlert], "did not fetch");
+
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"test:///checkXHR.html"]]];
+ EXPECT_WK_STREQ([webView _test_waitForAlert], "xhr error");
+ EXPECT_WK_STREQ([webView _test_waitForAlert], "xhr finished");
+ [userContentController removeAllContentRuleLists];
+ [webView reload];
+ EXPECT_WK_STREQ([webView _test_waitForAlert], "xhr finished");
+
+ HTTPServer beaconServer({
+ { "/", { "<script>navigator.sendBeacon('/testBeaconTarget', 'hello');fetch('/testFetchTarget').then(()=>{alert('fetch done')})</script>" } },
+ { "/testBeaconTarget", { "hi" } },
+ { "/testFetchTarget", { "hi" } },
+ });
+ [webView loadRequest:beaconServer.request()];
+ EXPECT_WK_STREQ([webView _test_waitForAlert], "fetch done");
+ EXPECT_EQ(beaconServer.totalRequests(), 3u);
+ [userContentController addContentRuleList:listWithResourceType("other").get()];
+ [webView reload];
+ EXPECT_WK_STREQ([webView _test_waitForAlert], "fetch done");
+ EXPECT_EQ(beaconServer.totalRequests(), 5u);
+}
+
TEST(ContentRuleList, SupportsRegex)
{
NSArray<NSString *> *allowed = @[
Modified: trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm (273896 => 273897)
--- trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm 2021-03-04 17:57:32 UTC (rev 273896)
+++ trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm 2021-03-04 18:00:49 UTC (rev 273897)
@@ -172,6 +172,8 @@
static String statusText(unsigned statusCode)
{
switch (statusCode) {
+ case 101:
+ return "Switching Protocols"_s;
case 200:
return "OK"_s;
case 301: