Changeset 292905 in webkit


Ignore:
Timestamp:
Apr 15, 2022 6:15:30 AM (3 months ago)
Author:
youenn@apple.com
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:
Location:
trunk
Files:
4 added
26 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r292904 r292905  
     12022-04-15  Youenn Fablet  <youenn@apple.com>
     2
     3        ServiceWorker.postMessage() doesn't work from inside iframe
     4        https://bugs.webkit.org/show_bug.cgi?id=213984
     5        <rdar://problem/65203340>
     6
     7        Reviewed by Chris Dumez.
     8
     9        * http/wpt/service-workers/about-blank-iframe-expected.txt: Added.
     10        * http/wpt/service-workers/about-blank-iframe-worker.js: Added.
     11        * http/wpt/service-workers/about-blank-iframe.html: Added.
     12        * http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache.html:
     13        * http/tests/workers/service/client-removed-from-clients-while-in-page-cache-expected.txt:
     14        * http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html:
     15        * http/tests/workers/service/other_resources/test.html:
     16        * http/tests/workers/service/resources/getClientIds-worker.js:
     17
    1182022-04-14  Claudio Saavedra  <csaavedra@igalia.com>
    219
  • trunk/LayoutTests/http/tests/workers/service/client-added-to-clients-when-restored-from-page-cache.html

    r288093 r292905  
    2323navigator.serviceWorker.addEventListener("message", function(event) {
    2424  if (step == "BothClientsInitiallyActive") {
    25     if (!containsExpectedClients(event.data)) {
     25    if (!containsExpectedClients(event.data.ids)) {
    2626      if (++tries > 20) {
    2727          log("FAIL: Wrong initial number of clients");
     
    6060
    6161  if (step == "SecondClientRestoredFromPageCache") {
    62     if (!containsExpectedClients(event.data)) {
     62    if (!containsExpectedClients(event.data.ids)) {
    6363      log("FAIL: Wrong number of clients after one client was restored from page cache");
    6464      finishSWTest();
  • trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache-expected.txt

    r226677 r292905  
    11* Tests that a client is removed from the list of service worker clients while it is in the page cache
    22
    3 PASS: service worker has initially 2 clients
     3PASS: service worker has initially 2 window clients
     4PASS: service worker has initially 2 worker clients
    45PASS: page is about to enter page cache
    5 PASS: service worker has only 1 client after 1 entered page cache
     6PASS: service worker has only 1 window client after 1 entered page cache
     7PASS: service worker has only 1 worker client after 1 entered page cache
    68
  • trunk/LayoutTests/http/tests/workers/service/client-removed-from-clients-while-in-page-cache.html

    r288093 r292905  
    1010let topClientIdentifier = null;
    1111let windowClientIdentifier = null;
    12 
     12let dedicatedWorker = null;
    1313let tries = 0;
    1414
     
    2424
    2525navigator.serviceWorker.addEventListener("message", function(event) {
    26   if (step == "BothClientsInitiallyActive") {
    27     if (!containsBothClients(event.data)) {
     26  if (step == "AllClientsInitiallyActive") {
     27    if (!containsBothClients(event.data.ids) && event.data.workersCount !== 2) {
    2828      if (++tries > 20) {
    2929          log("FAIL: Wrong initial number of clients");
     
    3434      return;
    3535    }
    36     log("PASS: service worker has initially 2 clients");
     36    log("PASS: service worker has initially 2 window clients");
     37    log("PASS: service worker has initially 2 worker clients");
    3738
    3839    otherWindow.addEventListener("pagehide", function(event) {
     
    5556
    5657  if (step == "OnlyOneClientRemainsActive") {
    57     if (!containsOnlyTopClient(event.data)) {
     58    if (!containsOnlyTopClient(event.data.ids) && event.data.workersCount !== 1) {
    5859      log("FAIL: Wrong number of clients after one client entered page cache");
    5960      finishSWTest();
    6061    }
    6162
    62     log("PASS: service worker has only 1 client after 1 entered page cache");
     63    log("PASS: service worker has only 1 window client after 1 entered page cache");
     64    log("PASS: service worker has only 1 worker client after 1 entered page cache");
    6365    finishSWTest();
    6466  }
    6567});
    6668
    67 navigator.serviceWorker.register("resources/getClientIds-worker.js", { }).then(function(registration) {
     69navigator.serviceWorker.register("resources/getClientIds-worker.js", { }).then(async (registration) => {
    6870    if (!window.internals)
    6971        return;
     
    7173
    7274    worker = registration.installing;
     75
     76    dedicatedWorker = new Worker("other_resources/dummy.js");
     77
    7378    otherWindow = open("other_resources/test.html");
    74     otherWindow.onload = function() {
    75       windowClientIdentifier = internals.serviceWorkerClientInternalIdentifier(otherWindow.document);
    76       step = "BothClientsInitiallyActive"
    77       worker.postMessage("getClientIds");
    78     };
     79    await new Promise(resolve => otherWindow.onload = resolve);
     80    windowClientIdentifier = internals.serviceWorkerClientInternalIdentifier(otherWindow.document);
     81    step = "AllClientsInitiallyActive"
     82    worker.postMessage("getClientIds");
    7983});
    8084</script>
  • trunk/LayoutTests/http/tests/workers/service/other_resources/test.html

    r226677 r292905  
     1<!DOCTYPE html>
     2<html>
     3<body>
     4<script src="resources/sw-test-pre.js"></script>
     5<script>
     6var dedicatedWorker = new Worker("dummy.js");
     7</script>
    18TEST
     9</body>
  • trunk/LayoutTests/http/tests/workers/service/resources/getClientIds-worker.js

    r288093 r292905  
    1 self.addEventListener("message", (event) => {
     1self.addEventListener("message", async (event) => {
    22    source = event.source;
    3     clients.matchAll({ includeUncontrolled : true }).then(function(clients) {
    4         let ids = [];
    5         for (let client of clients)
    6             ids.push(self.internals.serviceWorkerClientInternalIdentifier(client));
    7         source.postMessage(ids);
    8     });
     3    const matchedClients = await clients.matchAll({ includeUncontrolled : true, type: 'all' })
     4    let data = { ids: [], workerCount: 0 };
     5    for (let client of matchedClients) {
     6        if (client.type === 'worker')
     7            data.workerCount++;
     8        else
     9            data.ids.push(self.internals.serviceWorkerClientInternalIdentifier(client));
     10    }
     11    source.postMessage(data);
    912});
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r292893 r292905  
     12022-04-15  Youenn Fablet  <youenn@apple.com>
     2
     3        ServiceWorker.postMessage() doesn't work from inside iframe
     4        https://bugs.webkit.org/show_bug.cgi?id=213984
     5        <rdar://problem/65203340>
     6
     7        Reviewed by Chris Dumez.
     8
     9        * web-platform-tests/service-workers/service-worker/about-blank-replacement.https-expected.txt:
     10        * web-platform-tests/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt:
     11        * web-platform-tests/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt:
     12
    1132022-04-14  Nikolaos Mouchtaris  <nmouchtaris@apple.com>
    214
  • trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/about-blank-replacement.https-expected.txt

    r267647 r292905  
    66FAIL 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
    77PASS Initial about:blank is controlled, exposed to clients.matchAll(), and final Client is not controlled by a service worker.
    8 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
    9 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
    10 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
     8PASS Simple about:blank is controlled and is exposed to clients.matchAll().
     9PASS Nested about:srcdoc is controlled and is exposed to clients.matchAll().
     10PASS Dynamic about:blank is controlled and is exposed to clients.matchAll().
    1111
  • trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt

    r279389 r292905  
    11
    2 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"
     2PASS Client.url of a blob URL worker should be a blob URL.
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt

    r279389 r292905  
    11
    2 FAIL Test Clients.matchAll() with a blob URL worker client. assert_equals: expected 1 but got 0
    3 FAIL Test Clients.matchAll() with an uncontrolled blob URL worker client. assert_equals: expected 1 but got 0
     2PASS Test Clients.matchAll() with a blob URL worker client.
     3PASS Test Clients.matchAll() with an uncontrolled blob URL worker client.
    44
  • trunk/Source/WebCore/ChangeLog

    r292902 r292905  
     12022-04-15  Youenn Fablet  <youenn@apple.com>
     2
     3        ServiceWorker.postMessage() doesn't work from inside iframe
     4        https://bugs.webkit.org/show_bug.cgi?id=213984
     5        <rdar://problem/65203340>
     6
     7        Reviewed by Chris Dumez.
     8
     9        postMessage was not working as we do not postMessage to a service worker if the source is not registered.
     10        We now register service worker clients more aggresively and pass the client origin to better handle blob and about:blank clients.
     11        We also add support for registering/unregistering worker clients when they get suspended/resumed.
     12        To make sure a worker client is removed in failure case, WorkerScriptLoader is unregistering the service worker client if
     13        the service worker data was not taken by its Worker.
     14
     15        Test: http/wpt/service-workers/about-blank-iframe.html
     16
     17        * dom/Document.cpp:
     18        * loader/DocumentLoader.cpp:
     19        * workers/DedicatedWorkerThread.cpp:
     20        * workers/WorkerGlobalScope.cpp:
     21        * workers/WorkerGlobalScope.h:
     22        * workers/WorkerScriptLoader.cpp:
     23        * workers/service/SWClientConnection.h:
     24        * workers/service/WorkerSWClientConnection.cpp:
     25        * workers/service/WorkerSWClientConnection.h:
     26
    1272022-04-14  Antoine Quint  <graouts@apple.com>
    228
  • trunk/Source/WebCore/dom/Document.cpp

    r292857 r292905  
    87798779
    87808780    auto controllingServiceWorkerRegistrationIdentifier = activeServiceWorker() ? std::make_optional<ServiceWorkerRegistrationIdentifier>(activeServiceWorker()->registrationIdentifier()) : std::nullopt;
    8781     m_serviceWorkerConnection->registerServiceWorkerClient(topOrigin(), ServiceWorkerClientData::from(*this), controllingServiceWorkerRegistrationIdentifier, userAgent(url()));
     8781    m_serviceWorkerConnection->registerServiceWorkerClient(clientOrigin(), ServiceWorkerClientData::from(*this), controllingServiceWorkerRegistrationIdentifier, userAgent(url()));
    87828782}
    87838783
  • trunk/Source/WebCore/loader/DocumentLoader.cpp

    r292861 r292905  
    12601260            }
    12611261
    1262             if (m_frame->document()->activeServiceWorker() || document.url().protocolIsInHTTPFamily() || (document.page() && document.page()->isServiceWorkerPage()))
     1262            if (m_frame->document()->activeServiceWorker() || document.url().protocolIsInHTTPFamily() || (document.page() && document.page()->isServiceWorkerPage()) || (document.parentDocument() && shouldUseActiveServiceWorkerFromParent(document, *document.parentDocument())))
    12631263                document.setServiceWorkerConnection(&ServiceWorkerProvider::singleton().serviceWorkerConnection());
    12641264
  • trunk/Source/WebCore/workers/DedicatedWorkerThread.cpp

    r292861 r292905  
    5353    if (params.serviceWorkerData)
    5454        scope->setActiveServiceWorker(ServiceWorker::getOrCreate(scope.get(), ServiceWorkerData { *params.serviceWorkerData }));
     55    scope->updateServiceWorkerClientData();
    5556#endif
    5657    return scope;
  • trunk/Source/WebCore/workers/WorkerGlobalScope.cpp

    r292861 r292905  
    152152    WorkerOrWorkletGlobalScope::prepareForDestruction();
    153153
     154#if ENABLE(SERVICE_WORKER)
     155    if (settingsValues().serviceWorkersEnabled)
     156        swClientConnection().unregisterServiceWorkerClient(identifier());
     157#endif
     158
    154159    stopIndexedDatabase();
    155160
     
    230235    if (m_connectionProxy)
    231236        m_connectionProxy->setContextSuspended(*this, true);
     237
     238#if ENABLE(SERVICE_WORKER)
     239    if (settingsValues().serviceWorkersEnabled)
     240        swClientConnection().unregisterServiceWorkerClient(identifier());
     241#endif
    232242}
    233243
    234244void WorkerGlobalScope::resume()
    235245{
     246#if ENABLE(SERVICE_WORKER)
     247    if (settingsValues().serviceWorkersEnabled)
     248        updateServiceWorkerClientData();
     249#endif
     250
    236251    if (m_connectionProxy)
    237252        m_connectionProxy->setContextSuspended(*this, false);
     
    658673void WorkerGlobalScope::updateServiceWorkerClientData()
    659674{
    660     ASSERT(type() == WebCore::WorkerGlobalScope::Type::DedicatedWorker);
     675    if (!settingsValues().serviceWorkersEnabled)
     676        return;
     677
     678    ASSERT(type() == WebCore::WorkerGlobalScope::Type::DedicatedWorker || type() == WebCore::WorkerGlobalScope::Type::SharedWorker);
    661679    auto controllingServiceWorkerRegistrationIdentifier = activeServiceWorker() ? std::make_optional<ServiceWorkerRegistrationIdentifier>(activeServiceWorker()->registrationIdentifier()) : std::nullopt;
    662     SWClientConnection& connection = swClientConnection();
    663     connection.registerServiceWorkerClient(topOrigin(), ServiceWorkerClientData::from(*this), controllingServiceWorkerRegistrationIdentifier, String { m_userAgent });
     680    swClientConnection().registerServiceWorkerClient(clientOrigin(), ServiceWorkerClientData::from(*this), controllingServiceWorkerRegistrationIdentifier, String { m_userAgent });
    664681}
    665682#endif
  • trunk/Source/WebCore/workers/WorkerGlobalScope.h

    r292861 r292905  
    9898    WorkerCacheStorageConnection& cacheStorageConnection();
    9999    MessagePortChannelProvider& messagePortChannelProvider();
     100
    100101#if ENABLE(SERVICE_WORKER)
    101102    WorkerSWClientConnection& swClientConnection();
     103    void updateServiceWorkerClientData() final;
    102104#endif
    103105
     
    192194    bool wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) final;
    193195    bool unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) final;
    194 #endif
    195 #if ENABLE(SERVICE_WORKER)
    196     void updateServiceWorkerClientData() final;
    197196#endif
    198197
  • trunk/Source/WebCore/workers/WorkerScriptLoader.cpp

    r292861 r292905  
    3737#include "ServiceWorkerContextData.h"
    3838#include "ServiceWorkerGlobalScope.h"
     39#include "ServiceWorkerProvider.h"
    3940#include "TextResourceDecoder.h"
    4041#include "WorkerFetchResult.h"
     
    5960WorkerScriptLoader::~WorkerScriptLoader()
    6061{
    61     if (m_clientIdentifier)
    62         scriptExecutionContextIdentifierToWorkerScriptLoaderMap().remove(m_clientIdentifier);
     62    if (!m_clientIdentifier)
     63        return;
     64
     65    scriptExecutionContextIdentifierToWorkerScriptLoaderMap().remove(m_clientIdentifier);
     66#if ENABLE(SERVICE_WORKER)
     67    if (m_activeServiceWorkerData)
     68        ServiceWorkerProvider::singleton().serviceWorkerConnection().unregisterServiceWorkerClient(m_clientIdentifier);
     69#endif
    6370}
    6471
     
    152159    if (m_destination == FetchOptions::Destination::Worker && is<Document>(scriptExecutionContext)) {
    153160        ASSERT(clientIdentifier);
     161        options.clientIdentifier = m_clientIdentifier = clientIdentifier;
    154162        // In case of blob URLs, we reuse the document controlling service worker.
    155163        if (request->url().protocolIsBlob() && scriptExecutionContext.activeServiceWorker())
    156164            setControllingServiceWorker(ServiceWorkerData { scriptExecutionContext.activeServiceWorker()->data() });
    157         else {
    158             options.clientIdentifier = m_clientIdentifier = clientIdentifier;
     165        else
    159166            scriptExecutionContextIdentifierToWorkerScriptLoaderMap().add(m_clientIdentifier, this);
    160         }
    161167    } else if (auto* activeServiceWorker = scriptExecutionContext.activeServiceWorker())
    162168        options.serviceWorkerRegistrationIdentifier = activeServiceWorker->registrationIdentifier();
  • trunk/Source/WebCore/workers/service/SWClientConnection.h

    r292218 r292905  
    5151enum class ServiceWorkerState : uint8_t;
    5252enum class ShouldNotifyWhenResolved : bool;
     53struct ClientOrigin;
    5354struct ExceptionData;
    5455struct MessageWithMessagePorts;
     
    8586    virtual bool mayHaveServiceWorkerRegisteredForOrigin(const SecurityOriginData&) const = 0;
    8687
    87     virtual void registerServiceWorkerClient(const SecurityOrigin& topOrigin, ServiceWorkerClientData&&, const std::optional<ServiceWorkerRegistrationIdentifier>&, String&& userAgent) = 0;
     88    virtual void registerServiceWorkerClient(const ClientOrigin&, ServiceWorkerClientData&&, const std::optional<ServiceWorkerRegistrationIdentifier>&, String&& userAgent) = 0;
    8889    virtual void unregisterServiceWorkerClient(ScriptExecutionContextIdentifier) = 0;
    8990
  • trunk/Source/WebCore/workers/service/WorkerSWClientConnection.cpp

    r292218 r292905  
    185185}
    186186
    187 void WorkerSWClientConnection::registerServiceWorkerClient(const SecurityOrigin& topOrigin, ServiceWorkerClientData&& data, const std::optional<ServiceWorkerRegistrationIdentifier>& identifier, String&& userAgent)
    188 {
    189     callOnMainThread([topOrigin = topOrigin.isolatedCopy(), data = crossThreadCopy(WTFMove(data)), identifier, userAgent = crossThreadCopy(WTFMove(userAgent))]() mutable {
    190         auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
    191         connection.registerServiceWorkerClient(topOrigin, WTFMove(data), identifier, WTFMove(userAgent));
    192     });
    193 }
    194 
    195 void WorkerSWClientConnection::unregisterServiceWorkerClient(ScriptExecutionContextIdentifier)
     187void WorkerSWClientConnection::registerServiceWorkerClient(const ClientOrigin& clientOrigin, ServiceWorkerClientData&& data, const std::optional<ServiceWorkerRegistrationIdentifier>& identifier, String&& userAgent)
     188{
     189    callOnMainThread([clientOrigin = clientOrigin.isolatedCopy(), data = crossThreadCopy(WTFMove(data)), identifier, userAgent = crossThreadCopy(WTFMove(userAgent))]() mutable {
     190        auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
     191        connection.registerServiceWorkerClient(clientOrigin, WTFMove(data), identifier, WTFMove(userAgent));
     192    });
     193}
     194
     195void WorkerSWClientConnection::unregisterServiceWorkerClient(ScriptExecutionContextIdentifier identifier)
     196{
     197    callOnMainThread([identifier] {
     198        ServiceWorkerProvider::singleton().serviceWorkerConnection().unregisterServiceWorkerClient(identifier);
     199    });
     200}
     201
     202void WorkerSWClientConnection::finishFetchingScriptInServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, ServiceWorkerRegistrationKey&& registrationKey, WorkerFetchResult&& result)
     203{
     204    callOnMainThread([jobDataIdentifier, registrationKey = crossThreadCopy(WTFMove(registrationKey)), result = crossThreadCopy(WTFMove(result))]() mutable {
     205        auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
     206        connection.finishFetchingScriptInServer(jobDataIdentifier, WTFMove(registrationKey), WTFMove(result));
     207    });
     208}
     209
     210void WorkerSWClientConnection::scheduleJob(ServiceWorkerOrClientIdentifier identifier, const ServiceWorkerJobData& data)
     211{
     212    callOnMainThread([identifier, data = crossThreadCopy(data)]() mutable {
     213        auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
     214        connection.scheduleJob(identifier, data);
     215    });
     216}
     217
     218void WorkerSWClientConnection::scheduleUnregisterJobInServer(ServiceWorkerRegistrationIdentifier registrationIdentifier, ServiceWorkerOrClientIdentifier contextIdentifier, CompletionHandler<void(ExceptionOr<bool>&&)>&& callback)
     219{
     220    uint64_t requestIdentifier = ++m_lastRequestIdentifier;
     221    m_unregisterRequests.add(requestIdentifier, WTFMove(callback));
     222
     223    callOnMainThread([thread = m_thread, requestIdentifier, registrationIdentifier, contextIdentifier]() mutable {
     224        auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
     225        connection.scheduleUnregisterJobInServer(registrationIdentifier, contextIdentifier, [thread = WTFMove(thread), requestIdentifier](auto&& result) {
     226            thread->runLoop().postTaskForMode([requestIdentifier, result = crossThreadCopy(WTFMove(result))](auto& scope) mutable {
     227                auto callback = downcast<WorkerGlobalScope>(scope).swClientConnection().m_unregisterRequests.take(requestIdentifier);
     228                callback(WTFMove(result));
     229            }, WorkerRunLoop::defaultMode());
     230        });
     231    });
     232}
     233
     234void WorkerSWClientConnection::scheduleJobInServer(const ServiceWorkerJobData&)
    196235{
    197236    ASSERT_NOT_REACHED();
    198237}
    199238
    200 void WorkerSWClientConnection::finishFetchingScriptInServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, ServiceWorkerRegistrationKey&& registrationKey, WorkerFetchResult&& result)
    201 {
    202     callOnMainThread([jobDataIdentifier, registrationKey = crossThreadCopy(WTFMove(registrationKey)), result = crossThreadCopy(WTFMove(result))]() mutable {
    203         auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
    204         connection.finishFetchingScriptInServer(jobDataIdentifier, WTFMove(registrationKey), WTFMove(result));
    205     });
    206 }
    207 
    208 void WorkerSWClientConnection::scheduleJob(ServiceWorkerOrClientIdentifier identifier, const ServiceWorkerJobData& data)
    209 {
    210     callOnMainThread([identifier, data = crossThreadCopy(data)]() mutable {
    211         auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
    212         connection.scheduleJob(identifier, data);
    213     });
    214 }
    215 
    216 void WorkerSWClientConnection::scheduleUnregisterJobInServer(ServiceWorkerRegistrationIdentifier registrationIdentifier, ServiceWorkerOrClientIdentifier contextIdentifier, CompletionHandler<void(ExceptionOr<bool>&&)>&& callback)
    217 {
    218     uint64_t requestIdentifier = ++m_lastRequestIdentifier;
    219     m_unregisterRequests.add(requestIdentifier, WTFMove(callback));
    220 
    221     callOnMainThread([thread = m_thread, requestIdentifier, registrationIdentifier, contextIdentifier]() mutable {
    222         auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
    223         connection.scheduleUnregisterJobInServer(registrationIdentifier, contextIdentifier, [thread = WTFMove(thread), requestIdentifier](auto&& result) {
    224             thread->runLoop().postTaskForMode([requestIdentifier, result = crossThreadCopy(WTFMove(result))](auto& scope) mutable {
    225                 auto callback = downcast<WorkerGlobalScope>(scope).swClientConnection().m_unregisterRequests.take(requestIdentifier);
    226                 callback(WTFMove(result));
    227             }, WorkerRunLoop::defaultMode());
    228         });
    229     });
    230 }
    231 
    232 void WorkerSWClientConnection::scheduleJobInServer(const ServiceWorkerJobData&)
    233 {
    234     ASSERT_NOT_REACHED();
    235 }
    236 
    237239void WorkerSWClientConnection::subscribeToPushService(ServiceWorkerRegistrationIdentifier registrationIdentifier, const Vector<uint8_t>& applicationServerKey, SubscribeToPushServiceCallback&& callback)
    238240{
  • trunk/Source/WebCore/workers/service/WorkerSWClientConnection.h

    r292218 r292905  
    4040    ~WorkerSWClientConnection();
    4141
     42    void registerServiceWorkerClient(const ClientOrigin&, ServiceWorkerClientData&&, const std::optional<ServiceWorkerRegistrationIdentifier>&, String&& userAgent) final;
     43    void unregisterServiceWorkerClient(ScriptExecutionContextIdentifier) final;
     44
    4245private:
    4346    explicit WorkerSWClientConnection(WorkerGlobalScope&);
     
    5255    SWServerConnectionIdentifier serverConnectionIdentifier() const final;
    5356    bool mayHaveServiceWorkerRegisteredForOrigin(const SecurityOriginData&) const final;
    54     void registerServiceWorkerClient(const SecurityOrigin& topOrigin, ServiceWorkerClientData&&, const std::optional<ServiceWorkerRegistrationIdentifier>&, String&& userAgent) final;
    55     void unregisterServiceWorkerClient(ScriptExecutionContextIdentifier) final;
    5657    void finishFetchingScriptInServer(const ServiceWorkerJobDataIdentifier&, ServiceWorkerRegistrationKey&&, WorkerFetchResult&&) final;
    5758    void scheduleJobInServer(const ServiceWorkerJobData&) final;
  • trunk/Source/WebKit/ChangeLog

    r292904 r292905  
     12022-04-15  Youenn Fablet  <youenn@apple.com>
     2
     3        ServiceWorker.postMessage() doesn't work from inside iframe
     4        https://bugs.webkit.org/show_bug.cgi?id=213984
     5        <rdar://problem/65203340>
     6
     7        Reviewed by Chris Dumez.
     8
     9        Pass the full ClientOrigin when registering a service worker client.
     10        Filter out clients that cannot be matched:
     11        - non HTTP/blob/about:blank clients
     12        - sandboxed HTTP clients
     13
     14        * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
     15        * NetworkProcess/ServiceWorker/WebSWServerConnection.h:
     16        * NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in:
     17        * WebProcess/Storage/WebSWClientConnection.cpp:
     18        * WebProcess/Storage/WebSWClientConnection.h:
     19
    1202022-04-14  Claudio Saavedra  <csaavedra@igalia.com>
    221
  • trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp

    r292861 r292905  
    185185    auto ancestorOrigins = map(parameters.frameAncestorOrigins, [](auto& origin) { return origin->toString(); });
    186186    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) };
    187     registerServiceWorkerClient(SecurityOriginData { registration.key().topOrigin() }, WTFMove(data), registration.identifier(), request.httpUserAgent());
     187    registerServiceWorkerClient(ClientOrigin { registration.key().topOrigin(), SecurityOriginData::fromURL(request.url()) }, WTFMove(data), registration.identifier(), request.httpUserAgent());
    188188}
    189189
     
    396396}
    397397
    398 void WebSWServerConnection::registerServiceWorkerClient(SecurityOriginData&& topOrigin, ServiceWorkerClientData&& data, const std::optional<ServiceWorkerRegistrationIdentifier>& controllingServiceWorkerRegistrationIdentifier, String&& userAgent)
     398void WebSWServerConnection::registerServiceWorkerClient(WebCore::ClientOrigin&& clientOrigin, ServiceWorkerClientData&& data, const std::optional<ServiceWorkerRegistrationIdentifier>& controllingServiceWorkerRegistrationIdentifier, String&& userAgent)
    399399{
    400400    CONNECTION_MESSAGE_CHECK(data.identifier.processIdentifier() == identifier());
    401     CONNECTION_MESSAGE_CHECK(!topOrigin.isEmpty());
    402 
    403     auto contextOrigin = SecurityOriginData::fromURL(data.url);
     401    CONNECTION_MESSAGE_CHECK(!clientOrigin.topOrigin.isEmpty());
     402
     403    auto& contextOrigin = clientOrigin.clientOrigin;
     404    if (data.url.protocolIsInHTTPFamily()) {
     405        // We do not register any sandbox document.
     406        if (contextOrigin != SecurityOriginData::fromURL(data.url))
     407            return;
     408    }
     409
    404410    CONNECTION_MESSAGE_CHECK(!contextOrigin.isEmpty());
    405411
     
    409415    auto* contextConnection = isNewOrigin ? server().contextConnectionForRegistrableDomain(RegistrableDomain { contextOrigin }) : nullptr;
    410416
    411     auto clientOrigin = ClientOrigin { WTFMove(topOrigin), WTFMove(contextOrigin) };
    412417    m_clientOrigins.add(data.identifier, clientOrigin);
    413418    server().registerServiceWorkerClient(WTFMove(clientOrigin), WTFMove(data), controllingServiceWorkerRegistrationIdentifier, WTFMove(userAgent));
  • trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h

    r292468 r292905  
    111111    void getRegistrations(const WebCore::SecurityOriginData& topOrigin, const URL& clientURL, CompletionHandler<void(const Vector<WebCore::ServiceWorkerRegistrationData>&)>&&);
    112112
    113     void registerServiceWorkerClient(WebCore::SecurityOriginData&& topOrigin, WebCore::ServiceWorkerClientData&&, const std::optional<WebCore::ServiceWorkerRegistrationIdentifier>&, String&& userAgent);
     113    void registerServiceWorkerClient(WebCore::ClientOrigin&&, WebCore::ServiceWorkerClientData&&, const std::optional<WebCore::ServiceWorkerRegistrationIdentifier>&, String&& userAgent);
    114114    void unregisterServiceWorkerClient(const WebCore::ScriptExecutionContextIdentifier&);
    115115    void terminateWorkerFromClient(WebCore::ServiceWorkerIdentifier, CompletionHandler<void()>&&);
  • trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in

    r290903 r292905  
    3939    WhenRegistrationReady(struct WebCore::SecurityOriginData topOrigin, URL clientURL) -> (std::optional<WebCore::ServiceWorkerRegistrationData> registration)
    4040    GetRegistrations(struct WebCore::SecurityOriginData topOrigin, URL clientURL) -> (Vector<WebCore::ServiceWorkerRegistrationData> registrations)
    41     RegisterServiceWorkerClient(struct WebCore::SecurityOriginData topOrigin, struct WebCore::ServiceWorkerClientData data, std::optional<WebCore::ServiceWorkerRegistrationIdentifier> controllingServiceWorkerRegistrationIdentifier, String userAgent)
     41    RegisterServiceWorkerClient(struct WebCore::ClientOrigin clientOrigin, struct WebCore::ServiceWorkerClientData data, std::optional<WebCore::ServiceWorkerRegistrationIdentifier> controllingServiceWorkerRegistrationIdentifier, String userAgent)
    4242    UnregisterServiceWorkerClient(WebCore::ScriptExecutionContextIdentifier identifier)
    4343
  • trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp

    r292861 r292905  
    116116}
    117117
    118 void WebSWClientConnection::registerServiceWorkerClient(const SecurityOrigin& topOrigin, WebCore::ServiceWorkerClientData&& data, const std::optional<WebCore::ServiceWorkerRegistrationIdentifier>& controllingServiceWorkerRegistrationIdentifier, String&& userAgent)
    119 {
    120     send(Messages::WebSWServerConnection::RegisterServiceWorkerClient { topOrigin.data(), data, controllingServiceWorkerRegistrationIdentifier, userAgent });
     118void WebSWClientConnection::registerServiceWorkerClient(const ClientOrigin& clientOrigin, WebCore::ServiceWorkerClientData&& data, const std::optional<WebCore::ServiceWorkerRegistrationIdentifier>& controllingServiceWorkerRegistrationIdentifier, String&& userAgent)
     119{
     120    send(Messages::WebSWServerConnection::RegisterServiceWorkerClient { clientOrigin, data, controllingServiceWorkerRegistrationIdentifier, userAgent });
    121121}
    122122
  • trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.h

    r292861 r292905  
    7474    void finishFetchingScriptInServer(const WebCore::ServiceWorkerJobDataIdentifier&, WebCore::ServiceWorkerRegistrationKey&&, WebCore::WorkerFetchResult&&) final;
    7575    void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destinationIdentifier, WebCore::MessageWithMessagePorts&&, const WebCore::ServiceWorkerOrClientIdentifier& source) final;
    76     void registerServiceWorkerClient(const WebCore::SecurityOrigin& topOrigin, WebCore::ServiceWorkerClientData&&, const std::optional<WebCore::ServiceWorkerRegistrationIdentifier>&, String&& userAgent) final;
     76    void registerServiceWorkerClient(const WebCore::ClientOrigin&, WebCore::ServiceWorkerClientData&&, const std::optional<WebCore::ServiceWorkerRegistrationIdentifier>&, String&& userAgent) final;
    7777    void unregisterServiceWorkerClient(WebCore::ScriptExecutionContextIdentifier) final;
    7878    void scheduleUnregisterJobInServer(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::ServiceWorkerOrClientIdentifier, CompletionHandler<void(WebCore::ExceptionOr<bool>&&)>&&) final;
Note: See TracChangeset for help on using the changeset viewer.