Changeset 287915 in webkit
- Timestamp:
- Jan 12, 2022 1:44:27 AM (6 months ago)
- Location:
- trunk
- Files:
-
- 9 edited
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-handled.https-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-handled.https.html (modified) (2 diffs)
-
LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-handled-worker.js (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/workers/service/FetchEvent.cpp (modified) (2 diffs)
-
Source/WebCore/workers/service/FetchEvent.h (modified) (5 diffs)
-
Source/WebCore/workers/service/FetchEvent.idl (modified) (3 diffs)
-
Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/w3c/ChangeLog
r287909 r287915 1 2022-01-12 Youenn Fablet <youenn@apple.com> 2 3 New service worker API 'FetchEvent.handled' needs to be supported 4 https://bugs.webkit.org/show_bug.cgi?id=208185 5 <rdar://problem/59808975> 6 7 Reviewed by Chris Dumez. 8 9 * web-platform-tests/service-workers/service-worker/fetch-event-handled.https-expected.txt: 10 * web-platform-tests/service-workers/service-worker/fetch-event-handled.https.html: 11 * web-platform-tests/service-workers/service-worker/resources/fetch-event-handled-worker.js: 12 (try.event.handled.then): 13 (catch): 14 (send_message_to_client): Deleted. 15 1 16 2021-11-29 Simon Fraser <simon.fraser@apple.com> 2 17 -
trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-handled.https-expected.txt
r267647 r287915 1 2 3 Harness Error (TIMEOUT), message = null4 1 5 2 PASS global setup 6 TIMEOUT FetchEvent.handled should resolve when respondWith() is not called for a navigation request Test timed out7 NOTRUNFetchEvent.handled should resolve when respondWith() is not called for a sub-resource request8 NOTRUNFetchEvent.handled should reject when respondWith() is not called and the event is canceled9 NOTRUNFetchEvent.handled should resolve when the promise provided to respondWith() is resolved10 NOTRUNFetchEvent.handled should reject when the promise provided to respondWith() is resolved to an invalid response11 NOTRUNFetchEvent.handled should reject when the promise provided to respondWith() is rejected12 NOTRUNglobal cleanup3 PASS FetchEvent.handled should resolve when respondWith() is not called for a navigation request 4 PASS FetchEvent.handled should resolve when respondWith() is not called for a sub-resource request 5 PASS FetchEvent.handled should reject when respondWith() is not called and the event is canceled 6 PASS FetchEvent.handled should resolve when the promise provided to respondWith() is resolved 7 PASS FetchEvent.handled should reject when the promise provided to respondWith() is resolved to an invalid response 8 PASS FetchEvent.handled should reject when the promise provided to respondWith() is rejected 9 PASS global cleanup 13 10 -
trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-handled.https.html
r279389 r287915 11 11 const script = 'resources/fetch-event-handled-worker.js'; 12 12 const scope = 'resources/simple.html'; 13 const channel = new MessageChannel(); 13 14 14 15 // Wait for a message from the service worker and removes the message handler. 15 16 function wait_for_message_from_worker() { 16 return new Promise((resolve) => { 17 const handler = (event) => { 18 frame.contentWindow.navigator.serviceWorker.removeEventListener( 19 'message', handler); 20 resolve(event.data); 21 }; 22 frame.contentWindow.navigator.serviceWorker.addEventListener( 23 'message', handler); 24 }); 17 return new Promise((resolve) => channel.port2.onmessage = (event) => resolve(event.data)); 25 18 } 26 19 … … 30 23 await service_worker_unregister_and_register(t, script, scope); 31 24 worker = registration.installing; 25 if (!worker) 26 worker = registration.active; 27 worker.postMessage({port:channel.port1}, [channel.port1]); 32 28 await wait_for_state(t, worker, 'activated'); 33 29 }, 'global setup'); 34 30 35 31 promise_test(async (t) => { 36 frame = awaitwith_iframe(scope);32 const promise = with_iframe(scope); 37 33 const message = await wait_for_message_from_worker(); 34 frame = await promise; 38 35 assert_equals(message, 'RESOLVED'); 39 36 }, 'FetchEvent.handled should resolve when respondWith() is not called for a' + -
trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-event-handled-worker.js
r264043 r287915 2 2 // REJECTED) to the test. 3 3 4 // Send a message to the client with the client id. 5 function send_message_to_client(message, clientId) { 6 clients.get(clientId).then((client) => { 7 client.postMessage(message); 8 }); 9 } 4 self.addEventListener('message', function(event) { 5 self.port = event.data.port; 6 }); 10 7 11 8 self.addEventListener('fetch', function(event) { 12 const clientId = (event.request.mode === 'navigate') ?13 event.resultingClientId : event.clientId;14 15 9 try { 16 10 event.handled.then(() => { 17 se nd_message_to_client('RESOLVED', clientId);11 self.port.postMessage('RESOLVED'); 18 12 }, () => { 19 se nd_message_to_client('REJECTED', clientId);13 self.port.postMessage('REJECTED'); 20 14 }); 21 15 } catch (e) { 22 se nd_message_to_client('FAILED', clientId);16 self.port.postMessage('FAILED'); 23 17 return; 24 18 } -
trunk/Source/WebCore/ChangeLog
r287914 r287915 1 2022-01-12 Youenn Fablet <youenn@apple.com> 2 3 New service worker API 'FetchEvent.handled' needs to be supported 4 https://bugs.webkit.org/show_bug.cgi?id=208185 5 <rdar://problem/59808975> 6 7 Reviewed by Chris Dumez. 8 9 Expose FetchEvent.handled and resolve/reject it as per specification. 10 11 Covered by test that we update to not rely on clientIds that we do not support very well. 12 13 * workers/service/FetchEvent.cpp: 14 (WebCore::FetchEvent::createForTesting): 15 (WebCore::retrieveHandledPromise): 16 (WebCore::FetchEvent::FetchEvent): 17 * workers/service/FetchEvent.h: 18 * workers/service/FetchEvent.idl: 19 * workers/service/context/ServiceWorkerFetch.cpp: 20 (WebCore::ServiceWorkerFetch::processResponse): 21 (WebCore::ServiceWorkerFetch::dispatchFetchEvent): 22 1 23 2022-01-12 Frédéric Wang <fwang@igalia.com> 2 24 -
trunk/Source/WebCore/workers/service/FetchEvent.cpp
r286419 r287915 43 43 FetchEvent::Init init; 44 44 init.request = FetchRequest::create(context, { }, FetchHeaders::create(FetchHeaders::Guard::Immutable, { }), { }, { }, { }); 45 return FetchEvent::create( "fetch", WTFMove(init), Event::IsTrusted::Yes);45 return FetchEvent::create(*context.globalObject(), "fetch", WTFMove(init), Event::IsTrusted::Yes); 46 46 } 47 47 48 FetchEvent::FetchEvent(const AtomString& type, Init&& initializer, IsTrusted isTrusted) 48 static inline Ref<DOMPromise> retrieveHandledPromise(JSC::JSGlobalObject& globalObject, RefPtr<DOMPromise>&& promise) 49 { 50 if (promise) 51 return promise.releaseNonNull(); 52 53 JSC::JSLockHolder lock(globalObject.vm()); 54 55 auto& jsDOMGlobalObject = *JSC::jsCast<JSDOMGlobalObject*>(&globalObject); 56 auto deferredPromise = DeferredPromise::create(jsDOMGlobalObject); 57 return DOMPromise::create(jsDOMGlobalObject, *JSC::jsCast<JSC::JSPromise*>(deferredPromise->promise())); 58 } 59 60 FetchEvent::FetchEvent(JSC::JSGlobalObject& globalObject, const AtomString& type, Init&& initializer, IsTrusted isTrusted) 49 61 : ExtendableEvent(type, initializer, isTrusted) 50 62 , m_request(initializer.request.releaseNonNull()) … … 52 64 , m_reservedClientId(WTFMove(initializer.reservedClientId)) 53 65 , m_targetClientId(WTFMove(initializer.targetClientId)) 66 , m_handled(retrieveHandledPromise(globalObject, WTFMove(initializer.handled))) 54 67 { 55 68 } -
trunk/Source/WebCore/workers/service/FetchEvent.h
r286419 r287915 34 34 #include <wtf/Expected.h> 35 35 36 namespace JSC { 37 class JSGlobalObject; 38 } 39 36 40 namespace WebCore { 37 41 42 class DOMPromise; 38 43 class FetchResponse; 39 44 class ResourceError; … … 47 52 String reservedClientId; 48 53 String targetClientId; 54 RefPtr<DOMPromise> handled; 49 55 }; 50 56 51 57 WEBCORE_EXPORT static Ref<FetchEvent> createForTesting(ScriptExecutionContext&); 52 58 53 static Ref<FetchEvent> create( const AtomString& type, Init&& initializer, IsTrusted isTrusted = IsTrusted::No)59 static Ref<FetchEvent> create(JSC::JSGlobalObject& globalObject, const AtomString& type, Init&& initializer, IsTrusted isTrusted = IsTrusted::No) 54 60 { 55 return adoptRef(*new FetchEvent( type, WTFMove(initializer), isTrusted));61 return adoptRef(*new FetchEvent(globalObject, type, WTFMove(initializer), isTrusted)); 56 62 } 57 63 ~FetchEvent(); … … 68 74 const String& reservedClientId() const { return m_reservedClientId; } 69 75 const String& targetClientId() const { return m_targetClientId; } 76 DOMPromise& handled() const { return m_handled.get(); } 70 77 71 78 bool respondWithEntered() const { return m_respondWithEntered; } … … 79 86 80 87 private: 81 WEBCORE_EXPORT FetchEvent( const AtomString&, Init&&, IsTrusted);88 WEBCORE_EXPORT FetchEvent(JSC::JSGlobalObject&, const AtomString&, Init&&, IsTrusted); 82 89 83 90 void promiseIsSettled(); … … 94 101 bool m_respondWithError { false }; 95 102 RefPtr<DOMPromise> m_respondPromise; 103 Ref<DOMPromise> m_handled; 96 104 97 105 ResponseCallback m_onResponse; -
trunk/Source/WebCore/workers/service/FetchEvent.idl
r286419 r287915 32 32 JSGenerateToNativeObject 33 33 ] interface FetchEvent : ExtendableEvent { 34 constructor(DOMString type, FetchEventInit eventInitDict);34 [CallWith=GlobalObject] constructor(DOMString type, FetchEventInit eventInitDict); 35 35 [SameObject] readonly attribute FetchRequest request; 36 36 [CallWith=ScriptExecutionContext, EnabledBySetting=ServiceWorkerNavigationPreloadEnabled] readonly attribute Promise<any> preloadResponse; … … 38 38 readonly attribute DOMString reservedClientId; 39 39 readonly attribute DOMString targetClientId; 40 readonly attribute Promise<undefined> handled; 40 41 41 42 undefined respondWith(Promise<FetchResponse> r); … … 47 48 DOMString reservedClientId = ""; 48 49 DOMString targetClientId = ""; 50 Promise<undefined> handled; 49 51 }; -
trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp
r287612 r287915 34 34 #include "FetchRequest.h" 35 35 #include "FetchResponse.h" 36 #include "JSDOMPromise.h" 36 37 #include "MIMETypeRegistry.h" 37 38 #include "ResourceRequest.h" … … 65 66 } 66 67 67 static void processResponse(Ref<Client>&& client, Expected<Ref<FetchResponse>, std::optional<ResourceError>>&& result, FetchOptions::Mode mode, FetchOptions::Redirect redirect, const URL& requestURL, CertificateInfo&& certificateInfo )68 static void processResponse(Ref<Client>&& client, Expected<Ref<FetchResponse>, std::optional<ResourceError>>&& result, FetchOptions::Mode mode, FetchOptions::Redirect redirect, const URL& requestURL, CertificateInfo&& certificateInfo, DeferredPromise& promise) 68 69 { 69 70 if (!result.has_value()) { … … 71 72 if (!error) { 72 73 client->didNotHandle(); 74 promise.resolve(); 73 75 return; 74 76 } 75 77 client->didFail(*error); 78 promise.reject(Exception { ExceptionCode::NetworkError }); 76 79 return; 77 80 } … … 81 84 if (!loadingError.isNull()) { 82 85 client->didFail(loadingError); 86 promise.reject(Exception { ExceptionCode::NetworkError }); 83 87 return; 84 88 } … … 87 91 if (auto error = validateResponse(resourceResponse, mode, redirect); !error.isNull()) { 88 92 client->didFail(error); 89 return; 90 } 93 promise.reject(Exception { ExceptionCode::NetworkError }); 94 return; 95 } 96 97 promise.resolve(); 91 98 92 99 if (resourceResponse.isRedirection() && resourceResponse.httpHeaderFields().contains(HTTPHeaderName::Location)) { … … 182 189 init.clientId = clientId->toString(); 183 190 init.cancelable = true; 184 auto event = FetchEvent::create(eventNames().fetchEvent, WTFMove(init), Event::IsTrusted::Yes); 191 192 auto& jsDOMGlobalObject = *JSC::jsCast<JSDOMGlobalObject*>(globalScope.globalObject()); 193 JSC::JSLockHolder lock(jsDOMGlobalObject.vm()); 194 195 auto* promise = JSC::JSPromise::create(jsDOMGlobalObject.vm(), jsDOMGlobalObject.promiseStructure()); 196 ASSERT(promise); 197 198 auto deferredPromise = DeferredPromise::create(jsDOMGlobalObject, *promise); 199 init.handled = DOMPromise::create(jsDOMGlobalObject, *promise); 200 201 auto event = FetchEvent::create(*globalScope.globalObject(), eventNames().fetchEvent, WTFMove(init), Event::IsTrusted::Yes); 185 202 186 203 if (isServiceWorkerNavigationPreloadEnabled) … … 189 206 CertificateInfo certificateInfo = globalScope.certificateInfo(); 190 207 191 event->onResponse([client, mode, redirect, requestURL, certificateInfo = WTFMove(certificateInfo) ] (auto&& result) mutable {192 processResponse(WTFMove(client), WTFMove(result), mode, redirect, requestURL, WTFMove(certificateInfo) );208 event->onResponse([client, mode, redirect, requestURL, certificateInfo = WTFMove(certificateInfo), deferredPromise] (auto&& result) mutable { 209 processResponse(WTFMove(client), WTFMove(result), mode, redirect, requestURL, WTFMove(certificateInfo), deferredPromise.get()); 193 210 }); 194 211 … … 199 216 ResourceError error { errorDomainWebKitInternal, 0, requestURL, "Fetch event was canceled"_s, ResourceError::Type::General, ResourceError::IsSanitized::Yes }; 200 217 client->didFail(error); 218 deferredPromise->reject(Exception { NetworkError }); 201 219 return; 202 220 } 203 221 client->didNotHandle(); 222 deferredPromise->resolve(); 204 223 } 205 224
Note: See TracChangeset
for help on using the changeset viewer.