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