Changeset 224408 in webkit


Ignore:
Timestamp:
Nov 3, 2017 11:21:46 AM (6 years ago)
Author:
commit-queue@webkit.org
Message:

Implement Service Worker Matching Registration algorithm
https://bugs.webkit.org/show_bug.cgi?id=178882

Patch by Youenn Fablet <youenn@apple.com> on 2017-11-03
Reviewed by Chris Dumez.

LayoutTests/imported/w3c:

  • web-platform-tests/service-workers/service-worker/multi-globals/url-parsing.https-expected.txt:
  • web-platform-tests/service-workers/service-worker/multiple-register.https-expected.txt:
  • web-platform-tests/service-workers/service-worker/registration-basic.https-expected.txt:
  • web-platform-tests/service-workers/service-worker/registration-scope.https-expected.txt:
  • web-platform-tests/service-workers/service-worker/serviceworkerobject-scripturl.https-expected.txt:
  • web-platform-tests/service-workers/service-worker/unregister-controller.https-expected.txt:
  • web-platform-tests/service-workers/service-worker/unregister.https-expected.txt:

Source/WebCore:

Test: http/tests/workers/service/service-worker-clear.html

Adding support for scope as part of the ServiceWorkerRegistrationKey to disambiguate several service workers registered with different scopes.
Adding the Service Worker Registration algorithm in SWServer and adding internals API to test it.
Making ServiceWorkerRegistrationKey a class to protect its internal field to be reused in wrong places.

Added preliminary support for clearing service workers for a given session ID as this is needed by WTR for stable testing.

  • testing/Internals.cpp:

(WebCore::Internals::hasServiceWorkerRegistration):

  • testing/Internals.h:
  • testing/Internals.idl:
  • workers/service/ServiceWorkerJobData.cpp:

(WebCore::ServiceWorkerJobData::registrationKey const):

  • workers/service/ServiceWorkerRegistration.h:
  • workers/service/ServiceWorkerRegistrationKey.cpp:

(WebCore::ServiceWorkerRegistrationKey::hash const):
(WebCore::ServiceWorkerRegistrationKey::operator== const):
(WebCore::ServiceWorkerRegistrationKey::isolatedCopy const):

  • workers/service/ServiceWorkerRegistrationKey.h:

(WebCore::ServiceWorkerRegistrationKey::encode const):
(WebCore::ServiceWorkerRegistrationKey::decode):

  • workers/service/server/SWClientConnection.h:
  • workers/service/server/SWServer.cpp:

(WebCore::SWServer::clear):
(WebCore::SWServer::doRegistrationMatching const):

  • workers/service/server/SWServer.h:

(WebCore::SWServer::Connection::doRegistrationMatching const):

  • workers/service/server/SWServerJobQueue.cpp:

(WebCore::SWServerJobQueue::~SWServerJobQueue):

  • workers/service/server/SWServerRegistration.h:

Source/WebKit:

Added IPC plumbery for matchRegistration request and response.
Added some limited clearing of workers and registrations.

  • StorageProcess/ServiceWorker/WebSWServerConnection.cpp:

(WebKit::WebSWServerConnection::matchRegistration):

  • StorageProcess/ServiceWorker/WebSWServerConnection.h:
  • StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
  • StorageProcess/StorageProcess.cpp:

(WebKit::StorageProcess::deleteWebsiteData):
(WebKit::StorageProcess::deleteWebsiteDataForOrigins):

  • WebProcess/Storage/WebSWClientConnection.cpp:

(WebKit::WebSWClientConnection::didMatchRegistration):
(WebKit::WebSWClientConnection::matchRegistration):

  • WebProcess/Storage/WebSWClientConnection.h:
  • WebProcess/Storage/WebSWClientConnection.messages.in:
  • WebProcess/Storage/WebServiceWorkerProvider.h:

LayoutTests:

  • TestExpectations:
  • http/tests/workers/service/basic-register-exceptions-expected.txt:
  • http/tests/workers/service/resources/basic-register.js: Fixing flakiness.
  • http/tests/workers/service/service-worker-clear-expected.txt: Added.
  • http/tests/workers/service/service-worker-clear.html: Added.
Location:
trunk
Files:
2 added
32 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r224407 r224408  
     12017-11-03  Youenn Fablet  <youenn@apple.com>
     2
     3        Implement Service Worker Matching Registration algorithm
     4        https://bugs.webkit.org/show_bug.cgi?id=178882
     5
     6        Reviewed by Chris Dumez.
     7
     8        * TestExpectations:
     9        * http/tests/workers/service/basic-register-exceptions-expected.txt:
     10        * http/tests/workers/service/resources/basic-register.js: Fixing flakiness.
     11        * http/tests/workers/service/service-worker-clear-expected.txt: Added.
     12        * http/tests/workers/service/service-worker-clear.html: Added.
     13
    1142017-11-02  Dean Jackson  <dino@apple.com>
    215
  • trunk/LayoutTests/TestExpectations

    r224364 r224408  
    185185http/tests/workers/service/service-worker-cache-api.https.html [ Pass Failure ]
    186186imported/w3c/web-platform-tests/service-workers/service-worker/fetch-header-visibility.https.html [ Pass Failure ]
     187imported/w3c/web-platform-tests/service-workers/service-worker/unregister-controller.https.html [ Pass Failure ]
     188imported/w3c/web-platform-tests/service-workers/service-worker/update-bytecheck.https.html [ Pass Failure ]
    187189
    188190# textarea.animate is not supported
  • trunk/LayoutTests/http/tests/workers/service/basic-register-exceptions-expected.txt

    r223608 r224408  
    55CONSOLE MESSAGE: line 60: Registration failed with error: TypeError: Scope URL provided to serviceWorker.register() must be either HTTP or HTTPS
    66CONSOLE MESSAGE: line 70: Registration failed with error: TypeError: Scope URL provided to serviceWorker.register() cannot have a path that contains '%2f' or '%5c'
    7 CONSOLE MESSAGE: line 8: Registered! (unexpectedly)
    8 CONSOLE MESSAGE: line 80: Registration failed with error: SecurityError: Script origin does not match the registering client's origin
    97CONSOLE MESSAGE: line 91: Registration failed with error: SecurityError: Scope origin does not match the registering client's origin
    108
  • trunk/LayoutTests/http/tests/workers/service/resources/basic-register.js

    r223652 r224408  
    44}
    55
    6 function log(msg)
     6async function test()
    77{
    8     let console = document.getElementById("console");
    9     if (!console) {
    10         console = document.createElement("div");
    11         console.id = "console";
    12         document.body.appendChild(console);
    13     }
    14     let span = document.createElement("span");
    15     span.innerHTML = msg + "<br>";
    16     console.appendChild(span);
    17 }
     8    if (!internals.hasServiceWorkerRegisteredForOrigin(self.origin))
     9        log("PASS: No service worker is initially registered for this origin");
     10    else
     11        log("FAIL: A service worker is initially registered for this origin");
    1812
    19 if (!internals.hasServiceWorkerRegisteredForOrigin(self.origin))
    20     log("PASS: No service worker is initially registered for this origin");
    21 else
    22     log("FAIL: A service worker is initially registered for this origin");
     13    testRunner.setPrivateBrowsingEnabled(true);
    2314
    24 testRunner.setPrivateBrowsingEnabled(true);
     15    if (!internals.hasServiceWorkerRegisteredForOrigin(self.origin))
     16        log("PASS: No service worker is initially registered for this origin in private session");
     17    else
     18        log("FAIL: A service worker is initially registered for this origin in private session");
    2519
    26 if (!internals.hasServiceWorkerRegisteredForOrigin(self.origin))
    27     log("PASS: No service worker is initially registered for this origin in private session");
    28 else
    29     log("FAIL: A service worker is initially registered for this origin in private session");
    30 
    31 testRunner.setPrivateBrowsingEnabled(false);
    32 
    33 navigator.serviceWorker.register("resources/empty-worker.js", { scope: "/test", updateViaCache: "none" })
    34 .then(function(r) {
    35         log("Registered!");
     20    testRunner.setPrivateBrowsingEnabled(false);
     21    try {
     22        r = await navigator.serviceWorker.register("resources/empty-worker.js", { scope: "/test", updateViaCache: "none" })
     23        log("Registered!");
    3624
    3725        if (r.scope == "http://127.0.0.1:8000/test")
    38            log("PASS: registration object's scope is valid");
     26            log("PASS: registration object's scope is valid");
    3927        else
    40            log("FAIL: registration object's scope is invalid, got: " + r.scope);
     28            log("FAIL: registration object's scope is invalid, got: " + r.scope);
    4129
    4230        if (r.updateViaCache == "none")
    43            log("PASS: registration object's updateViaCache is valid");
     31            log("PASS: registration object's updateViaCache is valid");
    4432        else
    45            log("FAIL: registration object's updateViaCache is invalid, got: " + r.updateViaCache);
     33            log("FAIL: registration object's updateViaCache is invalid, got: " + r.updateViaCache);
    4634
    4735        if (internals.hasServiceWorkerRegisteredForOrigin(self.origin))
     
    5846
    5947        testRunner.setPrivateBrowsingEnabled(false);
    60 }, function(e) {
    61         log("Registration failed with error: " + e);
    62 })
    63 .catch(function(e) {
    64         log("Exception registering: " + e);
    65 });
    6648
    67 navigator.serviceWorker.register("resources/empty-worker-doesnt-exist.js", { })
    68 .then(function(r) {
    69         log("Registered!");
    70         done();
    71 }, function(e) {
    72         log("Registration failed with error: " + e);
    73         done();
    74 })
    75 .catch(function(e) {
    76         log("Exception registering: " + e);
    77         done();
    78 });
     49        r = await navigator.serviceWorker.register("resources/empty-worker-doesnt-exist.js", { })
     50        log("Registered!");
     51    } catch (e) {
     52        log("Exception registering: " + e);
     53    }
     54    done();
     55}
     56
     57test();
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r224400 r224408  
     12017-11-03  Youenn Fablet  <youenn@apple.com>
     2
     3        Implement Service Worker Matching Registration algorithm
     4        https://bugs.webkit.org/show_bug.cgi?id=178882
     5
     6        Reviewed by Chris Dumez.
     7
     8        * web-platform-tests/service-workers/service-worker/multi-globals/url-parsing.https-expected.txt:
     9        * web-platform-tests/service-workers/service-worker/multiple-register.https-expected.txt:
     10        * web-platform-tests/service-workers/service-worker/registration-basic.https-expected.txt:
     11        * web-platform-tests/service-workers/service-worker/registration-scope.https-expected.txt:
     12        * web-platform-tests/service-workers/service-worker/serviceworkerobject-scripturl.https-expected.txt:
     13        * web-platform-tests/service-workers/service-worker/unregister-controller.https-expected.txt:
     14        * web-platform-tests/service-workers/service-worker/unregister.https-expected.txt:
     15
    1162017-11-03  Ms2ger  <Ms2ger@igalia.com>
    217
  • trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/multiple-register.https-expected.txt

    r224218 r224408  
    22
    33FAIL Subsequent registrations resolve to the same registration object assert_unreached: unexpected rejection: assert_equals: register should resolve to the same registration expected object "[object ServiceWorkerRegistration]" but got object "[object ServiceWorkerRegistration]" Reached unreachable code
    4 FAIL Subsequent registrations from a different iframe resolve to the different registration object but they refer to the same registration and workers assert_unreached: unexpected rejection: assert_equals: registrations should have the same scope expected "https://localhost:9443/service-workers/service-worker/resources/scope/subsequent-register-from-different-iframe" but got "https://localhost:9443/service-workers/service-worker/resources/scope/subsequent-register-from-same-window" Reached unreachable code
     4FAIL Subsequent registrations from a different iframe resolve to the different registration object but they refer to the same registration and workers assert_unreached: unexpected rejection: assert_equals: installing worker should be null expected null but got object "[object ServiceWorker]" Reached unreachable code
    55FAIL Concurrent registrations resolve to the same registration object assert_unreached: unexpected rejection: assert_equals: register should resolve to the same registration expected object "[object ServiceWorkerRegistration]" but got object "[object ServiceWorkerRegistration]" Reached unreachable code
    66
  • trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/unregister-controller.https-expected.txt

    r224250 r224408  
    22
    33FAIL Unregister does not affect existing controller assert_unreached: unexpected rejection: assert_true: document should load with a controller expected true got false Reached unreachable code
    4 FAIL Unregister prevents control of subsequent navigations assert_unreached: unexpected rejection: assert_equals: requests should not be intercepted expected "a simple text file\n" but got "ERROR" Reached unreachable code
     4PASS Unregister prevents control of subsequent navigations
    55PASS Unregister prevents new controllee even if registration is still in use
    66
  • trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/unregister.https-expected.txt

    r224132 r224408  
    11
    22PASS Unregister twice
    3 FAIL Register then unregister assert_unreached: unexpected rejection: assert_equals: unregistration should resolve with true expected true but got false Reached unreachable code
     3PASS Register then unregister
    44
  • trunk/Source/WebCore/ChangeLog

    r224407 r224408  
     12017-11-03  Youenn Fablet  <youenn@apple.com>
     2
     3        Implement Service Worker Matching Registration algorithm
     4        https://bugs.webkit.org/show_bug.cgi?id=178882
     5
     6        Reviewed by Chris Dumez.
     7
     8        Test: http/tests/workers/service/service-worker-clear.html
     9
     10        Adding support for scope as part of the ServiceWorkerRegistrationKey to disambiguate several service workers registered with different scopes.
     11        Adding the Service Worker Registration algorithm in SWServer and adding internals API to test it.
     12        Making ServiceWorkerRegistrationKey a class to protect its internal field to be reused in wrong places.
     13
     14        Added preliminary support for clearing service workers for a given session ID as this is needed by WTR for stable testing.
     15
     16        * testing/Internals.cpp:
     17        (WebCore::Internals::hasServiceWorkerRegistration):
     18        * testing/Internals.h:
     19        * testing/Internals.idl:
     20        * workers/service/ServiceWorkerJobData.cpp:
     21        (WebCore::ServiceWorkerJobData::registrationKey const):
     22        * workers/service/ServiceWorkerRegistration.h:
     23        * workers/service/ServiceWorkerRegistrationKey.cpp:
     24        (WebCore::ServiceWorkerRegistrationKey::hash const):
     25        (WebCore::ServiceWorkerRegistrationKey::operator== const):
     26        (WebCore::ServiceWorkerRegistrationKey::isolatedCopy const):
     27        * workers/service/ServiceWorkerRegistrationKey.h:
     28        (WebCore::ServiceWorkerRegistrationKey::encode const):
     29        (WebCore::ServiceWorkerRegistrationKey::decode):
     30        * workers/service/server/SWClientConnection.h:
     31        * workers/service/server/SWServer.cpp:
     32        (WebCore::SWServer::clear):
     33        (WebCore::SWServer::doRegistrationMatching const):
     34        * workers/service/server/SWServer.h:
     35        (WebCore::SWServer::Connection::doRegistrationMatching const):
     36        * workers/service/server/SWServerJobQueue.cpp:
     37        (WebCore::SWServerJobQueue::~SWServerJobQueue):
     38        * workers/service/server/SWServerRegistration.h:
     39
    1402017-11-02  Dean Jackson  <dino@apple.com>
    241
  • trunk/Source/WebCore/page/SecurityOriginData.h

    r222233 r224408  
    8484
    8585WEBCORE_EXPORT bool operator==(const SecurityOriginData&, const SecurityOriginData&);
     86inline bool operator!=(const SecurityOriginData& first, const SecurityOriginData& second) { return !(first == second); }
    8687
    8788template<class Encoder>
  • trunk/Source/WebCore/testing/Internals.cpp

    r224320 r224408  
    133133#include "SerializedScriptValue.h"
    134134#include "ServiceWorkerProvider.h"
     135#include "ServiceWorkerRegistrationData.h"
    135136#include "Settings.h"
    136137#include "ShadowRoot.h"
     
    42664267}
    42674268
     4269void Internals::hasServiceWorkerRegistration(const String& clientURL, HasRegistrationPromise&& promise)
     4270{
     4271    if (!contextDocument())
     4272        return;
     4273
     4274    URL parsedURL = contextDocument()->completeURL(clientURL);
     4275
     4276    return ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(contextDocument()->sessionID()).matchRegistration(contextDocument()->topOrigin(), parsedURL, [promise = WTFMove(promise)] (auto&& result) mutable {
     4277        promise.resolve(!!result);
     4278    });
     4279}
    42684280#endif
    42694281
  • trunk/Source/WebCore/testing/Internals.h

    r224260 r224408  
    618618    Ref<FetchEvent> createBeingDispatchedFetchEvent(ScriptExecutionContext&);
    619619    Ref<ExtendableEvent> createTrustedExtendableEvent();
     620    using HasRegistrationPromise = DOMPromiseDeferred<IDLBoolean>;
     621    void hasServiceWorkerRegistration(const String& clientURL, HasRegistrationPromise&&);
    620622#endif
    621623
    622624    bool hasServiceWorkerRegisteredForOrigin(const String&);
    623        
     625
    624626#if ENABLE(APPLE_PAY)
    625627    MockPaymentCoordinator& mockPaymentCoordinator() const;
  • trunk/Source/WebCore/testing/Internals.idl

    r224260 r224408  
    563563    [Conditional=SERVICE_WORKER, CallWith=ScriptExecutionContext] FetchEvent createBeingDispatchedFetchEvent();
    564564    [Conditional=SERVICE_WORKER] ExtendableEvent createTrustedExtendableEvent();
     565    [Conditional=SERVICE_WORKER] Promise<boolean> hasServiceWorkerRegistration(DOMString scopeURL);
    565566
    566567    boolean hasServiceWorkerRegisteredForOrigin(DOMString origin);
  • trunk/Source/WebCore/workers/service/ServiceWorkerJobData.cpp

    r221399 r224408  
    4444ServiceWorkerRegistrationKey ServiceWorkerJobData::registrationKey() const
    4545{
    46     return { clientCreationURL, topOrigin };
     46    URL scope = scopeURL;
     47    scope.removeFragmentIdentifier();
     48    return { URL { clientCreationURL }, SecurityOriginData { topOrigin }, WTFMove(scope) };
    4749}
    4850
  • trunk/Source/WebCore/workers/service/ServiceWorkerRegistrationKey.cpp

    r221392 r224408  
    3333namespace WebCore {
    3434
     35ServiceWorkerRegistrationKey::ServiceWorkerRegistrationKey(URL&& clientURL, SecurityOriginData&& topOrigin, URL&& scope)
     36    : m_clientCreationURL(WTFMove(clientURL))
     37    , m_topOrigin(WTFMove(topOrigin))
     38    , m_scope(WTFMove(scope))
     39{
     40    ASSERT(!m_scope.hasFragment());
     41}
     42
    3543ServiceWorkerRegistrationKey ServiceWorkerRegistrationKey::emptyKey()
    3644{
     
    4048unsigned ServiceWorkerRegistrationKey::hash() const
    4149{
    42     unsigned hashes[2];
    43     hashes[0] = URLHash::hash(clientCreationURL);
    44     hashes[1] = SecurityOriginDataHash::hash(topOrigin);
     50    unsigned hashes[3];
     51    hashes[0] = URLHash::hash(m_clientCreationURL);
     52    hashes[1] = SecurityOriginDataHash::hash(m_topOrigin);
     53    hashes[2] = StringHash::hash(m_scope);
    4554
    4655    return StringHasher::hashMemory(hashes, sizeof(hashes));
     
    4958bool ServiceWorkerRegistrationKey::operator==(const ServiceWorkerRegistrationKey& other) const
    5059{
    51     return clientCreationURL == other.clientCreationURL && topOrigin == other.topOrigin;
     60    return m_clientCreationURL == other.m_clientCreationURL && m_topOrigin == other.m_topOrigin && m_scope == other.m_scope;
    5261}
    5362
    5463ServiceWorkerRegistrationKey ServiceWorkerRegistrationKey::isolatedCopy() const
    5564{
    56     ServiceWorkerRegistrationKey result;
    57     result.clientCreationURL = clientCreationURL.isolatedCopy();
    58     result.topOrigin = topOrigin.isolatedCopy();
    59     return result;
     65    return { m_clientCreationURL.isolatedCopy(), m_topOrigin.isolatedCopy(), m_scope.isolatedCopy() };
     66}
     67
     68bool ServiceWorkerRegistrationKey::isMatching(const SecurityOriginData& topOrigin, const URL& clientURL) const
     69{
     70    if (topOrigin != m_topOrigin)
     71        return false;
     72
     73    if (!protocolHostAndPortAreEqual(clientURL, m_scope))
     74        return false;
     75
     76    return clientURL.string().startsWith(m_scope);
    6077}
    6178
  • trunk/Source/WebCore/workers/service/ServiceWorkerRegistrationKey.h

    r222233 r224408  
    3333namespace WebCore {
    3434
    35 struct ServiceWorkerRegistrationKey {
    36     URL clientCreationURL;
    37     SecurityOriginData topOrigin;
     35class ServiceWorkerRegistrationKey {
     36public:
     37    ServiceWorkerRegistrationKey() = default;
     38    WEBCORE_EXPORT ServiceWorkerRegistrationKey(URL&& clientURL, SecurityOriginData&& topOrigin, URL&& scope);
    3839
    3940    static ServiceWorkerRegistrationKey emptyKey();
     
    4142
    4243    bool operator==(const ServiceWorkerRegistrationKey&) const;
     44    bool isMatching(const SecurityOriginData& topOrigin, const URL& clientURL) const;
     45    size_t scopeLength() const { return m_scope.string().length(); }
     46
     47    const SecurityOriginData& topOrigin() const { return m_topOrigin; }
     48    const URL& clientCreationURL() const { return m_clientCreationURL; }
     49    void setClientCreationURL(URL&& url) { m_clientCreationURL = WTFMove(url); }
    4350
    4451    ServiceWorkerRegistrationKey isolatedCopy() const;
     
    4653    template<class Encoder> void encode(Encoder&) const;
    4754    template<class Decoder> static std::optional<ServiceWorkerRegistrationKey> decode(Decoder&);
     55
     56private:
     57    URL m_clientCreationURL;
     58    SecurityOriginData m_topOrigin;
     59    URL m_scope;
    4860};
    4961
     
    5163void ServiceWorkerRegistrationKey::encode(Encoder& encoder) const
    5264{
    53     encoder << clientCreationURL << topOrigin;
     65    encoder << m_clientCreationURL << m_topOrigin << m_scope;
    5466}
    5567
     
    6577    if (!topOrigin)
    6678        return std::nullopt;
    67    
    68     return {{ WTFMove(clientCreationURL), WTFMove(*topOrigin) }};
     79
     80    URL scope;
     81    if (!decoder.decode(scope))
     82        return std::nullopt;
     83
     84    return { { WTFMove(clientCreationURL), WTFMove(*topOrigin), WTFMove(scope) } };
    6985}
    7086
     
    8298    static WebCore::ServiceWorkerRegistrationKey emptyValue() { return WebCore::ServiceWorkerRegistrationKey::emptyKey(); }
    8399
    84     static void constructDeletedValue(WebCore::ServiceWorkerRegistrationKey& slot) { slot.clientCreationURL = WebCore::URL(HashTableDeletedValue); }
    85     static bool isDeletedValue(const WebCore::ServiceWorkerRegistrationKey& slot) { return slot.clientCreationURL.isHashTableDeletedValue(); }
     100    static void constructDeletedValue(WebCore::ServiceWorkerRegistrationKey& slot) { slot.setClientCreationURL(WebCore::URL(HashTableDeletedValue)); }
     101    static bool isDeletedValue(const WebCore::ServiceWorkerRegistrationKey& slot) { return slot.clientCreationURL().isHashTableDeletedValue(); }
    86102};
    87103
  • trunk/Source/WebCore/workers/service/server/SWClientConnection.h

    r224403 r224408  
    4848    WEBCORE_EXPORT virtual ~SWClientConnection();
    4949
     50    using RegistrationCallback = WTF::CompletionHandler<void(std::optional<ServiceWorkerRegistrationData>&&)>;
     51    virtual void matchRegistration(const SecurityOrigin& topOrigin, const URL& clientURL, RegistrationCallback&&) = 0;
     52
    5053    void scheduleJob(ServiceWorkerJob&);
    5154    void finishedFetchingScript(ServiceWorkerJob&, const String&);
  • trunk/Source/WebCore/workers/service/server/SWServer.cpp

    r224403 r224408  
    3535#include "SWServerRegistration.h"
    3636#include "SWServerWorker.h"
     37#include "SecurityOrigin.h"
    3738#include "ServiceWorkerContextData.h"
    3839#include "ServiceWorkerFetchResult.h"
     
    9293}
    9394
     95void SWServer::clear()
     96{
     97    m_jobQueues.clear();
     98    m_registrations.clear();
     99    // FIXME: We should probably ask service workers to terminate.
     100}
     101
    94102void SWServer::Connection::scheduleJobInServer(const ServiceWorkerJobData& jobData)
    95103{
     
    305313}
    306314
     315const SWServerRegistration* SWServer::doRegistrationMatching(const SecurityOriginData& topOrigin, const URL& clientURL) const
     316{
     317    const SWServerRegistration* selectedRegistration = nullptr;
     318    for (auto& registration : m_registrations.values()) {
     319        if (!registration->key().isMatching(topOrigin, clientURL))
     320            continue;
     321        if (!selectedRegistration || selectedRegistration->key().scopeLength() < registration->key().scopeLength())
     322            selectedRegistration = registration.get();
     323    }
     324
     325    return (selectedRegistration && !selectedRegistration->isUninstalling()) ? selectedRegistration : nullptr;
     326}
     327
    307328} // namespace WebCore
    308329
  • trunk/Source/WebCore/workers/service/server/SWServer.h

    r224403 r224408  
    3030#include "ServiceWorkerIdentifier.h"
    3131#include "ServiceWorkerJob.h"
     32#include "ServiceWorkerRegistrationData.h"
    3233#include "ServiceWorkerRegistrationKey.h"
    3334#include <wtf/CrossThreadQueue.h>
     
    6061        WEBCORE_EXPORT void scriptContextFailedToStart(const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier, const String& message);
    6162        WEBCORE_EXPORT void scriptContextStarted(const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier);
    62        
     63        const SWServerRegistration* doRegistrationMatching(const SecurityOriginData& topOrigin, const URL& clientURL) const { return m_server.doRegistrationMatching(topOrigin, clientURL); }
     64
    6365        // Messages to the client WebProcess
    6466        virtual void updateRegistrationStateInClient(const ServiceWorkerRegistrationKey&, ServiceWorkerRegistrationState, std::optional<ServiceWorkerIdentifier>) = 0;
     
    8890    WEBCORE_EXPORT SWServer();
    8991    WEBCORE_EXPORT ~SWServer();
     92
     93    WEBCORE_EXPORT void clear();
    9094
    9195    SWServerRegistration* getRegistration(const ServiceWorkerRegistrationKey&);
     
    120124    void removeClientServiceWorkerRegistration(Connection&, const ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier);
    121125
     126    WEBCORE_EXPORT const SWServerRegistration* doRegistrationMatching(const SecurityOriginData& topOrigin, const URL& clientURL) const;
     127
    122128    HashMap<uint64_t, Connection*> m_connections;
    123129    HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerRegistration>> m_registrations;
  • trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp

    r224403 r224408  
    4949SWServerJobQueue::~SWServerJobQueue()
    5050{
    51     ASSERT(m_jobQueue.isEmpty());
    5251}
    5352
  • trunk/Source/WebCore/workers/service/server/SWServerRegistration.h

    r224403 r224408  
    4848
    4949    SWServerWorker* getNewestWorker();
    50     ServiceWorkerRegistrationData data() const;
     50    WEBCORE_EXPORT ServiceWorkerRegistrationData data() const;
    5151
    5252    bool isUninstalling() const { return m_uninstalling; }
  • trunk/Source/WebKit/ChangeLog

    r224406 r224408  
     12017-11-03  Youenn Fablet  <youenn@apple.com>
     2
     3        Implement Service Worker Matching Registration algorithm
     4        https://bugs.webkit.org/show_bug.cgi?id=178882
     5
     6        Reviewed by Chris Dumez.
     7
     8        Added IPC plumbery for matchRegistration request and response.
     9        Added some limited clearing of workers and registrations.
     10
     11        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
     12        (WebKit::WebSWServerConnection::matchRegistration):
     13        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
     14        * StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
     15        * StorageProcess/StorageProcess.cpp:
     16        (WebKit::StorageProcess::deleteWebsiteData):
     17        (WebKit::StorageProcess::deleteWebsiteDataForOrigins):
     18        * WebProcess/Storage/WebSWClientConnection.cpp:
     19        (WebKit::WebSWClientConnection::didMatchRegistration):
     20        (WebKit::WebSWClientConnection::matchRegistration):
     21        * WebProcess/Storage/WebSWClientConnection.h:
     22        * WebProcess/Storage/WebSWClientConnection.messages.in:
     23        * WebProcess/Storage/WebServiceWorkerProvider.h:
     24
    1252017-11-03  Jeremy Jones  <jeremyj@apple.com>
    226
  • trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp

    r224403 r224408  
    4444#include <WebCore/ExceptionData.h>
    4545#include <WebCore/NotImplemented.h>
     46#include <WebCore/SWServerRegistration.h>
    4647#include <WebCore/SecurityOrigin.h>
    4748#include <WebCore/ServiceWorkerClientIdentifier.h>
    4849#include <WebCore/ServiceWorkerContextData.h>
    4950#include <WebCore/ServiceWorkerJobData.h>
    50 #include <WebCore/ServiceWorkerRegistrationData.h>
    5151#include <wtf/MainThread.h>
    5252
     
    7979void WebSWServerConnection::resolveRegistrationJobInClient(uint64_t jobIdentifier, const ServiceWorkerRegistrationData& registrationData)
    8080{
    81     auto origin = registrationData.key.topOrigin.securityOrigin();
     81    auto origin = registrationData.key.topOrigin().securityOrigin();
    8282    StorageProcess::singleton().ensureSWOriginStoreForSession(m_sessionID).add(origin);
    8383    send(Messages::WebSWClientConnection::RegistrationJobResolvedInServer(jobIdentifier, registrationData));
     
    8686void WebSWServerConnection::resolveUnregistrationJobInClient(uint64_t jobIdentifier, const ServiceWorkerRegistrationKey& registrationKey, bool unregistrationResult)
    8787{
    88     auto origin = registrationKey.topOrigin.securityOrigin();
     88    auto origin = registrationKey.topOrigin().securityOrigin();
    8989    if (auto* store = StorageProcess::singleton().swOriginStoreForSession(m_sessionID))
    9090        store->remove(origin);
     
    151151}
    152152
     153void WebSWServerConnection::matchRegistration(uint64_t registrationMatchRequestIdentifier, const SecurityOriginData& topOrigin, const URL& clientURL)
     154{
     155    if (auto* registration = doRegistrationMatching(topOrigin, clientURL)) {
     156        send(Messages::WebSWClientConnection::DidMatchRegistration { registrationMatchRequestIdentifier, registration->data() });
     157        return;
     158    }
     159    send(Messages::WebSWClientConnection::DidMatchRegistration { registrationMatchRequestIdentifier, std::nullopt });
     160}
     161
    153162template<typename U> bool WebSWServerConnection::sendToContextProcess(U&& message)
    154163{
  • trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h

    r224403 r224408  
    3535namespace WebCore {
    3636struct ExceptionData;
    37 struct ServiceWorkerRegistrationKey;
     37class ServiceWorkerRegistrationKey;
    3838}
    3939
     
    7272    void postMessageToServiceWorkerGlobalScope(WebCore::ServiceWorkerIdentifier destinationIdentifier, const IPC::DataReference& message, uint64_t sourceScriptExecutionContextIdentifier, const String& sourceOrigin);
    7373
     74    void matchRegistration(uint64_t registrationMatchRequestIdentifier, const WebCore::SecurityOriginData&, const WebCore::URL& clientURL);
     75
    7476    // Messages to the SW context WebProcess
    7577    void updateServiceWorkerContext(const WebCore::ServiceWorkerContextData&) final;
  • trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.messages.in

    r224403 r224408  
    2727    ScheduleJobInServer(struct WebCore::ServiceWorkerJobData jobData)
    2828    FinishFetchingScriptInServer(struct WebCore::ServiceWorkerFetchResult result)
    29     AddServiceWorkerRegistrationInServer(struct WebCore::ServiceWorkerRegistrationKey key, uint64_t registrationIdentifier)
    30     RemoveServiceWorkerRegistrationInServer(struct WebCore::ServiceWorkerRegistrationKey key, uint64_t registrationIdentifier)
     29    AddServiceWorkerRegistrationInServer(WebCore::ServiceWorkerRegistrationKey key, uint64_t registrationIdentifier)
     30    RemoveServiceWorkerRegistrationInServer(WebCore::ServiceWorkerRegistrationKey key, uint64_t registrationIdentifier)
    3131
    3232    StartFetch(uint64_t identifier, std::optional<WebCore::ServiceWorkerIdentifier> serviceWorkerIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options)
    3333    PostMessageToServiceWorkerGlobalScope(WebCore::ServiceWorkerIdentifier destinationServiceWorkerIdentifier, IPC::DataReference message, uint64_t sourceScriptExecutionContextIdentifier, String sourceOrigin)
     34
     35    MatchRegistration(uint64_t serviceRegistrationMatchRequestIdentifier, struct WebCore::SecurityOriginData topOrigin, WebCore::URL clientURL)
    3436}
    3537
  • trunk/Source/WebKit/StorageProcess/StorageProcess.cpp

    r224403 r224408  
    227227        if (auto* store = swOriginStoreForSession(sessionID))
    228228            store->clear();
     229        if (auto* server = m_swServers.get(sessionID))
     230            server->clear();
    229231    }
    230232#endif
     
    252254                store->remove(originData.securityOrigin());
    253255        }
     256        // FIXME: Clear service workers and registrations related to the origin.
    254257    }
    255258#endif
  • trunk/Source/WebKit/StorageProcess/StorageProcess.h

    r224403 r224408  
    4040struct SecurityOriginData;
    4141struct ServiceWorkerClientIdentifier;
    42 struct ServiceWorkerRegistrationKey;
     42class ServiceWorkerRegistrationKey;
    4343}
    4444
  • trunk/Source/WebKit/StorageProcess/StorageProcess.messages.in

    r224403 r224408  
    3939    DidGetWorkerContextProcessConnection(IPC::Attachment connectionHandle)
    4040
    41     ServiceWorkerContextFailedToStart(uint64_t serverConnectionIdentifier, struct WebCore::ServiceWorkerRegistrationKey registrationKey, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, String message)
    42     ServiceWorkerContextStarted(uint64_t serverConnectionIdentifier, struct WebCore::ServiceWorkerRegistrationKey registrationKey, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier)
     41    ServiceWorkerContextFailedToStart(uint64_t serverConnectionIdentifier, WebCore::ServiceWorkerRegistrationKey registrationKey, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, String message)
     42    ServiceWorkerContextStarted(uint64_t serverConnectionIdentifier, WebCore::ServiceWorkerRegistrationKey registrationKey, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier)
    4343
    4444    DidNotHandleFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier)
  • trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp

    r224403 r224408  
    4040#include <WebCore/ServiceWorkerFetchResult.h>
    4141#include <WebCore/ServiceWorkerJobData.h>
     42#include <WebCore/ServiceWorkerRegistrationData.h>
    4243
    4344using namespace PAL;
     
    99100}
    100101
     102void WebSWClientConnection::didMatchRegistration(uint64_t matchingRequest, std::optional<ServiceWorkerRegistrationData>&& result)
     103{
     104    if (auto completionHandler = m_ongoingMatchRegistrationTasks.take(matchingRequest))
     105        completionHandler(WTFMove(result));
     106}
     107
     108void WebSWClientConnection::matchRegistration(const SecurityOrigin& topOrigin, const URL& clientURL, RegistrationCallback&& callback)
     109{
     110    uint64_t requestIdentifier = ++m_previousMatchRegistrationTaskIdentifier;
     111    m_ongoingMatchRegistrationTasks.add(requestIdentifier, WTFMove(callback));
     112    send(Messages::WebSWServerConnection::MatchRegistration(requestIdentifier, SecurityOriginData::fromSecurityOrigin(topOrigin), clientURL));
     113}
     114
    101115Ref<ServiceWorkerClientFetch> WebSWClientConnection::startFetch(WebServiceWorkerProvider& provider, Ref<WebCore::ResourceLoader>&& loader, uint64_t identifier, ServiceWorkerClientFetch::Callback&& callback)
    102116{
  • trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.h

    r224403 r224408  
    5555    uint64_t identifier() const final { return m_identifier; }
    5656
    57     void scheduleJobInServer(const WebCore::ServiceWorkerJobData&) final;
    58     void finishFetchingScriptInServer(const WebCore::ServiceWorkerFetchResult&) final;
    5957    void addServiceWorkerRegistrationInServer(const WebCore::ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier) final;
    6058    void removeServiceWorkerRegistrationInServer(const WebCore::ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier) final;
    61     void postMessageToServiceWorkerGlobalScope(WebCore::ServiceWorkerIdentifier destinationIdentifier, Ref<WebCore::SerializedScriptValue>&&, WebCore::ScriptExecutionContext& source) final;
    6259
    6360    void disconnectedFromWebProcess();
     
    7067
    7168private:
     69    void scheduleJobInServer(const WebCore::ServiceWorkerJobData&) final;
     70    void finishFetchingScriptInServer(const WebCore::ServiceWorkerFetchResult&) final;
     71    void postMessageToServiceWorkerGlobalScope(WebCore::ServiceWorkerIdentifier destinationIdentifier, Ref<WebCore::SerializedScriptValue>&&, WebCore::ScriptExecutionContext& source) final;
     72
     73    void matchRegistration(const WebCore::SecurityOrigin& topOrigin, const WebCore::URL& clientURL, RegistrationCallback&&) final;
     74    void didMatchRegistration(uint64_t matchRequestIdentifier, std::optional<WebCore::ServiceWorkerRegistrationData>&&);
     75
    7276    void scheduleStorageJob(const WebCore::ServiceWorkerJobData&);
    7377
     
    8286    Ref<IPC::Connection> m_connection;
    8387    UniqueRef<WebSWOriginTable> m_swOriginTable;
     88
     89    uint64_t m_previousMatchRegistrationTaskIdentifier { 0 };
     90    HashMap<uint64_t, RegistrationCallback> m_ongoingMatchRegistrationTasks;
     91
    8492}; // class WebSWServerConnection
    8593
  • trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in

    r224403 r224408  
    2929    UnregistrationJobResolvedInServer(uint64_t identifier, bool unregistrationResult)
    3030    StartScriptFetchForServer(uint64_t jobIdentifier)
    31     UpdateRegistrationState(struct WebCore::ServiceWorkerRegistrationKey key, enum WebCore::ServiceWorkerRegistrationState state, std::optional<WebCore::ServiceWorkerIdentifier> serviceWorkerIdentifier)
     31    UpdateRegistrationState(WebCore::ServiceWorkerRegistrationKey key, enum WebCore::ServiceWorkerRegistrationState state, std::optional<WebCore::ServiceWorkerIdentifier> serviceWorkerIdentifier)
    3232
    3333    SetSWOriginTableSharedMemory(WebKit::SharedMemory::Handle handle)
    3434    PostMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, IPC::DataReference message, WebCore::ServiceWorkerIdentifier sourceServiceWorkerIdentifier, String sourceOrigin)
     35
     36    DidMatchRegistration(uint64_t matchRequestIdentifier, std::optional<WebCore::ServiceWorkerRegistrationData> data)
    3537}
    3638
  • trunk/Source/WebKit/WebProcess/Storage/WebServiceWorkerProvider.h

    r223951 r224408  
    4747
    4848    void didReceiveServiceWorkerClientFetchMessage(IPC::Connection&, IPC::Decoder&);
     49    void didReceiveServiceWorkerClientRegistrationMatch(IPC::Connection&, IPC::Decoder&);
    4950
    5051private:
Note: See TracChangeset for help on using the changeset viewer.