Move soft update handling to network process
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Dec 2019 13:47:49 +0000 (13:47 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Dec 2019 13:47:49 +0000 (13:47 +0000)
https://bugs.webkit.org/show_bug.cgi?id=204678

Reviewed by Chris Dumez.

Source/WebCore:

* workers/WorkerScriptLoader.cpp:
(WebCore::WorkerScriptLoader::validateResponse):
(WebCore::WorkerScriptLoader::didReceiveResponse):
* workers/WorkerScriptLoader.h:
* workers/service/ServiceWorkerJobData.cpp:
(WebCore::ServiceWorkerJobData::isEquivalent const):
* workers/service/ServiceWorkerJobData.h:
* workers/service/ServiceWorkerRegistration.cpp:
(WebCore::ServiceWorkerRegistration::ServiceWorkerRegistration):
* workers/service/ServiceWorkerRegistration.h:
* workers/service/context/SWContextManager.cpp:
* workers/service/context/SWContextManager.h:
* workers/service/context/ServiceWorkerFetch.cpp:
(WebCore::ServiceWorkerFetch::dispatchFetchEvent):
* workers/service/context/ServiceWorkerThread.cpp:
* workers/service/context/ServiceWorkerThread.h:
* workers/service/server/SWServer.cpp:
(WebCore::SWServer::Connection::didResolveRegistrationPromise):
(WebCore::SWServer::SWServer):
(WebCore::SWServer::scheduleJob):
(WebCore::SWServer::resolveRegistrationJob):
(WebCore::originURL):
(WebCore::SWServer::startScriptFetch):
(WebCore::SWServer::scriptFetchFinished):
(WebCore::SWServer::didResolveRegistrationPromise):
(WebCore::SWServer::softUpdate):
* workers/service/server/SWServer.h:
(WebCore::SWServer::getRegistration):
* workers/service/server/SWServerJobQueue.cpp:
(WebCore::SWServerJobQueue::runUpdateJob):
* workers/service/server/SWServerJobQueue.h:
(WebCore::SWServerJobQueue::enqueueJob):
* workers/service/server/SWServerRegistration.cpp:
(WebCore::SWServerRegistration::SWServerRegistration):
(WebCore::SWServerRegistration::setUpdateViaCache):
(WebCore::SWServerRegistration::softUpdate):
(WebCore::SWServerRegistration::scheduleSoftUpdate):
* workers/service/server/SWServerRegistration.h:
(WebCore::SWServerRegistration::scopeURLWithoutFragment const):
(WebCore::SWServerRegistration::scriptURL const):
* workers/service/server/SWServerToContextConnection.h:

Source/WebKit:

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::swServerForSession):
* NetworkProcess/NetworkSession.h:
(WebKit::NetworkSession::addSoftUpdateLoader):
(WebKit::NetworkSession::removeSoftUpdateLoader):
* NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
(WebKit::ServiceWorkerFetchTask::ServiceWorkerFetchTask):
(WebKit::ServiceWorkerFetchTask::didReceiveRedirectResponse):
(WebKit::ServiceWorkerFetchTask::didReceiveResponse):
(WebKit::ServiceWorkerFetchTask::didFail):
(WebKit::ServiceWorkerFetchTask::didNotHandle):
(WebKit::ServiceWorkerFetchTask::continueFetchTaskWith):
(WebKit::ServiceWorkerFetchTask::timeoutTimerFired):
(WebKit::ServiceWorkerFetchTask::softUpdateIfNeeded):
* NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h:
* NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp: Added.
(WebKit::ServiceWorkerSoftUpdateLoader::start):
(WebKit::ServiceWorkerSoftUpdateLoader::ServiceWorkerSoftUpdateLoader):
(WebKit::ServiceWorkerSoftUpdateLoader::~ServiceWorkerSoftUpdateLoader):
(WebKit::ServiceWorkerSoftUpdateLoader::fail):
(WebKit::ServiceWorkerSoftUpdateLoader::loadWithCacheEntry):
(WebKit::ServiceWorkerSoftUpdateLoader::loadFromNetwork):
(WebKit::ServiceWorkerSoftUpdateLoader::willSendRedirectedRequest):
(WebKit::ServiceWorkerSoftUpdateLoader::didReceiveResponse):
(WebKit::ServiceWorkerSoftUpdateLoader::didReceiveBuffer):
(WebKit::ServiceWorkerSoftUpdateLoader::didFinishLoading):
(WebKit::ServiceWorkerSoftUpdateLoader::didFailLoading):
(WebKit::ServiceWorkerSoftUpdateLoader::didComplete):
* NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.h: Added.
* NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::createFetchTask):
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
* Shared/Authentication/AuthenticationManager.cpp:
(WebKit::AuthenticationManager::didReceiveAuthenticationChallenge):
* Sources.txt:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/Storage/WebSWContextManagerConnection.cpp:
* WebProcess/Storage/WebSWContextManagerConnection.h:
* WebProcess/Storage/WebSWContextManagerConnection.messages.in:

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

39 files changed:
LayoutTests/http/tests/workers/worker-importScripts-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/platform/network/HTTPHeaderNames.in
Source/WebCore/workers/WorkerScriptLoader.cpp
Source/WebCore/workers/WorkerScriptLoader.h
Source/WebCore/workers/service/ServiceWorkerJob.cpp
Source/WebCore/workers/service/ServiceWorkerJob.h
Source/WebCore/workers/service/ServiceWorkerJobData.cpp
Source/WebCore/workers/service/ServiceWorkerJobData.h
Source/WebCore/workers/service/ServiceWorkerRegistration.cpp
Source/WebCore/workers/service/ServiceWorkerRegistration.h
Source/WebCore/workers/service/context/SWContextManager.cpp
Source/WebCore/workers/service/context/SWContextManager.h
Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp
Source/WebCore/workers/service/context/ServiceWorkerThread.cpp
Source/WebCore/workers/service/context/ServiceWorkerThread.h
Source/WebCore/workers/service/server/SWServer.cpp
Source/WebCore/workers/service/server/SWServer.h
Source/WebCore/workers/service/server/SWServerJobQueue.cpp
Source/WebCore/workers/service/server/SWServerJobQueue.h
Source/WebCore/workers/service/server/SWServerRegistration.cpp
Source/WebCore/workers/service/server/SWServerRegistration.h
Source/WebCore/workers/service/server/SWServerToContextConnection.h
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkProcess.cpp
Source/WebKit/NetworkProcess/NetworkSession.h
Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp
Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h
Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp [new file with mode: 0644]
Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.h [new file with mode: 0644]
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h
Source/WebKit/Shared/Authentication/AuthenticationManager.cpp
Source/WebKit/Sources.txt
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in

index 3171db8..a12bfd2 100644 (file)
@@ -24,7 +24,7 @@ Loaded message from different origin
 Loaded resource 2
 PASS: all resources executed.
 Loaded resource 1
-PASS: Threw NetworkError: Failed to load script when load failed
+PASS: Threw NetworkError: Response is not 2xx when load failed
 PASS: some resources were loaded despite the network error
 Loaded resource 1
 PASS: Threw SyntaxError: Unexpected identifier 'syntax' when encountering a syntax error in imported script
index 2f851fc..b38008a 100644 (file)
@@ -1,3 +1,52 @@
+2019-12-04  youenn fablet  <youenn@apple.com>
+
+        Move soft update handling to network process
+        https://bugs.webkit.org/show_bug.cgi?id=204678
+
+        Reviewed by Chris Dumez.
+
+        * workers/WorkerScriptLoader.cpp:
+        (WebCore::WorkerScriptLoader::validateResponse):
+        (WebCore::WorkerScriptLoader::didReceiveResponse):
+        * workers/WorkerScriptLoader.h:
+        * workers/service/ServiceWorkerJobData.cpp:
+        (WebCore::ServiceWorkerJobData::isEquivalent const):
+        * workers/service/ServiceWorkerJobData.h:
+        * workers/service/ServiceWorkerRegistration.cpp:
+        (WebCore::ServiceWorkerRegistration::ServiceWorkerRegistration):
+        * workers/service/ServiceWorkerRegistration.h:
+        * workers/service/context/SWContextManager.cpp:
+        * workers/service/context/SWContextManager.h:
+        * workers/service/context/ServiceWorkerFetch.cpp:
+        (WebCore::ServiceWorkerFetch::dispatchFetchEvent):
+        * workers/service/context/ServiceWorkerThread.cpp:
+        * workers/service/context/ServiceWorkerThread.h:
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::Connection::didResolveRegistrationPromise):
+        (WebCore::SWServer::SWServer):
+        (WebCore::SWServer::scheduleJob):
+        (WebCore::SWServer::resolveRegistrationJob):
+        (WebCore::originURL):
+        (WebCore::SWServer::startScriptFetch):
+        (WebCore::SWServer::scriptFetchFinished):
+        (WebCore::SWServer::didResolveRegistrationPromise):
+        (WebCore::SWServer::softUpdate):
+        * workers/service/server/SWServer.h:
+        (WebCore::SWServer::getRegistration):
+        * workers/service/server/SWServerJobQueue.cpp:
+        (WebCore::SWServerJobQueue::runUpdateJob):
+        * workers/service/server/SWServerJobQueue.h:
+        (WebCore::SWServerJobQueue::enqueueJob):
+        * workers/service/server/SWServerRegistration.cpp:
+        (WebCore::SWServerRegistration::SWServerRegistration):
+        (WebCore::SWServerRegistration::setUpdateViaCache):
+        (WebCore::SWServerRegistration::softUpdate):
+        (WebCore::SWServerRegistration::scheduleSoftUpdate):
+        * workers/service/server/SWServerRegistration.h:
+        (WebCore::SWServerRegistration::scopeURLWithoutFragment const):
+        (WebCore::SWServerRegistration::scriptURL const):
+        * workers/service/server/SWServerToContextConnection.h:
+
 2019-12-04  Youenn Fablet  <youenn@apple.com>
 
         Add support for WebIDL setlike
index d3d965e..01cde3c 100644 (file)
@@ -84,6 +84,7 @@ Sec-WebSocket-Key
 Sec-WebSocket-Protocol
 Sec-WebSocket-Version
 Server-Timing
+Service-Worker
 Service-Worker-Allowed
 Set-Cookie
 Set-Cookie2
index 228f3d1..31dd8a9 100644 (file)
@@ -153,23 +153,28 @@ std::unique_ptr<ResourceRequest> WorkerScriptLoader::createResourceRequest(const
     return request;
 }
 
-void WorkerScriptLoader::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
+ResourceError WorkerScriptLoader::validateWorkerResponse(const ResourceResponse& response, FetchOptions::Destination destination)
 {
-    if (response.httpStatusCode() / 100 != 2 && response.httpStatusCode()) {
-        m_failed = true;
-        return;
-    }
+    if (response.httpStatusCode() / 100 != 2 && response.httpStatusCode())
+        return ResourceError { errorDomainWebKitInternal, 0, response.url(), "Response is not 2xx"_s, ResourceError::Type::General };
 
     if (!isScriptAllowedByNosniff(response)) {
         String message = makeString("Refused to execute ", response.url().stringCenterEllipsizedToLength(), " as script because \"X-Content-Type: nosniff\" was given and its Content-Type is not a script MIME type.");
-        m_error = ResourceError { errorDomainWebKitInternal, 0, url(), message, ResourceError::Type::General };
-        m_failed = true;
-        return;
+        return ResourceError { errorDomainWebKitInternal, 0, response.url(), WTFMove(message), ResourceError::Type::General };
     }
 
-    if (shouldBlockResponseDueToMIMEType(response, m_destination)) {
+    if (shouldBlockResponseDueToMIMEType(response, destination)) {
         String message = makeString("Refused to execute ", response.url().stringCenterEllipsizedToLength(), " as script because ", response.mimeType(), " is not a script MIME type.");
-        m_error = ResourceError { errorDomainWebKitInternal, 0, response.url(), message, ResourceError::Type::General };
+        return ResourceError { errorDomainWebKitInternal, 0, response.url(), WTFMove(message), ResourceError::Type::General };
+    }
+
+    return { };
+}
+
+void WorkerScriptLoader::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
+{
+    m_error = validateWorkerResponse(response, m_destination);
+    if (!m_error.isNull()) {
         m_failed = true;
         return;
     }
index 9a0f487..e5146a5 100644 (file)
@@ -77,6 +77,8 @@ public:
 
     void cancel();
 
+    WEBCORE_EXPORT static ResourceError validateWorkerResponse(const ResourceResponse&, FetchOptions::Destination);
+
 private:
     friend class WTF::RefCounted<WorkerScriptLoader>;
     friend struct std::default_delete<WorkerScriptLoader>;
index c6d2a28..e9f0c14 100644 (file)
@@ -113,46 +113,45 @@ void ServiceWorkerJob::fetchScriptWithContext(ScriptExecutionContext& context, F
     m_scriptLoader->loadAsynchronously(context, WTFMove(request), WTFMove(options), ContentSecurityPolicyEnforcement::DoNotEnforce, ServiceWorkersMode::None, *this);
 }
 
-void ServiceWorkerJob::didReceiveResponse(unsigned long, const ResourceResponse& response)
+ResourceError ServiceWorkerJob::validateServiceWorkerResponse(const ServiceWorkerJobData& jobData, const ResourceResponse& response)
 {
-    ASSERT(m_creationThread.ptr() == &Thread::current());
-    ASSERT(!m_completed);
-    ASSERT(m_scriptLoader);
-
     // Extract a MIME type from the response's header list. If this MIME type (ignoring parameters) is not a JavaScript MIME type, then:
-    if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(response.mimeType())) {
-        m_scriptLoader->cancel();
-        m_scriptLoader = nullptr;
-
-        // Invoke Reject Job Promise with job and "SecurityError" DOMException.
-        Exception exception { SecurityError, "MIME Type is not a JavaScript MIME type"_s };
-        // Asynchronously complete these steps with a network error.
-        ResourceError error { errorDomainWebKitInternal, 0, response.url(), "Unexpected MIME type"_s };
-        m_client.jobFailedLoadingScript(*this, WTFMove(error), WTFMove(exception));
-        return;
-    }
+    if (!MIMETypeRegistry::isSupportedJavaScriptMIMEType(response.mimeType()))
+        return { errorDomainWebKitInternal, 0, response.url(), "MIME Type is not a JavaScript MIME type"_s };
 
     String serviceWorkerAllowed = response.httpHeaderField(HTTPHeaderName::ServiceWorkerAllowed);
     String maxScopeString;
     if (serviceWorkerAllowed.isNull()) {
-        String path = m_jobData.scriptURL.path();
+        String path = jobData.scriptURL.path();
         // Last part of the path is the script's filename.
         maxScopeString = path.substring(0, path.reverseFind('/') + 1);
     } else {
-        auto maxScope = URL(m_jobData.scriptURL, serviceWorkerAllowed);
-        if (SecurityOrigin::create(maxScope)->isSameOriginAs(SecurityOrigin::create(m_jobData.scriptURL)))
+        auto maxScope = URL(jobData.scriptURL, serviceWorkerAllowed);
+        if (SecurityOrigin::create(maxScope)->isSameOriginAs(SecurityOrigin::create(jobData.scriptURL)))
             maxScopeString = maxScope.path();
     }
 
-    String scopeString = m_jobData.scopeURL.path();
-    if (scopeString.startsWith(maxScopeString))
+    String scopeString = jobData.scopeURL.path();
+    if (!scopeString.startsWith(maxScopeString))
+        return { errorDomainWebKitInternal, 0, response.url(), "Scope URL should start with the given script URL"_s };
+
+    return { };
+}
+
+void ServiceWorkerJob::didReceiveResponse(unsigned long, const ResourceResponse& response)
+{
+    ASSERT(m_creationThread.ptr() == &Thread::current());
+    ASSERT(!m_completed);
+    ASSERT(m_scriptLoader);
+
+    auto error = validateServiceWorkerResponse(m_jobData, response);
+    if (error.isNull())
         return;
 
     m_scriptLoader->cancel();
     m_scriptLoader = nullptr;
 
-    Exception exception { SecurityError, "Scope URL should start with the given script URL"_s };
-    ResourceError error { errorDomainWebKitInternal, 0, response.url(), "Scope URL should start with the given script URL"_s };
+    Exception exception { SecurityError, error.localizedDescription() };
     m_client.jobFailedLoadingScript(*this, WTFMove(error), WTFMove(exception));
 }
 
index 7dbb7d3..93a474c 100644 (file)
@@ -70,6 +70,8 @@ public:
 
     bool cancelPendingLoad();
 
+    WEBCORE_EXPORT static ResourceError validateServiceWorkerResponse(const ServiceWorkerJobData&, const ResourceResponse&);
+
 private:
     // WorkerScriptLoaderClient
     void didReceiveResponse(unsigned long identifier, const ResourceResponse&) final;
index 47a79f0..a0f3645 100644 (file)
@@ -67,6 +67,25 @@ ServiceWorkerJobData ServiceWorkerJobData::isolatedCopy() const
     return result;
 }
 
+// https://w3c.github.io/ServiceWorker/#dfn-job-equivalent
+bool ServiceWorkerJobData::isEquivalent(const ServiceWorkerJobData& job) const
+{
+    if (type != job.type)
+        return false;
+
+    switch (type) {
+    case ServiceWorkerJobType::Register:
+    case ServiceWorkerJobType::Update:
+        return scopeURL == job.scopeURL
+            && scriptURL == job.scriptURL
+            && registrationOptions.type == job.registrationOptions.type
+            && registrationOptions.updateViaCache == job.registrationOptions.updateViaCache;
+    case ServiceWorkerJobType::Unregister:
+        return scopeURL == job.scopeURL;
+    }
+    return false;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index c208537..5f337cb 100644 (file)
@@ -46,6 +46,8 @@ struct ServiceWorkerJobData {
 
     SWServerConnectionIdentifier connectionIdentifier() const { return m_identifier.connectionIdentifier; }
 
+    bool isEquivalent(const ServiceWorkerJobData&) const;
+
     URL scriptURL;
     URL clientCreationURL;
     SecurityOriginData topOrigin;
@@ -56,7 +58,7 @@ struct ServiceWorkerJobData {
     ServiceWorkerRegistrationOptions registrationOptions;
 
     Identifier identifier() const { return m_identifier; }
-    ServiceWorkerRegistrationKey registrationKey() const;
+    WEBCORE_EXPORT ServiceWorkerRegistrationKey registrationKey() const;
     ServiceWorkerJobData isolatedCopy() const;
 
     template<class Encoder> void encode(Encoder&) const;
index f218907..116bbb4 100644 (file)
@@ -46,8 +46,6 @@ namespace WebCore {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(ServiceWorkerRegistration);
 
-const Seconds softUpdateDelay { 1_s };
-
 Ref<ServiceWorkerRegistration> ServiceWorkerRegistration::getOrCreate(ScriptExecutionContext& context, Ref<ServiceWorkerContainer>&& container, ServiceWorkerRegistrationData&& data)
 {
     if (auto* registration = container->registration(data.identifier)) {
@@ -62,7 +60,6 @@ ServiceWorkerRegistration::ServiceWorkerRegistration(ScriptExecutionContext& con
     : ActiveDOMObject(&context)
     , m_registrationData(WTFMove(registrationData))
     , m_container(WTFMove(container))
-    , m_softUpdateTimer([this] { softUpdate(); })
 {
     LOG(ServiceWorker, "Creating registration %p for registration key %s", this, m_registrationData.key.loggingString().utf8().data());
     suspendIfNeeded();
@@ -156,28 +153,6 @@ void ServiceWorkerRegistration::update(Ref<DeferredPromise>&& promise)
     m_container->updateRegistration(m_registrationData.scopeURL, newestWorker->scriptURL(), WorkerType::Classic, WTFMove(promise));
 }
 
-// To avoid scheduling many updates during a single page load, we do soft updates on a 1 second delay and keep delaying
-// as long as soft update requests keep coming. This seems to match Chrome's behavior.
-void ServiceWorkerRegistration::scheduleSoftUpdate()
-{
-    if (m_softUpdateTimer.isActive())
-        m_softUpdateTimer.stop();
-    m_softUpdateTimer.startOneShot(softUpdateDelay);
-}
-
-void ServiceWorkerRegistration::softUpdate()
-{
-    if (m_isStopped)
-        return;
-
-    auto* newestWorker = getNewestWorker();
-    if (!newestWorker)
-        return;
-
-    // FIXME: Support worker types.
-    m_container->updateRegistration(m_registrationData.scopeURL, newestWorker->scriptURL(), WorkerType::Classic, nullptr);
-}
-
 void ServiceWorkerRegistration::unregister(Ref<DeferredPromise>&& promise)
 {
     if (m_isStopped) {
index 191fa40..6b8068e 100644 (file)
@@ -68,8 +68,6 @@ public:
     void update(Ref<DeferredPromise>&&);
     void unregister(Ref<DeferredPromise>&&);
 
-    void scheduleSoftUpdate();
-
     using RefCounted::ref;
     using RefCounted::deref;
     
@@ -87,8 +85,6 @@ private:
     void refEventTarget() final { ref(); }
     void derefEventTarget() final { deref(); }
 
-    void softUpdate();
-
     // ActiveDOMObject.
     const char* activeDOMObjectName() const final;
     void suspend(ReasonForSuspension) final;
@@ -106,7 +102,6 @@ private:
     bool m_isSuspended { false };
     bool m_shouldFireUpdateFoundEventUponResuming { false };
     RefPtr<PendingActivity<ServiceWorkerRegistration>> m_pendingActivityForEventDispatch;
-    Timer m_softUpdateTimer;
 };
 
 } // namespace WebCore
index 470c189..82d3e69 100644 (file)
@@ -108,15 +108,6 @@ void SWContextManager::fireActivateEvent(ServiceWorkerIdentifier identifier)
     serviceWorker->thread().fireActivateEvent();
 }
 
-void SWContextManager::softUpdate(ServiceWorkerIdentifier identifier)
-{
-    auto* serviceWorker = m_workerMap.get(identifier);
-    if (!serviceWorker)
-        return;
-
-    serviceWorker->thread().softUpdate();
-}
-
 void SWContextManager::terminateWorker(ServiceWorkerIdentifier identifier, Seconds timeout, Function<void()>&& completionHandler)
 {
     auto serviceWorker = m_workerMap.take(identifier);
index 6a05a3c..09bbcb5 100644 (file)
@@ -83,7 +83,6 @@ public:
     WEBCORE_EXPORT void postMessageToServiceWorker(ServiceWorkerIdentifier destination, MessageWithMessagePorts&&, ServiceWorkerOrClientData&& sourceData);
     WEBCORE_EXPORT void fireInstallEvent(ServiceWorkerIdentifier);
     WEBCORE_EXPORT void fireActivateEvent(ServiceWorkerIdentifier);
-    WEBCORE_EXPORT void softUpdate(ServiceWorkerIdentifier);
     WEBCORE_EXPORT void terminateWorker(ServiceWorkerIdentifier, Seconds timeout, Function<void()>&&);
 
     void forEachServiceWorkerThread(const WTF::Function<void(ServiceWorkerThreadProxy&)>&);
index 44969af..9783a9d 100644 (file)
@@ -140,7 +140,6 @@ void dispatchFetchEvent(Ref<Client>&& client, ServiceWorkerGlobalScope& globalSc
     FetchOptions::Redirect redirect = options.redirect;
 
     bool isNavigation = options.mode == FetchOptions::Mode::Navigate;
-    bool isNonSubresourceRequest = WebCore::isNonSubresourceRequest(options.destination);
 
     ASSERT(globalScope.registration().active());
     ASSERT(globalScope.registration().active()->identifier() == globalScope.thread().identifier());
@@ -188,10 +187,6 @@ void dispatchFetchEvent(Ref<Client>&& client, ServiceWorkerGlobalScope& globalSc
     }
 
     globalScope.updateExtendedEventsSet(event.ptr());
-
-    auto& registration = globalScope.registration();
-    if (isNonSubresourceRequest || registration.needsUpdate())
-        registration.scheduleSoftUpdate();
 }
 
 } // namespace ServiceWorkerFetch
index e4eeca0..04e9c88 100644 (file)
@@ -175,14 +175,6 @@ void ServiceWorkerThread::fireActivateEvent()
     });
 }
 
-void ServiceWorkerThread::softUpdate()
-{
-    runLoop().postTask([](auto& context) mutable {
-        auto& serviceWorkerGlobalScope = downcast<ServiceWorkerGlobalScope>(context);
-        serviceWorkerGlobalScope.registration().scheduleSoftUpdate();
-    });
-}
-
 void ServiceWorkerThread::finishedEvaluatingScript()
 {
     m_doesHandleFetch = workerGlobalScope()->hasEventListeners(eventNames().fetchEvent);
index 073cd62..a42579f 100644 (file)
@@ -61,7 +61,6 @@ public:
 
     void fireInstallEvent();
     void fireActivateEvent();
-    void softUpdate();
 
     const ServiceWorkerContextData& contextData() const { return m_data; }
 
index 0ddfcfc..6e440d6 100644 (file)
@@ -293,7 +293,7 @@ void SWServer::Connection::finishFetchingScriptInServer(const ServiceWorkerFetch
 
 void SWServer::Connection::didResolveRegistrationPromise(const ServiceWorkerRegistrationKey& key)
 {
-    m_server.didResolveRegistrationPromise(*this, key);
+    m_server.didResolveRegistrationPromise(this, key);
 }
 
 void SWServer::Connection::addServiceWorkerRegistrationInServer(ServiceWorkerRegistrationIdentifier identifier)
@@ -312,11 +312,12 @@ void SWServer::Connection::syncTerminateWorker(ServiceWorkerIdentifier identifie
         m_server.syncTerminateWorker(*worker);
 }
 
-SWServer::SWServer(UniqueRef<SWOriginStore>&& originStore, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID sessionID, CreateContextConnectionCallback&& callback)
+SWServer::SWServer(UniqueRef<SWOriginStore>&& originStore, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID sessionID, SoftUpdateCallback&& softUpdateCallback, CreateContextConnectionCallback&& callback)
     : m_originStore(WTFMove(originStore))
     , m_sessionID(sessionID)
     , m_isProcessTerminationDelayEnabled(processTerminationDelayEnabled)
     , m_createContextConnectionCallback(WTFMove(callback))
+    , m_softUpdateCallback(WTFMove(softUpdateCallback))
 {
     ASSERT(!registrationDatabaseDirectory.isEmpty() || m_sessionID.isEphemeral());
     if (!m_sessionID.isEphemeral())
@@ -331,16 +332,26 @@ SWServer::SWServer(UniqueRef<SWOriginStore>&& originStore, bool processTerminati
 // https://w3c.github.io/ServiceWorker/#schedule-job-algorithm
 void SWServer::scheduleJob(ServiceWorkerJobData&& jobData)
 {
-    ASSERT(m_connections.contains(jobData.connectionIdentifier()));
-
-    // FIXME: Per the spec, check if this job is equivalent to the last job on the queue.
-    // If it is, stack it along with that job.
+    ASSERT(m_connections.contains(jobData.connectionIdentifier()) || jobData.connectionIdentifier() == Process::identifier());
 
     auto& jobQueue = *m_jobQueues.ensure(jobData.registrationKey(), [this, &jobData] {
         return makeUnique<SWServerJobQueue>(*this, jobData.registrationKey());
     }).iterator->value;
 
-    jobQueue.enqueueJob(jobData);
+    if (!jobQueue.size()) {
+        jobQueue.enqueueJob(WTFMove(jobData));
+        jobQueue.runNextJob();
+        return;
+    }
+    auto& lastJob = jobQueue.lastJob();
+    if (jobData.isEquivalent(lastJob)) {
+        // FIXME: Per the spec, check if this job is equivalent to the last job on the queue.
+        // If it is, stack it along with that job. For now, we just make sure to not call soft-update too often.
+        if (jobData.type == ServiceWorkerJobType::Update && jobData.connectionIdentifier() == Process::identifier())
+            return;
+    }
+
+    jobQueue.enqueueJob(WTFMove(jobData));
     if (jobQueue.size() == 1)
         jobQueue.runNextJob();
 }
@@ -359,8 +370,11 @@ void SWServer::resolveRegistrationJob(const ServiceWorkerJobData& jobData, const
 {
     LOG(ServiceWorker, "Resolved ServiceWorker job %s in server with registration %s", jobData.identifier().loggingString().utf8().data(), registrationData.identifier.loggingString().utf8().data());
     auto* connection = m_connections.get(jobData.connectionIdentifier());
-    if (!connection)
+    if (!connection) {
+        if (shouldNotifyWhenResolved == ShouldNotifyWhenResolved::Yes && jobData.connectionIdentifier() == Process::identifier())
+            didResolveRegistrationPromise(nullptr, registrationData.key);
         return;
+    }
 
     connection->resolveRegistrationJobInClient(jobData.identifier().jobIdentifier, registrationData, shouldNotifyWhenResolved);
 }
@@ -374,20 +388,57 @@ void SWServer::resolveUnregistrationJob(const ServiceWorkerJobData& jobData, con
     connection->resolveUnregistrationJobInClient(jobData.identifier().jobIdentifier, registrationKey, unregistrationResult);
 }
 
-void SWServer::startScriptFetch(const ServiceWorkerJobData& jobData, FetchOptions::Cache cachePolicy)
+URL static inline originURL(const SecurityOrigin& origin)
+{
+    URL url;
+    url.setProtocol(origin.protocol());
+    url.setHost(origin.host());
+    if (origin.port())
+        url.setPort(*origin.port());
+    return url;
+}
+
+void SWServer::startScriptFetch(const ServiceWorkerJobData& jobData, bool shouldRefreshCache)
 {
     LOG(ServiceWorker, "Server issuing startScriptFetch for current job %s in client", jobData.identifier().loggingString().utf8().data());
     auto* connection = m_connections.get(jobData.connectionIdentifier());
+    if (connection) {
+        connection->startScriptFetchInClient(jobData.identifier().jobIdentifier, jobData.registrationKey(), shouldRefreshCache ? FetchOptions::Cache::NoCache : FetchOptions::Cache::Default);
+        return;
+    }
+    if (jobData.connectionIdentifier() == Process::identifier()) {
+        ASSERT(jobData.type == ServiceWorkerJobType::Update);
+        // This is a soft-update job, create directly a network load to fetch the script.
+        ResourceRequest request { jobData.scriptURL };
+
+        auto topOrigin = jobData.topOrigin.securityOrigin();
+        auto origin = SecurityOrigin::create(jobData.scriptURL);
+
+        request.setDomainForCachePartition(topOrigin->domainForCachePartition());
+        request.setAllowCookies(true);
+        request.setFirstPartyForCookies(originURL(topOrigin));
+
+        request.setHTTPHeaderField(HTTPHeaderName::Origin, origin->toString());
+        request.setHTTPHeaderField(HTTPHeaderName::ServiceWorker, "script"_s);
+        request.setHTTPReferrer(originURL(origin));
+        request.setHTTPUserAgent(serviceWorkerClientUserAgent(ClientOrigin { jobData.topOrigin, SecurityOrigin::create(jobData.scriptURL)->data() }));
+        request.setPriority(ResourceLoadPriority::Low);
+
+        m_softUpdateCallback(ServiceWorkerJobData { jobData }, shouldRefreshCache, WTFMove(request), [this, weakThis = makeWeakPtr(this)](auto& result) {
+            if (!weakThis)
+                return;
+            scriptFetchFinished(result);
+        });
+        return;
+    }
     ASSERT_WITH_MESSAGE(connection, "If the connection was lost, this job should have been cancelled");
-    if (connection)
-        connection->startScriptFetchInClient(jobData.identifier().jobIdentifier, jobData.registrationKey(), cachePolicy);
 }
 
 void SWServer::scriptFetchFinished(const ServiceWorkerFetchResult& result)
 {
     LOG(ServiceWorker, "Server handling scriptFetchFinished for current job %s in client", result.jobDataIdentifier.loggingString().utf8().data());
 
-    ASSERT(m_connections.contains(result.jobDataIdentifier.connectionIdentifier));
+    ASSERT(m_connections.contains(result.jobDataIdentifier.connectionIdentifier) || result.jobDataIdentifier.connectionIdentifier == Process::identifier());
 
     auto jobQueue = m_jobQueues.get(result.registrationKey);
     if (!jobQueue)
@@ -517,9 +568,9 @@ void SWServer::claim(SWServerWorker& worker)
     });
 }
 
-void SWServer::didResolveRegistrationPromise(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey)
+void SWServer::didResolveRegistrationPromise(Connection* connection, const ServiceWorkerRegistrationKey& registrationKey)
 {
-    ASSERT_UNUSED(connection, m_connections.contains(connection.identifier()));
+    ASSERT_UNUSED(connection, !connection || m_connections.contains(connection->identifier()));
 
     if (auto* jobQueue = m_jobQueues.get(registrationKey))
         jobQueue->didResolveRegistrationPromise();
@@ -998,6 +1049,17 @@ bool SWServer::canHandleScheme(StringView scheme) const
     return scheme.length() == 4;
 }
 
+// https://w3c.github.io/ServiceWorker/#soft-update
+void SWServer::softUpdate(SWServerRegistration& registration)
+{
+    ServiceWorkerJobData jobData(Process::identifier(), ServiceWorkerIdentifier::generate());
+    jobData.scriptURL = registration.scriptURL();
+    jobData.topOrigin = registration.key().topOrigin();
+    jobData.scopeURL = registration.scopeURLWithoutFragment();
+    jobData.type = ServiceWorkerJobType::Update;
+    scheduleJob(WTFMove(jobData));
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index 9cda9b3..bc11276 100644 (file)
@@ -124,8 +124,9 @@ public:
         Vector<RegistrationReadyRequest> m_registrationReadyRequests;
     };
 
+    using SoftUpdateCallback = Function<void(ServiceWorkerJobData&& jobData, bool shouldRefreshCache, ResourceRequest&&, CompletionHandler<void(const ServiceWorkerFetchResult&)>&&)>;
     using CreateContextConnectionCallback = Function<void(const WebCore::RegistrableDomain&)>;
-    WEBCORE_EXPORT SWServer(UniqueRef<SWOriginStore>&&, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID, CreateContextConnectionCallback&&);
+    WEBCORE_EXPORT SWServer(UniqueRef<SWOriginStore>&&, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID, SoftUpdateCallback&&, CreateContextConnectionCallback&&);
 
     WEBCORE_EXPORT ~SWServer();
 
@@ -135,6 +136,7 @@ public:
     WEBCORE_EXPORT void startSuspension(CompletionHandler<void()>&&);
     WEBCORE_EXPORT void endSuspension();
 
+    SWServerRegistration* getRegistration(ServiceWorkerRegistrationIdentifier identifier) { return m_registrations.get(identifier); }
     WEBCORE_EXPORT SWServerRegistration* getRegistration(const ServiceWorkerRegistrationKey&);
     void addRegistration(std::unique_ptr<SWServerRegistration>&&);
     void removeRegistration(ServiceWorkerRegistrationIdentifier);
@@ -144,7 +146,7 @@ public:
     void rejectJob(const ServiceWorkerJobData&, const ExceptionData&);
     void resolveRegistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationData&, ShouldNotifyWhenResolved);
     void resolveUnregistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationKey&, bool unregistrationResult);
-    void startScriptFetch(const ServiceWorkerJobData&, FetchOptions::Cache);
+    void startScriptFetch(const ServiceWorkerJobData&, bool shouldRefreshCache);
 
     void updateWorker(const ServiceWorkerJobDataIdentifier&, SWServerRegistration&, const URL&, const String& script, const ContentSecurityPolicyResponseHeaders&, const String& referrerPolicy, WorkerType, HashMap<URL, ServiceWorkerContextData::ImportedScript>&&);
     void terminateWorker(SWServerWorker&);
@@ -206,10 +208,12 @@ public:
     bool isImportCompleted() const { return m_importCompleted; }
     WEBCORE_EXPORT void whenImportIsCompleted(CompletionHandler<void()>&&);
 
+    void softUpdate(SWServerRegistration&);
+
 private:
     void scriptFetchFinished(const ServiceWorkerFetchResult&);
 
-    void didResolveRegistrationPromise(Connection&, const ServiceWorkerRegistrationKey&);
+    void didResolveRegistrationPromise(Connection*, const ServiceWorkerRegistrationKey&);
 
     void addClientServiceWorkerRegistration(Connection&, ServiceWorkerRegistrationIdentifier);
     void removeClientServiceWorkerRegistration(Connection&, ServiceWorkerRegistrationIdentifier);
@@ -266,6 +270,7 @@ private:
     CreateContextConnectionCallback m_createContextConnectionCallback;
     HashSet<WebCore::RegistrableDomain> m_pendingConnectionDomains;
     Vector<CompletionHandler<void()>> m_importCompletedCallbacks;
+    SoftUpdateCallback m_softUpdateCallback;
 };
 
 } // namespace WebCore
index 3a9727c..8940eb9 100644 (file)
@@ -332,17 +332,13 @@ void SWServerJobQueue::runUpdateJob(const ServiceWorkerJobData& job)
     if (job.type == ServiceWorkerJobType::Update && newestWorker && !equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()))
         return rejectCurrentJob(ExceptionData { TypeError, "Cannot update a service worker with a requested script URL whose newest worker has a different script URL"_s });
 
-    FetchOptions::Cache cachePolicy = FetchOptions::Cache::Default;
     // Set request's cache mode to "no-cache" if any of the following are true:
     // - registration's update via cache mode is not "all".
     // - job's force bypass cache flag is set.
     // - newestWorker is not null, and registration's last update check time is not null and the time difference in seconds calculated by the
     //   current time minus registration's last update check time is greater than 86400.
-    if (registration->updateViaCache() != ServiceWorkerUpdateViaCache::All
-        || (newestWorker && registration->isStale())) {
-        cachePolicy = FetchOptions::Cache::NoCache;
-    }
-    m_server.startScriptFetch(job, cachePolicy);
+    bool shouldRefreshCache = registration->updateViaCache() != ServiceWorkerUpdateViaCache::All || (newestWorker && registration->isStale());
+    m_server.startScriptFetch(job, shouldRefreshCache);
 }
 
 void SWServerJobQueue::rejectCurrentJob(const ExceptionData& exceptionData)
index 6c0434e..eb931e0 100644 (file)
@@ -45,7 +45,7 @@ public:
 
     const ServiceWorkerJobData& firstJob() const { return m_jobQueue.first(); }
     const ServiceWorkerJobData& lastJob() const { return m_jobQueue.last(); }
-    void enqueueJob(const ServiceWorkerJobData& jobData) { m_jobQueue.append(jobData); }
+    void enqueueJob(ServiceWorkerJobData&& jobData) { m_jobQueue.append(WTFMove(jobData)); }
     size_t size() const { return m_jobQueue.size(); }
 
     void runNextJob();
index 02a0c96..c29b462 100644 (file)
@@ -49,6 +49,7 @@ SWServerRegistration::SWServerRegistration(SWServer& server, const ServiceWorker
     , m_scriptURL(scriptURL)
     , m_server(server)
     , m_creationTime(MonotonicTime::now())
+    , m_softUpdateTimer { *this, &SWServerRegistration::softUpdate }
 {
     m_scopeURL.removeFragmentIdentifier();
 }
@@ -363,18 +364,16 @@ bool SWServerRegistration::shouldSoftUpdate(const FetchOptions& options) const
     return WebCore::isNonSubresourceRequest(options.destination) && isStale();
 }
 
-// https://w3c.github.io/ServiceWorker/#soft-update
 void SWServerRegistration::softUpdate()
 {
-    auto* worker = getNewestWorker();
-    if (!worker)
-        return;
+    m_server.softUpdate(*this);
+}
 
-    // FIXME: We should schedule an update job.
-    m_server.runServiceWorkerIfNecessary(worker->identifier(), [serviceWorkerIdentifier = worker->identifier()](auto* contextConnection) {
-        if (contextConnection)
-            contextConnection->softUpdate(serviceWorkerIdentifier);
-    });
+void SWServerRegistration::scheduleSoftUpdate()
+{
+    // To avoid scheduling many updates during a single page load, we do soft updates on a 1 second delay and keep delaying
+    // as long as soft update requests keep coming. This seems to match Chrome's behavior.
+    m_softUpdateTimer.startOneShot(softUpdateDelay);
 }
 
 } // namespace WebCore
index d0b62c1..705e6a7 100644 (file)
@@ -31,6 +31,7 @@
 #include "ServiceWorkerClientIdentifier.h"
 #include "ServiceWorkerRegistrationData.h"
 #include "ServiceWorkerTypes.h"
+#include "Timer.h"
 #include <wtf/HashCountedSet.h>
 #include <wtf/MonotonicTime.h>
 #include <wtf/WallTime.h>
@@ -98,13 +99,16 @@ public:
     void forEachConnection(const WTF::Function<void(SWServer::Connection&)>&);
 
     WEBCORE_EXPORT bool shouldSoftUpdate(const FetchOptions&) const;
-    WEBCORE_EXPORT void softUpdate();
-    
-    String scopeURLWithoutFragment() const { return m_scopeURL; }
+    WEBCORE_EXPORT void scheduleSoftUpdate();
+    static constexpr Seconds softUpdateDelay { 1_s };
+
+    URL scopeURLWithoutFragment() const { return m_scopeURL; }
+    URL scriptURL() const { return m_scriptURL; }
 
 private:
     void activate();
     void handleClientUnload();
+    void softUpdate();
 
     ServiceWorkerRegistrationIdentifier m_identifier;
     ServiceWorkerRegistrationKey m_registrationKey;
@@ -124,6 +128,8 @@ private:
 
     MonotonicTime m_creationTime;
     HashMap<SWServerConnectionIdentifier, HashSet<DocumentIdentifier>> m_clientsUsingRegistration;
+
+    WebCore::Timer m_softUpdateTimer;
 };
 
 } // namespace WebCore
index d47e9f1..8222999 100644 (file)
@@ -52,7 +52,6 @@ public:
     virtual void installServiceWorkerContext(const ServiceWorkerContextData&, const String& userAgent) = 0;
     virtual void fireInstallEvent(ServiceWorkerIdentifier) = 0;
     virtual void fireActivateEvent(ServiceWorkerIdentifier) = 0;
-    virtual void softUpdate(ServiceWorkerIdentifier) = 0;
     virtual void terminateWorker(ServiceWorkerIdentifier) = 0;
     virtual void syncTerminateWorker(ServiceWorkerIdentifier) = 0;
     virtual void findClientByIdentifierCompleted(uint64_t requestIdentifier, const Optional<ServiceWorkerClientData>&, bool hasSecurityError) = 0;
index 0b92c74..7926245 100644 (file)
@@ -1,3 +1,51 @@
+2019-12-04  youenn fablet  <youenn@apple.com>
+
+        Move soft update handling to network process
+        https://bugs.webkit.org/show_bug.cgi?id=204678
+
+        Reviewed by Chris Dumez.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::swServerForSession):
+        * NetworkProcess/NetworkSession.h:
+        (WebKit::NetworkSession::addSoftUpdateLoader):
+        (WebKit::NetworkSession::removeSoftUpdateLoader):
+        * NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
+        (WebKit::ServiceWorkerFetchTask::ServiceWorkerFetchTask):
+        (WebKit::ServiceWorkerFetchTask::didReceiveRedirectResponse):
+        (WebKit::ServiceWorkerFetchTask::didReceiveResponse):
+        (WebKit::ServiceWorkerFetchTask::didFail):
+        (WebKit::ServiceWorkerFetchTask::didNotHandle):
+        (WebKit::ServiceWorkerFetchTask::continueFetchTaskWith):
+        (WebKit::ServiceWorkerFetchTask::timeoutTimerFired):
+        (WebKit::ServiceWorkerFetchTask::softUpdateIfNeeded):
+        * NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h:
+        * NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp: Added.
+        (WebKit::ServiceWorkerSoftUpdateLoader::start):
+        (WebKit::ServiceWorkerSoftUpdateLoader::ServiceWorkerSoftUpdateLoader):
+        (WebKit::ServiceWorkerSoftUpdateLoader::~ServiceWorkerSoftUpdateLoader):
+        (WebKit::ServiceWorkerSoftUpdateLoader::fail):
+        (WebKit::ServiceWorkerSoftUpdateLoader::loadWithCacheEntry):
+        (WebKit::ServiceWorkerSoftUpdateLoader::loadFromNetwork):
+        (WebKit::ServiceWorkerSoftUpdateLoader::willSendRedirectedRequest):
+        (WebKit::ServiceWorkerSoftUpdateLoader::didReceiveResponse):
+        (WebKit::ServiceWorkerSoftUpdateLoader::didReceiveBuffer):
+        (WebKit::ServiceWorkerSoftUpdateLoader::didFinishLoading):
+        (WebKit::ServiceWorkerSoftUpdateLoader::didFailLoading):
+        (WebKit::ServiceWorkerSoftUpdateLoader::didComplete):
+        * NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.h: Added.
+        * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::createFetchTask):
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
+        * Shared/Authentication/AuthenticationManager.cpp:
+        (WebKit::AuthenticationManager::didReceiveAuthenticationChallenge):
+        * Sources.txt:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+        * WebProcess/Storage/WebSWContextManagerConnection.h:
+        * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
+
 2019-12-04  Tim Horton  <timothy_horton@apple.com>
 
         Introduce a GPU process
index 8b3da0e..1b19b67 100644 (file)
@@ -2349,7 +2349,9 @@ SWServer& NetworkProcess::swServerForSession(PAL::SessionID sessionID)
         // If there's not, then where did this PAL::SessionID come from?
         ASSERT(sessionID.isEphemeral() || !path.isEmpty());
 
-        return makeUnique<SWServer>(makeUniqueRef<WebSWOriginStore>(), info.processTerminationDelayEnabled, WTFMove(path), sessionID, [this, sessionID](auto& registrableDomain) {
+        return makeUnique<SWServer>(makeUniqueRef<WebSWOriginStore>(), info.processTerminationDelayEnabled, WTFMove(path), sessionID, [this, sessionID](auto&& jobData, bool shouldRefreshCache, auto&& request, auto&& completionHandler) mutable {
+            ServiceWorkerSoftUpdateLoader::start(networkSession(sessionID), WTFMove(jobData), shouldRefreshCache, WTFMove(request), WTFMove(completionHandler));
+        }, [this, sessionID](auto& registrableDomain) {
             ASSERT(!registrableDomain.isEmpty());
             parentProcessConnection()->send(Messages::NetworkProcessProxy::EstablishWorkerContextConnectionToNetworkProcess { registrableDomain, sessionID }, 0);
         });
index bc4351f..2a3819c 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "PrefetchCache.h"
 #include "SandboxExtension.h"
+#include "ServiceWorkerSoftUpdateLoader.h"
 #include "WebResourceLoadStatisticsStore.h"
 #include <WebCore/AdClickAttribution.h>
 #include <WebCore/BlobRegistryImpl.h>
@@ -127,6 +128,11 @@ public:
 
     bool isStaleWhileRevalidateEnabled() const { return m_isStaleWhileRevalidateEnabled; }
 
+#if ENABLE(SERVICE_WORKER)
+    void addSoftUpdateLoader(std::unique_ptr<ServiceWorkerSoftUpdateLoader>&& loader) { m_softUpdateLoaders.add(WTFMove(loader)); }
+    void removeSoftUpdateLoader(ServiceWorkerSoftUpdateLoader* loader) { m_softUpdateLoaders.remove(loader); }
+#endif
+
 protected:
     NetworkSession(NetworkProcess&, const NetworkSessionCreationParameters&);
 
@@ -162,6 +168,10 @@ protected:
     RefPtr<NetworkCache::Cache> m_cache;
     WebCore::BlobRegistryImpl m_blobRegistry;
     unsigned m_testSpeedMultiplier { 1 };
+
+#if ENABLE(SERVICE_WORKER)
+    HashSet<std::unique_ptr<ServiceWorkerSoftUpdateLoader>> m_softUpdateLoaders;
+#endif
 };
 
 } // namespace WebKit
index a0eba37..632d5c8 100644 (file)
@@ -41,6 +41,7 @@
 #include "WebSWServerConnection.h"
 #include "WebSWServerToContextConnection.h"
 #include <WebCore/CrossOriginAccessControl.h>
+#include <WebCore/SWServerRegistration.h>
 
 #define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(m_loader.sessionID().isAlwaysOnLoggingAllowed(), ServiceWorker, "%p - ServiceWorkerFetchTask::" fmt, this, ##__VA_ARGS__)
 #define RELEASE_LOG_ERROR_IF_ALLOWED(fmt, ...) RELEASE_LOG_ERROR_IF(m_loader.sessionID().isAlwaysOnLoggingAllowed(), ServiceWorker, "%p - ServiceWorkerFetchTask::" fmt, this, ##__VA_ARGS__)
@@ -49,13 +50,15 @@ using namespace WebCore;
 
 namespace WebKit {
 
-ServiceWorkerFetchTask::ServiceWorkerFetchTask(NetworkResourceLoader& loader, ResourceRequest&& request, SWServerConnectionIdentifier serverConnectionIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, ServiceWorkerRegistrationIdentifier serviceWorkerRegistrationIdentifier)
+ServiceWorkerFetchTask::ServiceWorkerFetchTask(NetworkResourceLoader& loader, ResourceRequest&& request, SWServerConnectionIdentifier serverConnectionIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, ServiceWorkerRegistrationIdentifier serviceWorkerRegistrationIdentifier, bool shouldSoftUpdate)
     : m_loader(loader)
     , m_fetchIdentifier(WebCore::FetchIdentifier::generate())
     , m_serverConnectionIdentifier(serverConnectionIdentifier)
     , m_serviceWorkerIdentifier(serviceWorkerIdentifier)
     , m_currentRequest(WTFMove(request))
     , m_timeoutTimer(*this, &ServiceWorkerFetchTask::timeoutTimerFired)
+    , m_serviceWorkerRegistrationIdentifier(serviceWorkerRegistrationIdentifier)
+    , m_shouldSoftUpdate(shouldSoftUpdate)
 {
     m_timeoutTimer.startOneShot(loader.connectionToWebProcess().networkProcess().serviceWorkerFetchTimeout());
 }
@@ -106,7 +109,8 @@ void ServiceWorkerFetchTask::startFetch()
 void ServiceWorkerFetchTask::didReceiveRedirectResponse(ResourceResponse&& response)
 {
     RELEASE_LOG_IF_ALLOWED("didReceiveRedirectResponse: %s", m_fetchIdentifier.loggingString().utf8().data());
-    m_wasHandled = true;
+    m_timeoutTimer.stop();
+    softUpdateIfNeeded();
 
     response.setSource(ResourceResponse::Source::ServiceWorker);
     auto newRequest = m_currentRequest.redirectedRequest(response, m_loader.parameters().shouldClearReferrerOnHTTPSToHTTPRedirect);
@@ -118,7 +122,7 @@ void ServiceWorkerFetchTask::didReceiveResponse(ResourceResponse&& response, boo
 {
     RELEASE_LOG_IF_ALLOWED("didReceiveResponse: %s", m_fetchIdentifier.loggingString().utf8().data());
     m_timeoutTimer.stop();
-    m_wasHandled = true;
+    softUpdateIfNeeded();
 
     response.setSource(ResourceResponse::Source::ServiceWorker);
     sendToClient(Messages::WebResourceLoader::DidReceiveResponse { response, needsContinueDidReceiveResponseMessage });
@@ -146,7 +150,10 @@ void ServiceWorkerFetchTask::didFinish()
 
 void ServiceWorkerFetchTask::didFail(const ResourceError& error)
 {
-    m_timeoutTimer.stop();
+    if (m_timeoutTimer.isActive()) {
+        m_timeoutTimer.stop();
+        softUpdateIfNeeded();
+    }
     RELEASE_LOG_ERROR_IF_ALLOWED("didFailFetch: fetchIdentifier: %s", m_fetchIdentifier.loggingString().utf8().data());
     m_loader.didFailLoading(error);
 }
@@ -155,6 +162,8 @@ void ServiceWorkerFetchTask::didNotHandle()
 {
     RELEASE_LOG_IF_ALLOWED("didNotHandleFetch: fetchIdentifier: %s", m_fetchIdentifier.loggingString().utf8().data());
     m_timeoutTimer.stop();
+    softUpdateIfNeeded();
+
     m_loader.serviceWorkerDidNotHandle();
 }
 
@@ -171,6 +180,7 @@ void ServiceWorkerFetchTask::continueDidReceiveFetchResponse()
 
 void ServiceWorkerFetchTask::continueFetchTaskWith(ResourceRequest&& request)
 {
+    m_timeoutTimer.startOneShot(m_loader.connectionToWebProcess().networkProcess().serviceWorkerFetchTimeout());
     if (!m_serviceWorkerConnection) {
         m_loader.serviceWorkerDidNotHandle();
         return;
@@ -181,11 +191,21 @@ void ServiceWorkerFetchTask::continueFetchTaskWith(ResourceRequest&& request)
 
 void ServiceWorkerFetchTask::timeoutTimerFired()
 {
+    softUpdateIfNeeded();
+
     RELEASE_LOG_IF_ALLOWED("timeoutTimerFired: fetchIdentifier: %s", m_fetchIdentifier.loggingString().utf8().data());
     if (m_serviceWorkerConnection)
         m_serviceWorkerConnection->fetchTaskTimedOut(serviceWorkerIdentifier());
 }
 
+void ServiceWorkerFetchTask::softUpdateIfNeeded()
+{
+    if (!m_shouldSoftUpdate)
+        return;
+    if (auto* registration = m_loader.connectionToWebProcess().swConnection().server().getRegistration(m_serviceWorkerRegistrationIdentifier))
+        registration->scheduleSoftUpdate();
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(SERVICE_WORKER)
index d716bbe..5db93c1 100644 (file)
@@ -56,7 +56,7 @@ class WebSWServerToContextConnection;
 class ServiceWorkerFetchTask : public CanMakeWeakPtr<ServiceWorkerFetchTask> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    ServiceWorkerFetchTask(NetworkResourceLoader&, WebCore::ResourceRequest&&, WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerRegistrationIdentifier);
+    ServiceWorkerFetchTask(NetworkResourceLoader&, WebCore::ResourceRequest&&, WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerRegistrationIdentifier, bool shouldSoftUpdate);
     ~ServiceWorkerFetchTask();
 
     void start(WebSWServerToContextConnection&);
@@ -88,6 +88,7 @@ private:
     void startFetch();
 
     void timeoutTimerFired();
+    void softUpdateIfNeeded();
 
     template<typename Message> bool sendToServiceWorker(Message&&);
     template<typename Message> bool sendToClient(Message&&);
@@ -100,6 +101,8 @@ private:
     WebCore::ResourceRequest m_currentRequest;
     WebCore::Timer m_timeoutTimer;
     bool m_wasHandled { false };
+    WebCore::ServiceWorkerRegistrationIdentifier m_serviceWorkerRegistrationIdentifier;
+    bool m_shouldSoftUpdate { false };
 };
 
 }
diff --git a/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp b/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp
new file mode 100644 (file)
index 0000000..b74da27
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ServiceWorkerSoftUpdateLoader.h"
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "Logging.h"
+#include "NetworkCache.h"
+#include "NetworkLoad.h"
+#include "NetworkSession.h"
+#include <WebCore/ServiceWorkerFetchResult.h>
+#include <WebCore/ServiceWorkerJob.h>
+#include <WebCore/TextResourceDecoder.h>
+#include <WebCore/WorkerScriptLoader.h>
+
+namespace WebKit {
+
+using namespace WebCore;
+
+void ServiceWorkerSoftUpdateLoader::start(NetworkSession* session, ServiceWorkerJobData&& jobData, bool shouldRefreshCache, ResourceRequest&& request, Handler&& completionHandler)
+{
+    if (!session)
+        return completionHandler(serviceWorkerFetchError(jobData.identifier(), ServiceWorkerRegistrationKey { jobData.registrationKey() }, ResourceError { ResourceError::Type::Cancellation }));
+    auto loader = std::unique_ptr<ServiceWorkerSoftUpdateLoader>(new ServiceWorkerSoftUpdateLoader(*session, WTFMove(jobData), shouldRefreshCache, WTFMove(request), WTFMove(completionHandler)));
+    session->addSoftUpdateLoader(WTFMove(loader));
+}
+
+ServiceWorkerSoftUpdateLoader::ServiceWorkerSoftUpdateLoader(NetworkSession& session, ServiceWorkerJobData&& jobData, bool shouldRefreshCache, ResourceRequest&& request, Handler&& completionHandler)
+    : m_completionHandler(WTFMove(completionHandler))
+    , m_jobData(WTFMove(jobData))
+    , m_session(makeWeakPtr(session))
+{
+    ASSERT(!request.isConditional());
+
+    if (session.cache()) {
+        // We set cache policy to disable speculative loading/async revalidation from the cache.
+        request.setCachePolicy(ResourceRequestCachePolicy::ReturnCacheDataDontLoad);
+        
+        session.cache()->retrieve(request, NetworkCache::GlobalFrameID { }, [this, weakThis = makeWeakPtr(*this), request, shouldRefreshCache](auto&& entry, auto&&) mutable {
+            if (!weakThis)
+                return;
+            if (!m_session) {
+                fail(ResourceError { ResourceError::Type::Cancellation });
+                return;
+            }
+            if (!shouldRefreshCache && entry && !entry->needsValidation()) {
+                loadWithCacheEntry(*entry);
+                return;
+            }
+
+            request.setCachePolicy(ResourceRequestCachePolicy::RefreshAnyCacheData);
+            if (entry) {
+                m_cacheEntry = WTFMove(entry);
+
+                String eTag = m_cacheEntry->response().httpHeaderField(HTTPHeaderName::ETag);
+                if (!eTag.isEmpty())
+                    request.setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag);
+
+                String lastModified = m_cacheEntry->response().httpHeaderField(HTTPHeaderName::LastModified);
+                if (!lastModified.isEmpty())
+                    request.setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified);
+            }
+            loadFromNetwork(*m_session, WTFMove(request));
+        });
+        return;
+    }
+    loadFromNetwork(session, WTFMove(request));
+}
+
+ServiceWorkerSoftUpdateLoader::~ServiceWorkerSoftUpdateLoader()
+{
+    if (m_completionHandler)
+        m_completionHandler(serviceWorkerFetchError(m_jobData.identifier(), ServiceWorkerRegistrationKey { m_jobData.registrationKey() }, ResourceError { ResourceError::Type::Cancellation }));
+}
+
+void ServiceWorkerSoftUpdateLoader::fail(ResourceError&& error)
+{
+    if (!m_completionHandler)
+        return;
+
+    m_completionHandler(serviceWorkerFetchError(m_jobData.identifier(), ServiceWorkerRegistrationKey { m_jobData.registrationKey() }, WTFMove(error)));
+    didComplete();
+}
+
+void ServiceWorkerSoftUpdateLoader::loadWithCacheEntry(NetworkCache::Entry& entry)
+{
+    didReceiveResponse(ResourceResponse { entry.response() }, [](auto) { });
+    if (m_completionHandler && entry.buffer())
+        didReceiveBuffer(makeRef(*entry.buffer()), 0);
+    if (m_completionHandler)
+        didFinishLoading({ });
+    didComplete();
+}
+
+void ServiceWorkerSoftUpdateLoader::loadFromNetwork(NetworkSession& session, ResourceRequest&& request)
+{
+    NetworkLoadParameters parameters;
+    parameters.storedCredentialsPolicy = StoredCredentialsPolicy::Use;
+    parameters.contentSniffingPolicy = ContentSniffingPolicy::DoNotSniffContent;
+    parameters.contentEncodingSniffingPolicy = ContentEncodingSniffingPolicy::Sniff;
+    parameters.request = WTFMove(request);
+    m_networkLoad = makeUnique<NetworkLoad>(*this, nullptr, WTFMove(parameters), session);
+}
+
+void ServiceWorkerSoftUpdateLoader::willSendRedirectedRequest(ResourceRequest&&, ResourceRequest&&, ResourceResponse&&)
+{
+    fail(ResourceError { ResourceError::Type::Cancellation });
+}
+
+// https://w3c.github.io/ServiceWorker/#update-algorithm, steps 9.7 to 9.17
+void ServiceWorkerSoftUpdateLoader::didReceiveResponse(ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
+{
+    if (response.httpStatusCode() == 304 && m_cacheEntry) {
+        loadWithCacheEntry(*m_cacheEntry);
+        completionHandler(PolicyAction::Ignore);
+        return;
+    }
+
+    auto error = WorkerScriptLoader::validateWorkerResponse(response, FetchOptions::Destination::Serviceworker);
+    if (!error.isNull()) {
+        fail(WTFMove(error));
+        completionHandler(PolicyAction::Ignore);
+        return;
+    }
+    error = ServiceWorkerJob::validateServiceWorkerResponse(m_jobData, response);
+    if (!error.isNull()) {
+        fail(WTFMove(error));
+        completionHandler(PolicyAction::Ignore);
+        return;
+    }
+
+    m_contentSecurityPolicy = ContentSecurityPolicyResponseHeaders { response };
+    m_referrerPolicy = response.httpHeaderField(HTTPHeaderName::ReferrerPolicy);
+    m_responseEncoding = response.textEncodingName();
+
+    completionHandler(PolicyAction::Use);
+}
+
+void ServiceWorkerSoftUpdateLoader::didReceiveBuffer(Ref<SharedBuffer>&& buffer, int reportedEncodedDataLength)
+{
+    if (!m_decoder) {
+        if (!m_responseEncoding.isEmpty())
+            m_decoder = TextResourceDecoder::create("text/javascript"_s, m_responseEncoding);
+        else
+            m_decoder = TextResourceDecoder::create("text/javascript"_s, "UTF-8");
+    }
+
+    if (auto size = buffer->size())
+        m_script.append(m_decoder->decode(buffer->data(), size));
+}
+
+void ServiceWorkerSoftUpdateLoader::didFinishLoading(const WebCore::NetworkLoadMetrics&)
+{
+    if (m_decoder)
+        m_script.append(m_decoder->flush());
+    m_completionHandler({ m_jobData.identifier(), m_jobData.registrationKey(), m_script.toString(), m_contentSecurityPolicy, m_referrerPolicy, { } });
+    didComplete();
+}
+
+void ServiceWorkerSoftUpdateLoader::didFailLoading(const ResourceError& error)
+{
+    fail(ResourceError(error));
+}
+
+void ServiceWorkerSoftUpdateLoader::didComplete()
+{
+    m_networkLoad = nullptr;
+    if (m_session)
+        m_session->removeSoftUpdateLoader(this);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(SERVICE_WORKER)
diff --git a/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.h b/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.h
new file mode 100644 (file)
index 0000000..422b125
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "NetworkCacheEntry.h"
+#include "NetworkLoadClient.h"
+#include <WebCore/ContentSecurityPolicyResponseHeaders.h>
+#include <WebCore/FetchOptions.h>
+#include <WebCore/ServiceWorkerJobData.h>
+#include <wtf/CompletionHandler.h>
+#include <wtf/WeakPtr.h>
+
+namespace WebCore {
+struct ServiceWorkerFetchResult;
+struct ServiceWorkerJobData;
+class TextResourceDecoder;
+}
+
+namespace WebKit {
+
+class NetworkLoad;
+class NetworkSession;
+
+class ServiceWorkerSoftUpdateLoader final : public NetworkLoadClient, public CanMakeWeakPtr<ServiceWorkerSoftUpdateLoader> {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    using Handler = CompletionHandler<void(const WebCore::ServiceWorkerFetchResult&)>;
+    static void start(NetworkSession*, WebCore::ServiceWorkerJobData&&, bool shouldRefreshCache, WebCore::ResourceRequest&&, Handler&&);
+
+    ~ServiceWorkerSoftUpdateLoader();
+    
+private:
+    ServiceWorkerSoftUpdateLoader(NetworkSession&, WebCore::ServiceWorkerJobData&&, bool shouldRefreshCache, WebCore::ResourceRequest&&, Handler&&);
+
+    // NetworkLoadClient.
+    void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) final { }
+    bool isSynchronous() const final { return false; }
+    bool isAllowedToAskUserForCredentials() const final { return false; }
+    void willSendRedirectedRequest(WebCore::ResourceRequest&&, WebCore::ResourceRequest&& redirectRequest, WebCore::ResourceResponse&& redirectResponse) final;
+    void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) final;
+    void didReceiveBuffer(Ref<WebCore::SharedBuffer>&&, int reportedEncodedDataLength) final;
+    void didFinishLoading(const WebCore::NetworkLoadMetrics&) final;
+    void didFailLoading(const WebCore::ResourceError&) final;
+
+    void loadWithCacheEntry(NetworkCache::Entry&);
+    void loadFromNetwork(NetworkSession&, WebCore::ResourceRequest&&);
+    void fail(WebCore::ResourceError&&);
+    void didComplete();
+
+    Handler m_completionHandler;
+    WebCore::ServiceWorkerJobData m_jobData;
+    std::unique_ptr<NetworkLoad> m_networkLoad;
+    WeakPtr<NetworkSession> m_session;
+
+    String m_responseEncoding;
+    String m_referrerPolicy;
+    WebCore::ContentSecurityPolicyResponseHeaders m_contentSecurityPolicy;
+
+    std::unique_ptr<NetworkCache::Entry> m_cacheEntry;
+    RefPtr<WebCore::TextResourceDecoder> m_decoder;
+    StringBuilder m_script;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(SERVICE_WORKER)
+
index 5606570..9c24c28 100644 (file)
@@ -177,14 +177,15 @@ std::unique_ptr<ServiceWorkerFetchTask> WebSWServerConnection::createFetchTask(N
         return nullptr;
     }
 
+    auto* registration = server().getRegistration(*serviceWorkerRegistrationIdentifier);
+    bool shouldSoftUpdate = registration && registration->shouldSoftUpdate(loader.parameters().options);
     if (worker->shouldSkipFetchEvent()) {
-        auto* registration = server().getRegistration(worker->registrationKey());
-        if (registration && registration->shouldSoftUpdate(loader.parameters().options))
-            registration->softUpdate();
+        if (shouldSoftUpdate)
+            registration->scheduleSoftUpdate();
         return nullptr;
     }
 
-    auto task = makeUnique<ServiceWorkerFetchTask>(loader, ResourceRequest { request }, identifier(), worker->identifier(), *serviceWorkerRegistrationIdentifier);
+    auto task = makeUnique<ServiceWorkerFetchTask>(loader, ResourceRequest { request }, identifier(), worker->identifier(), *serviceWorkerRegistrationIdentifier, shouldSoftUpdate);
     startFetch(*task, *worker);
     return task;
 }
index b835c56..4f2bf1b 100644 (file)
@@ -100,11 +100,6 @@ void WebSWServerToContextConnection::fireActivateEvent(ServiceWorkerIdentifier s
     send(Messages::WebSWContextManagerConnection::FireActivateEvent(serviceWorkerIdentifier));
 }
 
-void WebSWServerToContextConnection::softUpdate(ServiceWorkerIdentifier serviceWorkerIdentifier)
-{
-    send(Messages::WebSWContextManagerConnection::SoftUpdate(serviceWorkerIdentifier));
-}
-
 void WebSWServerToContextConnection::terminateWorker(ServiceWorkerIdentifier serviceWorkerIdentifier)
 {
     send(Messages::WebSWContextManagerConnection::TerminateWorker(serviceWorkerIdentifier));
index ef4f413..04c8d63 100644 (file)
@@ -88,7 +88,6 @@ private:
     void installServiceWorkerContext(const WebCore::ServiceWorkerContextData&, const String& userAgent) final;
     void fireInstallEvent(WebCore::ServiceWorkerIdentifier) final;
     void fireActivateEvent(WebCore::ServiceWorkerIdentifier) final;
-    void softUpdate(WebCore::ServiceWorkerIdentifier) final;
     void terminateWorker(WebCore::ServiceWorkerIdentifier) final;
     void syncTerminateWorker(WebCore::ServiceWorkerIdentifier) final;
     void findClientByIdentifierCompleted(uint64_t requestIdentifier, const Optional<WebCore::ServiceWorkerClientData>&, bool hasSecurityError) final;
index f24e671..56a6d65 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "AuthenticationManager.h"
 
+#include "AuthenticationChallengeDisposition.h"
 #include "AuthenticationManagerMessages.h"
 #include "Download.h"
 #include "DownloadProxyMessages.h"
@@ -110,7 +111,8 @@ Vector<uint64_t> AuthenticationManager::coalesceChallengesMatching(uint64_t chal
 
 void AuthenticationManager::didReceiveAuthenticationChallenge(PAL::SessionID sessionID, WebPageProxyIdentifier pageID, const SecurityOriginData* topOrigin, const AuthenticationChallenge& authenticationChallenge, ChallengeCompletionHandler&& completionHandler)
 {
-    ASSERT(pageID);
+    if (!pageID)
+        return completionHandler(AuthenticationChallengeDisposition::PerformDefaultHandling, { });
 
     uint64_t challengeID = addChallengeToChallengeMap({ pageID, authenticationChallenge, WTFMove(completionHandler) });
 
index 3f2d3d0..73ff4d2 100644 (file)
@@ -65,6 +65,7 @@ NetworkProcess/Downloads/PendingDownload.cpp
 NetworkProcess/IndexedDB/WebIDBConnectionToClient.cpp
 
 NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp @no-unify
+NetworkProcess/ServiceWorker/ServiceWorkerSoftUpdateLoader.cpp
 NetworkProcess/ServiceWorker/WebSWOriginStore.cpp @no-unify
 NetworkProcess/ServiceWorker/WebSWServerConnection.cpp @no-unify
 NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp @no-unify
index cb80182..b52455a 100644 (file)
                41C5378F21F1362D008B1FAD /* _WKWebsiteDataStoreDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKWebsiteDataStoreDelegate.h; sourceTree = "<group>"; };
                41C858191F510DEE0065E085 /* CacheStorageEngineCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheStorageEngineCache.cpp; sourceTree = "<group>"; };
                41D129D91F3D101400D15E47 /* WebCacheStorageProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebCacheStorageProvider.h; sourceTree = "<group>"; };
+               41D5C6D8238EB20D00B9B3CB /* ServiceWorkerSoftUpdateLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerSoftUpdateLoader.h; sourceTree = "<group>"; };
+               41D5C6D9238EB20E00B9B3CB /* ServiceWorkerSoftUpdateLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerSoftUpdateLoader.cpp; sourceTree = "<group>"; };
                41DC45941E3D6E1E00B11F51 /* NetworkRTCProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkRTCProvider.h; sourceTree = "<group>"; };
                41DC45951E3D6E1E00B11F51 /* NetworkRTCProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkRTCProvider.cpp; sourceTree = "<group>"; };
                41DC45981E3D6ED600B11F51 /* NetworkRTCProvider.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NetworkRTCProvider.messages.in; sourceTree = "<group>"; };
                                41518536222704F6005430C6 /* ServiceWorkerFetchTask.cpp */,
                                41518535222704F5005430C6 /* ServiceWorkerFetchTask.h */,
                                4151853822270F53005430C6 /* ServiceWorkerFetchTask.messages.in */,
+                               41D5C6D9238EB20E00B9B3CB /* ServiceWorkerSoftUpdateLoader.cpp */,
+                               41D5C6D8238EB20D00B9B3CB /* ServiceWorkerSoftUpdateLoader.h */,
                                93BA04DF2151ADF4007F455F /* WebSWOriginStore.cpp */,
                                93BA04DE2151ADF4007F455F /* WebSWOriginStore.h */,
                                93BA04E12151ADF4007F455F /* WebSWServerConnection.cpp */,
index ecf7a3b..2dd75cc 100644 (file)
@@ -256,11 +256,6 @@ void WebSWContextManagerConnection::fireActivateEvent(ServiceWorkerIdentifier id
     SWContextManager::singleton().fireActivateEvent(identifier);
 }
 
-void WebSWContextManagerConnection::softUpdate(WebCore::ServiceWorkerIdentifier identifier)
-{
-    SWContextManager::singleton().softUpdate(identifier);
-}
-
 void WebSWContextManagerConnection::terminateWorker(ServiceWorkerIdentifier identifier)
 {
     SWContextManager::singleton().terminateWorker(identifier, SWContextManager::workerTerminationTimeout, nullptr);
index 297351f..6990332 100644 (file)
@@ -90,7 +90,6 @@ private:
     void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destinationIdentifier, WebCore::MessageWithMessagePorts&&, WebCore::ServiceWorkerOrClientData&& sourceData);
     void fireInstallEvent(WebCore::ServiceWorkerIdentifier);
     void fireActivateEvent(WebCore::ServiceWorkerIdentifier);
-    void softUpdate(WebCore::ServiceWorkerIdentifier);
     void terminateWorker(WebCore::ServiceWorkerIdentifier);
     void syncTerminateWorker(WebCore::ServiceWorkerIdentifier, Messages::WebSWContextManagerConnection::SyncTerminateWorkerDelayedReply&&);
     void findClientByIdentifierCompleted(uint64_t requestIdentifier, Optional<WebCore::ServiceWorkerClientData>&&, bool hasSecurityError);
index 1be29aa..1d339cc 100644 (file)
@@ -30,7 +30,6 @@ messages -> WebSWContextManagerConnection NotRefCounted {
     PostMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destinationIdentifier, struct WebCore::MessageWithMessagePorts message, WebCore::ServiceWorkerOrClientData sourceData)
     FireInstallEvent(WebCore::ServiceWorkerIdentifier identifier)
     FireActivateEvent(WebCore::ServiceWorkerIdentifier identifier)
-    SoftUpdate(WebCore::ServiceWorkerIdentifier identifier)
     TerminateWorker(WebCore::ServiceWorkerIdentifier identifier)
     SyncTerminateWorker(WebCore::ServiceWorkerIdentifier identifier) -> () Synchronous
     FindClientByIdentifierCompleted(uint64_t clientIdRequestIdentifier, Optional<WebCore::ServiceWorkerClientData> data, bool hasSecurityError)