Title: [227153] trunk
Revision
227153
Author
[email protected]
Date
2018-01-18 10:46:43 -0800 (Thu, 18 Jan 2018)

Log Message

Service Workers restored from persistent storage have 'redundant' state
https://bugs.webkit.org/show_bug.cgi?id=181749
<rdar://problem/36556486>

Reviewed by Youenn Fablet.

Source/WebCore:

Tested by new API test.

* workers/service/server/SWServer.cpp:
(WebCore::SWServer::installContextData):
Make sure the SWServerWorker's state is set to "activated" after it is assigned to
the registrations' active slot. Otherwise, it stays in its default state (redundant).

Source/WebKit:

Allow service workers to intercept custom protocol loads as this is useful for
API testing.

* WebProcess/Network/WebLoaderStrategy.cpp:
(WebKit::WebLoaderStrategy::scheduleLoad):
(WebKit::WebLoaderStrategy::tryLoadingUsingURLSchemeHandler):
* WebProcess/Network/WebLoaderStrategy.h:

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
(-[SWMessageHandlerForFetchTest userContentController:didReceiveScriptMessage:]):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (227152 => 227153)


--- trunk/Source/WebCore/ChangeLog	2018-01-18 18:44:30 UTC (rev 227152)
+++ trunk/Source/WebCore/ChangeLog	2018-01-18 18:46:43 UTC (rev 227153)
@@ -1,3 +1,18 @@
+2018-01-18  Chris Dumez  <[email protected]>
+
+        Service Workers restored from persistent storage have 'redundant' state
+        https://bugs.webkit.org/show_bug.cgi?id=181749
+        <rdar://problem/36556486>
+
+        Reviewed by Youenn Fablet.
+
+        Tested by new API test.
+
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::installContextData):
+        Make sure the SWServerWorker's state is set to "activated" after it is assigned to
+        the registrations' active slot. Otherwise, it stays in its default state (redundant).
+
 2018-01-18  Antti Koivisto  <[email protected]>
 
         REGRESSION(r225650): The scores of MotionMark tests Multiply and Leaves dropped by 8%

Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (227152 => 227153)


--- trunk/Source/WebCore/workers/service/server/SWServer.cpp	2018-01-18 18:44:30 UTC (rev 227152)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp	2018-01-18 18:46:43 UTC (rev 227153)
@@ -490,6 +490,7 @@
     // as it is unlikely they will be needed immediately.
     if (data.loadedFromDisk) {
         registration->updateRegistrationState(ServiceWorkerRegistrationState::Active, worker.ptr());
+        worker->setState(ServiceWorkerState::Activated);
         return;
     }
 

Modified: trunk/Source/WebKit/ChangeLog (227152 => 227153)


--- trunk/Source/WebKit/ChangeLog	2018-01-18 18:44:30 UTC (rev 227152)
+++ trunk/Source/WebKit/ChangeLog	2018-01-18 18:46:43 UTC (rev 227153)
@@ -1,3 +1,19 @@
+2018-01-18  Chris Dumez  <[email protected]>
+
+        Service Workers restored from persistent storage have 'redundant' state
+        https://bugs.webkit.org/show_bug.cgi?id=181749
+        <rdar://problem/36556486>
+
+        Reviewed by Youenn Fablet.
+
+        Allow service workers to intercept custom protocol loads as this is useful for
+        API testing.
+
+        * WebProcess/Network/WebLoaderStrategy.cpp:
+        (WebKit::WebLoaderStrategy::scheduleLoad):
+        (WebKit::WebLoaderStrategy::tryLoadingUsingURLSchemeHandler):
+        * WebProcess/Network/WebLoaderStrategy.h:
+
 2018-01-18  Brent Fulgham  <[email protected]>
 
         REGRESSION(r225858): Sandbox violations due to blocked access to Spotlight search preferences

Modified: trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp (227152 => 227153)


--- trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp	2018-01-18 18:44:30 UTC (rev 227152)
+++ trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp	2018-01-18 18:46:43 UTC (rev 227153)
@@ -208,23 +208,12 @@
     }
 #endif
 
-    auto* webFrameLoaderClient = toWebFrameLoaderClient(resourceLoader.frameLoader()->client());
-    auto* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr;
-    auto* webPage = webFrame ? webFrame->page() : nullptr;
-    if (webPage) {
-        if (auto* handler = webPage->urlSchemeHandlerForScheme(resourceLoader.request().url().protocol().toStringWithoutCopying())) {
-            LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, URL '%s' will be handled by a UIProcess URL scheme handler.", resourceLoader.url().string().utf8().data());
-            RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: URL will be handled by a UIProcess URL scheme handler (frame = %p, resourceID = %" PRIu64 ")", resourceLoader.frame(), identifier);
-
-            handler->startNewTask(resourceLoader);
-            return;
-        }
-    }
-
 #if ENABLE(SERVICE_WORKER)
     WebServiceWorkerProvider::singleton().handleFetch(resourceLoader, resource, sessionID, shouldClearReferrerOnHTTPSToHTTPRedirect, [trackingParameters, sessionID, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime = maximumBufferingTime(resource), resourceLoader = makeRef(resourceLoader)] (ServiceWorkerClientFetch::Result result) mutable {
-        if (result != ServiceWorkerClientFetch::Result::Unhandled)
+        if (result != ServiceWorkerClientFetch::Result::Unhandled) {
+            LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be scheduled through ServiceWorker handle fetch algorithm", resourceLoader->url().string().latin1().data());
             return;
+        }
         if (resourceLoader->options().serviceWorkersMode == ServiceWorkersMode::Only) {
             callOnMainThread([resourceLoader = WTFMove(resourceLoader)] {
                 auto error = internalError(resourceLoader->request().url());
@@ -234,15 +223,32 @@
             return;
         }
 
-        LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be scheduled through ServiceWorker handle fetch algorithm", resourceLoader->url().string().latin1().data());
-        WebProcess::singleton().webLoaderStrategy().scheduleLoadFromNetworkProcess(resourceLoader.get(), resourceLoader->request(), trackingParameters, sessionID, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime);
+        if (!WebProcess::singleton().webLoaderStrategy().tryLoadingUsingURLSchemeHandler(resourceLoader))
+            WebProcess::singleton().webLoaderStrategy().scheduleLoadFromNetworkProcess(resourceLoader.get(), resourceLoader->request(), trackingParameters, sessionID, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime);
     });
 #else
-    LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be scheduled through ServiceWorker handle fetch algorithm", resourceLoader.url().string().latin1().data());
-    scheduleLoadFromNetworkProcess(resourceLoader, resourceLoader.request(), trackingParameters, sessionID, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime(resource));
+    if (!tryLoadingUsingURLSchemeHandler(resourceLoader))
+        scheduleLoadFromNetworkProcess(resourceLoader, resourceLoader.request(), trackingParameters, sessionID, shouldClearReferrerOnHTTPSToHTTPRedirect, maximumBufferingTime(resource));
 #endif
 }
 
+bool WebLoaderStrategy::tryLoadingUsingURLSchemeHandler(ResourceLoader& resourceLoader)
+{
+    auto* webFrameLoaderClient = toWebFrameLoaderClient(resourceLoader.frameLoader()->client());
+    auto* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr;
+    auto* webPage = webFrame ? webFrame->page() : nullptr;
+    if (webPage) {
+        if (auto* handler = webPage->urlSchemeHandlerForScheme(resourceLoader.request().url().protocol().toStringWithoutCopying())) {
+            LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, URL '%s' will be handled by a UIProcess URL scheme handler.", resourceLoader.url().string().utf8().data());
+            RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: URL will be handled by a UIProcess URL scheme handler (frame = %p, resourceID = %lu)", resourceLoader.frame(), resourceLoader.identifier());
+
+            handler->startNewTask(resourceLoader);
+            return true;
+        }
+    }
+    return false;
+}
+
 void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, PAL::SessionID sessionID, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime)
 {
     ResourceLoadIdentifier identifier = resourceLoader.identifier();

Modified: trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h (227152 => 227153)


--- trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h	2018-01-18 18:44:30 UTC (rev 227152)
+++ trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h	2018-01-18 18:46:43 UTC (rev 227153)
@@ -84,6 +84,7 @@
     void scheduleInternallyFailedLoad(WebCore::ResourceLoader&);
     void internallyFailedLoadTimerFired();
     void startLocalLoad(WebCore::ResourceLoader&);
+    bool tryLoadingUsingURLSchemeHandler(WebCore::ResourceLoader&);
 
     HashSet<RefPtr<WebCore::ResourceLoader>> m_internallyFailedResourceLoaders;
     RunLoop::Timer<WebLoaderStrategy> m_internallyFailedLoadTimer;

Modified: trunk/Tools/ChangeLog (227152 => 227153)


--- trunk/Tools/ChangeLog	2018-01-18 18:44:30 UTC (rev 227152)
+++ trunk/Tools/ChangeLog	2018-01-18 18:46:43 UTC (rev 227153)
@@ -1,3 +1,16 @@
+2018-01-18  Chris Dumez  <[email protected]>
+
+        Service Workers restored from persistent storage have 'redundant' state
+        https://bugs.webkit.org/show_bug.cgi?id=181749
+        <rdar://problem/36556486>
+
+        Reviewed by Youenn Fablet.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
+        (-[SWMessageHandlerForFetchTest userContentController:didReceiveScriptMessage:]):
+
 2018-01-18  Joanmarie Diggs  <[email protected]>
 
         [GTK] AX: Two layout tests crash with error 'g_strstr_len: assertion 'haystack != NULL' failed' in Accessibility::UIElement::url

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm (227152 => 227153)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm	2018-01-18 18:44:30 UTC (rev 227152)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm	2018-01-18 18:46:43 UTC (rev 227153)
@@ -64,6 +64,17 @@
 }
 @end
 
+@interface SWMessageHandlerForFetchTest : NSObject <WKScriptMessageHandler>
+@end
+
+@implementation SWMessageHandlerForFetchTest
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+    EXPECT_TRUE([[message body] isEqualToString:@"Intercepted by worker"]);
+    done = true;
+}
+@end
+
 @interface SWSchemes : NSObject <WKURLSchemeHandler> {
 @public
     HashMap<String, ResourceInfo> resources;
@@ -137,6 +148,58 @@
 
 )SWRESOURCE";
 
+static const char* mainForFetchTestBytes = R"SWRESOURCE(
+<html>
+<body>
+<script>
+try {
+
+function addFrame()
+{
+    frame = document.createElement('iframe');
+    frame.src = ""
+    frame._onload_ = function() { window.webkit.messageHandlers.sw.postMessage(frame.contentDocument.body.innerHTML); }
+    document.body.appendChild(frame);
+}
+
+navigator.serviceWorker.register('/sw.js').then(function(reg) {
+    if (reg.active) {
+        addFrame();
+        return;
+    }
+    worker = reg.installing;
+    worker.addEventListener('statechange', function() {
+        if (worker.state == 'activated')
+            addFrame();
+    });
+}).catch(function(error) {
+    log("Registration failed with: " + error);
+});
+} catch(e) {
+    log("Exception: " + e);
+}
+
+</script>
+</body>
+</html>
+)SWRESOURCE";
+
+static const char* scriptHandlingFetchBytes = R"SWRESOURCE(
+
+self.addEventListener("fetch", (event) => {
+    if (event.request.url.indexOf("test.html") !== -1) {
+        event.respondWith(new Response(new Blob(['Intercepted by worker'], {type: 'text/html'})));
+    }
+});
+
+)SWRESOURCE";
+
+static const char* testBytes = R"SWRESOURCE(
+<body>
+NOT intercepted by worker
+</body>
+)SWRESOURCE";
+
 TEST(ServiceWorkers, Basic)
 {
     ASSERT(mainBytes);
@@ -183,4 +246,64 @@
     done = false;
 }
 
+TEST(ServiceWorkers, FetchAfterRestoreFromDisk)
+{
+    ASSERT(mainForFetchTestBytes);
+    ASSERT(scriptHandlingFetchBytes);
+
+    [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
+
+    // Start with a clean slate data store
+    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+
+    RetainPtr<SWMessageHandlerForFetchTest> messageHandler = adoptNS([[SWMessageHandlerForFetchTest alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
+
+    RetainPtr<SWSchemes> handler = adoptNS([[SWSchemes alloc] init]);
+    handler->resources.set("sw://host/main.html", ResourceInfo { @"text/html", mainForFetchTestBytes });
+    handler->resources.set("sw://host/test.html", ResourceInfo { @"text/html", testBytes });
+    handler->resources.set("sw://host/sw.js", ResourceInfo { @"application/_javascript_", scriptHandlingFetchBytes });
+    [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SW"];
+
+    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    [webView.get().configuration.processPool _registerURLSchemeServiceWorkersCanHandle:@"sw"];
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"sw://host/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&done);
+
+    webView = nullptr;
+    configuration = nullptr;
+    messageHandler = nullptr;
+    handler = nullptr;
+
+    done = false;
+
+    configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    messageHandler = adoptNS([[SWMessageHandlerForFetchTest alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
+
+    handler = adoptNS([[SWSchemes alloc] init]);
+    handler->resources.set("sw://host/main.html", ResourceInfo { @"text/html", mainForFetchTestBytes });
+    handler->resources.set("sw://host/test.html", ResourceInfo { @"text/html", testBytes });
+    handler->resources.set("sw://host/sw.js", ResourceInfo { @"application/_javascript_", scriptHandlingFetchBytes });
+    [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SW"];
+
+    webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    [webView.get().configuration.processPool _registerURLSchemeServiceWorkersCanHandle:@"sw"];
+
+    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"sw://host/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+}
+
 #endif // WK_API_ENABLED
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to