Use a ServiceWorker process per registrable domain
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Mar 2019 20:51:37 +0000 (20:51 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Mar 2019 20:51:37 +0000 (20:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195649

Reviewed by Youenn Fablet.

Source/WebCore:

Use a ServiceWorker process per registrable domain instead of one per security origin. This is
more in line with PSON and avoids launching too many processes.

* page/ClientOrigin.h:
(WebCore::ClientOrigin::clientRegistrableDomain const):
* workers/service/server/SWServer.cpp:
(WebCore::SWServer::tryInstallContextData):
(WebCore::SWServer::serverToContextConnectionCreated):
(WebCore::SWServer::runServiceWorkerIfNecessary):
(WebCore::SWServer::markAllWorkersForRegistrableDomainAsTerminated):
(WebCore::SWServer::registerServiceWorkerClient):
(WebCore::SWServer::unregisterServiceWorkerClient):
(WebCore::SWServer::needsServerToContextConnectionForRegistrableDomain const):
* workers/service/server/SWServer.h:
* workers/service/server/SWServerToContextConnection.cpp:
(WebCore::SWServerToContextConnection::SWServerToContextConnection):
(WebCore::SWServerToContextConnection::~SWServerToContextConnection):
(WebCore::SWServerToContextConnection::connectionForRegistrableDomain):
* workers/service/server/SWServerToContextConnection.h:
(WebCore::SWServerToContextConnection::registrableDomain const):
* workers/service/server/SWServerWorker.cpp:
(WebCore::SWServerWorker::contextConnection):
* workers/service/server/SWServerWorker.h:
(WebCore::SWServerWorker::registrableDomain const):

Source/WebKit:

Use a ServiceWorker process per registrable domain instead of one per security origin. This is
more in line with PSON and avoids launching too many processes.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::createNetworkConnectionToWebProcess):
(WebKit::NetworkProcess::connectionToContextProcessWasClosed):
(WebKit::NetworkProcess::needsServerToContextConnectionForRegistrableDomain const):
(WebKit::NetworkProcess::serverToContextConnectionForRegistrableDomain):
(WebKit::NetworkProcess::createServerToContextConnection):
(WebKit::NetworkProcess::swContextConnectionMayNoLongerBeNeeded):
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:
* NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::scheduleJobInServer):
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
(WebKit::WebSWServerToContextConnection::WebSWServerToContextConnection):
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::getNetworkProcessConnection):
(WebKit::NetworkProcessProxy::establishWorkerContextConnectionToNetworkProcess):
(WebKit::NetworkProcessProxy::establishWorkerContextConnectionToNetworkProcessForExplicitSession):
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/Network/NetworkProcessProxy.messages.in:
* UIProcess/ServiceWorkerProcessProxy.cpp:
(WebKit::ServiceWorkerProcessProxy::create):
(WebKit::ServiceWorkerProcessProxy::ServiceWorkerProcessProxy):
(WebKit::ServiceWorkerProcessProxy::getLaunchOptions):
* UIProcess/ServiceWorkerProcessProxy.h:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::establishWorkerContextConnectionToNetworkProcess):
(WebKit::WebProcessPool::disconnectProcess):
(WebKit::WebProcessPool::updateProcessAssertions):
* UIProcess/WebProcessPool.h:

Tools:

Update API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242905 268f45cc-cd09-0410-ab3c-d52691b4dbfc

26 files changed:
Source/WebCore/ChangeLog
Source/WebCore/page/ClientOrigin.h
Source/WebCore/workers/service/server/SWServer.cpp
Source/WebCore/workers/service/server/SWServer.h
Source/WebCore/workers/service/server/SWServerToContextConnection.cpp
Source/WebCore/workers/service/server/SWServerToContextConnection.h
Source/WebCore/workers/service/server/SWServerWorker.cpp
Source/WebCore/workers/service/server/SWServerWorker.h
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkProcess.cpp
Source/WebKit/NetworkProcess/NetworkProcess.h
Source/WebKit/NetworkProcess/NetworkProcess.messages.in
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h
Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp
Source/WebKit/UIProcess/Network/NetworkProcessProxy.h
Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in
Source/WebKit/UIProcess/ServiceWorkerProcessProxy.cpp
Source/WebKit/UIProcess/ServiceWorkerProcessProxy.h
Source/WebKit/UIProcess/WebProcessPool.cpp
Source/WebKit/UIProcess/WebProcessPool.h
Source/WebKit/WebProcess/WebProcess.h
Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm

index 39b14f5..7671b7b 100644 (file)
@@ -1,5 +1,37 @@
 2019-03-13  Chris Dumez  <cdumez@apple.com>
 
+        Use a ServiceWorker process per registrable domain
+        https://bugs.webkit.org/show_bug.cgi?id=195649
+
+        Reviewed by Youenn Fablet.
+
+        Use a ServiceWorker process per registrable domain instead of one per security origin. This is
+        more in line with PSON and avoids launching too many processes.
+
+        * page/ClientOrigin.h:
+        (WebCore::ClientOrigin::clientRegistrableDomain const):
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::tryInstallContextData):
+        (WebCore::SWServer::serverToContextConnectionCreated):
+        (WebCore::SWServer::runServiceWorkerIfNecessary):
+        (WebCore::SWServer::markAllWorkersForRegistrableDomainAsTerminated):
+        (WebCore::SWServer::registerServiceWorkerClient):
+        (WebCore::SWServer::unregisterServiceWorkerClient):
+        (WebCore::SWServer::needsServerToContextConnectionForRegistrableDomain const):
+        * workers/service/server/SWServer.h:
+        * workers/service/server/SWServerToContextConnection.cpp:
+        (WebCore::SWServerToContextConnection::SWServerToContextConnection):
+        (WebCore::SWServerToContextConnection::~SWServerToContextConnection):
+        (WebCore::SWServerToContextConnection::connectionForRegistrableDomain):
+        * workers/service/server/SWServerToContextConnection.h:
+        (WebCore::SWServerToContextConnection::registrableDomain const):
+        * workers/service/server/SWServerWorker.cpp:
+        (WebCore::SWServerWorker::contextConnection):
+        * workers/service/server/SWServerWorker.h:
+        (WebCore::SWServerWorker::registrableDomain const):
+
+2019-03-13  Chris Dumez  <cdumez@apple.com>
+
         REGRESSION(PSON, r240660): Navigation over process boundary is flashy when using Cmd-left/right arrow to navigate
         https://bugs.webkit.org/show_bug.cgi?id=195684
         <rdar://problem/48294714>
index ebc13d5..d126fe7 100644 (file)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "RegistrableDomain.h"
 #include "SecurityOriginData.h"
 #include <wtf/HashTraits.h>
 #include <wtf/URL.h>
@@ -43,6 +44,8 @@ struct ClientOrigin {
     ClientOrigin isolatedCopy() const;
     bool isRelated(const SecurityOriginData& other) const { return topOrigin == other || clientOrigin == other; }
 
+    RegistrableDomain clientRegistrableDomain() const { return RegistrableDomain::uncheckedCreateFromHost(clientOrigin.host); }
+
     SecurityOriginData topOrigin;
     SecurityOriginData clientOrigin;
 };
index df2b8ee..4f670b3 100644 (file)
@@ -510,10 +510,10 @@ void SWServer::updateWorker(Connection&, const ServiceWorkerJobDataIdentifier& j
 
 void SWServer::tryInstallContextData(ServiceWorkerContextData&& data)
 {
-    auto securityOrigin = SecurityOriginData::fromURL(data.scriptURL);
-    auto* connection = SWServerToContextConnection::connectionForOrigin(securityOrigin);
+    RegistrableDomain registrableDomain(data.scriptURL);
+    auto* connection = SWServerToContextConnection::connectionForRegistrableDomain(registrableDomain);
     if (!connection) {
-        m_pendingContextDatas.ensure(WTFMove(securityOrigin), [] {
+        m_pendingContextDatas.ensure(WTFMove(registrableDomain), [] {
             return Vector<ServiceWorkerContextData> { };
         }).iterator->value.append(WTFMove(data));
         return;
@@ -524,11 +524,11 @@ void SWServer::tryInstallContextData(ServiceWorkerContextData&& data)
 
 void SWServer::serverToContextConnectionCreated(SWServerToContextConnection& contextConnection)
 {
-    auto pendingContextDatas = m_pendingContextDatas.take(contextConnection.securityOrigin());
+    auto pendingContextDatas = m_pendingContextDatas.take(contextConnection.registrableDomain());
     for (auto& data : pendingContextDatas)
         installContextData(data);
 
-    auto serviceWorkerRunRequests = m_serviceWorkerRunRequests.take(contextConnection.securityOrigin());
+    auto serviceWorkerRunRequests = m_serviceWorkerRunRequests.take(contextConnection.registrableDomain());
     for (auto& item : serviceWorkerRunRequests) {
         bool success = runServiceWorker(item.key);
         for (auto& callback : item.value)
@@ -580,7 +580,7 @@ void SWServer::runServiceWorkerIfNecessary(ServiceWorkerIdentifier identifier, R
     }
 
     if (!contextConnection) {
-        auto& serviceWorkerRunRequestsForOrigin = m_serviceWorkerRunRequests.ensure(worker->securityOrigin(), [] {
+        auto& serviceWorkerRunRequestsForOrigin = m_serviceWorkerRunRequests.ensure(worker->registrableDomain(), [] {
             return HashMap<ServiceWorkerIdentifier, Vector<RunServiceWorkerCallback>> { };
         }).iterator->value;
         serviceWorkerRunRequestsForOrigin.ensure(identifier, [&] {
@@ -654,11 +654,11 @@ void SWServer::terminateWorkerInternal(SWServerWorker& worker, TerminationMode m
     };
 }
 
-void SWServer::markAllWorkersForOriginAsTerminated(const SecurityOriginData& securityOrigin)
+void SWServer::markAllWorkersForRegistrableDomainAsTerminated(const RegistrableDomain& registrableDomain)
 {
     Vector<SWServerWorker*> terminatedWorkers;
     for (auto& worker : m_runningOrTerminatingWorkers.values()) {
-        if (worker->securityOrigin() == securityOrigin)
+        if (worker->registrableDomain() == registrableDomain)
             terminatedWorkers.append(worker.ptr());
     }
     for (auto& terminatedWorker : terminatedWorkers)
@@ -761,7 +761,7 @@ void SWServer::registerServiceWorkerClient(ClientOrigin&& clientOrigin, ServiceW
 
     clientIdentifiersForOrigin.terminateServiceWorkersTimer = nullptr;
 
-    m_clientsBySecurityOrigin.ensure(clientOrigin.clientOrigin, [] {
+    m_clientsByRegistrableDomain.ensure(clientOrigin.clientRegistrableDomain(), [] {
         return HashSet<ServiceWorkerClientIdentifier> { };
     }).iterator->value.add(clientIdentifier);
 
@@ -779,6 +779,8 @@ void SWServer::registerServiceWorkerClient(ClientOrigin&& clientOrigin, ServiceW
 
 void SWServer::unregisterServiceWorkerClient(const ClientOrigin& clientOrigin, ServiceWorkerClientIdentifier clientIdentifier)
 {
+    auto clientRegistrableDomain = clientOrigin.clientRegistrableDomain();
+
     bool wasRemoved = m_clientsById.remove(clientIdentifier);
     ASSERT_UNUSED(wasRemoved, wasRemoved);
 
@@ -789,9 +791,10 @@ void SWServer::unregisterServiceWorkerClient(const ClientOrigin& clientOrigin, S
     clientIdentifiers.removeFirstMatching([&] (const auto& identifier) {
         return clientIdentifier == identifier;
     });
+
     if (clientIdentifiers.isEmpty()) {
         ASSERT(!iterator->value.terminateServiceWorkersTimer);
-        iterator->value.terminateServiceWorkersTimer = std::make_unique<Timer>([clientOrigin, this] {
+        iterator->value.terminateServiceWorkersTimer = std::make_unique<Timer>([clientOrigin, clientRegistrableDomain, this] {
             Vector<SWServerWorker*> workersToTerminate;
             for (auto& worker : m_runningOrTerminatingWorkers.values()) {
                 if (worker->isRunning() && worker->origin() == clientOrigin)
@@ -800,8 +803,8 @@ void SWServer::unregisterServiceWorkerClient(const ClientOrigin& clientOrigin, S
             for (auto* worker : workersToTerminate)
                 terminateWorker(*worker);
 
-            if (!m_clientsBySecurityOrigin.contains(clientOrigin.clientOrigin)) {
-                if (auto* connection = SWServerToContextConnection::connectionForOrigin(clientOrigin.clientOrigin))
+            if (!m_clientsByRegistrableDomain.contains(clientRegistrableDomain)) {
+                if (auto* connection = SWServerToContextConnection::connectionForRegistrableDomain(clientRegistrableDomain))
                     connection->connectionMayNoLongerBeNeeded();
             }
 
@@ -810,12 +813,12 @@ void SWServer::unregisterServiceWorkerClient(const ClientOrigin& clientOrigin, S
         iterator->value.terminateServiceWorkersTimer->startOneShot(m_shouldDisableServiceWorkerProcessTerminationDelay ? 0_s : terminationDelay);
     }
 
-    auto clientsBySecurityOriginIterator = m_clientsBySecurityOrigin.find(clientOrigin.clientOrigin);
-    ASSERT(clientsBySecurityOriginIterator != m_clientsBySecurityOrigin.end());
-    auto& clientsForSecurityOrigin = clientsBySecurityOriginIterator->value;
-    clientsForSecurityOrigin.remove(clientIdentifier);
-    if (clientsForSecurityOrigin.isEmpty())
-        m_clientsBySecurityOrigin.remove(clientsBySecurityOriginIterator);
+    auto clientsByRegistrableDomainIterator = m_clientsByRegistrableDomain.find(clientRegistrableDomain);
+    ASSERT(clientsByRegistrableDomainIterator != m_clientsByRegistrableDomain.end());
+    auto& clientsForRegistrableDomain = clientsByRegistrableDomainIterator->value;
+    clientsForRegistrableDomain.remove(clientIdentifier);
+    if (clientsForRegistrableDomain.isEmpty())
+        m_clientsByRegistrableDomain.remove(clientsByRegistrableDomainIterator);
 
     auto registrationIterator = m_clientToControllingRegistration.find(clientIdentifier);
     if (registrationIterator == m_clientToControllingRegistration.end())
@@ -827,9 +830,9 @@ void SWServer::unregisterServiceWorkerClient(const ClientOrigin& clientOrigin, S
     m_clientToControllingRegistration.remove(registrationIterator);
 }
 
-bool SWServer::needsServerToContextConnectionForOrigin(const SecurityOriginData& securityOrigin) const
+bool SWServer::needsServerToContextConnectionForRegistrableDomain(const RegistrableDomain& registrableDomain) const
 {
-    return m_clientsBySecurityOrigin.contains(securityOrigin);
+    return m_clientsByRegistrableDomain.contains(registrableDomain);
 }
 
 void SWServer::resolveRegistrationReadyRequests(SWServerRegistration& registration)
index ca51b9b..0328b74 100644 (file)
@@ -144,7 +144,7 @@ public:
     String serviceWorkerClientUserAgent(const ClientOrigin&) const;
     WEBCORE_EXPORT SWServerWorker* activeWorkerFromRegistrationID(ServiceWorkerRegistrationIdentifier);
 
-    WEBCORE_EXPORT void markAllWorkersForOriginAsTerminated(const SecurityOriginData&);
+    WEBCORE_EXPORT void markAllWorkersForRegistrableDomainAsTerminated(const RegistrableDomain&);
     
     WEBCORE_EXPORT void addConnection(std::unique_ptr<Connection>&&);
     WEBCORE_EXPORT void removeConnection(SWServerConnectionIdentifier);
@@ -179,7 +179,7 @@ public:
     WEBCORE_EXPORT void getOriginsWithRegistrations(Function<void(const HashSet<SecurityOriginData>&)>&&);
 
     PAL::SessionID sessionID() const { return m_sessionID; }
-    WEBCORE_EXPORT bool needsServerToContextConnectionForOrigin(const SecurityOriginData&) const;
+    WEBCORE_EXPORT bool needsServerToContextConnectionForRegistrableDomain(const RegistrableDomain&) const;
 
     void disableServiceWorkerProcessTerminationDelay() { m_shouldDisableServiceWorkerProcessTerminationDelay = true; }
 
@@ -217,7 +217,7 @@ private:
 
     HashMap<ServiceWorkerIdentifier, Ref<SWServerWorker>> m_runningOrTerminatingWorkers;
 
-    HashMap<SecurityOriginData, HashSet<ServiceWorkerClientIdentifier>> m_clientsBySecurityOrigin;
+    HashMap<RegistrableDomain, HashSet<ServiceWorkerClientIdentifier>> m_clientsByRegistrableDomain;
     struct Clients {
         Vector<ServiceWorkerClientIdentifier> identifiers;
         std::unique_ptr<Timer> terminateServiceWorkersTimer;
@@ -229,8 +229,8 @@ private:
 
     UniqueRef<SWOriginStore> m_originStore;
     std::unique_ptr<RegistrationStore> m_registrationStore;
-    HashMap<SecurityOriginData, Vector<ServiceWorkerContextData>> m_pendingContextDatas;
-    HashMap<SecurityOriginData, HashMap<ServiceWorkerIdentifier, Vector<RunServiceWorkerCallback>>> m_serviceWorkerRunRequests;
+    HashMap<RegistrableDomain, Vector<ServiceWorkerContextData>> m_pendingContextDatas;
+    HashMap<RegistrableDomain, HashMap<ServiceWorkerIdentifier, Vector<RunServiceWorkerCallback>>> m_serviceWorkerRunRequests;
     PAL::SessionID m_sessionID;
     bool m_importCompleted { false };
     bool m_shouldDisableServiceWorkerProcessTerminationDelay { false };
index 70caf2f..459b1e2 100644 (file)
@@ -39,29 +39,29 @@ static SWServerToContextConnectionIdentifier generateServerToContextConnectionId
     return SWServerToContextConnectionIdentifier::generate();
 }
 
-static HashMap<SecurityOriginData, SWServerToContextConnection*>& allConnectionsByOrigin()
+static HashMap<RegistrableDomain, SWServerToContextConnection*>& allConnectionsByRegistrableDomain()
 {
-    static NeverDestroyed<HashMap<SecurityOriginData, SWServerToContextConnection*>> connectionsByOrigin;
+    static NeverDestroyed<HashMap<RegistrableDomain, SWServerToContextConnection*>> connectionsByOrigin;
     return connectionsByOrigin;
 }
 
-SWServerToContextConnection::SWServerToContextConnection(const SecurityOriginData& securityOrigin)
+SWServerToContextConnection::SWServerToContextConnection(const RegistrableDomain& registrableDomain)
     : m_identifier(generateServerToContextConnectionIdentifier())
-    , m_securityOrigin(securityOrigin)
+    , m_registrableDomain(registrableDomain)
 {
-    auto result = allConnectionsByOrigin().add(m_securityOrigin, this);
+    auto result = allConnectionsByRegistrableDomain().add(m_registrableDomain, this);
     ASSERT_UNUSED(result, result.isNewEntry);
 }
 
 SWServerToContextConnection::~SWServerToContextConnection()
 {
-    auto result = allConnectionsByOrigin().remove(m_securityOrigin);
+    auto result = allConnectionsByRegistrableDomain().remove(m_registrableDomain);
     ASSERT_UNUSED(result, result);
 }
 
-SWServerToContextConnection* SWServerToContextConnection::connectionForOrigin(const SecurityOriginData& securityOrigin)
+SWServerToContextConnection* SWServerToContextConnection::connectionForRegistrableDomain(const RegistrableDomain& registrableDomain)
 {
-    return allConnectionsByOrigin().get(securityOrigin);
+    return allConnectionsByRegistrableDomain().get(registrableDomain);
 }
 
 void SWServerToContextConnection::scriptContextFailedToStart(const Optional<ServiceWorkerJobDataIdentifier>& jobDataIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, const String& message)
index df4f175..2b60f1e 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
-#include "SecurityOriginData.h"
+#include "RegistrableDomain.h"
 #include "ServiceWorkerClientQueryOptions.h"
 #include "ServiceWorkerContextData.h"
 #include "ServiceWorkerIdentifier.h"
@@ -76,18 +76,18 @@ public:
     WEBCORE_EXPORT void claim(uint64_t requestIdentifier, ServiceWorkerIdentifier);
     WEBCORE_EXPORT void setScriptResource(ServiceWorkerIdentifier, URL&& scriptURL, String&& script, URL&& responseURL, String&& mimeType);
 
-    static SWServerToContextConnection* connectionForOrigin(const SecurityOriginData&);
+    static SWServerToContextConnection* connectionForRegistrableDomain(const RegistrableDomain&);
 
-    const SecurityOriginData& securityOrigin() const { return m_securityOrigin; }
+    const RegistrableDomain& registrableDomain() const { return m_registrableDomain; }
 
     virtual void connectionMayNoLongerBeNeeded() = 0;
 
 protected:
-    WEBCORE_EXPORT explicit SWServerToContextConnection(const SecurityOriginData&);
+    WEBCORE_EXPORT explicit SWServerToContextConnection(const RegistrableDomain&);
 
 private:
     SWServerToContextConnectionIdentifier m_identifier;
-    SecurityOriginData m_securityOrigin;
+    RegistrableDomain m_registrableDomain;
 };
 
 } // namespace WebCore
index 23370d2..2a4d5b0 100644 (file)
@@ -52,6 +52,7 @@ SWServerWorker::SWServerWorker(SWServer& server, SWServerRegistration& registrat
     , m_script(script)
     , m_contentSecurityPolicy(contentSecurityPolicy)
     , m_referrerPolicy(WTFMove(referrerPolicy))
+    , m_registrableDomain(m_data.scriptURL)
     , m_scriptResourceMap(WTFMove(scriptResourceMap))
 {
     m_data.scriptURL.removeFragmentIdentifier();
@@ -92,14 +93,9 @@ const ClientOrigin& SWServerWorker::origin() const
     return *m_origin;
 }
 
-const SecurityOriginData& SWServerWorker::securityOrigin() const
-{
-    return origin().clientOrigin;
-}
-
 SWServerToContextConnection* SWServerWorker::contextConnection()
 {
-    return SWServerToContextConnection::connectionForOrigin(securityOrigin());
+    return SWServerToContextConnection::connectionForRegistrableDomain(registrableDomain());
 }
 
 void SWServerWorker::scriptContextFailedToStart(const Optional<ServiceWorkerJobDataIdentifier>& jobDataIdentifier, const String& message)
index e2f744b..900a590 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(SERVICE_WORKER)
 
 #include "ContentSecurityPolicyResponseHeaders.h"
+#include "RegistrableDomain.h"
 #include "ServiceWorkerClientData.h"
 #include "ServiceWorkerContextData.h"
 #include "ServiceWorkerData.h"
@@ -106,7 +107,7 @@ public:
     ServiceWorkerContextData contextData() const;
 
     const ClientOrigin& origin() const;
-    WEBCORE_EXPORT const SecurityOriginData& securityOrigin() const;
+    const RegistrableDomain& registrableDomain() const { return m_registrableDomain; }
 
     WEBCORE_EXPORT SWServerToContextConnection* contextConnection();
     String userAgent() const;
@@ -125,6 +126,7 @@ private:
     bool m_hasPendingEvents { false };
     State m_state { State::NotRunning };
     mutable Optional<ClientOrigin> m_origin;
+    RegistrableDomain m_registrableDomain;
     bool m_isSkipWaitingFlagSet { false };
     Vector<Function<void(bool)>> m_whenActivatedHandlers;
     HashMap<URL, ServiceWorkerContextData::ImportedScript> m_scriptResourceMap;
index 89afea1..4fa03c6 100644 (file)
@@ -1,5 +1,46 @@
 2019-03-13  Chris Dumez  <cdumez@apple.com>
 
+        Use a ServiceWorker process per registrable domain
+        https://bugs.webkit.org/show_bug.cgi?id=195649
+
+        Reviewed by Youenn Fablet.
+
+        Use a ServiceWorker process per registrable domain instead of one per security origin. This is
+        more in line with PSON and avoids launching too many processes.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::createNetworkConnectionToWebProcess):
+        (WebKit::NetworkProcess::connectionToContextProcessWasClosed):
+        (WebKit::NetworkProcess::needsServerToContextConnectionForRegistrableDomain const):
+        (WebKit::NetworkProcess::serverToContextConnectionForRegistrableDomain):
+        (WebKit::NetworkProcess::createServerToContextConnection):
+        (WebKit::NetworkProcess::swContextConnectionMayNoLongerBeNeeded):
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+        * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::scheduleJobInServer):
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+        (WebKit::WebSWServerToContextConnection::WebSWServerToContextConnection):
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::getNetworkProcessConnection):
+        (WebKit::NetworkProcessProxy::establishWorkerContextConnectionToNetworkProcess):
+        (WebKit::NetworkProcessProxy::establishWorkerContextConnectionToNetworkProcessForExplicitSession):
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/Network/NetworkProcessProxy.messages.in:
+        * UIProcess/ServiceWorkerProcessProxy.cpp:
+        (WebKit::ServiceWorkerProcessProxy::create):
+        (WebKit::ServiceWorkerProcessProxy::ServiceWorkerProcessProxy):
+        (WebKit::ServiceWorkerProcessProxy::getLaunchOptions):
+        * UIProcess/ServiceWorkerProcessProxy.h:
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::establishWorkerContextConnectionToNetworkProcess):
+        (WebKit::WebProcessPool::disconnectProcess):
+        (WebKit::WebProcessPool::updateProcessAssertions):
+        * UIProcess/WebProcessPool.h:
+
+2019-03-13  Chris Dumez  <cdumez@apple.com>
+
         REGRESSION(PSON, r240660): Navigation over process boundary is flashy when using Cmd-left/right arrow to navigate
         https://bugs.webkit.org/show_bug.cgi?id=195684
         <rdar://problem/48294714>
index d13dfca..937f284 100644 (file)
@@ -377,7 +377,7 @@ void NetworkProcess::initializeConnection(IPC::Connection* connection)
         supplement->initializeConnection(connection);
 }
 
-void NetworkProcess::createNetworkConnectionToWebProcess(bool isServiceWorkerProcess, WebCore::SecurityOriginData&& securityOrigin)
+void NetworkProcess::createNetworkConnectionToWebProcess(bool isServiceWorkerProcess, WebCore::RegistrableDomain&& registrableDomain)
 {
 #if USE(UNIX_DOMAIN_SOCKETS)
     IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
@@ -429,8 +429,8 @@ void NetworkProcess::createNetworkConnectionToWebProcess(bool isServiceWorkerPro
     if (isServiceWorkerProcess && !m_webProcessConnections.isEmpty()) {
         ASSERT(parentProcessHasServiceWorkerEntitlement());
         ASSERT(m_waitingForServerToContextProcessConnection);
-        auto contextConnection = WebSWServerToContextConnection::create(*this, securityOrigin, m_webProcessConnections.last()->connection());
-        auto addResult = m_serverToContextConnections.add(WTFMove(securityOrigin), contextConnection.copyRef());
+        auto contextConnection = WebSWServerToContextConnection::create(*this, registrableDomain, m_webProcessConnections.last()->connection());
+        auto addResult = m_serverToContextConnections.add(WTFMove(registrableDomain), contextConnection.copyRef());
         ASSERT_UNUSED(addResult, addResult.isNewEntry);
 
         m_waitingForServerToContextProcessConnection = false;
@@ -440,7 +440,7 @@ void NetworkProcess::createNetworkConnectionToWebProcess(bool isServiceWorkerPro
     }
 #else
     UNUSED_PARAM(isServiceWorkerProcess);
-    UNUSED_PARAM(securityOrigin);
+    UNUSED_PARAM(registrableDomain);
 #endif
 }
 
@@ -2160,24 +2160,24 @@ WebSWServerToContextConnection* NetworkProcess::connectionToContextProcessFromIP
 
 void NetworkProcess::connectionToContextProcessWasClosed(Ref<WebSWServerToContextConnection>&& serverToContextConnection)
 {
-    auto& securityOrigin = serverToContextConnection->securityOrigin();
+    auto& registrableDomain = serverToContextConnection->registrableDomain();
     
     serverToContextConnection->connectionClosed();
-    m_serverToContextConnections.remove(securityOrigin);
+    m_serverToContextConnections.remove(registrableDomain);
     
     for (auto& swServer : m_swServers.values())
-        swServer->markAllWorkersForOriginAsTerminated(securityOrigin);
+        swServer->markAllWorkersForRegistrableDomainAsTerminated(registrableDomain);
     
-    if (needsServerToContextConnectionForOrigin(securityOrigin)) {
+    if (needsServerToContextConnectionForRegistrableDomain(registrableDomain)) {
         RELEASE_LOG(ServiceWorker, "Connection to service worker process was closed but is still needed, relaunching it");
-        createServerToContextConnection(securityOrigin, WTF::nullopt);
+        createServerToContextConnection(registrableDomain, WTF::nullopt);
     }
 }
 
-bool NetworkProcess::needsServerToContextConnectionForOrigin(const SecurityOriginData& securityOrigin) const
+bool NetworkProcess::needsServerToContextConnectionForRegistrableDomain(const RegistrableDomain& registrableDomain) const
 {
     return WTF::anyOf(m_swServers.values(), [&](auto& swServer) {
-        return swServer->needsServerToContextConnectionForOrigin(securityOrigin);
+        return swServer->needsServerToContextConnectionForRegistrableDomain(registrableDomain);
     });
 }
 
@@ -2213,21 +2213,21 @@ WebSWOriginStore* NetworkProcess::existingSWOriginStoreForSession(PAL::SessionID
     return &static_cast<WebSWOriginStore&>(swServer->originStore());
 }
 
-WebSWServerToContextConnection* NetworkProcess::serverToContextConnectionForOrigin(const SecurityOriginData& securityOrigin)
+WebSWServerToContextConnection* NetworkProcess::serverToContextConnectionForRegistrableDomain(const RegistrableDomain& registrableDomain)
 {
-    return m_serverToContextConnections.get(securityOrigin);
+    return m_serverToContextConnections.get(registrableDomain);
 }
 
-void NetworkProcess::createServerToContextConnection(const SecurityOriginData& securityOrigin, Optional<PAL::SessionID> sessionID)
+void NetworkProcess::createServerToContextConnection(const RegistrableDomain& registrableDomain, Optional<PAL::SessionID> sessionID)
 {
     if (m_waitingForServerToContextProcessConnection)
         return;
     
     m_waitingForServerToContextProcessConnection = true;
     if (sessionID)
-        parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcessForExplicitSession(securityOrigin, *sessionID), 0);
+        parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcessForExplicitSession(registrableDomain, *sessionID), 0);
     else
-        parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcess(securityOrigin), 0);
+        parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcess(registrableDomain), 0);
 }
 
 void NetworkProcess::postMessageToServiceWorkerClient(const ServiceWorkerClientIdentifier& destinationIdentifier, MessageWithMessagePorts&& message, ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin)
@@ -2260,18 +2260,18 @@ void NetworkProcess::unregisterSWServerConnection(WebSWServerConnection& connect
 
 void NetworkProcess::swContextConnectionMayNoLongerBeNeeded(WebSWServerToContextConnection& serverToContextConnection)
 {
-    auto& securityOrigin = serverToContextConnection.securityOrigin();
-    if (needsServerToContextConnectionForOrigin(securityOrigin))
+    auto& registrableDomain = serverToContextConnection.registrableDomain();
+    if (needsServerToContextConnectionForRegistrableDomain(registrableDomain))
         return;
     
     RELEASE_LOG(ServiceWorker, "Service worker process is no longer needed, terminating it");
     serverToContextConnection.terminate();
     
     for (auto& swServer : m_swServers.values())
-        swServer->markAllWorkersForOriginAsTerminated(securityOrigin);
+        swServer->markAllWorkersForRegistrableDomainAsTerminated(registrableDomain);
     
     serverToContextConnection.connectionClosed();
-    m_serverToContextConnections.remove(securityOrigin);
+    m_serverToContextConnections.remove(registrableDomain);
 }
 
 void NetworkProcess::disableServiceWorkerProcessTerminationDelay()
index 8b94bd7..600f1c1 100644 (file)
@@ -287,8 +287,8 @@ public:
     void didReceiveNetworkProcessMessage(IPC::Connection&, IPC::Decoder&);
 
 #if ENABLE(SERVICE_WORKER)
-    WebSWServerToContextConnection* serverToContextConnectionForOrigin(const WebCore::SecurityOriginData&);
-    void createServerToContextConnection(const WebCore::SecurityOriginData&, Optional<PAL::SessionID>);
+    WebSWServerToContextConnection* serverToContextConnectionForRegistrableDomain(const WebCore::RegistrableDomain&);
+    void createServerToContextConnection(const WebCore::RegistrableDomain&, Optional<PAL::SessionID>);
     
     WebCore::SWServer& swServerForSession(PAL::SessionID);
     void registerSWServerConnection(WebSWServerConnection&);
@@ -370,7 +370,7 @@ private:
     // Message Handlers
     void didReceiveSyncNetworkProcessMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&);
     void initializeNetworkProcess(NetworkProcessCreationParameters&&);
-    void createNetworkConnectionToWebProcess(bool isServiceWorkerProcess, WebCore::SecurityOriginData&&);
+    void createNetworkConnectionToWebProcess(bool isServiceWorkerProcess, WebCore::RegistrableDomain&&);
 
     void fetchWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, uint64_t callbackID);
     void deleteWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, WallTime modifiedSince, uint64_t callbackID);
@@ -442,7 +442,7 @@ private:
     
     WebSWOriginStore& swOriginStoreForSession(PAL::SessionID);
     WebSWOriginStore* existingSWOriginStoreForSession(PAL::SessionID) const;
-    bool needsServerToContextConnectionForOrigin(const WebCore::SecurityOriginData&) const;
+    bool needsServerToContextConnectionForRegistrableDomain(const WebCore::RegistrableDomain&) const;
 
     void addServiceWorkerSession(PAL::SessionID, String& serviceWorkerRegistrationDirectory, const SandboxExtension::Handle&);
 #endif
@@ -511,7 +511,7 @@ private:
     Lock m_storageTaskMutex;
     
 #if ENABLE(SERVICE_WORKER)
-    HashMap<WebCore::SecurityOriginData, RefPtr<WebSWServerToContextConnection>> m_serverToContextConnections;
+    HashMap<WebCore::RegistrableDomain, RefPtr<WebSWServerToContextConnection>> m_serverToContextConnections;
     bool m_waitingForServerToContextProcessConnection { false };
     bool m_shouldDisableServiceWorkerProcessTerminationDelay { false };
     HashMap<PAL::SessionID, String> m_swDatabasePaths;
index ee68086..e61524c 100644 (file)
@@ -25,7 +25,7 @@ messages -> NetworkProcess LegacyReceiver {
     InitializeNetworkProcess(struct WebKit::NetworkProcessCreationParameters processCreationParameters)
 
     # Creates a connection for communication with a WebProcess
-    CreateNetworkConnectionToWebProcess(bool isServiceWorkerProcess, struct WebCore::SecurityOriginData origin)
+    CreateNetworkConnectionToWebProcess(bool isServiceWorkerProcess, WebCore::RegistrableDomain registrableDomain)
 
 #if USE(SOUP)
     SetIgnoreTLSErrors(bool ignoreTLSErrors)
index a49535b..88d5176 100644 (file)
@@ -180,7 +180,7 @@ void WebSWServerConnection::startFetch(ServiceWorkerRegistrationIdentifier servi
         }
 
         if (!worker->contextConnection())
-            m_networkProcess->createServerToContextConnection(worker->securityOrigin(), server().sessionID());
+            m_networkProcess->createServerToContextConnection(worker->registrableDomain(), server().sessionID());
 
         server().runServiceWorkerIfNecessary(serviceWorkerIdentifier, [weakThis = WTFMove(weakThis), this, fetchIdentifier, serviceWorkerIdentifier, request = WTFMove(request), options = WTFMove(options), formData = WTFMove(formData), referrer = WTFMove(referrer)](auto* contextConnection) {
             if (!weakThis)
@@ -223,7 +223,7 @@ void WebSWServerConnection::postMessageToServiceWorker(ServiceWorkerIdentifier d
         return;
 
     if (!destinationWorker->contextConnection())
-        m_networkProcess->createServerToContextConnection(destinationWorker->securityOrigin(), server().sessionID());
+        m_networkProcess->createServerToContextConnection(destinationWorker->registrableDomain(), server().sessionID());
 
     // It's possible this specific worker cannot be re-run (e.g. its registration has been removed)
     server().runServiceWorkerIfNecessary(destinationIdentifier, [destinationIdentifier, message = WTFMove(message), sourceData = WTFMove(*sourceData)](auto* contextConnection) mutable {
@@ -234,9 +234,9 @@ void WebSWServerConnection::postMessageToServiceWorker(ServiceWorkerIdentifier d
 
 void WebSWServerConnection::scheduleJobInServer(ServiceWorkerJobData&& jobData)
 {
-    auto securityOrigin = SecurityOriginData::fromURL(jobData.scriptURL);
-    if (!m_networkProcess->serverToContextConnectionForOrigin(securityOrigin))
-        m_networkProcess->createServerToContextConnection(securityOrigin, server().sessionID());
+    RegistrableDomain registrableDomain(jobData.scriptURL);
+    if (!m_networkProcess->serverToContextConnectionForRegistrableDomain(registrableDomain))
+        m_networkProcess->createServerToContextConnection(registrableDomain, server().sessionID());
 
     SWSERVERCONNECTION_RELEASE_LOG_IF_ALLOWED("Scheduling ServiceWorker job %s in server", jobData.identifier().loggingString().utf8().data());
     ASSERT(identifier() == jobData.connectionIdentifier());
index ea043a9..3752e56 100644 (file)
@@ -39,8 +39,8 @@
 namespace WebKit {
 using namespace WebCore;
 
-WebSWServerToContextConnection::WebSWServerToContextConnection(NetworkProcess& networkProcess, const SecurityOriginData& securityOrigin, Ref<IPC::Connection>&& connection)
-    : SWServerToContextConnection(securityOrigin)
+WebSWServerToContextConnection::WebSWServerToContextConnection(NetworkProcess& networkProcess, const RegistrableDomain& registrableDomain, Ref<IPC::Connection>&& connection)
+    : SWServerToContextConnection(registrableDomain)
     , m_ipcConnection(WTFMove(connection))
     , m_networkProcess(networkProcess)
 {
index 255d27c..82905ea 100644 (file)
@@ -72,7 +72,7 @@ public:
     void didReceiveFetchTaskMessage(IPC::Connection&, IPC::Decoder&);
 
 private:
-    WebSWServerToContextConnection(NetworkProcess&, const WebCore::SecurityOriginData&, Ref<IPC::Connection>&&);
+    WebSWServerToContextConnection(NetworkProcess&, const WebCore::RegistrableDomain&, Ref<IPC::Connection>&&);
     ~WebSWServerToContextConnection();
 
     // IPC::MessageSender
index d60d8ee..1b46937 100644 (file)
@@ -136,15 +136,15 @@ void NetworkProcessProxy::getNetworkProcessConnection(WebProcessProxy& webProces
     }
 
     bool isServiceWorkerProcess = false;
-    SecurityOriginData securityOrigin;
+    RegistrableDomain registrableDomain;
 #if ENABLE(SERVICE_WORKER)
     if (is<ServiceWorkerProcessProxy>(webProcessProxy)) {
         isServiceWorkerProcess = true;
-        securityOrigin = downcast<ServiceWorkerProcessProxy>(webProcessProxy).securityOrigin();
+        registrableDomain = downcast<ServiceWorkerProcessProxy>(webProcessProxy).registrableDomain();
     }
 #endif
 
-    connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess(isServiceWorkerProcess, securityOrigin), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
+    connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess(isServiceWorkerProcess, registrableDomain), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 }
 
 DownloadProxy* NetworkProcessProxy::createDownloadProxy(const ResourceRequest& resourceRequest)
@@ -1178,14 +1178,14 @@ void NetworkProcessProxy::getSandboxExtensionsForBlobFiles(const Vector<String>&
 #endif
 
 #if ENABLE(SERVICE_WORKER)
-void NetworkProcessProxy::establishWorkerContextConnectionToNetworkProcess(SecurityOriginData&& origin)
+void NetworkProcessProxy::establishWorkerContextConnectionToNetworkProcess(RegistrableDomain&& registrableDomain)
 {
-    m_processPool.establishWorkerContextConnectionToNetworkProcess(*this, WTFMove(origin), WTF::nullopt);
+    m_processPool.establishWorkerContextConnectionToNetworkProcess(*this, WTFMove(registrableDomain), WTF::nullopt);
 }
 
-void NetworkProcessProxy::establishWorkerContextConnectionToNetworkProcessForExplicitSession(SecurityOriginData&& origin, PAL::SessionID sessionID)
+void NetworkProcessProxy::establishWorkerContextConnectionToNetworkProcessForExplicitSession(RegistrableDomain&& registrableDomain, PAL::SessionID sessionID)
 {
-    m_processPool.establishWorkerContextConnectionToNetworkProcess(*this, WTFMove(origin), sessionID);
+    m_processPool.establishWorkerContextConnectionToNetworkProcess(*this, WTFMove(registrableDomain), sessionID);
 }
 #endif
 
index b2fbca5..7fe54cb 100644 (file)
@@ -228,8 +228,8 @@ private:
 #endif
 
 #if ENABLE(SERVICE_WORKER)
-    void establishWorkerContextConnectionToNetworkProcess(WebCore::SecurityOriginData&&);
-    void establishWorkerContextConnectionToNetworkProcessForExplicitSession(WebCore::SecurityOriginData&&, PAL::SessionID);
+    void establishWorkerContextConnectionToNetworkProcess(WebCore::RegistrableDomain&&);
+    void establishWorkerContextConnectionToNetworkProcessForExplicitSession(WebCore::RegistrableDomain&&, PAL::SessionID);
 #endif
 
     void requestStorageSpace(PAL::SessionID, const WebCore::ClientOrigin&, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t> quota)>&&);
index 499ac87..563889b 100644 (file)
@@ -60,8 +60,8 @@ messages -> NetworkProcessProxy LegacyReceiver {
 #endif
 
 #if ENABLE(SERVICE_WORKER)
-    EstablishWorkerContextConnectionToNetworkProcess(struct WebCore::SecurityOriginData origin)
-    EstablishWorkerContextConnectionToNetworkProcessForExplicitSession(struct WebCore::SecurityOriginData origin, PAL::SessionID explicitSession)
+    EstablishWorkerContextConnectionToNetworkProcess(WebCore::RegistrableDomain registrableDomain)
+    EstablishWorkerContextConnectionToNetworkProcessForExplicitSession(WebCore::RegistrableDomain registrableDomain, PAL::SessionID explicitSession)
 #endif
 
     RequestStorageSpace(PAL::SessionID sessionID, struct WebCore::ClientOrigin origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired) -> (Optional<uint64_t> newQuota) Async
index 5bcda63..fa8c490 100644 (file)
 namespace WebKit {
 using namespace WebCore;
 
-Ref<ServiceWorkerProcessProxy> ServiceWorkerProcessProxy::create(WebProcessPool& pool, const SecurityOriginData& securityOrigin, WebsiteDataStore& store)
+Ref<ServiceWorkerProcessProxy> ServiceWorkerProcessProxy::create(WebProcessPool& pool, const RegistrableDomain& registrableDomain, WebsiteDataStore& store)
 {
-    auto proxy = adoptRef(*new ServiceWorkerProcessProxy { pool, securityOrigin, store });
+    auto proxy = adoptRef(*new ServiceWorkerProcessProxy { pool, registrableDomain, store });
     proxy->connect();
     return proxy;
 }
 
-ServiceWorkerProcessProxy::ServiceWorkerProcessProxy(WebProcessPool& pool, const SecurityOriginData& securityOrigin, WebsiteDataStore& store)
+ServiceWorkerProcessProxy::ServiceWorkerProcessProxy(WebProcessPool& pool, const RegistrableDomain& registrableDomain, WebsiteDataStore& store)
     : WebProcessProxy { pool, store, IsPrewarmed::No }
-    , m_securityOrigin(securityOrigin)
+    , m_registrableDomain(registrableDomain)
     , m_serviceWorkerPageID(generatePageID())
 {
 }
@@ -72,7 +72,7 @@ void ServiceWorkerProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions&
     WebProcessProxy::getLaunchOptions(launchOptions);
 
     launchOptions.extraInitializationData.add("service-worker-process"_s, "1"_s);
-    launchOptions.extraInitializationData.add("security-origin"_s, securityOrigin().toString());
+    launchOptions.extraInitializationData.add("registrable-domain"_s, registrableDomain().string());
 }
 
 void ServiceWorkerProcessProxy::start(const WebPreferencesStore& store, Optional<PAL::SessionID> initialSessionID)
index 783ce09..6f759e9 100644 (file)
@@ -28,7 +28,7 @@
 #if ENABLE(SERVICE_WORKER)
 
 #include "WebProcessProxy.h"
-#include <WebCore/SecurityOriginData.h>
+#include <WebCore/RegistrableDomain.h>
 
 namespace WebKit {
 class AuthenticationChallengeProxy;
@@ -36,7 +36,7 @@ struct WebPreferencesStore;
 
 class ServiceWorkerProcessProxy final : public WebProcessProxy {
 public:
-    static Ref<ServiceWorkerProcessProxy> create(WebProcessPool&, const WebCore::SecurityOriginData&, WebsiteDataStore&);
+    static Ref<ServiceWorkerProcessProxy> create(WebProcessPool&, const WebCore::RegistrableDomain&, WebsiteDataStore&);
     ~ServiceWorkerProcessProxy();
 
     static bool hasRegisteredServiceWorkers(const String& serviceWorkerDirectory);
@@ -47,7 +47,7 @@ public:
     void setUserAgent(const String&);
     void updatePreferencesStore(const WebPreferencesStore&);
 
-    const WebCore::SecurityOriginData& securityOrigin() { return m_securityOrigin; }
+    const WebCore::RegistrableDomain& registrableDomain() { return m_registrableDomain; }
     uint64_t pageID() const { return m_serviceWorkerPageID; }
 
 private:
@@ -59,9 +59,9 @@ private:
 
     bool isServiceWorkerProcess() const final { return true; }
 
-    ServiceWorkerProcessProxy(WebProcessPool&, const WebCore::SecurityOriginData&, WebsiteDataStore&);
+    ServiceWorkerProcessProxy(WebProcessPool&, const WebCore::RegistrableDomain&, WebsiteDataStore&);
 
-    WebCore::SecurityOriginData m_securityOrigin;
+    WebCore::RegistrableDomain m_registrableDomain;
     uint64_t m_serviceWorkerPageID { 0 };
 };
 
index 44eea45..8c139d4 100644 (file)
@@ -666,11 +666,11 @@ void WebProcessPool::getNetworkProcessConnection(WebProcessProxy& webProcessProx
 }
 
 #if ENABLE(SERVICE_WORKER)
-void WebProcessPool::establishWorkerContextConnectionToNetworkProcess(NetworkProcessProxy& proxy, SecurityOriginData&& securityOrigin, Optional<PAL::SessionID> sessionID)
+void WebProcessPool::establishWorkerContextConnectionToNetworkProcess(NetworkProcessProxy& proxy, RegistrableDomain&& registrableDomain, Optional<PAL::SessionID> sessionID)
 {
     ASSERT_UNUSED(proxy, &proxy == m_networkProcess.get());
 
-    if (m_serviceWorkerProcesses.contains(securityOrigin))
+    if (m_serviceWorkerProcesses.contains(registrableDomain))
         return;
 
     m_mayHaveRegisteredServiceWorkers.clear();
@@ -688,8 +688,8 @@ void WebProcessPool::establishWorkerContextConnectionToNetworkProcess(NetworkPro
     if (m_serviceWorkerProcesses.isEmpty())
         sendToAllProcesses(Messages::WebProcess::RegisterServiceWorkerClients { });
 
-    auto serviceWorkerProcessProxy = ServiceWorkerProcessProxy::create(*this, securityOrigin, *websiteDataStore);
-    m_serviceWorkerProcesses.add(WTFMove(securityOrigin), serviceWorkerProcessProxy.ptr());
+    auto serviceWorkerProcessProxy = ServiceWorkerProcessProxy::create(*this, registrableDomain, *websiteDataStore);
+    m_serviceWorkerProcesses.add(WTFMove(registrableDomain), serviceWorkerProcessProxy.ptr());
 
     updateProcessAssertions();
     initializeNewWebProcess(serviceWorkerProcessProxy, *websiteDataStore);
@@ -1115,7 +1115,7 @@ void WebProcessPool::disconnectProcess(WebProcessProxy* process)
 
 #if ENABLE(SERVICE_WORKER)
     if (is<ServiceWorkerProcessProxy>(*process)) {
-        auto* removedProcess = m_serviceWorkerProcesses.take(downcast<ServiceWorkerProcessProxy>(*process).securityOrigin());
+        auto* removedProcess = m_serviceWorkerProcesses.take(downcast<ServiceWorkerProcessProxy>(*process).registrableDomain());
         ASSERT_UNUSED(removedProcess, removedProcess == process);
         updateProcessAssertions();
     }
@@ -2071,9 +2071,9 @@ void WebProcessPool::updateProcessAssertions()
         if (!m_serviceWorkerProcesses.isEmpty() && m_foregroundWebProcessCounter.value()) {
             // FIXME: We can do better than this once we have process per origin.
             for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values()) {
-                auto& securityOrigin = serviceWorkerProcess->securityOrigin();
-                if (!m_foregroundTokensForServiceWorkerProcesses.contains(securityOrigin))
-                    m_foregroundTokensForServiceWorkerProcesses.add(securityOrigin, serviceWorkerProcess->throttler().foregroundActivityToken());
+                auto& registrableDomain = serviceWorkerProcess->registrableDomain();
+                if (!m_foregroundTokensForServiceWorkerProcesses.contains(registrableDomain))
+                    m_foregroundTokensForServiceWorkerProcesses.add(registrableDomain, serviceWorkerProcess->throttler().foregroundActivityToken());
             }
             m_backgroundTokensForServiceWorkerProcesses.clear();
             return;
@@ -2081,9 +2081,9 @@ void WebProcessPool::updateProcessAssertions()
         if (!m_serviceWorkerProcesses.isEmpty() && m_backgroundWebProcessCounter.value()) {
             // FIXME: We can do better than this once we have process per origin.
             for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values()) {
-                auto& securityOrigin = serviceWorkerProcess->securityOrigin();
-                if (!m_backgroundTokensForServiceWorkerProcesses.contains(securityOrigin))
-                    m_backgroundTokensForServiceWorkerProcesses.add(securityOrigin, serviceWorkerProcess->throttler().backgroundActivityToken());
+                auto& registrableDomain = serviceWorkerProcess->registrableDomain();
+                if (!m_backgroundTokensForServiceWorkerProcesses.contains(registrableDomain))
+                    m_backgroundTokensForServiceWorkerProcesses.add(registrableDomain, serviceWorkerProcess->throttler().backgroundActivityToken());
             }
             m_foregroundTokensForServiceWorkerProcesses.clear();
             return;
index ec34718..2bec2fc 100644 (file)
@@ -357,9 +357,9 @@ public:
     void getNetworkProcessConnection(WebProcessProxy&, Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply&&);
 
 #if ENABLE(SERVICE_WORKER)
-    void establishWorkerContextConnectionToNetworkProcess(NetworkProcessProxy&, WebCore::SecurityOriginData&&, Optional<PAL::SessionID>);
+    void establishWorkerContextConnectionToNetworkProcess(NetworkProcessProxy&, WebCore::RegistrableDomain&&, Optional<PAL::SessionID>);
     ServiceWorkerProcessProxy* serviceWorkerProcessProxyFromPageID(uint64_t pageID) const;
-    const HashMap<WebCore::SecurityOriginData, ServiceWorkerProcessProxy*>& serviceWorkerProxies() const { return m_serviceWorkerProcesses; }
+    const HashMap<WebCore::RegistrableDomain, ServiceWorkerProcessProxy*>& serviceWorkerProxies() const { return m_serviceWorkerProcesses; }
     void setAllowsAnySSLCertificateForServiceWorker(bool allows) { m_allowsAnySSLCertificateForServiceWorker = allows; }
     bool allowsAnySSLCertificateForServiceWorker() const { return m_allowsAnySSLCertificateForServiceWorker; }
     void updateServiceWorkerUserAgent(const String& userAgent);
@@ -589,7 +589,7 @@ private:
 
     WebProcessProxy* m_processWithPageCache { nullptr };
 #if ENABLE(SERVICE_WORKER)
-    HashMap<WebCore::SecurityOriginData, ServiceWorkerProcessProxy*> m_serviceWorkerProcesses;
+    HashMap<WebCore::RegistrableDomain, ServiceWorkerProcessProxy*> m_serviceWorkerProcesses;
     bool m_waitingForWorkerContextProcessConnection { false };
     bool m_allowsAnySSLCertificateForServiceWorker { false };
     bool m_shouldDisableServiceWorkerProcessTerminationDelay { false };
@@ -750,8 +750,8 @@ private:
     ProcessThrottler::ForegroundActivityToken m_foregroundTokenForNetworkProcess;
     ProcessThrottler::BackgroundActivityToken m_backgroundTokenForNetworkProcess;
 #if ENABLE(SERVICE_WORKER)
-    HashMap<WebCore::SecurityOriginData, ProcessThrottler::ForegroundActivityToken> m_foregroundTokensForServiceWorkerProcesses;
-    HashMap<WebCore::SecurityOriginData, ProcessThrottler::BackgroundActivityToken> m_backgroundTokensForServiceWorkerProcesses;
+    HashMap<WebCore::RegistrableDomain, ProcessThrottler::ForegroundActivityToken> m_foregroundTokensForServiceWorkerProcesses;
+    HashMap<WebCore::RegistrableDomain, ProcessThrottler::BackgroundActivityToken> m_backgroundTokensForServiceWorkerProcesses;
 #endif
 #endif
 
index 68d57e4..f17584a 100644 (file)
@@ -37,6 +37,7 @@
 #include "ViewUpdateDispatcher.h"
 #include "WebInspectorInterruptDispatcher.h"
 #include <WebCore/ActivityState.h>
+#include <WebCore/RegistrableDomain.h>
 #if PLATFORM(MAC)
 #include <WebCore/ScreenProperties.h>
 #endif
@@ -500,7 +501,7 @@ private:
     enum class ProcessType { Inspector, ServiceWorker, PrewarmedWebContent, CachedWebContent, WebContent };
     ProcessType m_processType { ProcessType::WebContent };
     String m_uiProcessName;
-    String m_securityOrigin;
+    WebCore::RegistrableDomain m_registrableDomain;
 #endif
 
     HashMap<WebCore::UserGestureToken *, uint64_t> m_userGestureTokens;
index 838fe6e..e60fdad 100644 (file)
@@ -239,7 +239,7 @@ void WebProcess::updateProcessName()
         applicationName = [NSString stringWithFormat:WEB_UI_STRING("%@ Web Inspector", "Visible name of Web Inspector's web process. The argument is the application name."), (NSString *)m_uiProcessName];
         break;
     case ProcessType::ServiceWorker:
-        applicationName = [NSString stringWithFormat:WEB_UI_STRING("%@ Service Worker (%@)", "Visible name of Service Worker process. The argument is the application name."), (NSString *)m_uiProcessName, (NSString *)m_securityOrigin];
+        applicationName = [NSString stringWithFormat:WEB_UI_STRING("%@ Service Worker (%@)", "Visible name of Service Worker process. The argument is the application name."), (NSString *)m_uiProcessName, (NSString *)m_registrableDomain.string()];
         break;
     case ProcessType::PrewarmedWebContent:
         applicationName = [NSString stringWithFormat:WEB_UI_STRING("%@ Web Content (Prewarmed)", "Visible name of the web process. The argument is the application name."), (NSString *)m_uiProcessName];
@@ -392,7 +392,7 @@ void WebProcess::platformInitializeProcess(const AuxiliaryProcessInitializationP
 #if ENABLE(SERVICE_WORKER)
     else if (parameters.extraInitializationData.get("service-worker-process"_s) == "1") {
         m_processType = ProcessType::ServiceWorker;
-        m_securityOrigin = parameters.extraInitializationData.get("security-origin"_s);
+        m_registrableDomain = RegistrableDomain::uncheckedCreateFromRegistrableDomainString(parameters.extraInitializationData.get("registrable-domain"_s));
     }
 #endif
     else if (parameters.extraInitializationData.get("is-prewarmed"_s) == "1")
index b2434d7..2acffdb 100644 (file)
@@ -1,5 +1,16 @@
 2019-03-13  Chris Dumez  <cdumez@apple.com>
 
+        Use a ServiceWorker process per registrable domain
+        https://bugs.webkit.org/show_bug.cgi?id=195649
+
+        Reviewed by Youenn Fablet.
+
+        Update API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
+
+2019-03-13  Chris Dumez  <cdumez@apple.com>
+
         REGRESSION(PSON, r240660): Navigation over process boundary is flashy when using Cmd-left/right arrow to navigate
         https://bugs.webkit.org/show_bug.cgi?id=195684
         <rdar://problem/48294714>
index fe5c3ed..9ac8869 100644 (file)
@@ -1450,7 +1450,7 @@ void waitUntilServiceWorkerProcessCount(WKProcessPool *processPool, unsigned pro
     } while (true);
 }
 
-TEST(ServiceWorkers, ProcessPerOrigin)
+TEST(ServiceWorkers, ProcessPerSite)
 {
     ASSERT(mainBytes);
     ASSERT(scriptBytes);
@@ -1472,6 +1472,8 @@ TEST(ServiceWorkers, ProcessPerOrigin)
     RetainPtr<SWSchemes> handler1 = adoptNS([[SWSchemes alloc] init]);
     handler1->resources.set("sw1://host/main.html", ResourceInfo { @"text/html", mainBytes });
     handler1->resources.set("sw1://host/sw.js", ResourceInfo { @"application/javascript", scriptBytes });
+    handler1->resources.set("sw1://host2/main.html", ResourceInfo { @"text/html", mainBytes });
+    handler1->resources.set("sw1://host2/sw.js", ResourceInfo { @"application/javascript", scriptBytes });
     [configuration setURLSchemeHandler:handler1.get() forURLScheme:@"sw1"];
 
     RetainPtr<SWSchemes> handler2 = adoptNS([[SWSchemes alloc] init]);
@@ -1512,10 +1514,19 @@ TEST(ServiceWorkers, ProcessPerOrigin)
     TestWebKitAPI::Util::run(&done);
     done = false;
 
+    EXPECT_EQ(1U, processPool._serviceWorkerProcessCount);
+
+    RetainPtr<WKWebView> webView4 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    NSURLRequest *request3 = [NSURLRequest requestWithURL:[NSURL URLWithString:@"sw1://host2/main.html"]];
+    [webView4 loadRequest:request3];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
     EXPECT_EQ(2U, processPool._serviceWorkerProcessCount);
 
     NSURLRequest *aboutBlankRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]];
-    [webView3 loadRequest:aboutBlankRequest];
+    [webView4 loadRequest:aboutBlankRequest];
 
     waitUntilServiceWorkerProcessCount(processPool, 1);
     EXPECT_EQ(1U, processPool._serviceWorkerProcessCount);
@@ -1525,6 +1536,7 @@ TEST(ServiceWorkers, ProcessPerOrigin)
     EXPECT_EQ(1U, processPool._serviceWorkerProcessCount);
 
     [webView1 loadRequest:aboutBlankRequest];
+    [webView3 loadRequest:aboutBlankRequest];
     waitUntilServiceWorkerProcessCount(processPool, 0);
     EXPECT_EQ(0U, processPool._serviceWorkerProcessCount);
 }