Title: [292905] trunk
Revision
292905
Author
[email protected]
Date
2022-04-15 06:15:30 -0700 (Fri, 15 Apr 2022)

Log Message

ServiceWorker.postMessage() doesn't work from inside iframe
https://bugs.webkit.org/show_bug.cgi?id=213984
<rdar://problem/65203340>

Reviewed by Chris Dumez.

LayoutTests/imported/w3c:

* web-platform-tests/service-workers/service-worker/about-blank-replacement.https-expected.txt:
* web-platform-tests/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt:
* web-platform-tests/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt:

Source/WebCore:

postMessage was not working as we do not postMessage to a service worker if the source is not registered.
We now register service worker clients more aggresively and pass the client origin to better handle blob and about:blank clients.
We also add support for registering/unregistering worker clients when they get suspended/resumed.
To make sure a worker client is removed in failure case, WorkerScriptLoader is unregistering the service worker client if
the service worker data was not taken by its Worker.

Test: http/wpt/service-workers/about-blank-iframe.html

* dom/Document.cpp:
* loader/DocumentLoader.cpp:
* workers/DedicatedWorkerThread.cpp:
* workers/WorkerGlobalScope.cpp:
* workers/WorkerGlobalScope.h:
* workers/WorkerScriptLoader.cpp:
* workers/service/SWClientConnection.h:
* workers/service/WorkerSWClientConnection.cpp:
* workers/service/WorkerSWClientConnection.h:

Source/WebKit:

Pass the full ClientOrigin when registering a service worker client.
Filter out clients that cannot be matched:
- non HTTP/blob/about:blank clients
- sandboxed HTTP clients

* NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
* NetworkProcess/ServiceWorker/WebSWServerConnection.h:
* NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in:
* WebProcess/Storage/WebSWClientConnection.cpp:
* WebProcess/Storage/WebSWClientConnection.h:

LayoutTests:

* http/wpt/service-workers/about-blank-iframe-expected.txt: Added.
* http/wpt/service-workers/about-blank-iframe-worker.js: Added.
* http/wpt/service-workers/about-blank-iframe.html: Added.
* http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache.html:
* http/tests/workers/service/client-removed-from-clients-while-in-page-cache-expected.txt:
* http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html:
* http/tests/workers/service/other_resources/test.html:
* http/tests/workers/service/resources/getClientIds-worker.js:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (292904 => 292905)


--- trunk/LayoutTests/ChangeLog	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/LayoutTests/ChangeLog	2022-04-15 13:15:30 UTC (rev 292905)
@@ -1,3 +1,20 @@
+2022-04-15  Youenn Fablet  <[email protected]>
+
+        ServiceWorker.postMessage() doesn't work from inside iframe
+        https://bugs.webkit.org/show_bug.cgi?id=213984
+        <rdar://problem/65203340>
+
+        Reviewed by Chris Dumez.
+
+        * http/wpt/service-workers/about-blank-iframe-expected.txt: Added.
+        * http/wpt/service-workers/about-blank-iframe-worker.js: Added.
+        * http/wpt/service-workers/about-blank-iframe.html: Added.
+        * http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache.html:
+        * http/tests/workers/service/client-removed-from-clients-while-in-page-cache-expected.txt:
+        * http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html:
+        * http/tests/workers/service/other_resources/test.html:
+        * http/tests/workers/service/resources/getClientIds-worker.js:
+
 2022-04-14  Claudio Saavedra  <[email protected]>
 
         [GTK] Default initialize GTK-specific print info in WebKit::PrintInfo

Modified: trunk/LayoutTests/http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache.html (292904 => 292905)


--- trunk/LayoutTests/http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache.html	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/LayoutTests/http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache.html	2022-04-15 13:15:30 UTC (rev 292905)
@@ -22,7 +22,7 @@
 
 navigator.serviceWorker.addEventListener("message", function(event) {
   if (step == "BothClientsInitiallyActive") {
-    if (!containsExpectedClients(event.data)) {
+    if (!containsExpectedClients(event.data.ids)) {
       if (++tries > 20) {
           log("FAIL: Wrong initial number of clients");
           finishSWTest();
@@ -59,7 +59,7 @@
   }
 
   if (step == "SecondClientRestoredFromPageCache") {
-    if (!containsExpectedClients(event.data)) {
+    if (!containsExpectedClients(event.data.ids)) {
       log("FAIL: Wrong number of clients after one client was restored from page cache");
       finishSWTest();
     }

Modified: trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache-expected.txt (292904 => 292905)


--- trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache-expected.txt	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache-expected.txt	2022-04-15 13:15:30 UTC (rev 292905)
@@ -1,6 +1,8 @@
 * Tests that a client is removed from the list of service worker clients while it is in the page cache
 
-PASS: service worker has initially 2 clients
+PASS: service worker has initially 2 window clients
+PASS: service worker has initially 2 worker clients
 PASS: page is about to enter page cache
-PASS: service worker has only 1 client after 1 entered page cache
+PASS: service worker has only 1 window client after 1 entered page cache
+PASS: service worker has only 1 worker client after 1 entered page cache
 

Modified: trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html (292904 => 292905)


--- trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html	2022-04-15 13:15:30 UTC (rev 292905)
@@ -9,7 +9,7 @@
 
 let topClientIdentifier = null;
 let windowClientIdentifier = null;
-
+let dedicatedWorker = null;
 let tries = 0;
 
 function containsBothClients(clientIdentifiers)
@@ -23,8 +23,8 @@
 }
 
 navigator.serviceWorker.addEventListener("message", function(event) {
-  if (step == "BothClientsInitiallyActive") {
-    if (!containsBothClients(event.data)) {
+  if (step == "AllClientsInitiallyActive") {
+    if (!containsBothClients(event.data.ids) && event.data.workersCount !== 2) {
       if (++tries > 20) {
           log("FAIL: Wrong initial number of clients");
           finishSWTest();
@@ -33,7 +33,8 @@
       worker.postMessage("getClientIds");
       return;
     }
-    log("PASS: service worker has initially 2 clients");
+    log("PASS: service worker has initially 2 window clients");
+    log("PASS: service worker has initially 2 worker clients");
 
     otherWindow.addEventListener("pagehide", function(event) {
        if (!event.persisted) {
@@ -54,28 +55,31 @@
   }
 
   if (step == "OnlyOneClientRemainsActive") {
-    if (!containsOnlyTopClient(event.data)) {
+    if (!containsOnlyTopClient(event.data.ids) && event.data.workersCount !== 1) {
       log("FAIL: Wrong number of clients after one client entered page cache");
       finishSWTest();
     }
 
-    log("PASS: service worker has only 1 client after 1 entered page cache");
+    log("PASS: service worker has only 1 window client after 1 entered page cache");
+    log("PASS: service worker has only 1 worker client after 1 entered page cache");
     finishSWTest();
   }
 });
 
-navigator.serviceWorker.register("resources/getClientIds-worker.js", { }).then(function(registration) {
+navigator.serviceWorker.register("resources/getClientIds-worker.js", { }).then(async (registration) => {
     if (!window.internals)
         return;
     topClientIdentifier = internals.serviceWorkerClientInternalIdentifier(document);
 
     worker = registration.installing;
+
+    dedicatedWorker = new Worker("other_resources/dummy.js");
+
     otherWindow = open("other_resources/test.html");
-    otherWindow._onload_ = function() {
-      windowClientIdentifier = internals.serviceWorkerClientInternalIdentifier(otherWindow.document);
-      step = "BothClientsInitiallyActive"
-      worker.postMessage("getClientIds");
-    };
+    await new Promise(resolve => otherWindow._onload_ = resolve);
+    windowClientIdentifier = internals.serviceWorkerClientInternalIdentifier(otherWindow.document);
+    step = "AllClientsInitiallyActive"
+    worker.postMessage("getClientIds");
 });
 </script>
 </body>

Added: trunk/LayoutTests/http/tests/workers/service/other_resources/dummy.js ( => )


Modified: trunk/LayoutTests/http/tests/workers/service/other_resources/test.html
===================================================================
--- trunk/LayoutTests/http/tests/workers/service/other_resources/test.html	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/LayoutTests/http/tests/workers/service/other_resources/test.html	2022-04-15 13:15:30 UTC (rev 292905)
@@ -1 +1,9 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+var dedicatedWorker = new Worker("dummy.js");
+</script>
 TEST
+</body>

Modified: trunk/LayoutTests/http/tests/workers/service/resources/getClientIds-worker.js (292904 => 292905)


--- trunk/LayoutTests/http/tests/workers/service/resources/getClientIds-worker.js	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/LayoutTests/http/tests/workers/service/resources/getClientIds-worker.js	2022-04-15 13:15:30 UTC (rev 292905)
@@ -1,9 +1,12 @@
-self.addEventListener("message", (event) => {
+self.addEventListener("message", async (event) => {
     source = event.source;
-    clients.matchAll({ includeUncontrolled : true }).then(function(clients) {
-        let ids = [];
-        for (let client of clients)
-            ids.push(self.internals.serviceWorkerClientInternalIdentifier(client));
-        source.postMessage(ids);
-    });
+    const matchedClients = await clients.matchAll({ includeUncontrolled : true, type: 'all' })
+    let data = { ids: [], workerCount: 0 };
+    for (let client of matchedClients) {
+        if (client.type === 'worker')
+            data.workerCount++;
+        else
+            data.ids.push(self.internals.serviceWorkerClientInternalIdentifier(client));
+    }
+    source.postMessage(data);
 });

Added: trunk/LayoutTests/http/wpt/service-workers/about-blank-iframe-expected.txt (0 => 292905)


--- trunk/LayoutTests/http/wpt/service-workers/about-blank-iframe-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/about-blank-iframe-expected.txt	2022-04-15 13:15:30 UTC (rev 292905)
@@ -0,0 +1,5 @@
+
+PASS setup
+PASS post messaging from an iframe
+PASS remove iframe
+

Added: trunk/LayoutTests/http/wpt/service-workers/about-blank-iframe-worker.js (0 => 292905)


--- trunk/LayoutTests/http/wpt/service-workers/about-blank-iframe-worker.js	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/about-blank-iframe-worker.js	2022-04-15 13:15:30 UTC (rev 292905)
@@ -0,0 +1,4 @@
+addEventListener('message', async event => {
+    const clients = await self.clients.matchAll({ includeUncontrolled : true });
+    clients.forEach(client => client.postMessage(event.data));
+});

Added: trunk/LayoutTests/http/wpt/service-workers/about-blank-iframe.html (0 => 292905)


--- trunk/LayoutTests/http/wpt/service-workers/about-blank-iframe.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/about-blank-iframe.html	2022-04-15 13:15:30 UTC (rev 292905)
@@ -0,0 +1,44 @@
+<html>
+<head>
+<title>Service Worker Fetch Event</title>
+<script src=""
+<script src=""
+</head>
+<body>
+<iframe id='myframe'></iframe>
+<script>
+promise_test(async () => {
+    const promise = new Promise(resolve => window.resolveCallback = resolve);
+    myframe.contentDocument.write(`
+    <body>
+        <script>
+            navigator.serviceWorker.register('about-blank-iframe-worker.js').then(registration => {
+                window.worker = registration.active ? registration.active : registration.installing;
+                parent.resolveCallback();
+            });
+        </${'script'}>
+    </body>`);
+    return promise;
+}, "setup");
+
+promise_test(async () => {
+    const promise = new Promise((resolve, reject) => {
+        navigator.serviceWorker.addEventListener("message", (event) => {
+            resolve(event.data);
+        });
+        setTimeout(() => reject("No response message from service worker"), 5000);
+    });
+
+    myframe.contentWindow.worker.postMessage("hello");
+    assert_equals(await promise, "hello");
+}, "post messaging from an iframe");
+
+promise_test(async () => {
+    const registrations = await navigator.serviceWorker.getRegistrations();
+    for (let registration of registrations)
+        await registration.unregister();
+    myframe.remove();
+}, "remove iframe");
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (292904 => 292905)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2022-04-15 13:15:30 UTC (rev 292905)
@@ -1,3 +1,15 @@
+2022-04-15  Youenn Fablet  <[email protected]>
+
+        ServiceWorker.postMessage() doesn't work from inside iframe
+        https://bugs.webkit.org/show_bug.cgi?id=213984
+        <rdar://problem/65203340>
+
+        Reviewed by Chris Dumez.
+
+        * web-platform-tests/service-workers/service-worker/about-blank-replacement.https-expected.txt:
+        * web-platform-tests/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt:
+        * web-platform-tests/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt:
+
 2022-04-14  Nikolaos Mouchtaris  <[email protected]>
 
         calc(): Serialize top level min/max/hypot as calc()

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https-expected.txt (292904 => 292905)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https-expected.txt	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https-expected.txt	2022-04-15 13:15:30 UTC (rev 292905)
@@ -5,7 +5,7 @@
 FAIL Initial about:blank modified by parent is controlled, exposed to clients.matchAll(), and matches final Client. assert_false: result: failure: could not find about:blank client expected false got true
 FAIL Popup initial about:blank is controlled, exposed to clients.matchAll(), and matches final Client. assert_false: result: failure: could not find about:blank client expected false got true
 PASS Initial about:blank is controlled, exposed to clients.matchAll(), and final Client is not controlled by a service worker.
-FAIL Simple about:blank is controlled and is exposed to clients.matchAll(). assert_false: result: failure: could not find about:blank client expected false got true
-FAIL Nested about:srcdoc is controlled and is exposed to clients.matchAll(). assert_false: result: failure: could not find about:srcdoc client expected false got true
-FAIL Dynamic about:blank is controlled and is exposed to clients.matchAll(). assert_false: result: failure: could not find about:blank client expected false got true
+PASS Simple about:blank is controlled and is exposed to clients.matchAll().
+PASS Nested about:srcdoc is controlled and is exposed to clients.matchAll().
+PASS Dynamic about:blank is controlled and is exposed to clients.matchAll().
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt (292904 => 292905)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt	2022-04-15 13:15:30 UTC (rev 292905)
@@ -1,3 +1,3 @@
 
-FAIL Client.url of a blob URL worker should be a blob URL. assert_not_equals: worker client should exist got disallowed value "one worker client should exist"
+PASS Client.url of a blob URL worker should be a blob URL.
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt (292904 => 292905)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt	2022-04-15 13:15:30 UTC (rev 292905)
@@ -1,4 +1,4 @@
 
-FAIL Test Clients.matchAll() with a blob URL worker client. assert_equals: expected 1 but got 0
-FAIL Test Clients.matchAll() with an uncontrolled blob URL worker client. assert_equals: expected 1 but got 0
+PASS Test Clients.matchAll() with a blob URL worker client.
+PASS Test Clients.matchAll() with an uncontrolled blob URL worker client.
 

Modified: trunk/Source/WebCore/ChangeLog (292904 => 292905)


--- trunk/Source/WebCore/ChangeLog	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebCore/ChangeLog	2022-04-15 13:15:30 UTC (rev 292905)
@@ -1,3 +1,29 @@
+2022-04-15  Youenn Fablet  <[email protected]>
+
+        ServiceWorker.postMessage() doesn't work from inside iframe
+        https://bugs.webkit.org/show_bug.cgi?id=213984
+        <rdar://problem/65203340>
+
+        Reviewed by Chris Dumez.
+
+        postMessage was not working as we do not postMessage to a service worker if the source is not registered.
+        We now register service worker clients more aggresively and pass the client origin to better handle blob and about:blank clients.
+        We also add support for registering/unregistering worker clients when they get suspended/resumed.
+        To make sure a worker client is removed in failure case, WorkerScriptLoader is unregistering the service worker client if
+        the service worker data was not taken by its Worker.
+
+        Test: http/wpt/service-workers/about-blank-iframe.html
+
+        * dom/Document.cpp:
+        * loader/DocumentLoader.cpp:
+        * workers/DedicatedWorkerThread.cpp:
+        * workers/WorkerGlobalScope.cpp:
+        * workers/WorkerGlobalScope.h:
+        * workers/WorkerScriptLoader.cpp:
+        * workers/service/SWClientConnection.h:
+        * workers/service/WorkerSWClientConnection.cpp:
+        * workers/service/WorkerSWClientConnection.h:
+
 2022-04-14  Antoine Quint  <[email protected]>
 
         [model] ASVInlinePreview objects don't get cleared when the model source changes

Modified: trunk/Source/WebCore/dom/Document.cpp (292904 => 292905)


--- trunk/Source/WebCore/dom/Document.cpp	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebCore/dom/Document.cpp	2022-04-15 13:15:30 UTC (rev 292905)
@@ -8778,7 +8778,7 @@
         return;
 
     auto controllingServiceWorkerRegistrationIdentifier = activeServiceWorker() ? std::make_optional<ServiceWorkerRegistrationIdentifier>(activeServiceWorker()->registrationIdentifier()) : std::nullopt;
-    m_serviceWorkerConnection->registerServiceWorkerClient(topOrigin(), ServiceWorkerClientData::from(*this), controllingServiceWorkerRegistrationIdentifier, userAgent(url()));
+    m_serviceWorkerConnection->registerServiceWorkerClient(clientOrigin(), ServiceWorkerClientData::from(*this), controllingServiceWorkerRegistrationIdentifier, userAgent(url()));
 }
 
 void Document::navigateFromServiceWorker(const URL& url, CompletionHandler<void(bool)>&& callback)

Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (292904 => 292905)


--- trunk/Source/WebCore/loader/DocumentLoader.cpp	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp	2022-04-15 13:15:30 UTC (rev 292905)
@@ -1259,7 +1259,7 @@
                     document.createNewIdentifier();
             }
 
-            if (m_frame->document()->activeServiceWorker() || document.url().protocolIsInHTTPFamily() || (document.page() && document.page()->isServiceWorkerPage()))
+            if (m_frame->document()->activeServiceWorker() || document.url().protocolIsInHTTPFamily() || (document.page() && document.page()->isServiceWorkerPage()) || (document.parentDocument() && shouldUseActiveServiceWorkerFromParent(document, *document.parentDocument())))
                 document.setServiceWorkerConnection(&ServiceWorkerProvider::singleton().serviceWorkerConnection());
 
             if (m_resultingClientId) {

Modified: trunk/Source/WebCore/workers/DedicatedWorkerThread.cpp (292904 => 292905)


--- trunk/Source/WebCore/workers/DedicatedWorkerThread.cpp	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebCore/workers/DedicatedWorkerThread.cpp	2022-04-15 13:15:30 UTC (rev 292905)
@@ -52,6 +52,7 @@
 #if ENABLE(SERVICE_WORKER)
     if (params.serviceWorkerData)
         scope->setActiveServiceWorker(ServiceWorker::getOrCreate(scope.get(), ServiceWorkerData { *params.serviceWorkerData }));
+    scope->updateServiceWorkerClientData();
 #endif
     return scope;
 }

Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.cpp (292904 => 292905)


--- trunk/Source/WebCore/workers/WorkerGlobalScope.cpp	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.cpp	2022-04-15 13:15:30 UTC (rev 292905)
@@ -151,6 +151,11 @@
 {
     WorkerOrWorkletGlobalScope::prepareForDestruction();
 
+#if ENABLE(SERVICE_WORKER)
+    if (settingsValues().serviceWorkersEnabled)
+        swClientConnection().unregisterServiceWorkerClient(identifier());
+#endif
+
     stopIndexedDatabase();
 
     if (m_cacheStorageConnection)
@@ -229,10 +234,20 @@
 {
     if (m_connectionProxy)
         m_connectionProxy->setContextSuspended(*this, true);
+
+#if ENABLE(SERVICE_WORKER)
+    if (settingsValues().serviceWorkersEnabled)
+        swClientConnection().unregisterServiceWorkerClient(identifier());
+#endif
 }
 
 void WorkerGlobalScope::resume()
 {
+#if ENABLE(SERVICE_WORKER)
+    if (settingsValues().serviceWorkersEnabled)
+        updateServiceWorkerClientData();
+#endif
+
     if (m_connectionProxy)
         m_connectionProxy->setContextSuspended(*this, false);
 }
@@ -657,10 +672,12 @@
 #if ENABLE(SERVICE_WORKER)
 void WorkerGlobalScope::updateServiceWorkerClientData()
 {
-    ASSERT(type() == WebCore::WorkerGlobalScope::Type::DedicatedWorker);
+    if (!settingsValues().serviceWorkersEnabled)
+        return;
+
+    ASSERT(type() == WebCore::WorkerGlobalScope::Type::DedicatedWorker || type() == WebCore::WorkerGlobalScope::Type::SharedWorker);
     auto controllingServiceWorkerRegistrationIdentifier = activeServiceWorker() ? std::make_optional<ServiceWorkerRegistrationIdentifier>(activeServiceWorker()->registrationIdentifier()) : std::nullopt;
-    SWClientConnection& connection = swClientConnection();
-    connection.registerServiceWorkerClient(topOrigin(), ServiceWorkerClientData::from(*this), controllingServiceWorkerRegistrationIdentifier, String { m_userAgent });
+    swClientConnection().registerServiceWorkerClient(clientOrigin(), ServiceWorkerClientData::from(*this), controllingServiceWorkerRegistrationIdentifier, String { m_userAgent });
 }
 #endif
 

Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.h (292904 => 292905)


--- trunk/Source/WebCore/workers/WorkerGlobalScope.h	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.h	2022-04-15 13:15:30 UTC (rev 292905)
@@ -97,8 +97,10 @@
     WEBCORE_EXPORT WorkerFileSystemStorageConnection* fileSystemStorageConnection();
     WorkerCacheStorageConnection& cacheStorageConnection();
     MessagePortChannelProvider& messagePortChannelProvider();
+
 #if ENABLE(SERVICE_WORKER)
     WorkerSWClientConnection& swClientConnection();
+    void updateServiceWorkerClientData() final;
 #endif
 
     WorkerThread& thread() const;
@@ -192,9 +194,6 @@
     bool wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) final;
     bool unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) final;
 #endif
-#if ENABLE(SERVICE_WORKER)
-    void updateServiceWorkerClientData() final;
-#endif
 
     void stopIndexedDatabase();
 

Modified: trunk/Source/WebCore/workers/WorkerScriptLoader.cpp (292904 => 292905)


--- trunk/Source/WebCore/workers/WorkerScriptLoader.cpp	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebCore/workers/WorkerScriptLoader.cpp	2022-04-15 13:15:30 UTC (rev 292905)
@@ -36,6 +36,7 @@
 #include "ServiceWorker.h"
 #include "ServiceWorkerContextData.h"
 #include "ServiceWorkerGlobalScope.h"
+#include "ServiceWorkerProvider.h"
 #include "TextResourceDecoder.h"
 #include "WorkerFetchResult.h"
 #include "WorkerGlobalScope.h"
@@ -58,8 +59,14 @@
 
 WorkerScriptLoader::~WorkerScriptLoader()
 {
-    if (m_clientIdentifier)
-        scriptExecutionContextIdentifierToWorkerScriptLoaderMap().remove(m_clientIdentifier);
+    if (!m_clientIdentifier)
+        return;
+
+    scriptExecutionContextIdentifierToWorkerScriptLoaderMap().remove(m_clientIdentifier);
+#if ENABLE(SERVICE_WORKER)
+    if (m_activeServiceWorkerData)
+        ServiceWorkerProvider::singleton().serviceWorkerConnection().unregisterServiceWorkerClient(m_clientIdentifier);
+#endif
 }
 
 std::optional<Exception> WorkerScriptLoader::loadSynchronously(ScriptExecutionContext* scriptExecutionContext, const URL& url, Source source, FetchOptions::Mode mode, FetchOptions::Cache cachePolicy, ContentSecurityPolicyEnforcement contentSecurityPolicyEnforcement, const String& initiatorIdentifier)
@@ -151,13 +158,12 @@
     // FIXME: Add support for shared worker.
     if (m_destination == FetchOptions::Destination::Worker && is<Document>(scriptExecutionContext)) {
         ASSERT(clientIdentifier);
+        options.clientIdentifier = m_clientIdentifier = clientIdentifier;
         // In case of blob URLs, we reuse the document controlling service worker.
         if (request->url().protocolIsBlob() && scriptExecutionContext.activeServiceWorker())
             setControllingServiceWorker(ServiceWorkerData { scriptExecutionContext.activeServiceWorker()->data() });
-        else {
-            options.clientIdentifier = m_clientIdentifier = clientIdentifier;
+        else
             scriptExecutionContextIdentifierToWorkerScriptLoaderMap().add(m_clientIdentifier, this);
-        }
     } else if (auto* activeServiceWorker = scriptExecutionContext.activeServiceWorker())
         options.serviceWorkerRegistrationIdentifier = activeServiceWorker->registrationIdentifier();
 #endif

Modified: trunk/Source/WebCore/workers/service/SWClientConnection.h (292904 => 292905)


--- trunk/Source/WebCore/workers/service/SWClientConnection.h	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebCore/workers/service/SWClientConnection.h	2022-04-15 13:15:30 UTC (rev 292905)
@@ -50,6 +50,7 @@
 enum class ServiceWorkerRegistrationState : uint8_t;
 enum class ServiceWorkerState : uint8_t;
 enum class ShouldNotifyWhenResolved : bool;
+struct ClientOrigin;
 struct ExceptionData;
 struct MessageWithMessagePorts;
 struct NotificationData;
@@ -84,7 +85,7 @@
     virtual SWServerConnectionIdentifier serverConnectionIdentifier() const = 0;
     virtual bool mayHaveServiceWorkerRegisteredForOrigin(const SecurityOriginData&) const = 0;
 
-    virtual void registerServiceWorkerClient(const SecurityOrigin& topOrigin, ServiceWorkerClientData&&, const std::optional<ServiceWorkerRegistrationIdentifier>&, String&& userAgent) = 0;
+    virtual void registerServiceWorkerClient(const ClientOrigin&, ServiceWorkerClientData&&, const std::optional<ServiceWorkerRegistrationIdentifier>&, String&& userAgent) = 0;
     virtual void unregisterServiceWorkerClient(ScriptExecutionContextIdentifier) = 0;
 
     virtual void finishFetchingScriptInServer(const ServiceWorkerJobDataIdentifier&, ServiceWorkerRegistrationKey&&, WorkerFetchResult&&) = 0;

Modified: trunk/Source/WebCore/workers/service/WorkerSWClientConnection.cpp (292904 => 292905)


--- trunk/Source/WebCore/workers/service/WorkerSWClientConnection.cpp	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebCore/workers/service/WorkerSWClientConnection.cpp	2022-04-15 13:15:30 UTC (rev 292905)
@@ -184,17 +184,19 @@
     return true;
 }
 
-void WorkerSWClientConnection::registerServiceWorkerClient(const SecurityOrigin& topOrigin, ServiceWorkerClientData&& data, const std::optional<ServiceWorkerRegistrationIdentifier>& identifier, String&& userAgent)
+void WorkerSWClientConnection::registerServiceWorkerClient(const ClientOrigin& clientOrigin, ServiceWorkerClientData&& data, const std::optional<ServiceWorkerRegistrationIdentifier>& identifier, String&& userAgent)
 {
-    callOnMainThread([topOrigin = topOrigin.isolatedCopy(), data = "" identifier, userAgent = crossThreadCopy(WTFMove(userAgent))]() mutable {
+    callOnMainThread([clientOrigin = clientOrigin.isolatedCopy(), data = "" identifier, userAgent = crossThreadCopy(WTFMove(userAgent))]() mutable {
         auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
-        connection.registerServiceWorkerClient(topOrigin, WTFMove(data), identifier, WTFMove(userAgent));
+        connection.registerServiceWorkerClient(clientOrigin, WTFMove(data), identifier, WTFMove(userAgent));
     });
 }
 
-void WorkerSWClientConnection::unregisterServiceWorkerClient(ScriptExecutionContextIdentifier)
+void WorkerSWClientConnection::unregisterServiceWorkerClient(ScriptExecutionContextIdentifier identifier)
 {
-    ASSERT_NOT_REACHED();
+    callOnMainThread([identifier] {
+        ServiceWorkerProvider::singleton().serviceWorkerConnection().unregisterServiceWorkerClient(identifier);
+    });
 }
 
 void WorkerSWClientConnection::finishFetchingScriptInServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, ServiceWorkerRegistrationKey&& registrationKey, WorkerFetchResult&& result)

Modified: trunk/Source/WebCore/workers/service/WorkerSWClientConnection.h (292904 => 292905)


--- trunk/Source/WebCore/workers/service/WorkerSWClientConnection.h	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebCore/workers/service/WorkerSWClientConnection.h	2022-04-15 13:15:30 UTC (rev 292905)
@@ -39,6 +39,9 @@
     static Ref<WorkerSWClientConnection> create(WorkerGlobalScope& scope) { return adoptRef(*new WorkerSWClientConnection { scope }); }
     ~WorkerSWClientConnection();
 
+    void registerServiceWorkerClient(const ClientOrigin&, ServiceWorkerClientData&&, const std::optional<ServiceWorkerRegistrationIdentifier>&, String&& userAgent) final;
+    void unregisterServiceWorkerClient(ScriptExecutionContextIdentifier) final;
+
 private:
     explicit WorkerSWClientConnection(WorkerGlobalScope&);
 
@@ -51,8 +54,6 @@
     void postMessageToServiceWorker(ServiceWorkerIdentifier destination, MessageWithMessagePorts&&, const ServiceWorkerOrClientIdentifier& source) final;
     SWServerConnectionIdentifier serverConnectionIdentifier() const final;
     bool mayHaveServiceWorkerRegisteredForOrigin(const SecurityOriginData&) const final;
-    void registerServiceWorkerClient(const SecurityOrigin& topOrigin, ServiceWorkerClientData&&, const std::optional<ServiceWorkerRegistrationIdentifier>&, String&& userAgent) final;
-    void unregisterServiceWorkerClient(ScriptExecutionContextIdentifier) final;
     void finishFetchingScriptInServer(const ServiceWorkerJobDataIdentifier&, ServiceWorkerRegistrationKey&&, WorkerFetchResult&&) final;
     void scheduleJobInServer(const ServiceWorkerJobData&) final;
     void scheduleJob(ServiceWorkerOrClientIdentifier, const ServiceWorkerJobData&) final;

Modified: trunk/Source/WebKit/ChangeLog (292904 => 292905)


--- trunk/Source/WebKit/ChangeLog	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebKit/ChangeLog	2022-04-15 13:15:30 UTC (rev 292905)
@@ -1,3 +1,22 @@
+2022-04-15  Youenn Fablet  <[email protected]>
+
+        ServiceWorker.postMessage() doesn't work from inside iframe
+        https://bugs.webkit.org/show_bug.cgi?id=213984
+        <rdar://problem/65203340>
+
+        Reviewed by Chris Dumez.
+
+        Pass the full ClientOrigin when registering a service worker client.
+        Filter out clients that cannot be matched:
+        - non HTTP/blob/about:blank clients
+        - sandboxed HTTP clients
+
+        * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
+        * NetworkProcess/ServiceWorker/WebSWServerConnection.h:
+        * NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in:
+        * WebProcess/Storage/WebSWClientConnection.cpp:
+        * WebProcess/Storage/WebSWClientConnection.h:
+
 2022-04-14  Claudio Saavedra  <[email protected]>
 
         [GTK] Default initialize GTK-specific print info in WebKit::PrintInfo

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp (292904 => 292905)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp	2022-04-15 13:15:30 UTC (rev 292905)
@@ -184,7 +184,7 @@
 
     auto ancestorOrigins = map(parameters.frameAncestorOrigins, [](auto& origin) { return origin->toString(); });
     ServiceWorkerClientData data { clientIdentifier, clientType, ServiceWorkerClientFrameType::None, request.url(), parameters.webPageID, parameters.webFrameID, request.isAppInitiated() ? WebCore::LastNavigationWasAppInitiated::Yes : WebCore::LastNavigationWasAppInitiated::No, false, false, 0, WTFMove(ancestorOrigins) };
-    registerServiceWorkerClient(SecurityOriginData { registration.key().topOrigin() }, WTFMove(data), registration.identifier(), request.httpUserAgent());
+    registerServiceWorkerClient(ClientOrigin { registration.key().topOrigin(), SecurityOriginData::fromURL(request.url()) }, WTFMove(data), registration.identifier(), request.httpUserAgent());
 }
 
 std::unique_ptr<ServiceWorkerFetchTask> WebSWServerConnection::createFetchTask(NetworkResourceLoader& loader, const ResourceRequest& request)
@@ -395,12 +395,18 @@
     callback(server().getRegistrations(topOrigin, clientURL));
 }
 
-void WebSWServerConnection::registerServiceWorkerClient(SecurityOriginData&& topOrigin, ServiceWorkerClientData&& data, const std::optional<ServiceWorkerRegistrationIdentifier>& controllingServiceWorkerRegistrationIdentifier, String&& userAgent)
+void WebSWServerConnection::registerServiceWorkerClient(WebCore::ClientOrigin&& clientOrigin, ServiceWorkerClientData&& data, const std::optional<ServiceWorkerRegistrationIdentifier>& controllingServiceWorkerRegistrationIdentifier, String&& userAgent)
 {
     CONNECTION_MESSAGE_CHECK(data.identifier.processIdentifier() == identifier());
-    CONNECTION_MESSAGE_CHECK(!topOrigin.isEmpty());
+    CONNECTION_MESSAGE_CHECK(!clientOrigin.topOrigin.isEmpty());
 
-    auto contextOrigin = SecurityOriginData::fromURL(data.url);
+    auto& contextOrigin = clientOrigin.clientOrigin;
+    if (data.url.protocolIsInHTTPFamily()) {
+        // We do not register any sandbox document.
+        if (contextOrigin != SecurityOriginData::fromURL(data.url))
+            return;
+    }
+
     CONNECTION_MESSAGE_CHECK(!contextOrigin.isEmpty());
 
     bool isNewOrigin = WTF::allOf(m_clientOrigins.values(), [&contextOrigin](auto& origin) {
@@ -408,7 +414,6 @@
     });
     auto* contextConnection = isNewOrigin ? server().contextConnectionForRegistrableDomain(RegistrableDomain { contextOrigin }) : nullptr;
 
-    auto clientOrigin = ClientOrigin { WTFMove(topOrigin), WTFMove(contextOrigin) };
     m_clientOrigins.add(data.identifier, clientOrigin);
     server().registerServiceWorkerClient(WTFMove(clientOrigin), WTFMove(data), controllingServiceWorkerRegistrationIdentifier, WTFMove(userAgent));
 

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h (292904 => 292905)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h	2022-04-15 13:15:30 UTC (rev 292905)
@@ -110,7 +110,7 @@
     void matchRegistration(const WebCore::SecurityOriginData& topOrigin, const URL& clientURL, CompletionHandler<void(std::optional<WebCore::ServiceWorkerRegistrationData>&&)>&&);
     void getRegistrations(const WebCore::SecurityOriginData& topOrigin, const URL& clientURL, CompletionHandler<void(const Vector<WebCore::ServiceWorkerRegistrationData>&)>&&);
 
-    void registerServiceWorkerClient(WebCore::SecurityOriginData&& topOrigin, WebCore::ServiceWorkerClientData&&, const std::optional<WebCore::ServiceWorkerRegistrationIdentifier>&, String&& userAgent);
+    void registerServiceWorkerClient(WebCore::ClientOrigin&&, WebCore::ServiceWorkerClientData&&, const std::optional<WebCore::ServiceWorkerRegistrationIdentifier>&, String&& userAgent);
     void unregisterServiceWorkerClient(const WebCore::ScriptExecutionContextIdentifier&);
     void terminateWorkerFromClient(WebCore::ServiceWorkerIdentifier, CompletionHandler<void()>&&);
     void whenServiceWorkerIsTerminatedForTesting(WebCore::ServiceWorkerIdentifier, CompletionHandler<void()>&&);

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in (292904 => 292905)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in	2022-04-15 13:15:30 UTC (rev 292905)
@@ -38,7 +38,7 @@
     MatchRegistration(struct WebCore::SecurityOriginData topOrigin, URL clientURL) -> (std::optional<WebCore::ServiceWorkerRegistrationData> registration)
     WhenRegistrationReady(struct WebCore::SecurityOriginData topOrigin, URL clientURL) -> (std::optional<WebCore::ServiceWorkerRegistrationData> registration)
     GetRegistrations(struct WebCore::SecurityOriginData topOrigin, URL clientURL) -> (Vector<WebCore::ServiceWorkerRegistrationData> registrations)
-    RegisterServiceWorkerClient(struct WebCore::SecurityOriginData topOrigin, struct WebCore::ServiceWorkerClientData data, std::optional<WebCore::ServiceWorkerRegistrationIdentifier> controllingServiceWorkerRegistrationIdentifier, String userAgent)
+    RegisterServiceWorkerClient(struct WebCore::ClientOrigin clientOrigin, struct WebCore::ServiceWorkerClientData data, std::optional<WebCore::ServiceWorkerRegistrationIdentifier> controllingServiceWorkerRegistrationIdentifier, String userAgent)
     UnregisterServiceWorkerClient(WebCore::ScriptExecutionContextIdentifier identifier)
 
     TerminateWorkerFromClient(WebCore::ServiceWorkerIdentifier workerIdentifier) -> ()

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp (292904 => 292905)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp	2022-04-15 13:15:30 UTC (rev 292905)
@@ -115,9 +115,9 @@
     send(Messages::WebSWServerConnection::PostMessageToServiceWorker { destinationIdentifier, WTFMove(message), sourceIdentifier });
 }
 
-void WebSWClientConnection::registerServiceWorkerClient(const SecurityOrigin& topOrigin, WebCore::ServiceWorkerClientData&& data, const std::optional<WebCore::ServiceWorkerRegistrationIdentifier>& controllingServiceWorkerRegistrationIdentifier, String&& userAgent)
+void WebSWClientConnection::registerServiceWorkerClient(const ClientOrigin& clientOrigin, WebCore::ServiceWorkerClientData&& data, const std::optional<WebCore::ServiceWorkerRegistrationIdentifier>& controllingServiceWorkerRegistrationIdentifier, String&& userAgent)
 {
-    send(Messages::WebSWServerConnection::RegisterServiceWorkerClient { topOrigin.data(), data, controllingServiceWorkerRegistrationIdentifier, userAgent });
+    send(Messages::WebSWServerConnection::RegisterServiceWorkerClient { clientOrigin, data, controllingServiceWorkerRegistrationIdentifier, userAgent });
 }
 
 void WebSWClientConnection::unregisterServiceWorkerClient(ScriptExecutionContextIdentifier contextIdentifier)

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.h (292904 => 292905)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.h	2022-04-15 11:41:51 UTC (rev 292904)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.h	2022-04-15 13:15:30 UTC (rev 292905)
@@ -73,7 +73,7 @@
     void scheduleJobInServer(const WebCore::ServiceWorkerJobData&) final;
     void finishFetchingScriptInServer(const WebCore::ServiceWorkerJobDataIdentifier&, WebCore::ServiceWorkerRegistrationKey&&, WebCore::WorkerFetchResult&&) final;
     void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destinationIdentifier, WebCore::MessageWithMessagePorts&&, const WebCore::ServiceWorkerOrClientIdentifier& source) final;
-    void registerServiceWorkerClient(const WebCore::SecurityOrigin& topOrigin, WebCore::ServiceWorkerClientData&&, const std::optional<WebCore::ServiceWorkerRegistrationIdentifier>&, String&& userAgent) final;
+    void registerServiceWorkerClient(const WebCore::ClientOrigin&, WebCore::ServiceWorkerClientData&&, const std::optional<WebCore::ServiceWorkerRegistrationIdentifier>&, String&& userAgent) final;
     void unregisterServiceWorkerClient(WebCore::ScriptExecutionContextIdentifier) final;
     void scheduleUnregisterJobInServer(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::ServiceWorkerOrClientIdentifier, CompletionHandler<void(WebCore::ExceptionOr<bool>&&)>&&) final;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to