Title: [286944] trunk
Revision
286944
Author
you...@apple.com
Date
2021-12-13 02:41:06 -0800 (Mon, 13 Dec 2021)

Log Message

Fix ServiceWorker downloads
https://bugs.webkit.org/show_bug.cgi?id=202142
<rdar://problem/55721934>

Reviewed by Alex Christensen.

Source/WebCore:

Add API to ask the fetch task to become a download.

Tests: http/tests/workers/service/service-worker-download-body.https.html
       http/tests/workers/service/service-worker-download-stream.https.html
       http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https.html
       http/wpt/service-workers/fetch-service-worker-preload-download.https.html

* workers/service/context/ServiceWorkerFetch.h:
* workers/service/context/ServiceWorkerThreadProxy.cpp:
* workers/service/context/ServiceWorkerThreadProxy.h:

Source/WebKit:

Add ServiceWorkerDownloadTask class as a NetworkDataTask whose purpose is to download the content of a response given from service worker.
Add a way to convert ServiceWorkerFetchTask into downloads:
- If a preload is ongoing and can be used for navigation, use this preload as the download NetworkLoad.
- If a preload does not exist, create a ServiceWorkerDownloadTask and a corresponding NetworkLoad to start downloading the service worker response data.
When creating a ServiceWorkerDownloadTask, the WebServiceWorkerFetchTaskClient will be notified to start sending response data using ServiceWorkerDownloadTask
instead of ServiceWorkerFetchTask messages. This allows cancelling the ServiceWorkerFetchTask without any issue.

Note that the service worker lifetime is not augmented: if the service worker exits due to all its clients being closed, the download will fail.

Increase unified build files to 112.

* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* NetworkProcess/NetworkConnectionToWebProcess.cpp:
* NetworkProcess/NetworkLoad.cpp:
* NetworkProcess/NetworkLoad.h:
* NetworkProcess/NetworkResourceLoader.cpp:
* NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.cpp: Added.
* NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.h: Added.
* NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.messages.in: Added.
* NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
* NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h:
* NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.cpp:
* NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.h:
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
* NetworkProcess/storage/NetworkStorageManager.cpp:
* Scripts/generate-unified-sources.sh:
* Scripts/webkit/messages.py:
* Scripts/webkit/tests/TestWithCVPixelBufferMessageReceiver.cpp:
(WebKit::TestWithCVPixelBuffer::didReceiveMessage):
* Scripts/webkit/tests/TestWithIfMessageMessageReceiver.cpp:
(WebKit::TestWithIfMessage::didReceiveMessage):
* Scripts/webkit/tests/TestWithImageDataMessageReceiver.cpp:
(WebKit::TestWithImageData::didReceiveMessage):
* Scripts/webkit/tests/TestWithLegacyReceiverMessageReceiver.cpp:
(WebKit::TestWithLegacyReceiver::didReceiveTestWithLegacyReceiverMessage):
* Scripts/webkit/tests/TestWithSemaphoreMessageReceiver.cpp:
(WebKit::TestWithSemaphore::didReceiveMessage):
* Scripts/webkit/tests/TestWithStreamBufferMessageReceiver.cpp:
(WebKit::TestWithStreamBuffer::didReceiveMessage):
* Scripts/webkit/tests/TestWithStreamMessageReceiver.cpp:
(WebKit::TestWithStream::didReceiveStreamMessage):
* Scripts/webkit/tests/TestWithoutAttributesMessageReceiver.cpp:
(WebKit::TestWithoutAttributes::didReceiveMessage):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::receivedPolicyDecision):
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::download):
(WebKit::WebProcessPool::createDownloadProxy):
* Sources.txt:
* UnifiedSources-output.xcfilelist:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/Storage/WebSWContextManagerConnection.cpp:
* WebProcess/Storage/WebSWContextManagerConnection.h:
* WebProcess/Storage/WebSWContextManagerConnection.messages.in:
* WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp:
* WebProcess/Storage/WebServiceWorkerFetchTaskClient.h:

Tools:

Add test runner API to log the total download size.
This helps ensuring that service worker loads are correctly downloaded and do not rely on networking.

* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestController.cpp:
* WebKitTestRunner/TestController.h:
* WebKitTestRunner/TestInvocation.cpp:

LayoutTests:

* http/tests/workers/service/resources/service-worker-download-worker.js:
* http/tests/workers/service/service-worker-download-body.https-expected.txt: Added.
* http/tests/workers/service/service-worker-download-body.https.html: Added.
* http/tests/workers/service/service-worker-download-stream.https-expected.txt: Added.
* http/tests/workers/service/service-worker-download-stream.https.html: Added.
* http/tests/workers/service/service-worker-download.https-expected.txt:
* http/tests/workers/service/service-worker-download.https.html:
* http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https-expected.txt: Added.
* http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https.html: Added.
* http/wpt/service-workers/fetch-service-worker-preload-download.https-expected.txt: Added.
* http/wpt/service-workers/fetch-service-worker-preload-download.https.html: Added.
* http/wpt/service-workers/fetch-service-worker-preload-worker.js:
* http/wpt/service-workers/resources/fetch-service-worker-preload-script.py:
* platform/ios/http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https-expected.txt: Added.
* platform/ios/http/wpt/service-workers/fetch-service-worker-preload-download.https-expected.txt: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (286943 => 286944)


--- trunk/LayoutTests/ChangeLog	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/LayoutTests/ChangeLog	2021-12-13 10:41:06 UTC (rev 286944)
@@ -1,3 +1,27 @@
+2021-12-13  Youenn Fablet  <you...@apple.com>
+
+        Fix ServiceWorker downloads
+        https://bugs.webkit.org/show_bug.cgi?id=202142
+        <rdar://problem/55721934>
+
+        Reviewed by Alex Christensen.
+
+        * http/tests/workers/service/resources/service-worker-download-worker.js:
+        * http/tests/workers/service/service-worker-download-body.https-expected.txt: Added.
+        * http/tests/workers/service/service-worker-download-body.https.html: Added.
+        * http/tests/workers/service/service-worker-download-stream.https-expected.txt: Added.
+        * http/tests/workers/service/service-worker-download-stream.https.html: Added.
+        * http/tests/workers/service/service-worker-download.https-expected.txt:
+        * http/tests/workers/service/service-worker-download.https.html:
+        * http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https-expected.txt: Added.
+        * http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https.html: Added.
+        * http/wpt/service-workers/fetch-service-worker-preload-download.https-expected.txt: Added.
+        * http/wpt/service-workers/fetch-service-worker-preload-download.https.html: Added.
+        * http/wpt/service-workers/fetch-service-worker-preload-worker.js:
+        * http/wpt/service-workers/resources/fetch-service-worker-preload-script.py:
+        * platform/ios/http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https-expected.txt: Added.
+        * platform/ios/http/wpt/service-workers/fetch-service-worker-preload-download.https-expected.txt: Added.
+
 2021-12-13  Martin Robinson  <mrobin...@webkit.org>
 
         `transform-origin` on SVG elements does not take into account the transform reference box origin

Modified: trunk/LayoutTests/http/tests/workers/service/resources/service-worker-download-worker.js (286943 => 286944)


--- trunk/LayoutTests/http/tests/workers/service/resources/service-worker-download-worker.js	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/LayoutTests/http/tests/workers/service/resources/service-worker-download-worker.js	2021-12-13 10:41:06 UTC (rev 286944)
@@ -1,3 +1,21 @@
 self.addEventListener("fetch", (event) => {
+    if (event.request.url.includes("download-body")) {
+        const response = new Response("a download body", {"headers" : [["Content-Type", "application/binary"]]});
+        event.respondWith(response);
+        return;
+    }
+    if (event.request.url.includes("download-stream")) {
+        const stream = new ReadableStream({
+            start: (controller) => {
+                const encoder = new TextEncoder();
+                controller.enqueue(encoder.encode("a first chunk, "));
+                setTimeout(() => { controller.enqueue(encoder.encode("then a second chunk")); }, 100);
+                setTimeout(() => { controller.close(); }, 200);
+            }
+        });
+        const response = new Response(stream, {"headers" : [["Content-Type", "application/binary"]]});
+        event.respondWith(response);
+        return;
+    }
     event.respondWith(fetch(event.request.url));
 });

Added: trunk/LayoutTests/http/tests/workers/service/service-worker-download-body.https-expected.txt (0 => 286944)


--- trunk/LayoutTests/http/tests/workers/service/service-worker-download-body.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/service-worker-download-body.https-expected.txt	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,5 @@
+Download started.
+Downloading URL with suggested filename "download-body"
+Download size: 15.
+Download completed.
+

Copied: trunk/LayoutTests/http/tests/workers/service/service-worker-download-body.https.html (from rev 286943, trunk/LayoutTests/http/tests/workers/service/service-worker-download.https.html) (0 => 286944)


--- trunk/LayoutTests/http/tests/workers/service/service-worker-download-body.https.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/service-worker-download-body.https.html	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,23 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+if (window.testRunner) {
+  testRunner.dumpAsText();
+  testRunner.setShouldLogDownloadCallbacks(true);
+  testRunner.setShouldLogDownloadSize(true);
+  testRunner.waitUntilDownloadFinished();
+  testRunner.setShouldDownloadUndisplayableMIMETypes(true);
+}
+
+async function doTest()
+{
+    await interceptedFrame("resources/service-worker-download-worker.js", "/workers/service/resources/");
+    window.location = "/workers/service/resources/download-body";
+}
+doTest();
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/workers/service/service-worker-download-stream.https-expected.txt (0 => 286944)


--- trunk/LayoutTests/http/tests/workers/service/service-worker-download-stream.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/service-worker-download-stream.https-expected.txt	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,5 @@
+Download started.
+Downloading URL with suggested filename "download-stream"
+Download size: 34.
+Download completed.
+

Copied: trunk/LayoutTests/http/tests/workers/service/service-worker-download-stream.https.html (from rev 286943, trunk/LayoutTests/http/tests/workers/service/service-worker-download.https.html) (0 => 286944)


--- trunk/LayoutTests/http/tests/workers/service/service-worker-download-stream.https.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/service-worker-download-stream.https.html	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,23 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+if (window.testRunner) {
+  testRunner.dumpAsText();
+  testRunner.setShouldLogDownloadCallbacks(true);
+  testRunner.setShouldLogDownloadSize(true);
+  testRunner.waitUntilDownloadFinished();
+  testRunner.setShouldDownloadUndisplayableMIMETypes(true);
+}
+
+async function doTest()
+{
+    await interceptedFrame("resources/service-worker-download-worker.js", "/workers/service/resources/");
+    window.location = "/workers/service/resources/download-stream";
+}
+doTest();
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/http/tests/workers/service/service-worker-download.https-expected.txt (286943 => 286944)


--- trunk/LayoutTests/http/tests/workers/service/service-worker-download.https-expected.txt	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/LayoutTests/http/tests/workers/service/service-worker-download.https-expected.txt	2021-12-13 10:41:06 UTC (rev 286944)
@@ -1,4 +1,5 @@
 Download started.
 Downloading URL with suggested filename "download-binary.py"
+Download size: 9.
 Download completed.
 

Modified: trunk/LayoutTests/http/tests/workers/service/service-worker-download.https.html (286943 => 286944)


--- trunk/LayoutTests/http/tests/workers/service/service-worker-download.https.html	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/LayoutTests/http/tests/workers/service/service-worker-download.https.html	2021-12-13 10:41:06 UTC (rev 286944)
@@ -7,6 +7,7 @@
 if (window.testRunner) {
   testRunner.dumpAsText();
   testRunner.setShouldLogDownloadCallbacks(true);
+  testRunner.setShouldLogDownloadSize(true);
   testRunner.waitUntilDownloadFinished();
   testRunner.setShouldDownloadUndisplayableMIMETypes(true);
 }

Added: trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https-expected.txt (0 => 286944)


--- trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https-expected.txt	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,5 @@
+Download started.
+Downloading URL with suggested filename "fetch-service-worker-preload-script.py.vcf"
+Download size: 11.
+Download completed.
+

Added: trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https.html (0 => 286944)


--- trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https.html	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,66 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+if (window.testRunner) {
+  testRunner.dumpAsText();
+  testRunner.setShouldLogDownloadCallbacks(true);
+  testRunner.setShouldLogDownloadSize(true);
+  testRunner.waitUntilDownloadFinished();
+  testRunner.setShouldDownloadUndisplayableMIMETypes(true);
+}
+
+var activeWorker;
+var uuid = token();
+var url = "" + uuid;
+var frame;
+const channel = new MessageChannel();
+
+function waitUntilActivating()
+{
+    return new Promise(resolve => {
+        channel.port2._onmessage_ = (event) => {
+            if (event.data ="" "activating")
+                resolve();
+        };
+    });
+}
+
+function triggerActivation()
+{
+    activeWorker.postMessage("activate");
+}
+
+async function doTest() {
+    if (window.testRunner) {
+        testRunner.setUseSeparateServiceWorkerProcess(true);
+        await fetch("").then(() => { }, () => { });
+    }
+
+    let registration = await navigator.serviceWorker.register("/WebKit/service-workers/fetch-service-worker-preload-worker.js", { scope : url });
+    if (!registration.installing) {
+        registration.unregister();
+        registration = await navigator.serviceWorker.register("/WebKit/service-workers/fetch-service-worker-preload-worker.js", { scope : url });
+    }
+
+    activeWorker = registration.installing;
+    activeWorker.postMessage({ port: channel.port1 }, [channel.port1]);
+
+    await waitUntilActivating();
+
+    fetch(url + "&value=use-preload", { method: 'POST' });
+
+    // Load iframe, with activating worker, so preload will start and will be the one to be downloaded, directly through preload since service worker did not handle the event.
+    // Download size should be size of "use-preload".
+    const promise = withIframe(url);
+
+    triggerActivation();
+}
+doTest();
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-download.https-expected.txt (0 => 286944)


--- trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-download.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-download.https-expected.txt	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,5 @@
+Download started.
+Downloading URL with suggested filename "fetch-service-worker-preload-script.py.vcf"
+Download size: 11.
+Download completed.
+

Added: trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-download.https.html (0 => 286944)


--- trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-download.https.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-download.https.html	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,66 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+if (window.testRunner) {
+  testRunner.dumpAsText();
+  testRunner.setShouldLogDownloadCallbacks(true);
+  testRunner.setShouldLogDownloadSize(true);
+  testRunner.waitUntilDownloadFinished();
+  testRunner.setShouldDownloadUndisplayableMIMETypes(true);
+}
+
+var activeWorker;
+var uuid = token();
+var url = "" + uuid;
+var frame;
+const channel = new MessageChannel();
+
+function waitUntilActivating()
+{
+    return new Promise(resolve => {
+        channel.port2._onmessage_ = (event) => {
+            if (event.data ="" "activating")
+                resolve();
+        };
+    });
+}
+
+function triggerActivation()
+{
+    activeWorker.postMessage("activate");
+}
+
+async function doTest() {
+    if (window.testRunner) {
+        testRunner.setUseSeparateServiceWorkerProcess(true);
+        await fetch("").then(() => { }, () => { });
+    }
+
+    let registration = await navigator.serviceWorker.register("/WebKit/service-workers/fetch-service-worker-preload-worker.js", { scope : url });
+    if (!registration.installing) {
+        registration.unregister();
+        registration = await navigator.serviceWorker.register("/WebKit/service-workers/fetch-service-worker-preload-worker.js", { scope : url });
+    }
+
+    activeWorker = registration.installing;
+    activeWorker.postMessage({ port: channel.port1 }, [channel.port1]);
+
+    await waitUntilActivating();
+
+    fetch(url + "&value=use-preload", { method: 'POST' });
+
+    // Load iframe, with activating worker, so preload will start and will be the one to be downloaded, through the service worker.
+    // Download size should be size of "use-preload".
+    const promise = withIframe(url);
+
+    triggerActivation();
+}
+doTest();
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-worker.js (286943 => 286944)


--- trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-worker.js	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/LayoutTests/http/wpt/service-workers/fetch-service-worker-preload-worker.js	2021-12-13 10:41:06 UTC (rev 286944)
@@ -23,5 +23,7 @@
 }
 
 self.addEventListener('fetch', (event) => {
+    if (event.request.url.includes("no-fetch-event-handling"))
+        return;
     event.respondWith(fetch(event.request));
 });

Modified: trunk/LayoutTests/http/wpt/service-workers/resources/fetch-service-worker-preload-script.py (286943 => 286944)


--- trunk/LayoutTests/http/wpt/service-workers/resources/fetch-service-worker-preload-script.py	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/LayoutTests/http/wpt/service-workers/resources/fetch-service-worker-preload-script.py	2021-12-13 10:41:06 UTC (rev 286944)
@@ -31,5 +31,10 @@
     if not value:
         value = b"nothing"
     response.headers.set(b"Cache-Control", b"no-cache")
+
+    if b"download" in request.GET:
+        response.headers.set(b"Content-Type", b"text/vcard")
+        return value.decode()
+
     response.headers.set(b"Content-Type", b"text/html")
     return "<html><body><script>window.value = '%s';</script></body></html>" % value.decode()

Added: trunk/LayoutTests/platform/ios/http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https-expected.txt (0 => 286944)


--- trunk/LayoutTests/platform/ios/http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/ios/http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https-expected.txt	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,5 @@
+Download started.
+Downloading URL with suggested filename "fetch-service-worker-preload-script.py"
+Download size: 11.
+Download completed.
+

Added: trunk/LayoutTests/platform/ios/http/wpt/service-workers/fetch-service-worker-preload-download.https-expected.txt (0 => 286944)


--- trunk/LayoutTests/platform/ios/http/wpt/service-workers/fetch-service-worker-preload-download.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/ios/http/wpt/service-workers/fetch-service-worker-preload-download.https-expected.txt	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,5 @@
+Download started.
+Downloading URL with suggested filename "fetch-service-worker-preload-script.py"
+Download size: 11.
+Download completed.
+

Modified: trunk/Source/WebCore/ChangeLog (286943 => 286944)


--- trunk/Source/WebCore/ChangeLog	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebCore/ChangeLog	2021-12-13 10:41:06 UTC (rev 286944)
@@ -1,3 +1,22 @@
+2021-12-13  Youenn Fablet  <you...@apple.com>
+
+        Fix ServiceWorker downloads
+        https://bugs.webkit.org/show_bug.cgi?id=202142
+        <rdar://problem/55721934>
+
+        Reviewed by Alex Christensen.
+
+        Add API to ask the fetch task to become a download.
+
+        Tests: http/tests/workers/service/service-worker-download-body.https.html
+               http/tests/workers/service/service-worker-download-stream.https.html
+               http/wpt/service-workers/fetch-service-worker-preload-download-through-direct-preload.https.html
+               http/wpt/service-workers/fetch-service-worker-preload-download.https.html
+
+        * workers/service/context/ServiceWorkerFetch.h:
+        * workers/service/context/ServiceWorkerThreadProxy.cpp:
+        * workers/service/context/ServiceWorkerThreadProxy.h:
+
 2021-12-13  Kimmo Kinnunen  <kkinnu...@apple.com>
 
         Cocoa WebGL should support UI side compositing

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h (286943 => 286944)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h	2021-12-13 10:41:06 UTC (rev 286944)
@@ -58,6 +58,7 @@
     virtual void didNotHandle() = 0;
     virtual void cancel() = 0;
     virtual void continueDidReceiveResponse() = 0;
+    virtual void convertFetchToDownload() = 0;
 };
 
 void dispatchFetchEvent(Ref<Client>&&, ServiceWorkerGlobalScope&, std::optional<ScriptExecutionContextIdentifier>, ResourceRequest&&, String&& referrer, FetchOptions&&, FetchIdentifier, bool isServiceWorkerNavigationPreloadEnabled);

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp (286943 => 286944)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -242,6 +242,20 @@
     }, WorkerRunLoop::defaultMode());
 }
 
+
+void ServiceWorkerThreadProxy::convertFetchToDownload(SWServerConnectionIdentifier connectionIdentifier, FetchIdentifier fetchIdentifier)
+{
+    RELEASE_LOG(ServiceWorker, "ServiceWorkerThreadProxy::convertFetchToDownload %llu", fetchIdentifier.toUInt64());
+
+    auto client = m_ongoingFetchTasks.take(std::make_pair(connectionIdentifier, fetchIdentifier));
+    if (!client)
+        return;
+
+    postTaskForModeToWorkerOrWorkletGlobalScope([client = Ref { *client }] (auto&) {
+        client->convertFetchToDownload();
+    }, WorkerRunLoop::defaultMode());
+}
+
 void ServiceWorkerThreadProxy::continueDidReceiveFetchResponse(SWServerConnectionIdentifier connectionIdentifier, FetchIdentifier fetchIdentifier)
 {
     auto client = m_ongoingFetchTasks.get(std::make_pair(connectionIdentifier, fetchIdentifier));

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h (286943 => 286944)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h	2021-12-13 10:41:06 UTC (rev 286944)
@@ -77,6 +77,7 @@
 
     WEBCORE_EXPORT void startFetch(SWServerConnectionIdentifier, FetchIdentifier, Ref<ServiceWorkerFetch::Client>&&, std::optional<ScriptExecutionContextIdentifier>&&, ResourceRequest&&, String&& referrer, FetchOptions&&, bool isServiceWorkerNavigationPreloadEnabled);
     WEBCORE_EXPORT void cancelFetch(SWServerConnectionIdentifier, FetchIdentifier);
+    WEBCORE_EXPORT void convertFetchToDownload(SWServerConnectionIdentifier, FetchIdentifier);
     WEBCORE_EXPORT void continueDidReceiveFetchResponse(SWServerConnectionIdentifier, FetchIdentifier);
     WEBCORE_EXPORT void removeFetch(SWServerConnectionIdentifier, FetchIdentifier);
 

Modified: trunk/Source/WebKit/CMakeLists.txt (286943 => 286944)


--- trunk/Source/WebKit/CMakeLists.txt	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/CMakeLists.txt	2021-12-13 10:41:06 UTC (rev 286944)
@@ -197,6 +197,7 @@
     NetworkProcess/NetworkSocketChannel
     NetworkProcess/NetworkSocketStream
 
+    NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask
     NetworkProcess/ServiceWorker/ServiceWorkerFetchTask
     NetworkProcess/ServiceWorker/WebSWServerConnection
     NetworkProcess/ServiceWorker/WebSWServerToContextConnection

Modified: trunk/Source/WebKit/ChangeLog (286943 => 286944)


--- trunk/Source/WebKit/ChangeLog	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/ChangeLog	2021-12-13 10:41:06 UTC (rev 286944)
@@ -1,3 +1,72 @@
+2021-12-13  Youenn Fablet  <you...@apple.com>
+
+        Fix ServiceWorker downloads
+        https://bugs.webkit.org/show_bug.cgi?id=202142
+        <rdar://problem/55721934>
+
+        Reviewed by Alex Christensen.
+
+        Add ServiceWorkerDownloadTask class as a NetworkDataTask whose purpose is to download the content of a response given from service worker.
+        Add a way to convert ServiceWorkerFetchTask into downloads:
+        - If a preload is ongoing and can be used for navigation, use this preload as the download NetworkLoad.
+        - If a preload does not exist, create a ServiceWorkerDownloadTask and a corresponding NetworkLoad to start downloading the service worker response data.
+        When creating a ServiceWorkerDownloadTask, the WebServiceWorkerFetchTaskClient will be notified to start sending response data using ServiceWorkerDownloadTask
+        instead of ServiceWorkerFetchTask messages. This allows cancelling the ServiceWorkerFetchTask without any issue.
+
+        Note that the service worker lifetime is not augmented: if the service worker exits due to all its clients being closed, the download will fail.
+
+        Increase unified build files to 112.
+
+        * CMakeLists.txt:
+        * DerivedSources-input.xcfilelist:
+        * DerivedSources-output.xcfilelist:
+        * DerivedSources.make:
+        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+        * NetworkProcess/NetworkLoad.cpp:
+        * NetworkProcess/NetworkLoad.h:
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        * NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.cpp: Added.
+        * NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.h: Added.
+        * NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.messages.in: Added.
+        * NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
+        * NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h:
+        * NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.cpp:
+        * NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.h:
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
+        * NetworkProcess/storage/NetworkStorageManager.cpp:
+        * Scripts/generate-unified-sources.sh:
+        * Scripts/webkit/messages.py:
+        * Scripts/webkit/tests/TestWithCVPixelBufferMessageReceiver.cpp:
+        (WebKit::TestWithCVPixelBuffer::didReceiveMessage):
+        * Scripts/webkit/tests/TestWithIfMessageMessageReceiver.cpp:
+        (WebKit::TestWithIfMessage::didReceiveMessage):
+        * Scripts/webkit/tests/TestWithImageDataMessageReceiver.cpp:
+        (WebKit::TestWithImageData::didReceiveMessage):
+        * Scripts/webkit/tests/TestWithLegacyReceiverMessageReceiver.cpp:
+        (WebKit::TestWithLegacyReceiver::didReceiveTestWithLegacyReceiverMessage):
+        * Scripts/webkit/tests/TestWithSemaphoreMessageReceiver.cpp:
+        (WebKit::TestWithSemaphore::didReceiveMessage):
+        * Scripts/webkit/tests/TestWithStreamBufferMessageReceiver.cpp:
+        (WebKit::TestWithStreamBuffer::didReceiveMessage):
+        * Scripts/webkit/tests/TestWithStreamMessageReceiver.cpp:
+        (WebKit::TestWithStream::didReceiveStreamMessage):
+        * Scripts/webkit/tests/TestWithoutAttributesMessageReceiver.cpp:
+        (WebKit::TestWithoutAttributes::didReceiveMessage):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::receivedPolicyDecision):
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::download):
+        (WebKit::WebProcessPool::createDownloadProxy):
+        * Sources.txt:
+        * UnifiedSources-output.xcfilelist:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+        * WebProcess/Storage/WebSWContextManagerConnection.h:
+        * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
+        * WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp:
+        * WebProcess/Storage/WebServiceWorkerFetchTaskClient.h:
+
 2021-12-13  Kimmo Kinnunen  <kkinnu...@apple.com>
 
         Cocoa WebGL should support UI side compositing

Modified: trunk/Source/WebKit/DerivedSources-input.xcfilelist (286943 => 286944)


--- trunk/Source/WebKit/DerivedSources-input.xcfilelist	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/DerivedSources-input.xcfilelist	2021-12-13 10:41:06 UTC (rev 286944)
@@ -87,6 +87,7 @@
 $(PROJECT_DIR)/NetworkProcess/NetworkResourceLoader.messages.in
 $(PROJECT_DIR)/NetworkProcess/NetworkSocketChannel.messages.in
 $(PROJECT_DIR)/NetworkProcess/NetworkSocketStream.messages.in
+$(PROJECT_DIR)/NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.messages.in
 $(PROJECT_DIR)/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.messages.in
 $(PROJECT_DIR)/NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in
 $(PROJECT_DIR)/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.messages.in

Modified: trunk/Source/WebKit/DerivedSources-output.xcfilelist (286943 => 286944)


--- trunk/Source/WebKit/DerivedSources-output.xcfilelist	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/DerivedSources-output.xcfilelist	2021-12-13 10:41:06 UTC (rev 286944)
@@ -396,6 +396,9 @@
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/SecItemShimProxyMessageReceiver.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/SecItemShimProxyMessages.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/SecItemShimProxyMessagesReplies.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/ServiceWorkerDownloadTaskMessageReceiver.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/ServiceWorkerDownloadTaskMessages.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/ServiceWorkerDownloadTaskMessagesReplies.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/ServiceWorkerFetchTaskMessageReceiver.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/ServiceWorkerFetchTaskMessages.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/ServiceWorkerFetchTaskMessagesReplies.h

Modified: trunk/Source/WebKit/DerivedSources.make (286943 => 286944)


--- trunk/Source/WebKit/DerivedSources.make	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/DerivedSources.make	2021-12-13 10:41:06 UTC (rev 286944)
@@ -132,6 +132,7 @@
 	NetworkProcess/CustomProtocols/LegacyCustomProtocolManager \
 	NetworkProcess/NetworkSocketChannel \
 	NetworkProcess/ServiceWorker/WebSWServerConnection \
+	NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask \
 	NetworkProcess/ServiceWorker/ServiceWorkerFetchTask \
 	NetworkProcess/ServiceWorker/WebSWServerToContextConnection \
 	NetworkProcess/NetworkSocketStream \

Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp (286943 => 286944)


--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -695,8 +695,7 @@
 {
     RELEASE_ASSERT(RunLoop::isMain());
 
-    // In case a response is served from service worker, we do not have yet the ability to convert the load.
-    if (!mainResourceLoadIdentifier || response.source() == ResourceResponse::Source::ServiceWorker) {
+    if (!mainResourceLoadIdentifier) {
         m_networkProcess->downloadManager().startDownload(m_sessionID, downloadID, request, isNavigatingToAppBoundDomain);
         return;
     }

Modified: trunk/Source/WebKit/NetworkProcess/NetworkLoad.cpp (286943 => 286944)


--- trunk/Source/WebKit/NetworkProcess/NetworkLoad.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/NetworkProcess/NetworkLoad.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -56,6 +56,13 @@
         m_task = NetworkDataTask::create(networkSession, *this, m_parameters);
 }
 
+NetworkLoad::NetworkLoad(NetworkLoadClient& client, NetworkSession& networkSession, const Function<RefPtr<NetworkDataTask>(NetworkDataTaskClient&)>& createTask)
+    : m_client(client)
+    , m_networkProcess(networkSession.networkProcess())
+    , m_task(createTask(*this))
+{
+}
+
 void NetworkLoad::start()
 {
     if (!m_task)

Modified: trunk/Source/WebKit/NetworkProcess/NetworkLoad.h (286943 => 286944)


--- trunk/Source/WebKit/NetworkProcess/NetworkLoad.h	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/NetworkProcess/NetworkLoad.h	2021-12-13 10:41:06 UTC (rev 286944)
@@ -46,6 +46,7 @@
     WTF_MAKE_FAST_ALLOCATED;
 public:
     NetworkLoad(NetworkLoadClient&, WebCore::BlobRegistryImpl*, NetworkLoadParameters&&, NetworkSession&);
+    NetworkLoad(NetworkLoadClient&, NetworkSession&, const Function<RefPtr<NetworkDataTask>(NetworkDataTaskClient&)>&);
     ~NetworkLoad();
 
     void start();

Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (286943 => 286944)


--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -484,6 +484,11 @@
 {
     LOADER_RELEASE_LOG("convertToDownload: (downloadID=%" PRIu64 ", hasNetworkLoad=%d, hasResponseCompletionHandler=%d)", downloadID.toUInt64(), !!m_networkLoad, !!m_responseCompletionHandler);
 
+#if ENABLE(SERVICE_WORKER)
+    if (m_serviceWorkerFetchTask && m_serviceWorkerFetchTask->convertToDownload(m_connection->networkProcess().downloadManager(), downloadID, request, response))
+        return;
+#endif
+
     // This can happen if the resource came from the disk cache.
     if (!m_networkLoad) {
         m_connection->networkProcess().downloadManager().startDownload(sessionID(), downloadID, request, m_parameters.isNavigatingToAppBoundDomain);

Added: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.cpp (0 => 286944)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.cpp	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ServiceWorkerDownloadTask.h"
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "DownloadManager.h"
+#include "Logging.h"
+#include "NetworkProcess.h"
+#include "WebErrors.h"
+#include "WebSWContextManagerConnectionMessages.h"
+#include "WebSWServerToContextConnection.h"
+#include <wtf/WorkQueue.h>
+
+namespace WebKit {
+
+using namespace WebCore;
+
+static WorkQueue& sharedServiceWorkerDownloadTaskQueue()
+{
+    static NeverDestroyed<Ref<WorkQueue>> queue(WorkQueue::create("Shared ServiceWorkerDownloadTask Queue"));
+    return queue.get();
+}
+
+ServiceWorkerDownloadTask::ServiceWorkerDownloadTask(NetworkSession& session, NetworkDataTaskClient& client, WebSWServerToContextConnection& serviceWorkerConnection, ServiceWorkerIdentifier serviceWorkerIdentifier, SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier, const WebCore::ResourceRequest& request, DownloadID downloadID)
+    : NetworkDataTask(session, client, request, StoredCredentialsPolicy::DoNotUse, false, false)
+    , m_serviceWorkerConnection(serviceWorkerConnection)
+    , m_serviceWorkerIdentifier(serviceWorkerIdentifier)
+    , m_serverConnectionIdentifier(serverConnectionIdentifier)
+    , m_fetchIdentifier(fetchIdentifier)
+    , m_downloadID(downloadID)
+    , m_networkProcess(serviceWorkerConnection.networkProcess())
+{
+    serviceWorkerConnection.registerDownload(*this);
+}
+
+ServiceWorkerDownloadTask::~ServiceWorkerDownloadTask()
+{
+    ASSERT(!m_serviceWorkerConnection);
+}
+
+void ServiceWorkerDownloadTask::close()
+{
+    ASSERT(isMainRunLoop());
+
+    if (m_serviceWorkerConnection) {
+        m_serviceWorkerConnection->unregisterDownload(*this);
+        m_serviceWorkerConnection = nullptr;
+    }
+}
+
+template<typename Message> bool ServiceWorkerDownloadTask::sendToServiceWorker(Message&& message)
+{
+    return m_serviceWorkerConnection ? m_serviceWorkerConnection->ipcConnection().send(std::forward<Message>(message), 0) : false;
+}
+
+void ServiceWorkerDownloadTask::dispatchToThread(Function<void()>&& function)
+{
+    sharedServiceWorkerDownloadTaskQueue().dispatch([protectedThis = Ref { *this }, function = WTFMove(function)] {
+        function();
+    });
+}
+
+void ServiceWorkerDownloadTask::cancel()
+{
+    ASSERT(isMainRunLoop());
+
+    sharedServiceWorkerDownloadTaskQueue().dispatch([this, protectedThis = Ref { *this }] {
+        if (m_downloadFile != FileSystem::invalidPlatformFileHandle) {
+            FileSystem::closeFile(m_downloadFile);
+            m_downloadFile = FileSystem::invalidPlatformFileHandle;
+        }
+    });
+
+    if (m_sandboxExtension) {
+        m_sandboxExtension->revoke();
+        m_sandboxExtension = nullptr;
+    }
+
+    sendToServiceWorker(Messages::WebSWContextManagerConnection::CancelFetch { m_serverConnectionIdentifier, m_serviceWorkerIdentifier, m_fetchIdentifier });
+
+    m_state = State::Completed;
+    close();
+}
+
+void ServiceWorkerDownloadTask::resume()
+{
+    ASSERT(isMainRunLoop());
+
+    m_state = State::Running;
+}
+
+void ServiceWorkerDownloadTask::invalidateAndCancel()
+{
+    ASSERT(isMainRunLoop());
+
+    cancel();
+}
+
+void ServiceWorkerDownloadTask::setPendingDownloadLocation(const WTF::String& filename, SandboxExtension::Handle&& sandboxExtensionHandle, bool allowOverwrite)
+{
+    ASSERT(isMainRunLoop());
+
+    if (!networkSession()) {
+        sharedServiceWorkerDownloadTaskQueue().dispatch([this, protectedThis = Ref { *this }]() mutable {
+            didFailDownload();
+        });
+        return;
+    }
+
+    NetworkDataTask::setPendingDownloadLocation(filename, { }, allowOverwrite);
+
+    ASSERT(!m_sandboxExtension);
+    m_sandboxExtension = SandboxExtension::create(WTFMove(sandboxExtensionHandle));
+    if (m_sandboxExtension)
+        m_sandboxExtension->consume();
+
+    sharedServiceWorkerDownloadTaskQueue().dispatch([this, protectedThis = Ref { *this }, allowOverwrite , filename = filename.isolatedCopy()]() mutable {
+        if (allowOverwrite && FileSystem::fileExists(filename)) {
+            if (!FileSystem::deleteFile(filename)) {
+                didFailDownload();
+                return;
+            }
+        }
+
+        m_downloadFile = FileSystem::openFile(m_pendingDownloadLocation, FileSystem::FileOpenMode::Write);
+        if (m_downloadFile == FileSystem::invalidPlatformFileHandle)
+            didFailDownload();
+    });
+}
+
+void ServiceWorkerDownloadTask::start()
+{
+    ASSERT(m_state != State::Completed);
+
+    if (!sendToServiceWorker(Messages::WebSWContextManagerConnection::ConvertFetchToDownload { m_serverConnectionIdentifier, m_serviceWorkerIdentifier, m_fetchIdentifier })) {
+        sharedServiceWorkerDownloadTaskQueue().dispatch([this, protectedThis = Ref { *this }]() mutable {
+            didFailDownload();
+        });
+        return;
+    }
+
+    m_state = State::Running;
+
+    auto& manager = m_networkProcess->downloadManager();
+    auto download = makeUnique<Download>(manager, m_downloadID, *this, *networkSession());
+    auto* downloadPtr = download.get();
+    manager.dataTaskBecameDownloadTask(m_downloadID, WTFMove(download));
+    downloadPtr->didCreateDestination(m_pendingDownloadLocation);
+}
+
+void ServiceWorkerDownloadTask::didReceiveData(const IPC::DataReference& data, int64_t encodedDataLength)
+{
+    ASSERT(!isMainRunLoop());
+
+    if (m_downloadFile == FileSystem::invalidPlatformFileHandle)
+        return;
+
+    size_t bytesWritten = FileSystem::writeToFile(m_downloadFile, data.data(), data.size());
+
+    if (bytesWritten != data.size()) {
+        didFailDownload();
+        return;
+    }
+
+    callOnMainRunLoop([this, protectedThis = Ref { *this }, bytesWritten] {
+        m_downloadBytesWritten += bytesWritten;
+        if (auto* download = m_networkProcess->downloadManager().download(m_pendingDownloadID))
+            download->didReceiveData(bytesWritten, m_downloadBytesWritten, 0);
+    });
+}
+
+void ServiceWorkerDownloadTask::didReceiveFormData(const IPC::FormDataReference& formData)
+{
+    ASSERT(!isMainRunLoop());
+
+    // FIXME: Support writing formData in downloads.
+    RELEASE_LOG_ERROR(ServiceWorker, "ServiceWorkerDownloadTask::didReceiveFormData not implemented");
+    didFailDownload();
+}
+
+void ServiceWorkerDownloadTask::didFinish()
+{
+    ASSERT(!isMainRunLoop());
+
+    FileSystem::closeFile(m_downloadFile);
+    m_downloadFile = FileSystem::invalidPlatformFileHandle;
+
+    callOnMainRunLoop([this, protectedThis = Ref { *this }] {
+        m_state = State::Completed;
+        close();
+
+        if (m_sandboxExtension) {
+            m_sandboxExtension->revoke();
+            m_sandboxExtension = nullptr;
+        }
+
+        if (auto download = m_networkProcess->downloadManager().download(m_pendingDownloadID))
+            download->didFinish();
+
+        if (m_client)
+            m_client->didCompleteWithError({ });
+    });
+}
+
+void ServiceWorkerDownloadTask::didFail(ResourceError&& error)
+{
+    ASSERT(!isMainRunLoop());
+
+    didFailDownload(WTFMove(error));
+}
+
+void ServiceWorkerDownloadTask::didFailDownload(std::optional<ResourceError>&& error)
+{
+    ASSERT(!isMainRunLoop());
+
+    if (m_downloadFile != FileSystem::invalidPlatformFileHandle) {
+        FileSystem::closeFile(m_downloadFile);
+        m_downloadFile = FileSystem::invalidPlatformFileHandle;
+    }
+
+    callOnMainRunLoop([this, protectedThis = Ref { *this }, error = crossThreadCopy(WTFMove(error))] {
+        if (m_state == State::Completed)
+            return;
+
+        m_state = State::Completed;
+        close();
+
+        if (m_sandboxExtension) {
+            m_sandboxExtension->revoke();
+            m_sandboxExtension = nullptr;
+        }
+
+        auto resourceError = error.value_or(cancelledError(firstRequest()));
+        if (auto download = m_networkProcess->downloadManager().download(m_pendingDownloadID))
+            download->didFail(resourceError, IPC::DataReference());
+
+        if (m_client)
+            m_client->didCompleteWithError(resourceError);
+    });
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(SERVICE_WORKER)

Added: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.h (0 => 286944)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.h	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.h	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "Connection.h"
+#include "DataReference.h"
+#include "Download.h"
+#include "NetworkConnectionToWebProcess.h"
+#include "NetworkDataTask.h"
+#include <WebCore/FetchIdentifier.h>
+#include <wtf/FileSystem.h>
+
+namespace IPC {
+class FormDataReference;
+}
+
+namespace WebKit {
+
+class NetworkLoad;
+class NetworkProcess;
+class SandboxExtension;
+class WebSWServerToContextConnection;
+
+class ServiceWorkerDownloadTask : public NetworkDataTask, public IPC::Connection::ThreadMessageReceiver {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static Ref<ServiceWorkerDownloadTask> create(NetworkSession& session, NetworkDataTaskClient& client, WebSWServerToContextConnection& connection, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::FetchIdentifier fetchIdentifier, const WebCore::ResourceRequest& request, DownloadID downloadID) { return adoptRef(* new ServiceWorkerDownloadTask(session, client, connection, serviceWorkerIdentifier, serverConnectionIdentifier, fetchIdentifier, request, downloadID)); }
+    ~ServiceWorkerDownloadTask();
+
+    WebCore::FetchIdentifier fetchIdentifier() const { return m_fetchIdentifier; }
+    void contextClosed() { cancel(); }
+    void start();
+    void stop() { cancel(); }
+
+    using NetworkDataTask::ref;
+    using NetworkDataTask::deref;
+    using NetworkDataTask::weakPtrFactory;
+    using NetworkDataTask::WeakValueType;
+
+private:
+    ServiceWorkerDownloadTask(NetworkSession&, NetworkDataTaskClient&, WebSWServerToContextConnection&, WebCore::ServiceWorkerIdentifier, WebCore::SWServerConnectionIdentifier, WebCore::FetchIdentifier, const WebCore::ResourceRequest&, DownloadID);
+
+    // IPC Message
+    void didReceiveData(const IPC::DataReference&, int64_t encodedDataLength);
+    void didReceiveFormData(const IPC::FormDataReference&);
+    void didFinish();
+    void didFail(WebCore::ResourceError&&);
+
+    // NetworkDataTask
+    void cancel() final;
+    void resume() final;
+    void invalidateAndCancel() final;
+    State state() const final { return m_state; }
+    void setPendingDownloadLocation(const String& filename, SandboxExtension::Handle&&, bool /*allowOverwrite*/) final;
+
+    // IPC::Connection::ThreadMessageReceiver
+    void dispatchToThread(Function<void()>&&) final;
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
+    void refMessageReceiver() final { ref(); }
+    void derefMessageReceiver() final { deref(); }
+
+    template<typename Message> bool sendToServiceWorker(Message&&);
+    void didFailDownload(std::optional<WebCore::ResourceError>&& = { });
+    void close();
+
+    WeakPtr<WebSWServerToContextConnection> m_serviceWorkerConnection;
+    WebCore::ServiceWorkerIdentifier m_serviceWorkerIdentifier;
+    WebCore::SWServerConnectionIdentifier m_serverConnectionIdentifier;
+    WebCore::FetchIdentifier m_fetchIdentifier;
+    DownloadID m_downloadID;
+    Ref<NetworkProcess> m_networkProcess;
+    RefPtr<SandboxExtension> m_sandboxExtension;
+    FileSystem::PlatformFileHandle m_downloadFile { FileSystem::invalidPlatformFileHandle };
+    int64_t m_downloadBytesWritten { 0 };
+    State m_state { State::Suspended };
+};
+
+}
+
+#endif // ENABLE(SERVICE_WORKER)

Added: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.messages.in (0 => 286944)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.messages.in	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.messages.in	2021-12-13 10:41:06 UTC (rev 286944)
@@ -0,0 +1,32 @@
+# Copyright (C) 2021 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#if ENABLE(SERVICE_WORKER)
+
+messages -> ServiceWorkerDownloadTask NotRefCounted {
+    DidFail(WebCore::ResourceError error)
+    DidReceiveData(IPC::SharedBufferDataReference data, int64_t encodedDataLength)
+    DidReceiveFormData(IPC::FormDataReference data)
+    DidFinish()
+}
+
+#endif // ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp (286943 => 286944)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -31,6 +31,7 @@
 #include "Connection.h"
 #include "FormDataReference.h"
 #include "Logging.h"
+#include "NetworkLoad.h"
 #include "NetworkProcess.h"
 #include "NetworkResourceLoader.h"
 #include "NetworkSession.h"
@@ -302,7 +303,10 @@
 
 void ServiceWorkerFetchTask::cancelFromClient()
 {
-    SWFETCH_RELEASE_LOG("cancelFromClient:");
+    SWFETCH_RELEASE_LOG("cancelFromClient: isDone=%d", m_isDone);
+    if (m_isDone)
+        return;
+
     sendToServiceWorker(Messages::WebSWContextManagerConnection::CancelFetch { m_serverConnectionIdentifier, m_serviceWorkerIdentifier, m_fetchIdentifier });
 }
 
@@ -418,6 +422,36 @@
     return m_swServerConnection ? m_swServerConnection->session() : nullptr;
 }
 
+bool ServiceWorkerFetchTask::convertToDownload(DownloadManager& manager, DownloadID downloadID, const ResourceRequest& request, const ResourceResponse& response)
+{
+    if (m_preloader  && !m_preloader->isServiceWorkerNavigationPreloadEnabled())
+        return m_preloader->convertToDownload(manager, downloadID, request, response);
+
+    auto* session = this->session();
+    if (!session || !m_serviceWorkerConnection)
+        return false;
+
+    m_isDone = true;
+
+    // FIXME: We might want to keep the service worker alive until the download ends.
+    RefPtr<ServiceWorkerDownloadTask> serviceWorkerDownloadTask;
+    auto serviceWorkerDownloadLoad = makeUnique<NetworkLoad>(m_loader, *session, [&](auto& client) {
+        serviceWorkerDownloadTask =  ServiceWorkerDownloadTask::create(*session, client, *m_serviceWorkerConnection, m_serviceWorkerIdentifier, m_serverConnectionIdentifier, m_fetchIdentifier, request, downloadID);
+        return serviceWorkerDownloadTask.copyRef();
+    });
+
+    ResponseCompletionHandler completionHandler = [serviceWorkerDownloadTask = WTFMove(serviceWorkerDownloadTask)](auto policy) {
+        if (policy != PolicyAction::Download) {
+            serviceWorkerDownloadTask->stop();
+            return;
+        }
+        serviceWorkerDownloadTask->start();
+    };
+
+    manager.convertNetworkLoadToDownload(downloadID, WTFMove(serviceWorkerDownloadLoad), WTFMove(completionHandler), { }, request, response);
+    return true;
+}
+
 } // namespace WebKit
 
 #undef SWFETCH_RELEASE_LOG

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h (286943 => 286944)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h	2021-12-13 10:41:06 UTC (rev 286944)
@@ -28,6 +28,7 @@
 #if ENABLE(SERVICE_WORKER)
 
 #include "DataReference.h"
+#include "DownloadID.h"
 #include <WebCore/FetchIdentifier.h>
 #include <WebCore/ResourceRequest.h>
 #include <WebCore/ScriptExecutionContextIdentifier.h>
@@ -54,6 +55,7 @@
 }
 
 namespace WebKit {
+class DownloadManager;
 class NetworkResourceLoader;
 class NetworkSession;
 class ServiceWorkerNavigationPreloader;
@@ -85,6 +87,8 @@
     void cannotHandle();
     void contextClosed();
 
+    bool convertToDownload(DownloadManager&, DownloadID, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
+
 private:
     enum class ShouldSetSource : bool { No, Yes };
     void didReceiveRedirectResponse(WebCore::ResourceResponse&&);

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.cpp (286943 => 286944)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -28,6 +28,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "DownloadManager.h"
 #include "Logging.h"
 #include "NetworkCache.h"
 #include "NetworkLoad.h"
@@ -242,6 +243,15 @@
     m_bodyCallback = WTFMove(callback);
 }
 
+bool ServiceWorkerNavigationPreloader::convertToDownload(DownloadManager& manager, DownloadID downloadID, const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response)
+{
+    if (!m_networkLoad)
+        return false;
+
+    manager.convertNetworkLoadToDownload(downloadID, std::exchange(m_networkLoad, nullptr), WTFMove(m_responseCompletionHandler), { }, request, response);
+    return true;
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.h (286943 => 286944)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.h	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.h	2021-12-13 10:41:06 UTC (rev 286944)
@@ -27,6 +27,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "DownloadID.h"
 #include "NetworkCacheEntry.h"
 #include "NetworkLoadClient.h"
 #include "NetworkLoadParameters.h"
@@ -39,6 +40,7 @@
 
 namespace WebKit {
 
+class DownloadManager;
 class NetworkLoad;
 class NetworkSession;
 
@@ -60,6 +62,8 @@
     const WebCore::NetworkLoadMetrics& networkLoadMetrics() const { return m_networkLoadMetrics; }
     bool isServiceWorkerNavigationPreloadEnabled() const { return m_state.enabled; }
 
+    bool convertToDownload(DownloadManager&, DownloadID, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
+
 private:
     // NetworkLoadClient.
     void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) final { }

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp (286943 => 286944)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -33,6 +33,7 @@
 #include "NetworkConnectionToWebProcess.h"
 #include "NetworkProcess.h"
 #include "NetworkProcessProxyMessages.h"
+#include "ServiceWorkerDownloadTaskMessages.h"
 #include "ServiceWorkerFetchTask.h"
 #include "ServiceWorkerFetchTaskMessages.h"
 #include "WebCoreArgumentCoders.h"
@@ -59,6 +60,10 @@
     for (auto& fetch : fetches.values())
         fetch->contextClosed();
 
+    auto downloads = WTFMove(m_ongoingDownloads);
+    for (auto& download : downloads.values())
+        download->contextClosed();
+
     if (m_server && m_server->contextConnectionForRegistrableDomain(registrableDomain()) == this)
         m_server->removeContextConnection(*this);
 }
@@ -197,6 +202,19 @@
     m_ongoingFetches.remove(task.fetchIdentifier());
 }
 
+void WebSWServerToContextConnection::registerDownload(ServiceWorkerDownloadTask& task)
+{
+    ASSERT(!m_ongoingDownloads.contains(task.fetchIdentifier()));
+    m_ongoingDownloads.add(task.fetchIdentifier(), task);
+    m_connection.connection().addThreadMessageReceiver(Messages::ServiceWorkerDownloadTask::messageReceiverName(), &task, task.fetchIdentifier().toUInt64());
+}
+
+void WebSWServerToContextConnection::unregisterDownload(ServiceWorkerDownloadTask& task)
+{
+    m_ongoingDownloads.remove(task.fetchIdentifier());
+    m_connection.connection().removeThreadMessageReceiver(Messages::ServiceWorkerDownloadTask::messageReceiverName(), task.fetchIdentifier().toUInt64());
+}
+
 WebCore::ProcessIdentifier WebSWServerToContextConnection::webProcessIdentifier() const
 {
     return m_connection.webProcessIdentifier();

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h (286943 => 286944)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h	2021-12-13 10:41:06 UTC (rev 286944)
@@ -29,6 +29,7 @@
 
 #include "MessageReceiver.h"
 #include "MessageSender.h"
+#include "ServiceWorkerDownloadTask.h"
 #include "ServiceWorkerFetchTask.h"
 #include "WebPageProxyIdentifier.h"
 #include <WebCore/SWServerToContextConnection.h>
@@ -74,8 +75,11 @@
 
     void registerFetch(ServiceWorkerFetchTask&);
     void unregisterFetch(ServiceWorkerFetchTask&);
+    void registerDownload(ServiceWorkerDownloadTask&);
+    void unregisterDownload(ServiceWorkerDownloadTask&);
 
     WebCore::ProcessIdentifier webProcessIdentifier() const;
+    NetworkProcess& networkProcess() { return m_connection.networkProcess(); }
 
 private:
     // IPC::MessageSender
@@ -103,6 +107,7 @@
     NetworkConnectionToWebProcess& m_connection;
     WeakPtr<WebCore::SWServer> m_server;
     HashMap<WebCore::FetchIdentifier, WeakPtr<ServiceWorkerFetchTask>> m_ongoingFetches;
+    HashMap<WebCore::FetchIdentifier, WeakPtr<ServiceWorkerDownloadTask>> m_ongoingDownloads;
     bool m_isThrottleable { true };
     WebPageProxyIdentifier m_webPageProxyID;
     size_t m_processingPushEventsCount { 0 };

Modified: trunk/Source/WebKit/NetworkProcess/storage/LocalStorageManager.h (286943 => 286944)


--- trunk/Source/WebKit/NetworkProcess/storage/LocalStorageManager.h	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/NetworkProcess/storage/LocalStorageManager.h	2021-12-13 10:41:06 UTC (rev 286944)
@@ -25,7 +25,9 @@
 
 #pragma once
 
+#include "Connection.h"
 #include "StorageAreaIdentifier.h"
+#include <wtf/WorkQueue.h>
 
 namespace WebCore {
 struct ClientOrigin;

Modified: trunk/Source/WebKit/Scripts/generate-unified-sources.sh (286943 => 286944)


--- trunk/Source/WebKit/Scripts/generate-unified-sources.sh	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/Scripts/generate-unified-sources.sh	2021-12-13 10:41:06 UTC (rev 286944)
@@ -14,7 +14,7 @@
     fi
 fi
 
-UnifiedSourceCppFileCount=112
+UnifiedSourceCppFileCount=115
 UnifiedSourceMmFileCount=80
 
 if [ $# -eq 0 ]; then

Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (286943 => 286944)


--- trunk/Source/WebKit/Scripts/webkit/messages.py	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py	2021-12-13 10:41:06 UTC (rev 286944)
@@ -1126,7 +1126,7 @@
             result.append('    if (connection.connection().ignoreInvalidMessageForTesting())\n')
             result.append('        return;\n')
             result.append('#endif // ENABLE(IPC_TESTING_API)\n')
-            result.append('    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled stream message %s to %" PRIu64, description(decoder.messageName()), decoder.destinationID());\n')
+            result.append('    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled stream message %s to %" PRIu64, IPC::description(decoder.messageName()), decoder.destinationID());\n')
         result.append('}\n')
     elif async_messages or receiver.has_attribute(WANTS_DISPATCH_MESSAGE_ATTRIBUTE) or receiver.has_attribute(WANTS_ASYNC_DISPATCH_MESSAGE_ATTRIBUTE):
         receive_variant = receiver.name if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE) else ''
@@ -1149,7 +1149,7 @@
             result.append('    if (connection.ignoreInvalidMessageForTesting())\n')
             result.append('        return;\n')
             result.append('#endif // ENABLE(IPC_TESTING_API)\n')
-            result.append('    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, description(decoder.messageName()), decoder.destinationID());\n')
+            result.append('    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, IPC::description(decoder.messageName()), decoder.destinationID());\n')
         result.append('}\n')
 
     if not receiver.has_attribute(STREAM_ATTRIBUTE) and (sync_messages or receiver.has_attribute(WANTS_DISPATCH_MESSAGE_ATTRIBUTE)):

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithCVPixelBufferMessageReceiver.cpp (286943 => 286944)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithCVPixelBufferMessageReceiver.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithCVPixelBufferMessageReceiver.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -53,7 +53,7 @@
     if (connection.ignoreInvalidMessageForTesting())
         return;
 #endif // ENABLE(IPC_TESTING_API)
-    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, description(decoder.messageName()), decoder.destinationID());
+    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, IPC::description(decoder.messageName()), decoder.destinationID());
 }
 
 bool TestWithCVPixelBuffer::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, UniqueRef<IPC::Encoder>& replyEncoder)

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithIfMessageMessageReceiver.cpp (286943 => 286944)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithIfMessageMessageReceiver.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithIfMessageMessageReceiver.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -54,7 +54,7 @@
     if (connection.ignoreInvalidMessageForTesting())
         return;
 #endif // ENABLE(IPC_TESTING_API)
-    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, description(decoder.messageName()), decoder.destinationID());
+    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, IPC::description(decoder.messageName()), decoder.destinationID());
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithImageDataMessageReceiver.cpp (286943 => 286944)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithImageDataMessageReceiver.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithImageDataMessageReceiver.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -46,7 +46,7 @@
     if (connection.ignoreInvalidMessageForTesting())
         return;
 #endif // ENABLE(IPC_TESTING_API)
-    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, description(decoder.messageName()), decoder.destinationID());
+    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, IPC::description(decoder.messageName()), decoder.destinationID());
 }
 
 bool TestWithImageData::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, UniqueRef<IPC::Encoder>& replyEncoder)

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithLegacyReceiverMessageReceiver.cpp (286943 => 286944)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithLegacyReceiverMessageReceiver.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithLegacyReceiverMessageReceiver.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -135,7 +135,7 @@
     if (connection.ignoreInvalidMessageForTesting())
         return;
 #endif // ENABLE(IPC_TESTING_API)
-    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, description(decoder.messageName()), decoder.destinationID());
+    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, IPC::description(decoder.messageName()), decoder.destinationID());
 }
 
 bool TestWithLegacyReceiver::didReceiveSyncTestWithLegacyReceiverMessage(IPC::Connection& connection, IPC::Decoder& decoder, UniqueRef<IPC::Encoder>& replyEncoder)

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithSemaphoreMessageReceiver.cpp (286943 => 286944)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithSemaphoreMessageReceiver.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithSemaphoreMessageReceiver.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -43,7 +43,7 @@
     if (connection.ignoreInvalidMessageForTesting())
         return;
 #endif // ENABLE(IPC_TESTING_API)
-    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, description(decoder.messageName()), decoder.destinationID());
+    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, IPC::description(decoder.messageName()), decoder.destinationID());
 }
 
 bool TestWithSemaphore::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, UniqueRef<IPC::Encoder>& replyEncoder)

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamBufferMessageReceiver.cpp (286943 => 286944)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamBufferMessageReceiver.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamBufferMessageReceiver.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -43,7 +43,7 @@
     if (connection.ignoreInvalidMessageForTesting())
         return;
 #endif // ENABLE(IPC_TESTING_API)
-    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, description(decoder.messageName()), decoder.destinationID());
+    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, IPC::description(decoder.messageName()), decoder.destinationID());
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamMessageReceiver.cpp (286943 => 286944)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamMessageReceiver.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamMessageReceiver.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -60,7 +60,7 @@
     if (connection.connection().ignoreInvalidMessageForTesting())
         return;
 #endif // ENABLE(IPC_TESTING_API)
-    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled stream message %s to %" PRIu64, description(decoder.messageName()), decoder.destinationID());
+    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled stream message %s to %" PRIu64, IPC::description(decoder.messageName()), decoder.destinationID());
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithoutAttributesMessageReceiver.cpp (286943 => 286944)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithoutAttributesMessageReceiver.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithoutAttributesMessageReceiver.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -135,7 +135,7 @@
     if (connection.ignoreInvalidMessageForTesting())
         return;
 #endif // ENABLE(IPC_TESTING_API)
-    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, description(decoder.messageName()), decoder.destinationID());
+    ASSERT_NOT_REACHED_WITH_MESSAGE("Unhandled message %s to %" PRIu64, IPC::description(decoder.messageName()), decoder.destinationID());
 }
 
 bool TestWithoutAttributes::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, UniqueRef<IPC::Encoder>& replyEncoder)

Modified: trunk/Source/WebKit/Sources.txt (286943 => 286944)


--- trunk/Source/WebKit/Sources.txt	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/Sources.txt	2021-12-13 10:41:06 UTC (rev 286944)
@@ -133,7 +133,8 @@
 NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDaemonClient.cpp
 NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManagerProxy.cpp
 
-NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp @no-unify
+NetworkProcess/ServiceWorker/ServiceWorkerDownloadTask.cpp
+NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp
 NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.cpp
 NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp
 NetworkProcess/ServiceWorker/WebSWOriginStore.cpp @no-unify
@@ -880,5 +881,6 @@
 RemoteTextureMessageReceiver.cpp
 RemoteTextureViewMessageReceiver.cpp
 RemoteWebLockRegistryMessageReceiver.cpp
+ServiceWorkerDownloadTaskMessageReceiver.cpp
 WebBroadcastChannelRegistryMessageReceiver.cpp
 WebLockRegistryProxyMessageReceiver.cpp

Modified: trunk/Source/WebKit/UnifiedSources-output.xcfilelist (286943 => 286944)


--- trunk/Source/WebKit/UnifiedSources-output.xcfilelist	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/UnifiedSources-output.xcfilelist	2021-12-13 10:41:06 UTC (rev 286944)
@@ -18,6 +18,9 @@
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/unified-sources/UnifiedSource110.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/unified-sources/UnifiedSource111.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/unified-sources/UnifiedSource112.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/unified-sources/UnifiedSource113.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/unified-sources/UnifiedSource114.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/unified-sources/UnifiedSource115.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/unified-sources/UnifiedSource12-mm.mm
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/unified-sources/UnifiedSource12.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit/unified-sources/UnifiedSource13-mm.mm

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (286943 => 286944)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-12-13 10:41:06 UTC (rev 286944)
@@ -395,6 +395,9 @@
 		1CA8B946127C882A00576C2B /* WebInspectorUIProxyMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CA8B944127C882A00576C2B /* WebInspectorUIProxyMessages.h */; };
 		1CAECB6527465AE400AB78D0 /* UnifiedSource109.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CAECB5D27465AE300AB78D0 /* UnifiedSource109.cpp */; };
 		1CAECB6627465AE400AB78D0 /* UnifiedSource111.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CAECB5E27465AE300AB78D0 /* UnifiedSource111.cpp */; };
+		3CAECB6627465AE400AB78D0 /* UnifiedSource113.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CAECB5E27465AE300AB78D0 /* UnifiedSource113.cpp */; };
+		4CAECB6627465AE400AB78D0 /* UnifiedSource114.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CAECB5E27465AE300AB78D0 /* UnifiedSource114.cpp */; };
+		5CAECB6627465AE400AB78D0 /* UnifiedSource115.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CAECB5E27465AE300AB78D0 /* UnifiedSource115.cpp */; };
 		1CAECB6727465AE400AB78D0 /* UnifiedSource108.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CAECB5F27465AE300AB78D0 /* UnifiedSource108.cpp */; };
 		1CAECB6827465AE400AB78D0 /* UnifiedSource110.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CAECB6027465AE300AB78D0 /* UnifiedSource110.cpp */; };
 		1CAECB6927465AE400AB78D0 /* UnifiedSource104.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CAECB6127465AE300AB78D0 /* UnifiedSource104.cpp */; };
@@ -881,7 +884,6 @@
 		41DC45961E3D6E2200B11F51 /* NetworkRTCProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 41DC45941E3D6E1E00B11F51 /* NetworkRTCProvider.h */; };
 		41DC459C1E3DBB2800B11F51 /* LibWebRTCSocketClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 41DC459A1E3DBB2400B11F51 /* LibWebRTCSocketClient.h */; };
 		41DD72AB2682167300A90C71 /* NWSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 41DD72AA2682167300A90C71 /* NWSPI.h */; };
-		41DE7C6C22278F1E00532B65 /* ServiceWorkerFetchTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41518536222704F6005430C6 /* ServiceWorkerFetchTask.cpp */; };
 		41E0A7CB23B645CD00561060 /* WebSocketChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 417915AC2256BB7400D6F97E /* WebSocketChannel.cpp */; };
 		41E242E026E0C908009A8C64 /* NetworkRTCUtilitiesCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 41E242DF26E0C904009A8C64 /* NetworkRTCUtilitiesCocoa.mm */; };
 		41F060E11654318500F3281C /* WebSocketChannelMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F060DD1654317500F3281C /* WebSocketChannelMessageReceiver.cpp */; };
@@ -3216,6 +3218,9 @@
 		1CA8B944127C882A00576C2B /* WebInspectorUIProxyMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebInspectorUIProxyMessages.h; path = DerivedSources/WebKit/WebInspectorUIProxyMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
 		1CAECB5D27465AE300AB78D0 /* UnifiedSource109.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource109.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource109.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
 		1CAECB5E27465AE300AB78D0 /* UnifiedSource111.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource111.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource111.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
+		3CAECB5E27465AE300AB78D0 /* UnifiedSource113.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource113.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource113.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
+		4CAECB5E27465AE300AB78D0 /* UnifiedSource114.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource114.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource114.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
+		5CAECB5E27465AE300AB78D0 /* UnifiedSource115.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource115.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource115.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
 		1CAECB5F27465AE300AB78D0 /* UnifiedSource108.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource108.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource108.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
 		1CAECB6027465AE300AB78D0 /* UnifiedSource110.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource110.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource110.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
 		1CAECB6127465AE300AB78D0 /* UnifiedSource104.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = UnifiedSource104.cpp; path = "DerivedSources/WebKit/unified-sources/UnifiedSource104.cpp"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -4188,6 +4193,9 @@
 		41FCD6BD23CE043F00C62567 /* RemoteSampleBufferDisplayLayerManager.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RemoteSampleBufferDisplayLayerManager.messages.in; sourceTree = "<group>"; };
 		41FCD6BE23CE044000C62567 /* RemoteSampleBufferDisplayLayerManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RemoteSampleBufferDisplayLayerManager.cpp; sourceTree = "<group>"; };
 		41FCD6BF23CE044000C62567 /* RemoteSampleBufferDisplayLayerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteSampleBufferDisplayLayerManager.h; sourceTree = "<group>"; };
+		41FFD2DA275A560B00501BBF /* ServiceWorkerDownloadTask.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerDownloadTask.cpp; sourceTree = "<group>"; };
+		41FFD2DB275A560C00501BBF /* ServiceWorkerDownloadTask.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerDownloadTask.h; sourceTree = "<group>"; };
+		41FFD2DC275A6A9400501BBF /* ServiceWorkerDownloadTask.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = ServiceWorkerDownloadTask.messages.in; sourceTree = "<group>"; };
 		4450AEBF1DC3FAE5009943F2 /* SharedMemoryCocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedMemoryCocoa.cpp; sourceTree = "<group>"; };
 		4459984122833E6000E61373 /* SyntheticEditingCommandType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SyntheticEditingCommandType.h; sourceTree = "<group>"; };
 		446DC64B24A2D8AD0061F390 /* PlaybackSessionContextIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaybackSessionContextIdentifier.h; sourceTree = "<group>"; };
@@ -8256,6 +8264,9 @@
 				1CAECB6027465AE300AB78D0 /* UnifiedSource110.cpp */,
 				1CAECB5E27465AE300AB78D0 /* UnifiedSource111.cpp */,
 				93E799D12760AA5A0074008A /* UnifiedSource112.cpp */,
+				3CAECB5E27465AE300AB78D0 /* UnifiedSource113.cpp */,
+				4CAECB5E27465AE300AB78D0 /* UnifiedSource114.cpp */,
+				5CAECB5E27465AE300AB78D0 /* UnifiedSource115.cpp */,
 			);
 			name = "unified-sources";
 			path = "DerivedSources/WebKit/unified-sources";
@@ -10421,6 +10432,9 @@
 		93BA04D92151ADCD007F455F /* ServiceWorker */ = {
 			isa = PBXGroup;
 			children = (
+				41FFD2DA275A560B00501BBF /* ServiceWorkerDownloadTask.cpp */,
+				41FFD2DB275A560C00501BBF /* ServiceWorkerDownloadTask.h */,
+				41FFD2DC275A6A9400501BBF /* ServiceWorkerDownloadTask.messages.in */,
 				41518536222704F6005430C6 /* ServiceWorkerFetchTask.cpp */,
 				41518535222704F5005430C6 /* ServiceWorkerFetchTask.h */,
 				4151853822270F53005430C6 /* ServiceWorkerFetchTask.messages.in */,
@@ -15331,7 +15345,6 @@
 				A55BA8261BA25CFD007CD33D /* RemoteWebInspectorUIProxyMessageReceiver.cpp in Sources */,
 				7BCF70DE2615D06E00E4FB70 /* ScopedRenderingResourcesRequestCocoa.mm in Sources */,
 				E18E6917169B667B009B6670 /* SecItemShimProxyMessageReceiver.cpp in Sources */,
-				41DE7C6C22278F1E00532B65 /* ServiceWorkerFetchTask.cpp in Sources */,
 				2D92A787212B6AB100F493FD /* ShareableBitmap.cpp in Sources */,
 				2DC18FEBF337B9671C88E3CD /* SharedBufferCopy.cpp in Sources */,
 				2DC181245B549343BC98164C /* SharedBufferDataReference.cpp in Sources */,
@@ -15543,6 +15556,9 @@
 				1CAECB6827465AE400AB78D0 /* UnifiedSource110.cpp in Sources */,
 				1CAECB6627465AE400AB78D0 /* UnifiedSource111.cpp in Sources */,
 				93E799D22760AA5B0074008A /* UnifiedSource112.cpp in Sources */,
+				3CAECB6627465AE400AB78D0 /* UnifiedSource113.cpp in Sources */,
+				4CAECB6627465AE400AB78D0 /* UnifiedSource114.cpp in Sources */,
+				5CAECB6627465AE400AB78D0 /* UnifiedSource115.cpp in Sources */,
 				E38A1FC023A551BF00D2374F /* UserInterfaceIdiom.mm in Sources */,
 				CD491B0D1E732E4D00009066 /* UserMediaCaptureManagerMessageReceiver.cpp in Sources */,
 				CD491B171E73525500009066 /* UserMediaCaptureManagerProxyMessageReceiver.cpp in Sources */,

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp (286943 => 286944)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -393,6 +393,12 @@
     return m_isThrottleable;
 }
 
+void WebSWContextManagerConnection::convertFetchToDownload(SWServerConnectionIdentifier serverConnectionIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, FetchIdentifier fetchIdentifier)
+{
+    if (auto* serviceWorkerThreadProxy = SWContextManager::singleton().serviceWorkerThreadProxy(serviceWorkerIdentifier))
+        serviceWorkerThreadProxy->convertFetchToDownload(serverConnectionIdentifier, fetchIdentifier);
+}
+
 void WebSWContextManagerConnection::didFailHeartBeatCheck(ServiceWorkerIdentifier serviceWorkerIdentifier)
 {
     m_connectionToNetworkProcess->send(Messages::WebSWServerToContextConnection::DidFailHeartBeatCheck { serviceWorkerIdentifier }, 0);

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h (286943 => 286944)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h	2021-12-13 10:41:06 UTC (rev 286944)
@@ -106,6 +106,8 @@
     void setUserAgent(String&& userAgent);
     void close();
     void setThrottleState(bool isThrottleable);
+    void convertFetchToDownload(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier);
+    void cancelFetchDownload(WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier);
 
     Ref<IPC::Connection> m_connectionToNetworkProcess;
     WebCore::RegistrableDomain m_registrableDomain;

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in (286943 => 286944)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in	2021-12-13 10:41:06 UTC (rev 286944)
@@ -43,6 +43,8 @@
     UpdatePreferencesStore(struct WebKit::WebPreferencesStore store)
     Close()
     SetThrottleState(bool isThrottleable)
+
+    ConvertFetchToDownload(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier identifier)
 }
 
 #endif

Modified: trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp (286943 => 286944)


--- trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -30,6 +30,7 @@
 
 #include "FormDataReference.h"
 #include "Logging.h"
+#include "ServiceWorkerDownloadTaskMessages.h"
 #include "ServiceWorkerFetchTaskMessages.h"
 #include "SharedBufferDataReference.h"
 #include "WebCoreArgumentCoders.h"
@@ -84,7 +85,10 @@
         return;
     }
 
-    m_connection->send(Messages::ServiceWorkerFetchTask::DidReceiveData { buffer.get(), static_cast<int64_t>(buffer->size()) }, m_fetchIdentifier);
+    if (m_isDownload)
+        m_connection->send(Messages::ServiceWorkerDownloadTask::DidReceiveData { buffer.get(), static_cast<int64_t>(buffer->size()) }, m_fetchIdentifier);
+    else
+        m_connection->send(Messages::ServiceWorkerFetchTask::DidReceiveData { buffer.get(), static_cast<int64_t>(buffer->size()) }, m_fetchIdentifier);
 }
 
 void WebServiceWorkerFetchTaskClient::didReceiveFormDataAndFinish(Ref<FormData>&& formData)
@@ -107,7 +111,10 @@
     // For now and for the case of blobs, we read it there and send the data through IPC.
     URL blobURL = formData->asBlobURL();
     if (blobURL.isNull()) {
-        m_connection->send(Messages::ServiceWorkerFetchTask::DidReceiveFormData { IPC::FormDataReference { WTFMove(formData) } }, m_fetchIdentifier);
+        if (m_isDownload)
+            m_connection->send(Messages::ServiceWorkerDownloadTask::DidReceiveFormData { IPC::FormDataReference { WTFMove(formData) } }, m_fetchIdentifier);
+        else
+            m_connection->send(Messages::ServiceWorkerFetchTask::DidReceiveFormData { IPC::FormDataReference { WTFMove(formData) } }, m_fetchIdentifier);
         return;
     }
 
@@ -135,7 +142,10 @@
     if (!m_connection)
         return;
 
-    m_connection->send(Messages::ServiceWorkerFetchTask::DidReceiveData { { data, size }, static_cast<int64_t>(size) }, m_fetchIdentifier);
+    if (m_isDownload)
+        m_connection->send(Messages::ServiceWorkerDownloadTask::DidReceiveData { { data, size }, static_cast<int64_t>(size) }, m_fetchIdentifier);
+    else
+        m_connection->send(Messages::ServiceWorkerFetchTask::DidReceiveData { { data, size }, static_cast<int64_t>(size) }, m_fetchIdentifier);
 }
 
 void WebServiceWorkerFetchTaskClient::didFinishBlobLoading()
@@ -157,7 +167,10 @@
         return;
     }
 
-    m_connection->send(Messages::ServiceWorkerFetchTask::DidFail { error }, m_fetchIdentifier);
+    if (m_isDownload)
+        m_connection->send(Messages::ServiceWorkerDownloadTask::DidFail { error }, m_fetchIdentifier);
+    else
+        m_connection->send(Messages::ServiceWorkerFetchTask::DidFail { error }, m_fetchIdentifier);
 
     cleanup();
 }
@@ -174,7 +187,10 @@
         return;
     }
 
-    m_connection->send(Messages::ServiceWorkerFetchTask::DidFinish { }, m_fetchIdentifier);
+    if (m_isDownload)
+        m_connection->send(Messages::ServiceWorkerDownloadTask::DidFinish { }, m_fetchIdentifier);
+    else
+        m_connection->send(Messages::ServiceWorkerFetchTask::DidFinish { }, m_fetchIdentifier);
 
     cleanup();
 }
@@ -194,6 +210,12 @@
     m_connection = nullptr;
 }
 
+void WebServiceWorkerFetchTaskClient::convertFetchToDownload()
+{
+    m_isDownload = true;
+    continueDidReceiveResponse();
+}
+
 void WebServiceWorkerFetchTaskClient::continueDidReceiveResponse()
 {
     RELEASE_LOG(ServiceWorker, "ServiceWorkerFrameLoaderClient::continueDidReceiveResponse, has connection %d, didFinish %d, response type %ld", !!m_connection, m_didFinish, static_cast<long>(m_responseData.index()));

Modified: trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.h (286943 => 286944)


--- trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.h	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.h	2021-12-13 10:41:06 UTC (rev 286944)
@@ -56,6 +56,7 @@
     void didNotHandle() final;
     void cancel() final;
     void continueDidReceiveResponse() final;
+    void convertFetchToDownload() final;
 
     void cleanup();
     
@@ -84,6 +85,7 @@
     bool m_waitingForContinueDidReceiveResponseMessage { false };
     std::variant<std::nullptr_t, Ref<WebCore::SharedBuffer>, Ref<WebCore::FormData>, UniqueRef<WebCore::ResourceError>> m_responseData;
     bool m_didFinish { false };
+    bool m_isDownload { false };
 };
 
 } // namespace WebKit

Modified: trunk/Tools/ChangeLog (286943 => 286944)


--- trunk/Tools/ChangeLog	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Tools/ChangeLog	2021-12-13 10:41:06 UTC (rev 286944)
@@ -1,3 +1,21 @@
+2021-12-13  Youenn Fablet  <you...@apple.com>
+
+        Fix ServiceWorker downloads
+        https://bugs.webkit.org/show_bug.cgi?id=202142
+        <rdar://problem/55721934>
+
+        Reviewed by Alex Christensen.
+
+        Add test runner API to log the total download size.
+        This helps ensuring that service worker loads are correctly downloaded and do not rely on networking.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestController.cpp:
+        * WebKitTestRunner/TestController.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+
 2021-12-13  Kimmo Kinnunen  <kkinnu...@apple.com>
 
         Cocoa WebGL should support UI side compositing

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (286943 => 286944)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2021-12-13 10:41:06 UTC (rev 286944)
@@ -39,6 +39,7 @@
     // Downloads.
     undefined waitUntilDownloadFinished();
     undefined setShouldLogDownloadCallbacks(boolean value);
+    undefined setShouldLogDownloadSize(boolean value);
 
     const unsigned short RENDER_TREE_SHOW_ALL_LAYERS            = 1;
     const unsigned short RENDER_TREE_SHOW_LAYER_NESTING         = 2;

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (286943 => 286944)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -1008,6 +1008,11 @@
     postPageMessage("SetShouldLogDownloadCallbacks", value);
 }
 
+void TestRunner::setShouldLogDownloadSize(bool value)
+{
+    postPageMessage("SetShouldLogDownloadSize", value);
+}
+
 void TestRunner::setAuthenticationUsername(JSStringRef username)
 {
     postPageMessage("SetAuthenticationUsername", toWK(username));

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (286943 => 286944)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2021-12-13 10:41:06 UTC (rev 286944)
@@ -215,6 +215,7 @@
     // Downloads
     bool shouldFinishAfterDownload() const { return m_shouldFinishAfterDownload; }
     void setShouldLogDownloadCallbacks(bool);
+    void setShouldLogDownloadSize(bool);
 
     bool shouldAllowEditing() const { return m_shouldAllowEditing; }
 

Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (286943 => 286944)


--- trunk/Tools/WebKitTestRunner/TestController.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -146,7 +146,7 @@
         TestController::downloadDidReceiveServerRedirectToURL,
         TestController::downloadDidReceiveAuthenticationChallenge,
         TestController::decideDestinationWithSuggestedFilename,
-        nullptr, // didWriteData
+        TestController::downloadDidWriteData,
         TestController::downloadDidFinish,
         TestController::downloadDidFail
     };
@@ -1108,6 +1108,8 @@
         clearBundleIdentifierInNetworkProcess();
     }
 
+    m_downloadTotalBytesWritten = { };
+
     return m_doneResetting;
 }
 
@@ -2237,6 +2239,8 @@
 
 void TestController::downloadDidFinish(WKDownloadRef)
 {
+    if (m_shouldLogDownloadSize)
+        m_currentInvocation->outputText(makeString("Download size: ", m_downloadTotalBytesWritten.value_or(0), ".\n"));
     if (m_shouldLogDownloadCallbacks)
         m_currentInvocation->outputText("Download completed.\n");
     m_currentInvocation->notifyDownloadDone();
@@ -2269,6 +2273,18 @@
     static_cast<TestController*>(const_cast<void*>(clientInfo))->didReceiveAuthenticationChallenge(nullptr, authenticationChallenge);
 }
 
+void TestController::downloadDidWriteData(long long totalBytesWritten)
+{
+    if (!m_shouldLogDownloadCallbacks)
+        return;
+    m_downloadTotalBytesWritten = totalBytesWritten;
+}
+
+void TestController::downloadDidWriteData(WKDownloadRef download, long long bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite, const void* clientInfo)
+{
+    static_cast<TestController*>(const_cast<void*>(clientInfo))->downloadDidWriteData(totalBytesWritten);
+}
+
 void TestController::webProcessDidTerminate(WKProcessTerminationReason reason)
 {
     // This function can be called multiple times when crash logs are being saved on Windows, so

Modified: trunk/Tools/WebKitTestRunner/TestController.h (286943 => 286944)


--- trunk/Tools/WebKitTestRunner/TestController.h	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Tools/WebKitTestRunner/TestController.h	2021-12-13 10:41:06 UTC (rev 286944)
@@ -190,6 +190,7 @@
     void setShouldLogHistoryClientCallbacks(bool shouldLog) { m_shouldLogHistoryClientCallbacks = shouldLog; }
     void setShouldLogCanAuthenticateAgainstProtectionSpace(bool shouldLog) { m_shouldLogCanAuthenticateAgainstProtectionSpace = shouldLog; }
     void setShouldLogDownloadCallbacks(bool shouldLog) { m_shouldLogDownloadCallbacks = shouldLog; }
+    void setShouldLogDownloadSize(bool shouldLog) { m_shouldLogDownloadSize = shouldLog; }
 
     bool isCurrentInvocation(TestInvocation* invocation) const { return invocation == m_currentInvocation.get(); }
 
@@ -473,7 +474,10 @@
     static bool downloadDidReceiveServerRedirectToURL(WKDownloadRef, WKURLResponseRef, WKURLRequestRef, const void*);
     bool downloadDidReceiveServerRedirectToURL(WKDownloadRef, WKURLRequestRef);
     static void downloadDidReceiveAuthenticationChallenge(WKDownloadRef, WKAuthenticationChallengeRef, const void *clientInfo);
-    
+
+    void downloadDidWriteData(long long totalBytesWritten);
+    static void downloadDidWriteData(WKDownloadRef, long long bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite, const void* clientInfo);
+
     static void webProcessDidTerminate(WKPageRef,  WKProcessTerminationReason, const void* clientInfo);
     void webProcessDidTerminate(WKProcessTerminationReason);
 
@@ -663,6 +667,9 @@
     bool m_isSpeechRecognitionPermissionGranted { false };
 
     bool m_isMediaKeySystemPermissionGranted { true };
+
+    std::optional<long long> m_downloadTotalBytesWritten;
+    bool m_shouldLogDownloadSize { false };
 };
 
 } // namespace WTR

Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (286943 => 286944)


--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2021-12-13 10:37:37 UTC (rev 286943)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2021-12-13 10:41:06 UTC (rev 286944)
@@ -537,6 +537,11 @@
         return;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "SetShouldLogDownloadSize")) {
+        TestController::singleton().setShouldLogDownloadSize(booleanValue(messageBody));
+        return;
+    }
+
     if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationUsername")) {
         WKStringRef username = stringValue(messageBody);
         TestController::singleton().setAuthenticationUsername(toWTFString(username));
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to