Diff
Added: trunk/LayoutTests/http/wpt/service-workers/navigation-optimization-worker.js (0 => 295488)
--- trunk/LayoutTests/http/wpt/service-workers/navigation-optimization-worker.js (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/navigation-optimization-worker.js 2022-06-13 14:07:54 UTC (rev 295488)
@@ -0,0 +1,19 @@
+async function doTest(event)
+{
+ if (event.preloadResponse) {
+ event.respondWith(event.preloadResponse.then((response) => {
+ if (event.request.url.includes("get-body")) {
+ const clone = response.clone();
+ clone.body.getReader();
+ return response;
+ }
+ if (self.internals)
+ setTimeout(() => internals.terminate(), 0);
+ return response;
+ }));
+ return;
+ }
+ event.respondWith(fetch(event.request));
+}
+
+self.addEventListener("fetch", doTest);
Added: trunk/LayoutTests/http/wpt/service-workers/navigation-optimization.https-expected.txt (0 => 295488)
--- trunk/LayoutTests/http/wpt/service-workers/navigation-optimization.https-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/navigation-optimization.https-expected.txt 2022-06-13 14:07:54 UTC (rev 295488)
@@ -0,0 +1,6 @@
+
+
+PASS Setup worker
+PASS Make sure a load that is transferred in network process continues even if service worker gets terminated.
+PASS Make sure a load that a preload response can be read right away.
+
Added: trunk/LayoutTests/http/wpt/service-workers/navigation-optimization.https.html (0 => 295488)
--- trunk/LayoutTests/http/wpt/service-workers/navigation-optimization.https.html (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/navigation-optimization.https.html 2022-06-13 14:07:54 UTC (rev 295488)
@@ -0,0 +1,49 @@
+<html>
+<head>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+promise_test(async (test) => {
+ const scope = "resources";
+ const registration = await navigator.serviceWorker.register("navigation-optimization-worker.js", { scope : scope });
+ activeWorker = registration.active;
+ if (activeWorker)
+ return;
+ activeWorker = registration.installing;
+ await new Promise(resolve => {
+ activeWorker.addEventListener('statechange', () => {
+ if (activeWorker.state === "activated")
+ resolve();
+ });
+ });
+
+ await registration.navigationPreload.enable();
+}, "Setup worker");
+
+promise_test(async (test) => {
+ const promise1 = new Promise((resolve, reject) => { window.callback1 = resolve; setTimeout(() => reject("callback1"), 4000); });
+ const promise2 = new Promise((resolve, reject) => { window.callback2 = resolve; setTimeout(() => reject("callback2"), 5000); });
+
+ // The iframe is responsible to call callback1 and callback2.
+ with_iframe("/WebKit/service-workers/resources/navigation-optimization.py?delay=1.0");
+
+ await promise1;
+ await promise2;
+}, "Make sure a load that is transferred in network process continues even if service worker gets terminated.");
+
+promise_test(async (test) => {
+ const promise1 = new Promise((resolve, reject) => { window.callback1 = resolve; setTimeout(() => reject("callback1"), 4000); });
+ const promise2 = new Promise((resolve, reject) => { window.callback2 = resolve; setTimeout(() => reject("callback2"), 5000); });
+
+ // The iframe is responsible to call callback1 and callback2.
+ with_iframe("/WebKit/service-workers/resources/navigation-optimization.py?get-body");
+
+ await promise1;
+ await promise2;
+}, "Make sure a load that a preload response can be read right away.");
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/wpt/service-workers/resources/navigation-optimization.py (0 => 295488)
--- trunk/LayoutTests/http/wpt/service-workers/resources/navigation-optimization.py (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/resources/navigation-optimization.py 2022-06-13 14:07:54 UTC (rev 295488)
@@ -0,0 +1,14 @@
+import time
+
+def main(request, response):
+ delay = 0.05
+ headers = []
+ if b"delay" in request.GET:
+ delay = float(request.GET.first(b"delay"))
+ response.headers.set(b"Content-type", b"text/html")
+ response.headers.append(b"Access-Control-Allow-Origin", b"*")
+ response.write_status_headers()
+ response.writer.write_content("<script>parent.callback1();</script>")
+ time.sleep(delay)
+ response.writer.write_content("<script>parent.callback2();</script>")
+ time.sleep(delay)
Modified: trunk/LayoutTests/http/wpt/service-workers/resources/service-worker-iframe-preload-script.py (295487 => 295488)
--- trunk/LayoutTests/http/wpt/service-workers/resources/service-worker-iframe-preload-script.py 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/LayoutTests/http/wpt/service-workers/resources/service-worker-iframe-preload-script.py 2022-06-13 14:07:54 UTC (rev 295488)
@@ -17,7 +17,7 @@
if not value:
response.headers.set(b"Cache-Control", b"no-cache")
response.headers.set(b"Content-Type", b"text/html")
- return "<html><body><script>window.value = 'nothing';</script></body></html>"
+ return "nothing"
response.headers.set(b"Cache-Control", b"no-cache")
response.headers.set(b"Content-Type", b"text/ascii")
Modified: trunk/LayoutTests/http/wpt/service-workers/service-worker-iframe-preload.https-expected.txt (295487 => 295488)
--- trunk/LayoutTests/http/wpt/service-workers/service-worker-iframe-preload.https-expected.txt 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/LayoutTests/http/wpt/service-workers/service-worker-iframe-preload.https-expected.txt 2022-06-13 14:07:54 UTC (rev 295488)
@@ -1,5 +1,5 @@
PASS Setup activating worker
-PASS Service worker load uses preload if available and fetch event was not handled
+PASS Service worker load uses preload that starts as soon as possible
Modified: trunk/LayoutTests/http/wpt/service-workers/service-worker-iframe-preload.https.html (295487 => 295488)
--- trunk/LayoutTests/http/wpt/service-workers/service-worker-iframe-preload.https.html 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/LayoutTests/http/wpt/service-workers/service-worker-iframe-preload.https.html 2022-06-13 14:07:54 UTC (rev 295488)
@@ -64,11 +64,11 @@
activeWorker.postMessage("fetch");
const response = await fetchPromise;
- assert_equals(await response.text(), "before-navigation");
+ assert_equals(await response.text(), "nothing");
const frame = await iframePromise;
- assert_equals(frame.contentWindow.value, "nothing");
-}, "Service worker load uses preload if available and fetch event was not handled");
+ assert_equals(frame.contentWindow.document.body.innerText, "before-navigation");
+}, "Service worker load uses preload that starts as soon as possible");
</script>
</body>
</html>
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/resource-timing-scope.py (295487 => 295488)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/resource-timing-scope.py 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigation-preload/resources/resource-timing-scope.py 2022-06-13 14:07:54 UTC (rev 295488)
@@ -1,3 +1,4 @@
+import time
import zlib
def main(request, response):
Modified: trunk/Source/WebCore/Headers.cmake (295487 => 295488)
--- trunk/Source/WebCore/Headers.cmake 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebCore/Headers.cmake 2022-06-13 14:07:54 UTC (rev 295488)
@@ -164,11 +164,11 @@
Modules/fetch/FetchBodyConsumer.h
Modules/fetch/FetchBodySource.h
- Modules/fetch/FetchRequestCredentials.h
Modules/fetch/FetchHeaders.h
Modules/fetch/FetchIdentifier.h
Modules/fetch/FetchLoader.h
Modules/fetch/FetchLoaderClient.h
+ Modules/fetch/FetchRequestCredentials.h
Modules/filesystemaccess/FileSystemDirectoryHandle.h
Modules/filesystemaccess/FileSystemFileHandle.h
@@ -425,6 +425,7 @@
bindings/js/BufferSource.h
bindings/js/CachedScriptFetcher.h
bindings/js/CommonVM.h
+ bindings/js/DOMPromiseProxy.h
bindings/js/DOMWrapperWorld.h
bindings/js/ExceptionDetails.h
bindings/js/GCController.h
@@ -2026,6 +2027,9 @@
workers/WorkerThreadType.h
workers/WorkerType.h
+ workers/service/ExtendableEvent.h
+ workers/service/ExtendableEventInit.h
+ workers/service/FetchEvent.h
workers/service/NavigationPreloadState.h
workers/service/SWClientConnection.h
workers/service/ServiceWorkerClientData.h
Modified: trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp (295487 => 295488)
--- trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp 2022-06-13 14:07:54 UTC (rev 295488)
@@ -235,15 +235,8 @@
});
}
-void FetchResponse::fetch(ScriptExecutionContext& context, FetchRequest& request, NotificationCallback&& responseCallback, const String& initiator)
+Ref<FetchResponse> FetchResponse::createFetchResponse(ScriptExecutionContext& context, FetchRequest& request, NotificationCallback&& responseCallback)
{
- if (request.isReadableStreamBody()) {
- responseCallback(Exception { NotSupportedError, "ReadableStream uploading is not supported"_s });
- return;
- }
-
- InspectorInstrumentation::willFetch(context, request.url().string());
-
auto response = adoptRef(*new FetchResponse(&context, FetchBody { }, FetchHeaders::create(FetchHeaders::Guard::Immutable), { }));
response->suspendIfNeeded();
@@ -252,10 +245,28 @@
response->addAbortSteps(request.signal());
response->m_bodyLoader = makeUnique<BodyLoader>(response.get(), WTFMove(responseCallback));
- if (!response->m_bodyLoader->start(context, request, initiator))
- response->m_bodyLoader = nullptr;
+ return response;
}
+void FetchResponse::fetch(ScriptExecutionContext& context, FetchRequest& request, NotificationCallback&& responseCallback, const String& initiator)
+{
+ if (request.isReadableStreamBody()) {
+ responseCallback(Exception { NotSupportedError, "ReadableStream uploading is not supported"_s });
+ return;
+ }
+
+ auto response = createFetchResponse(context, request, WTFMove(responseCallback));
+ response->startLoader(context, request, initiator);
+}
+
+void FetchResponse::startLoader(ScriptExecutionContext& context, FetchRequest& request, const String& initiator)
+{
+ InspectorInstrumentation::willFetch(context, request.url().string());
+
+ if (m_bodyLoader && !m_bodyLoader->start(context, request, initiator))
+ m_bodyLoader = nullptr;
+}
+
const String& FetchResponse::url() const
{
if (m_responseURL.isNull()) {
@@ -322,6 +333,26 @@
}
}
+static std::atomic<uint64_t> nextOpaqueLoadIdentifier;
+void FetchResponse::setReceivedInternalResponse(const ResourceResponse& resourceResponse, FetchOptions::Credentials credentials)
+{
+ if (m_hasInitializedInternalResponse)
+ return;
+
+ m_hasInitializedInternalResponse = true;
+ auto performCheck = credentials == FetchOptions::Credentials::Include ? ResourceResponse::PerformExposeAllHeadersCheck::No : ResourceResponse::PerformExposeAllHeadersCheck::Yes;
+ m_filteredResponse = ResourceResponseBase::filter(resourceResponse, performCheck);
+ m_internalResponse = resourceResponse;
+ m_internalResponse.setType(m_filteredResponse->type());
+ if (resourceResponse.tainting() == ResourceResponse::Tainting::Opaque) {
+ m_opaqueLoadIdentifier = ++nextOpaqueLoadIdentifier;
+ setBodyAsOpaque();
+ }
+
+ m_headers->filterAndFill(m_filteredResponse->httpHeaderFields(), FetchHeaders::Guard::Response);
+ updateContentType();
+}
+
FetchResponse::BodyLoader::BodyLoader(FetchResponse& response, NotificationCallback&& responseCallback)
: m_response(response)
, m_responseCallback(WTFMove(responseCallback))
@@ -333,21 +364,10 @@
{
}
-static uint64_t nextOpaqueLoadIdentifier { 0 };
void FetchResponse::BodyLoader::didReceiveResponse(const ResourceResponse& resourceResponse)
{
- auto performCheck = m_credentials == FetchOptions::Credentials::Include ? ResourceResponse::PerformExposeAllHeadersCheck::No : ResourceResponse::PerformExposeAllHeadersCheck::Yes;
- m_response.m_filteredResponse = ResourceResponseBase::filter(resourceResponse, performCheck);
- m_response.m_internalResponse = resourceResponse;
- m_response.m_internalResponse.setType(m_response.m_filteredResponse->type());
- if (resourceResponse.tainting() == ResourceResponse::Tainting::Opaque) {
- m_response.m_opaqueLoadIdentifier = ++nextOpaqueLoadIdentifier;
- m_response.setBodyAsOpaque();
- }
+ m_response.setReceivedInternalResponse(resourceResponse, m_credentials);
- m_response.m_headers->filterAndFill(m_response.m_filteredResponse->httpHeaderFields(), FetchHeaders::Guard::Response);
- m_response.updateContentType();
-
if (auto responseCallback = WTFMove(m_responseCallback))
responseCallback(Ref { m_response });
}
@@ -385,7 +405,16 @@
m_credentials = request.fetchOptions().credentials;
m_loader = makeUnique<FetchLoader>(*this, &m_response.m_body->consumer());
m_loader->start(context, request, initiator);
- return m_loader->isStarted();
+
+ if (!m_loader->isStarted())
+ return false;
+
+ if (m_shouldStartStreaming) {
+ auto data = ""
+ ASSERT_UNUSED(data, !data);
+ }
+
+ return true;
}
void FetchResponse::BodyLoader::stop()
@@ -399,7 +428,7 @@
{
ASSERT(!m_consumeDataCallback);
m_consumeDataCallback = WTFMove(consumeDataCallback);
- auto data = ""
+ auto data = ""
if (!data)
return;
@@ -421,6 +450,12 @@
return body().take();
}
+void FetchResponse::markAsDisturbed()
+{
+ ASSERT(!m_isDisturbed);
+ m_isDisturbed = true;
+}
+
void FetchResponse::consumeBodyReceivedByChunk(ConsumeDataByChunkCallback&& callback)
{
ASSERT(isBodyReceivedByChunk());
@@ -518,7 +553,11 @@
RefPtr<FragmentedSharedBuffer> FetchResponse::BodyLoader::startStreaming()
{
- ASSERT(m_loader);
+ if (!m_loader) {
+ m_shouldStartStreaming = true;
+ return nullptr;
+ }
+
return m_loader->startStreaming();
}
Modified: trunk/Source/WebCore/Modules/fetch/FetchResponse.h (295487 => 295488)
--- trunk/Source/WebCore/Modules/fetch/FetchResponse.h 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebCore/Modules/fetch/FetchResponse.h 2022-06-13 14:07:54 UTC (rev 295488)
@@ -65,6 +65,7 @@
using NotificationCallback = Function<void(ExceptionOr<Ref<FetchResponse>>&&)>;
static void fetch(ScriptExecutionContext&, FetchRequest&, NotificationCallback&&, const String& initiator);
+ static Ref<FetchResponse> createFetchResponse(ScriptExecutionContext&, FetchRequest&, NotificationCallback&&);
void startConsumingStream(unsigned);
void consumeChunk(Ref<JSC::Uint8Array>&&);
@@ -113,7 +114,13 @@
bool hasWasmMIMEType() const;
const NetworkLoadMetrics& networkLoadMetrics() const { return m_networkLoadMetrics; }
+ void setReceivedInternalResponse(const ResourceResponse&, FetchOptions::Credentials);
+ void startLoader(ScriptExecutionContext&, FetchRequest&, const String& initiator);
+ void setIsNavigationPreload(bool isNavigationPreload) { m_isNavigationPreload = isNavigationPreload; }
+ bool isAvailableNavigationPreload() const { return m_isNavigationPreload && m_bodyLoader && !m_bodyLoader->hasLoader() && !hasReadableStreamBody(); }
+ void markAsDisturbed();
+
private:
FetchResponse(ScriptExecutionContext*, std::optional<FetchBody>&&, Ref<FetchHeaders>&&, ResourceResponse&&);
@@ -137,6 +144,8 @@
void consumeDataByChunk(ConsumeDataByChunkCallback&&);
+ bool hasLoader() const { return !!m_loader; }
+
RefPtr<FragmentedSharedBuffer> startStreaming();
NotificationCallback takeNotificationCallback() { return WTFMove(m_responseCallback); }
ConsumeDataByChunkCallback takeConsumeDataCallback() { return WTFMove(m_consumeDataCallback); }
@@ -154,6 +163,7 @@
std::unique_ptr<FetchLoader> m_loader;
Ref<PendingActivity<FetchResponse>> m_pendingActivity;
FetchOptions::Credentials m_credentials;
+ bool m_shouldStartStreaming { false };
};
mutable std::optional<ResourceResponse> m_filteredResponse;
@@ -165,6 +175,8 @@
uint64_t m_opaqueLoadIdentifier { 0 };
RefPtr<AbortSignal> m_abortSignal;
NetworkLoadMetrics m_networkLoadMetrics;
+ bool m_hasInitializedInternalResponse { false };
+ bool m_isNavigationPreload { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (295487 => 295488)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2022-06-13 14:07:54 UTC (rev 295488)
@@ -1174,6 +1174,9 @@
4181C64A255B4C2800AEB0FF /* RTCRtpSFrameTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 4181C644255B4C2700AEB0FF /* RTCRtpSFrameTransform.h */; };
418205471E53E98C00D62207 /* RTCController.h in Headers */ = {isa = PBXBuildFile; fileRef = 418205451E53C8CD00D62207 /* RTCController.h */; settings = {ATTRIBUTES = (Private, ); }; };
4184F5161EAF05A800F18BF0 /* OrientationNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 4184F5151EAF059800F18BF0 /* OrientationNotifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 41860F0D2847A49600E4A395 /* FetchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 41AF37881F8C1E7900111C31 /* FetchEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 41860F0E2847A58B00E4A395 /* ExtendableEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 41AF378A1F8C1E7A00111C31 /* ExtendableEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 41860F0F2847A5BE00E4A395 /* ExtendableEventInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 4131F3B41F955BC30059995A /* ExtendableEventInit.h */; settings = {ATTRIBUTES = (Private, ); }; };
4186BD3E213EE3400001826F /* LibWebRTCUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D1A049213EDDFD0063FB6B /* LibWebRTCUtils.cpp */; };
4186BD3F213EE3430001826F /* LibWebRTCRtpSenderBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D1A04B213EDDFE0063FB6B /* LibWebRTCRtpSenderBackend.cpp */; };
4186BD40213EE3450001826F /* LibWebRTCRtpReceiverBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D1A04A213EDDFE0063FB6B /* LibWebRTCRtpReceiverBackend.cpp */; };
@@ -2508,7 +2511,7 @@
7C4C96DF1AD4483500363572 /* JSReadableStreamBYOBReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C4C96DB1AD4483500363572 /* JSReadableStreamBYOBReader.h */; };
7C4C96DF1AD4483500365A50 /* JSReadableStreamDefaultReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C4C96DB1AD4483500365A50 /* JSReadableStreamDefaultReader.h */; };
7C514E0324AF805E0050710F /* ColorConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C514E0024AF80580050710F /* ColorConversion.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 7C516AD41F3525200034B6BF /* DOMPromiseProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C516AD21F3525200034B6BF /* DOMPromiseProxy.h */; };
+ 7C516AD41F3525200034B6BF /* DOMPromiseProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C516AD21F3525200034B6BF /* DOMPromiseProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
7C5222961E1DAE03002CB8F7 /* IDLTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C5222951E1DADF8002CB8F7 /* IDLTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
7C5222991E1DAE1C002CB8F7 /* ActiveDOMCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C5222981E1DAE16002CB8F7 /* ActiveDOMCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
7C52229E1E1DAE47002CB8F7 /* RuntimeEnabledFeatures.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C52229C1E1DAE47002CB8F7 /* RuntimeEnabledFeatures.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -36470,6 +36473,7 @@
BCEA485A097D93020094C9E4 /* LegacyInlineTextBox.h in Headers */,
E4E94D6122FF158A00DD191F /* LegacyLineLayout.h in Headers */,
F44A5F591FED38F2007F5944 /* LegacyNSPasteboardTypes.h in Headers */,
+ 41860F0E2847A58B00E4A395 /* ExtendableEvent.h in Headers */,
A185B42A1E8211A100DC9118 /* LegacyPreviewLoader.h in Headers */,
A10DBF4718F92317000D70C6 /* LegacyPreviewLoaderClient.h in Headers */,
436708C312D9CA4B00044234 /* LegacyRenderSVGContainer.h in Headers */,
@@ -37145,6 +37149,7 @@
550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */,
83C1F5941EDF69D300410D27 /* QualifiedNameCache.h in Headers */,
CD20ED3C27878FFB0038BE44 /* QueuedVideoOutput.h in Headers */,
+ 41860F0F2847A5BE00E4A395 /* ExtendableEventInit.h in Headers */,
A15E31F41E0CB0B5004B371C /* QuickLook.h in Headers */,
9BAEE92C22388A7D004157A9 /* Quirks.h in Headers */,
379E371713736A6600B9E919 /* QuotedPrintable.h in Headers */,
@@ -38166,6 +38171,7 @@
97AABD1714FA09D5007457AE /* ThreadableWebSocketChannel.h in Headers */,
97AABD1914FA09D5007457AE /* ThreadableWebSocketChannelClientWrapper.h in Headers */,
51DF6D7E0B92A16D00C2DC85 /* ThreadCheck.h in Headers */,
+ 41860F0D2847A49600E4A395 /* FetchEvent.h in Headers */,
0F6383DE18615B29003E5DB5 /* ThreadedScrollingTree.h in Headers */,
E1FF57A30F01255B00891EBB /* ThreadGlobalData.h in Headers */,
51D7EFEA1BDE8F8C00E93E10 /* ThreadSafeDataBuffer.h in Headers */,
Modified: trunk/Source/WebCore/bindings/js/JSFetchEventCustom.cpp (295487 => 295488)
--- trunk/Source/WebCore/bindings/js/JSFetchEventCustom.cpp 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebCore/bindings/js/JSFetchEventCustom.cpp 2022-06-13 14:07:54 UTC (rev 295488)
@@ -28,6 +28,7 @@
#if ENABLE(SERVICE_WORKER)
+#include "FetchRequest.h"
#include "WebCoreOpaqueRoot.h"
#include "WebCoreOpaqueRoot.h"
Modified: trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp (295487 => 295488)
--- trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp 2022-06-13 14:07:54 UTC (rev 295488)
@@ -29,6 +29,7 @@
#if ENABLE(SERVICE_WORKER)
#include "FetchEvent.h"
+#include "FetchRequest.h"
#include "JSFetchResponse.h"
#include "PushSubscription.h"
#include "PushSubscriptionData.h"
Modified: trunk/Source/WebCore/workers/service/FetchEvent.cpp (295487 => 295488)
--- trunk/Source/WebCore/workers/service/FetchEvent.cpp 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebCore/workers/service/FetchEvent.cpp 2022-06-13 14:07:54 UTC (rev 295488)
@@ -28,6 +28,7 @@
#include "CachedResourceRequestInitiators.h"
#include "EventNames.h"
+#include "FetchRequest.h"
#include "JSDOMPromise.h"
#include "JSFetchResponse.h"
#include "Logging.h"
@@ -163,32 +164,45 @@
}
return *m_preloadResponsePromise;
}
+ }
+ return *m_preloadResponsePromise;
+}
- auto request = FetchRequest::create(context, { }, FetchHeaders::create(), ResourceRequest { m_request->internalRequest() } , FetchOptions { m_request->fetchOptions() }, String { m_request->internalRequestReferrer() });
- request->setNavigationPreloadIdentifier(m_navigationPreloadIdentifier);
- FetchResponse::fetch(context, request.get(), [protectedThis = Ref { *this }](auto&& result) {
- if (result.hasException()) {
- protectedThis->m_preloadResponsePromise->reject(result.releaseException());
- return;
- }
+void FetchEvent::navigationPreloadIsReady(ResourceResponse&& response)
+{
+ auto* globalObject = m_handled->globalObject();
+ auto* context = globalObject ? globalObject->scriptExecutionContext() : nullptr;
+ if (!context)
+ return;
- Ref response = result.releaseReturnValue();
- auto* context = response->scriptExecutionContext();
- if (!context)
- return;
- auto* globalObject = context->globalObject();
- if (!globalObject)
- return;
+ if (!m_preloadResponsePromise)
+ m_preloadResponsePromise = makeUnique<PreloadResponsePromise>();
- auto& vm = globalObject->vm();
- JSC::JSLockHolder lock(vm);
- JSC::Strong<JSC::Unknown> value { vm, toJS(globalObject, JSC::jsCast<JSDOMGlobalObject*>(globalObject), response.get()) };
- protectedThis->m_preloadResponsePromise->resolve(value);
- }, cachedResourceRequestInitiators().navigation);
- }
- return *m_preloadResponsePromise;
+ auto request = FetchRequest::create(*context, { }, FetchHeaders::create(), ResourceRequest { m_request->internalRequest() } , FetchOptions { m_request->fetchOptions() }, String { m_request->internalRequestReferrer() });
+ request->setNavigationPreloadIdentifier(m_navigationPreloadIdentifier);
+
+ auto fetchResponse = FetchResponse::createFetchResponse(*context, request.get(), { });
+ fetchResponse->setReceivedInternalResponse(response, FetchOptions::Credentials::Include);
+ fetchResponse->setIsNavigationPreload(true);
+
+ auto& vm = globalObject->vm();
+ JSC::JSLockHolder lock(vm);
+ JSC::Strong<JSC::Unknown> value { vm, toJS(globalObject, JSC::jsCast<JSDOMGlobalObject*>(globalObject), fetchResponse.get()) };
+ m_preloadResponsePromise->resolve(value);
+
+ // We postpone the load to leave some time for the service worker to use the preload before loading it.
+ context->postTask([fetchResponse = WTFMove(fetchResponse), request = WTFMove(request)](auto& context) {
+ fetchResponse->startLoader(context, request.get(), cachedResourceRequestInitiators().navigation);
+ });
}
+void FetchEvent::navigationPreloadFailed(ResourceError&& error)
+{
+ if (!m_preloadResponsePromise)
+ m_preloadResponsePromise = makeUnique<PreloadResponsePromise>();
+ m_preloadResponsePromise->reject(Exception { TypeError, error.sanitizedDescription() });
+}
+
} // namespace WebCore
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebCore/workers/service/FetchEvent.h (295487 => 295488)
--- trunk/Source/WebCore/workers/service/FetchEvent.h 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebCore/workers/service/FetchEvent.h 2022-06-13 14:07:54 UTC (rev 295488)
@@ -29,7 +29,8 @@
#include "DOMPromiseProxy.h"
#include "ExtendableEvent.h"
-#include "FetchRequest.h"
+#include "FetchIdentifier.h"
+#include "ResourceError.h"
#include <wtf/CompletionHandler.h>
#include <wtf/Expected.h>
@@ -40,8 +41,8 @@
namespace WebCore {
class DOMPromise;
+class FetchRequest;
class FetchResponse;
-class ResourceError;
class FetchEvent final : public ExtendableEvent {
WTF_MAKE_ISO_ALLOCATED(FetchEvent);
@@ -81,6 +82,8 @@
PreloadResponsePromise& preloadResponse(ScriptExecutionContext&);
void setNavigationPreloadIdentifier(FetchIdentifier);
+ WEBCORE_EXPORT void navigationPreloadIsReady(ResourceResponse&&);
+ WEBCORE_EXPORT void navigationPreloadFailed(ResourceError&&);
private:
WEBCORE_EXPORT FetchEvent(JSC::JSGlobalObject&, const AtomString&, Init&&, IsTrusted);
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp (295487 => 295488)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp 2022-06-13 14:07:54 UTC (rev 295488)
@@ -99,6 +99,12 @@
promise.resolve();
+ if (response->isAvailableNavigationPreload()) {
+ client->usePreload();
+ response->markAsDisturbed();
+ return;
+ }
+
if (resourceResponse.isRedirection() && resourceResponse.httpHeaderFields().contains(HTTPHeaderName::Location)) {
client->didReceiveRedirection(resourceResponse);
return;
@@ -202,9 +208,10 @@
init.handled = DOMPromise::create(jsDOMGlobalObject, *promise);
auto event = FetchEvent::create(*globalScope.globalObject(), eventNames().fetchEvent, WTFMove(init), Event::IsTrusted::Yes);
-
- if (isServiceWorkerNavigationPreloadEnabled)
+ if (isServiceWorkerNavigationPreloadEnabled) {
+ client->setFetchEvent(event.copyRef());
event->setNavigationPreloadIdentifier(fetchIdentifier);
+ }
CertificateInfo certificateInfo = globalScope.certificateInfo();
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h (295487 => 295488)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h 2022-06-13 14:07:54 UTC (rev 295488)
@@ -61,6 +61,10 @@
virtual void setCancelledCallback(Function<void()>&&) = 0;
virtual void continueDidReceiveResponse() = 0;
virtual void convertFetchToDownload() = 0;
+ virtual void setFetchEvent(Ref<FetchEvent>&&) = 0;
+ virtual void navigationPreloadIsReady(ResourceResponse&&) = 0;
+ virtual void navigationPreloadFailed(ResourceError&&) = 0;
+ virtual void usePreload() = 0;
};
void dispatchFetchEvent(Ref<Client>&&, ServiceWorkerGlobalScope&, ResourceRequest&&, String&& referrer, FetchOptions&&, FetchIdentifier, bool isServiceWorkerNavigationPreloadEnabled, String&& clientIdentifier, String&& resultingClientIdentifier);
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp (295487 => 295488)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp 2022-06-13 14:07:54 UTC (rev 295488)
@@ -269,6 +269,24 @@
}, WorkerRunLoop::defaultMode());
}
+void ServiceWorkerThreadProxy::navigationPreloadIsReady(SWServerConnectionIdentifier connectionIdentifier, FetchIdentifier fetchIdentifier, ResourceResponse&& response)
+{
+ ASSERT(!isMainThread());
+ postTaskForModeToWorkerOrWorkletGlobalScope([this, protectedThis = Ref { *this }, connectionIdentifier, fetchIdentifier, responseData = response.crossThreadData()] (auto&) mutable {
+ if (auto client = m_ongoingFetchTasks.get({ connectionIdentifier, fetchIdentifier }))
+ client->navigationPreloadIsReady(ResourceResponse::fromCrossThreadData(WTFMove(responseData)));
+ }, WorkerRunLoop::defaultMode());
+}
+
+void ServiceWorkerThreadProxy::navigationPreloadFailed(SWServerConnectionIdentifier connectionIdentifier, FetchIdentifier fetchIdentifier, ResourceError&& error)
+{
+ ASSERT(!isMainThread());
+ postTaskForModeToWorkerOrWorkletGlobalScope([this, protectedThis = Ref { *this }, connectionIdentifier, fetchIdentifier, error = WTFMove(error).isolatedCopy()] (auto&) mutable {
+ if (auto client = m_ongoingFetchTasks.get({ connectionIdentifier, fetchIdentifier }))
+ client->navigationPreloadFailed(WTFMove(error));
+ }, WorkerRunLoop::defaultMode());
+}
+
void ServiceWorkerThreadProxy::continueDidReceiveFetchResponse(SWServerConnectionIdentifier connectionIdentifier, FetchIdentifier fetchIdentifier)
{
ASSERT(!isMainThread());
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h (295487 => 295488)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h 2022-06-13 14:07:54 UTC (rev 295488)
@@ -79,6 +79,8 @@
WEBCORE_EXPORT void convertFetchToDownload(SWServerConnectionIdentifier, FetchIdentifier);
WEBCORE_EXPORT void continueDidReceiveFetchResponse(SWServerConnectionIdentifier, FetchIdentifier);
WEBCORE_EXPORT void removeFetch(SWServerConnectionIdentifier, FetchIdentifier);
+ WEBCORE_EXPORT void navigationPreloadIsReady(SWServerConnectionIdentifier, FetchIdentifier, ResourceResponse&&);
+ WEBCORE_EXPORT void navigationPreloadFailed(SWServerConnectionIdentifier, FetchIdentifier, ResourceError&&);
WEBCORE_EXPORT void fireMessageEvent(MessageWithMessagePorts&&, ServiceWorkerOrClientData&&);
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (295487 => 295488)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2022-06-13 14:07:54 UTC (rev 295488)
@@ -1180,6 +1180,9 @@
networkLoadMetrics.markComplete();
networkLoadMetrics.responseBodyBytesReceived = 0;
networkLoadMetrics.responseBodyDecodedSize = 0;
+
+ if (m_serviceWorkerFetchTask)
+ networkLoadMetrics.fetchStart = m_serviceWorkerFetchTask->startTime();
send(Messages::WebResourceLoader::DidFinishResourceLoad { networkLoadMetrics });
cleanup(LoadResult::Success);
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp (295487 => 295488)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp 2022-06-13 14:07:54 UTC (rev 295488)
@@ -72,7 +72,10 @@
, m_fetchIdentifier(WebCore::FetchIdentifier::generate())
, m_preloader(WTFMove(preloader))
{
- loadResponseFromPreloader();
+ callOnMainRunLoop([weakThis = WeakPtr { *this }] {
+ if (weakThis)
+ weakThis->loadResponseFromPreloader();
+ });
}
ServiceWorkerFetchTask::ServiceWorkerFetchTask(WebSWServerConnection& swServerConnection, NetworkResourceLoader& loader, ResourceRequest&& request, SWServerConnectionIdentifier serverConnectionIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, SWServerRegistration& registration, NetworkSession* session, bool isWorkerReady)
@@ -96,6 +99,11 @@
parameters.request = m_currentRequest;
m_preloader = makeUnique<ServiceWorkerNavigationPreloader>(*session, WTFMove(parameters), registration.navigationPreloadState(), loader.shouldCaptureExtraNetworkLoadMetrics());
session->addNavigationPreloaderTask(*this);
+
+ m_preloader->waitForResponse([weakThis = WeakPtr { *this }] {
+ if (weakThis)
+ weakThis->preloadResponseIsReady();
+ });
}
}
@@ -157,6 +165,7 @@
if (auto identifier = m_loader.parameters().options.clientIdentifier)
clientIdentifier = identifier->toString();
}
+
bool isSent = sendToServiceWorker(Messages::WebSWContextManagerConnection::StartFetch { m_serverConnectionIdentifier, m_serviceWorkerIdentifier, m_fetchIdentifier, request, options, IPC::FormDataReference { m_currentRequest.httpBody() }, referrer, m_preloader && m_preloader->isServiceWorkerNavigationPreloadEnabled(), clientIdentifier, m_loader.resultingClientIdentifier() });
ASSERT_UNUSED(isSent, isSent);
}
@@ -295,6 +304,21 @@
m_loader.serviceWorkerDidNotHandle(this);
}
+void ServiceWorkerFetchTask::usePreload()
+{
+ if (m_isDone)
+ return;
+
+ ASSERT(m_preloader);
+ if (m_preloader) {
+ loadResponseFromPreloader();
+ return;
+ }
+
+ m_isDone = true;
+ m_loader.serviceWorkerDidNotHandle(this);
+}
+
void ServiceWorkerFetchTask::cannotHandle()
{
SWFETCH_RELEASE_LOG("cannotHandle:");
@@ -371,26 +395,38 @@
return;
m_isLoadingFromPreloader = true;
+ m_preloader->waitForResponse([weakThis = WeakPtr { *this }] {
+ if (weakThis)
+ weakThis->preloadResponseIsReady();
+ });
+}
- m_preloader->waitForResponse([weakThis = WeakPtr { *this }, this] {
- if (!weakThis)
- return;
-
- if (!m_preloader->error().isNull()) {
- // Let's copy the error as calling didFail might destroy m_preloader.
- didFail(ResourceError { m_preloader->error() });
- return;
+void ServiceWorkerFetchTask::preloadResponseIsReady()
+{
+ if (!m_isLoadingFromPreloader) {
+ if (m_preloader && m_preloader->isServiceWorkerNavigationPreloadEnabled()) {
+ if (!m_preloader->error().isNull())
+ sendToServiceWorker(Messages::WebSWContextManagerConnection::NavigationPreloadFailed { m_serverConnectionIdentifier, m_serviceWorkerIdentifier, m_fetchIdentifier, m_preloader->error() });
+ else
+ sendToServiceWorker(Messages::WebSWContextManagerConnection::NavigationPreloadIsReady { m_serverConnectionIdentifier, m_serviceWorkerIdentifier, m_fetchIdentifier, m_preloader->response() });
}
+ return;
+ }
- auto response = m_preloader->response();
- if (response.isRedirection() && response.httpHeaderFields().contains(HTTPHeaderName::Location)) {
- processRedirectResponse(WTFMove(response), ShouldSetSource::No);
- return;
- }
+ if (!m_preloader->error().isNull()) {
+ // Let's copy the error as calling didFail might destroy m_preloader.
+ didFail(ResourceError { m_preloader->error() });
+ return;
+ }
- bool needsContinueDidReceiveResponseMessage = true;
- processResponse(WTFMove(response), needsContinueDidReceiveResponseMessage, ShouldSetSource::No);
- });
+ auto response = m_preloader->response();
+ if (response.isRedirection() && response.httpHeaderFields().contains(HTTPHeaderName::Location)) {
+ processRedirectResponse(WTFMove(response), ShouldSetSource::No);
+ return;
+ }
+
+ bool needsContinueDidReceiveResponseMessage = true;
+ processResponse(WTFMove(response), needsContinueDidReceiveResponseMessage, ShouldSetSource::No);
}
void ServiceWorkerFetchTask::loadBodyFromPreloader()
@@ -467,6 +503,11 @@
return true;
}
+MonotonicTime ServiceWorkerFetchTask::startTime() const
+{
+ return m_preloader ? m_preloader->startTime() : MonotonicTime { };
+}
+
} // namespace WebKit
#undef SWFETCH_RELEASE_LOG
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h (295487 => 295488)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h 2022-06-13 14:07:54 UTC (rev 295488)
@@ -90,6 +90,8 @@
bool convertToDownload(DownloadManager&, DownloadID, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
+ MonotonicTime startTime() const;
+
private:
enum class ShouldSetSource : bool { No, Yes };
void didReceiveRedirectResponse(WebCore::ResourceResponse&&);
@@ -99,6 +101,7 @@
void didFinish(const WebCore::NetworkLoadMetrics&);
void didFail(const WebCore::ResourceError&);
void didNotHandle();
+ void usePreload();
void processRedirectResponse(WebCore::ResourceResponse&&, ShouldSetSource);
void processResponse(WebCore::ResourceResponse&&, bool needsContinueDidReceiveResponseMessage, ShouldSetSource);
@@ -111,6 +114,7 @@
void loadBodyFromPreloader();
void cancelPreloadIfNecessary();
NetworkSession* session();
+ void preloadResponseIsReady();
template<typename Message> bool sendToServiceWorker(Message&&);
template<typename Message> bool sendToClient(Message&&);
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.messages.in (295487 => 295488)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.messages.in 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.messages.in 2022-06-13 14:07:54 UTC (rev 295488)
@@ -30,6 +30,7 @@
DidReceiveData(IPC::SharedBufferReference data, int64_t encodedDataLength)
DidReceiveFormData(IPC::FormDataReference data)
DidFinish(WebCore::NetworkLoadMetrics metrics)
+ UsePreload()
}
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.cpp (295487 => 295488)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.cpp 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.cpp 2022-06-13 14:07:54 UTC (rev 295488)
@@ -45,10 +45,10 @@
, m_parameters(WTFMove(parameters))
, m_state(state)
, m_shouldCaptureExtraNetworkLoadMetrics(shouldCaptureExtraNetworkLoadMetrics())
+ , m_startTime(MonotonicTime::now())
{
RELEASE_LOG(ServiceWorker, "ServiceWorkerNavigationPreloader::ServiceWorkerNavigationPreloader %p", this);
- if (!m_state.enabled || parameters.isMainFrameNavigation)
- start();
+ start();
}
void ServiceWorkerNavigationPreloader::start()
@@ -164,6 +164,9 @@
{
RELEASE_LOG(ServiceWorker, "ServiceWorkerNavigationPreloader::didReceiveResponse %p", this);
+ if (response.isRedirection())
+ response.setTainting(ResourceResponse::Tainting::Opaqueredirect);
+
if (response.httpStatusCode() == 304 && m_cacheEntry) {
auto cacheEntry = WTFMove(m_cacheEntry);
loadWithCacheEntry(*cacheEntry);
@@ -217,8 +220,6 @@
void ServiceWorkerNavigationPreloader::waitForResponse(ResponseCallback&& callback)
{
- start();
-
if (!m_error.isNull()) {
callback();
return;
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.h (295487 => 295488)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.h 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerNavigationPreloader.h 2022-06-13 14:07:54 UTC (rev 295488)
@@ -65,6 +65,8 @@
bool convertToDownload(DownloadManager&, DownloadID, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
+ MonotonicTime startTime() const { return m_startTime; }
+
private:
// NetworkLoadClient.
void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) final { }
@@ -100,6 +102,7 @@
bool m_isStarted { false };
bool m_isCancelled { false };
bool m_shouldCaptureExtraNetworkLoadMetrics { false };
+ MonotonicTime m_startTime;
};
} // namespace WebKit
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp (295487 => 295488)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp 2022-06-13 14:07:54 UTC (rev 295488)
@@ -334,6 +334,22 @@
serviceWorkerThreadProxy->convertFetchToDownload(serverConnectionIdentifier, fetchIdentifier);
}
+void WebSWContextManagerConnection::navigationPreloadIsReady(SWServerConnectionIdentifier serverConnectionIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, FetchIdentifier fetchIdentifier, ResourceResponse&& response)
+{
+ assertIsCurrent(m_queue.get());
+
+ if (auto serviceWorkerThreadProxy = SWContextManager::singleton().serviceWorkerThreadProxyFromBackgroundThread(serviceWorkerIdentifier))
+ serviceWorkerThreadProxy->navigationPreloadIsReady(serverConnectionIdentifier, fetchIdentifier, WTFMove(response));
+}
+
+void WebSWContextManagerConnection::navigationPreloadFailed(SWServerConnectionIdentifier serverConnectionIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, FetchIdentifier fetchIdentifier, ResourceError&& error)
+{
+ assertIsCurrent(m_queue.get());
+
+ if (auto serviceWorkerThreadProxy = SWContextManager::singleton().serviceWorkerThreadProxyFromBackgroundThread(serviceWorkerIdentifier))
+ serviceWorkerThreadProxy->navigationPreloadFailed(serverConnectionIdentifier, fetchIdentifier, WTFMove(error));
+}
+
void WebSWContextManagerConnection::postMessageToServiceWorkerClient(const ScriptExecutionContextIdentifier& destinationIdentifier, const MessageWithMessagePorts& message, ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin)
{
m_connectionToNetworkProcess->send(Messages::WebSWServerToContextConnection::PostMessageToServiceWorkerClient(destinationIdentifier, message, sourceIdentifier, sourceOrigin), 0);
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h (295487 => 295488)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h 2022-06-13 14:07:54 UTC (rev 295488)
@@ -119,6 +119,8 @@
void setThrottleState(bool isThrottleable);
void convertFetchToDownload(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier);
void cancelFetchDownload(WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier);
+ void navigationPreloadIsReady(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier, WebCore::ResourceResponse&&);
+ void navigationPreloadFailed(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier, WebCore::ResourceError&&);
Ref<IPC::Connection> m_connectionToNetworkProcess;
WebCore::RegistrableDomain m_registrableDomain;
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in (295487 => 295488)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in 2022-06-13 14:07:54 UTC (rev 295488)
@@ -46,6 +46,9 @@
SetThrottleState(bool isThrottleable)
ConvertFetchToDownload(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier identifier)
+
+ NavigationPreloadIsReady(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier identifier, WebCore::ResourceResponse response)
+ NavigationPreloadFailed(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier identifier, WebCore::ResourceError error)
}
#endif
Modified: trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp (295487 => 295488)
--- trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp 2022-06-13 14:07:54 UTC (rev 295488)
@@ -35,6 +35,7 @@
#include "SharedBufferReference.h"
#include "WebCoreArgumentCoders.h"
#include "WebErrors.h"
+#include <WebCore/FetchEvent.h>
#include <WebCore/ResourceError.h>
#include <WebCore/ResourceResponse.h>
#include <WebCore/SWContextManager.h>
@@ -225,6 +226,53 @@
m_cancelledCallback = WTFMove(callback);
}
+void WebServiceWorkerFetchTaskClient::setFetchEvent(Ref<WebCore::FetchEvent>&& event)
+{
+ m_event = WTFMove(event);
+
+ if (!m_preloadResponse.isNull()) {
+ m_event->navigationPreloadIsReady(WTFMove(m_preloadResponse));
+ m_event = nullptr;
+ return;
+ }
+
+ if (!m_preloadError.isNull()) {
+ m_event->navigationPreloadFailed(WTFMove(m_preloadError));
+ m_event = nullptr;
+ }
+}
+
+void WebServiceWorkerFetchTaskClient::navigationPreloadIsReady(ResourceResponse&& response)
+{
+ if (!m_event) {
+ m_preloadResponse = WTFMove(response);
+ return;
+ }
+
+ m_event->navigationPreloadIsReady(WTFMove(response));
+ m_event = nullptr;
+}
+
+void WebServiceWorkerFetchTaskClient::navigationPreloadFailed(ResourceError&& error)
+{
+ if (!m_event) {
+ m_preloadError = WTFMove(error);
+ return;
+ }
+ m_event->navigationPreloadFailed(WTFMove(error));
+ m_event = nullptr;
+}
+
+void WebServiceWorkerFetchTaskClient::usePreload()
+{
+ if (!m_connection)
+ return;
+
+ m_connection->send(Messages::ServiceWorkerFetchTask::UsePreload { }, m_fetchIdentifier);
+
+ cleanup();
+}
+
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()));
@@ -252,7 +300,7 @@
void WebServiceWorkerFetchTaskClient::cleanup()
{
m_connection = nullptr;
-
+ m_event = nullptr;
ensureOnMainRunLoop([serviceWorkerIdentifier = m_serviceWorkerIdentifier, serverConnectionIdentifier = m_serverConnectionIdentifier, fetchIdentifier = m_fetchIdentifier] {
if (auto* proxy = SWContextManager::singleton().serviceWorkerThreadProxy(serviceWorkerIdentifier))
proxy->removeFetch(serverConnectionIdentifier, fetchIdentifier);
Modified: trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.h (295487 => 295488)
--- trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.h 2022-06-13 12:12:37 UTC (rev 295487)
+++ trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.h 2022-06-13 14:07:54 UTC (rev 295488)
@@ -28,7 +28,7 @@
#if ENABLE(SERVICE_WORKER)
#include "Connection.h"
-#include <WebCore/FetchIdentifier.h>
+#include <WebCore/FetchEvent.h>
#include <WebCore/FetchLoader.h>
#include <WebCore/FetchLoaderClient.h>
#include <WebCore/NetworkLoadMetrics.h>
@@ -60,6 +60,10 @@
void continueDidReceiveResponse() final;
void convertFetchToDownload() final;
void setCancelledCallback(Function<void()>&&) final;
+ void setFetchEvent(Ref<WebCore::FetchEvent>&&);
+ void navigationPreloadIsReady(WebCore::ResourceResponse&&) final;
+ void navigationPreloadFailed(WebCore::ResourceError&&) final;
+ void usePreload() final;
void cleanup();
@@ -90,7 +94,10 @@
WebCore::NetworkLoadMetrics m_networkLoadMetrics;
bool m_didFinish { false };
bool m_isDownload { false };
+ RefPtr<WebCore::FetchEvent> m_event;
Function<void()> m_cancelledCallback;
+ WebCore::ResourceResponse m_preloadResponse;
+ WebCore::ResourceError m_preloadError;
};
} // namespace WebKit