Title: [275751] trunk
Revision
275751
Author
[email protected]
Date
2021-04-09 01:54:34 -0700 (Fri, 09 Apr 2021)

Log Message

ServiceWorker should save module scripts
https://bugs.webkit.org/show_bug.cgi?id=224356
<rdar://problem/75634897>

Reviewed by Youenn Fablet.

Source/WebCore:

Test: http/wpt/service-workers/persistent-modules.html

In this patch, we call setScriptResource / scriptResource while loading service-worker module scripts in module loaders,
so that we can ensure that they are saved on the disk.

* bindings/js/ScriptModuleLoader.cpp:
(WebCore::ScriptModuleLoader::notifyFinished):
* bindings/js/WorkerModuleScriptLoader.cpp:
(WebCore::WorkerModuleScriptLoader::load):
(WebCore::WorkerModuleScriptLoader::notifyFinished):
(WebCore::WorkerModuleScriptLoader::notifyClientFinished):
* bindings/js/WorkerModuleScriptLoader.h:

LayoutTests:

* http/wpt/service-workers/persistent-modules-expected.txt: Added.
* http/wpt/service-workers/persistent-modules.html: Added.
* http/wpt/service-workers/resources/persistent-imported-module-script.py: Added.
(main):
* http/wpt/service-workers/resources/persistent-module-worker.js: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (275750 => 275751)


--- trunk/LayoutTests/ChangeLog	2021-04-09 06:05:46 UTC (rev 275750)
+++ trunk/LayoutTests/ChangeLog	2021-04-09 08:54:34 UTC (rev 275751)
@@ -1,3 +1,17 @@
+2021-04-09  Yusuke Suzuki  <[email protected]>
+
+        ServiceWorker should save module scripts
+        https://bugs.webkit.org/show_bug.cgi?id=224356
+        <rdar://problem/75634897>
+
+        Reviewed by Youenn Fablet.
+
+        * http/wpt/service-workers/persistent-modules-expected.txt: Added.
+        * http/wpt/service-workers/persistent-modules.html: Added.
+        * http/wpt/service-workers/resources/persistent-imported-module-script.py: Added.
+        (main):
+        * http/wpt/service-workers/resources/persistent-module-worker.js: Added.
+
 2021-04-08  Jiewen Tan  <[email protected]>
 
         PCM: Write more blinded secret tests

Added: trunk/LayoutTests/http/wpt/service-workers/persistent-modules-expected.txt (0 => 275751)


--- trunk/LayoutTests/http/wpt/service-workers/persistent-modules-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/persistent-modules-expected.txt	2021-04-09 08:54:34 UTC (rev 275751)
@@ -0,0 +1 @@
+PASS

Added: trunk/LayoutTests/http/wpt/service-workers/persistent-modules.html (0 => 275751)


--- trunk/LayoutTests/http/wpt/service-workers/persistent-modules.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/persistent-modules.html	2021-04-09 08:54:34 UTC (rev 275751)
@@ -0,0 +1,73 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+function getRandomIdFromWorker(worker)
+{
+    worker.postMessage("getRandomId");
+    return new Promise(function(resolve) {
+      navigator.serviceWorker.addEventListener('message', function(e) {
+            resolve(e.data);
+        });
+    });
+}
+
+function withIframe2(url) {
+  return new Promise(function(resolve) {
+      window.addEventListener("message", function (ev) {
+        resolve(ev.data);
+      }, false);
+      var frame = document.createElement('iframe');
+      frame.src = ""
+      document.body.appendChild(frame);
+    });
+}
+
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+var registration;
+var worker;
+async function doTest() {
+    if (!window.testRunner)
+        return Promise.reject('Internals API needed for this test');
+
+    registration = await navigator.serviceWorker.register("resources/persistent-module-worker.js", {
+        type: "module"
+    });
+    if (registration.installing) {
+        worker = registration.installing;
+        await waitForState(worker, "activated");
+    } else
+        worker = registration.active;
+
+    let randomId = await getRandomIdFromWorker(worker);
+
+    if (!window.location.hash.length) {
+        if (window.internals)
+            await internals.storeRegistrationsOnDisk();
+
+        if (window.testRunner)
+            testRunner.terminateNetworkProcess();
+        await waitFor(100);
+
+        let randomId2 = await withIframe2("./persistent-modules.html#iframe");
+
+        document.body.innerHTML = randomId === randomId2 ? "PASS" : "FAIL";
+        if (window.testRunner)
+            testRunner.notifyDone();
+    } else {
+        window.parent.postMessage(randomId, '*');
+        return;
+    }
+}
+doTest();
+
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/http/wpt/service-workers/resources/persistent-imported-module-script.py (0 => 275751)


--- trunk/LayoutTests/http/wpt/service-workers/resources/persistent-imported-module-script.py	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/resources/persistent-imported-module-script.py	2021-04-09 08:54:34 UTC (rev 275751)
@@ -0,0 +1,9 @@
+import random
+
+
+def main(request, response):
+    headers = [
+        ("Content-type", "text/_javascript_"),
+        ("Cache-Control", "no-store")
+    ]
+    return headers, "self.addEventListener('message', function(e) { e.source.postMessage('" + str(random.random()) + "'); });"

Added: trunk/LayoutTests/http/wpt/service-workers/resources/persistent-module-worker.js (0 => 275751)


--- trunk/LayoutTests/http/wpt/service-workers/resources/persistent-module-worker.js	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/resources/persistent-module-worker.js	2021-04-09 08:54:34 UTC (rev 275751)
@@ -0,0 +1,2 @@
+import "./persistent-imported-module-script.py";
+

Modified: trunk/Source/WebCore/ChangeLog (275750 => 275751)


--- trunk/Source/WebCore/ChangeLog	2021-04-09 06:05:46 UTC (rev 275750)
+++ trunk/Source/WebCore/ChangeLog	2021-04-09 08:54:34 UTC (rev 275751)
@@ -1,3 +1,24 @@
+2021-04-09  Yusuke Suzuki  <[email protected]>
+
+        ServiceWorker should save module scripts
+        https://bugs.webkit.org/show_bug.cgi?id=224356
+        <rdar://problem/75634897>
+
+        Reviewed by Youenn Fablet.
+
+        Test: http/wpt/service-workers/persistent-modules.html
+
+        In this patch, we call setScriptResource / scriptResource while loading service-worker module scripts in module loaders,
+        so that we can ensure that they are saved on the disk.
+
+        * bindings/js/ScriptModuleLoader.cpp:
+        (WebCore::ScriptModuleLoader::notifyFinished):
+        * bindings/js/WorkerModuleScriptLoader.cpp:
+        (WebCore::WorkerModuleScriptLoader::load):
+        (WebCore::WorkerModuleScriptLoader::notifyFinished):
+        (WebCore::WorkerModuleScriptLoader::notifyClientFinished):
+        * bindings/js/WorkerModuleScriptLoader.h:
+
 2021-04-08  Fujii Hironori  <[email protected]>
 
         [Win] Wrong KeyboardEvent.key for numeric key pad with NumLock

Modified: trunk/Source/WebCore/bindings/js/ScriptModuleLoader.cpp (275750 => 275751)


--- trunk/Source/WebCore/bindings/js/ScriptModuleLoader.cpp	2021-04-09 06:05:46 UTC (rev 275750)
+++ trunk/Source/WebCore/bindings/js/ScriptModuleLoader.cpp	2021-04-09 08:54:34 UTC (rev 275751)
@@ -369,8 +369,6 @@
             if (sourceURL.hasFragmentIdentifier())
                 responseURL.setFragmentIdentifier(sourceURL.fragmentIdentifier());
         }
-
-        m_requestURLToResponseURLMap.add(sourceURL.string(), responseURL);
         return responseURL;
     };
 
@@ -408,7 +406,8 @@
             }
         }
 
-        canonicalizeAndRegisterResponseURL(cachedScript.response().url(), cachedScript.hasRedirections(), cachedScript.response().source());
+        URL responseURL = canonicalizeAndRegisterResponseURL(cachedScript.response().url(), cachedScript.hasRedirections(), cachedScript.response().source());
+        m_requestURLToResponseURLMap.add(sourceURL.string(), WTFMove(responseURL));
         promise->resolveWithCallback([&] (JSDOMGlobalObject& jsGlobalObject) {
             return JSC::JSSourceCode::create(jsGlobalObject.vm(),
                 JSC::SourceCode { ScriptSourceCode { &cachedScript, JSC::SourceProviderSourceType::Module, loader.scriptFetcher() }.jsSourceCode() });
@@ -415,9 +414,11 @@
         });
     } else {
         auto& loader = static_cast<WorkerModuleScriptLoader&>(moduleScriptLoader);
-        auto& workerScriptLoader = loader.scriptLoader();
 
-        if (workerScriptLoader.failed()) {
+        if (loader.failed()) {
+            ASSERT(!loader.retrievedFromServiceWorkerCache());
+            auto& workerScriptLoader = loader.scriptLoader();
+            ASSERT(workerScriptLoader.failed());
             if (workerScriptLoader.error().isAccessControl()) {
                 rejectToPropagateNetworkError(promise.get(), ModuleFetchFailureKind::WasErrored, "Cross-origin script load denied by Cross-Origin Resource Sharing policy."_s);
                 return;
@@ -432,24 +433,32 @@
             return;
         }
 
-        if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(workerScriptLoader.responseMIMEType())) {
+        if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(loader.responseMIMEType())) {
             // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script
             // The result of extracting a MIME type from response's header list (ignoring parameters) is not a _javascript_ MIME type.
             // For historical reasons, fetching a classic script does not include MIME type checking. In contrast, module scripts will fail to load if they are not of a correct MIME type.
-            promise->reject(TypeError, makeString("'", workerScriptLoader.responseMIMEType(), "' is not a valid _javascript_ MIME type."));
+            promise->reject(TypeError, makeString("'", loader.responseMIMEType(), "' is not a valid _javascript_ MIME type."));
             return;
         }
 
-        if (auto* parameters = loader.parameters()) {
-            // If this is top-level-module, then we extract referrer-policy and apply to the dependent modules.
-            if (parameters->isTopLevelModule())
-                static_cast<WorkerScriptFetcher&>(loader.scriptFetcher()).setReferrerPolicy(loader.referrerPolicy());
+        URL responseURL = loader.responseURL();
+        if (!loader.retrievedFromServiceWorkerCache()) {
+            auto& workerScriptLoader = loader.scriptLoader();
+            if (auto* parameters = loader.parameters()) {
+                // If this is top-level-module, then we extract referrer-policy and apply to the dependent modules.
+                if (parameters->isTopLevelModule())
+                    static_cast<WorkerScriptFetcher&>(loader.scriptFetcher()).setReferrerPolicy(loader.referrerPolicy());
+            }
+            responseURL = canonicalizeAndRegisterResponseURL(responseURL, workerScriptLoader.isRedirected(), workerScriptLoader.responseSource());
+#if ENABLE(SERVICE_WORKER)
+            if (is<ServiceWorkerGlobalScope>(m_context))
+                downcast<ServiceWorkerGlobalScope>(m_context).setScriptResource(sourceURL, ServiceWorkerContextData::ImportedScript { loader.script(), responseURL, loader.responseMIMEType() });
+#endif
         }
-
-        URL responseURL = canonicalizeAndRegisterResponseURL(workerScriptLoader.responseURL(), workerScriptLoader.isRedirected(), workerScriptLoader.responseSource());
+        m_requestURLToResponseURLMap.add(sourceURL.string(), responseURL);
         promise->resolveWithCallback([&] (JSDOMGlobalObject& jsGlobalObject) {
             return JSC::JSSourceCode::create(jsGlobalObject.vm(),
-                JSC::SourceCode { ScriptSourceCode { workerScriptLoader.script(), WTFMove(responseURL), { }, JSC::SourceProviderSourceType::Module, loader.scriptFetcher() }.jsSourceCode() });
+                JSC::SourceCode { ScriptSourceCode { loader.script(), WTFMove(responseURL), { }, JSC::SourceProviderSourceType::Module, loader.scriptFetcher() }.jsSourceCode() });
         });
     }
 }

Modified: trunk/Source/WebCore/bindings/js/WorkerModuleScriptLoader.cpp (275750 => 275751)


--- trunk/Source/WebCore/bindings/js/WorkerModuleScriptLoader.cpp	2021-04-09 06:05:46 UTC (rev 275750)
+++ trunk/Source/WebCore/bindings/js/WorkerModuleScriptLoader.cpp	2021-04-09 08:54:34 UTC (rev 275751)
@@ -61,6 +61,19 @@
 {
     m_sourceURL = WTFMove(sourceURL);
 
+#if ENABLE(SERVICE_WORKER)
+    if (is<ServiceWorkerGlobalScope>(context)) {
+        if (auto* scriptResource = downcast<ServiceWorkerGlobalScope>(context).scriptResource(m_sourceURL)) {
+            m_script = scriptResource->script;
+            m_responseURL = scriptResource->responseURL;
+            m_responseMIMEType = scriptResource->mimeType;
+            m_retrievedFromServiceWorkerCache = true;
+            notifyClientFinished();
+            return true;
+        }
+    }
+#endif
+
     ResourceRequest request { m_sourceURL };
 
     FetchOptions fetchOptions;
@@ -94,7 +107,21 @@
 {
     ASSERT(m_promise);
 
+    if (m_scriptLoader->failed())
+        m_failed = true;
+    else {
+        m_script = m_scriptLoader->script();
+        m_responseURL = m_scriptLoader->responseURL();
+        m_responseMIMEType = m_scriptLoader->responseMIMEType();
+    }
+
+    notifyClientFinished();
+}
+
+void WorkerModuleScriptLoader::notifyClientFinished()
+{
     auto protectedThis = makeRef(*this);
+
     if (m_client)
         m_client->notifyFinished(*this, WTFMove(m_sourceURL), m_promise.releaseNonNull());
 }

Modified: trunk/Source/WebCore/bindings/js/WorkerModuleScriptLoader.h (275750 => 275751)


--- trunk/Source/WebCore/bindings/js/WorkerModuleScriptLoader.h	2021-04-09 06:05:46 UTC (rev 275750)
+++ trunk/Source/WebCore/bindings/js/WorkerModuleScriptLoader.h	2021-04-09 08:54:34 UTC (rev 275751)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "ModuleScriptLoader.h"
+#include "ScriptBuffer.h"
 #include "WorkerScriptFetcher.h"
 #include "WorkerScriptLoaderClient.h"
 #include <wtf/Ref.h>
@@ -54,7 +55,13 @@
 
     static String taskMode();
     ReferrerPolicy referrerPolicy();
+    bool failed() const { return m_failed; }
+    bool retrievedFromServiceWorkerCache() const { return m_retrievedFromServiceWorkerCache; }
 
+    const ScriptBuffer& script() { return m_script; }
+    const URL& responseURL() const { return m_responseURL; }
+    const String& responseMIMEType() const { return m_responseMIMEType; }
+
 private:
     WorkerModuleScriptLoader(ModuleScriptLoaderClient&, DeferredPromise&, WorkerScriptFetcher&, RefPtr<ModuleFetchParameters>&&);
 
@@ -61,8 +68,15 @@
     void didReceiveResponse(unsigned long, const ResourceResponse&) final { }
     void notifyFinished() final;
 
+    void notifyClientFinished();
+
     Ref<WorkerScriptLoader> m_scriptLoader;
     URL m_sourceURL;
+    ScriptBuffer m_script;
+    URL m_responseURL;
+    String m_responseMIMEType;
+    bool m_failed { false };
+    bool m_retrievedFromServiceWorkerCache { false };
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to