Service worker script fetching currently always uses the network cache
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Dec 2017 19:55:01 +0000 (19:55 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Dec 2017 19:55:01 +0000 (19:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180816

Reviewed by Alex Christensen.

Source/WebCore:

Service worker script fetching currently always uses the network cache. This is incorrect as per:
- https://w3c.github.io/ServiceWorker/#update-algorithm (step 7.2)

Tests: http/tests/workers/service/registration-updateViaCache-all.html
       http/tests/workers/service/registration-updateViaCache-none.html

* workers/Worker.cpp:
(WebCore::Worker::create):
* workers/WorkerScriptLoader.cpp:
(WebCore::WorkerScriptLoader::loadAsynchronously):
* workers/WorkerScriptLoader.h:
* workers/service/SWClientConnection.cpp:
(WebCore::SWClientConnection::startScriptFetchForServer):
* workers/service/SWClientConnection.h:
* workers/service/ServiceWorkerContainer.cpp:
(WebCore::ServiceWorkerContainer::startScriptFetchForJob):
* workers/service/ServiceWorkerContainer.h:
* workers/service/ServiceWorkerJob.cpp:
(WebCore::ServiceWorkerJob::startScriptFetch):
(WebCore::ServiceWorkerJob::fetchScriptWithContext):
* workers/service/ServiceWorkerJob.h:
* workers/service/ServiceWorkerJobClient.h:
* workers/service/server/SWServer.cpp:
(WebCore::SWServer::startScriptFetch):
* workers/service/server/SWServer.h:
* workers/service/server/SWServerJobQueue.cpp:
(WebCore::SWServerJobQueue::runUpdateJob):
* workers/service/server/SWServerRegistration.h:
(WebCore::SWServerRegistration::lastUpdateTime const):

Source/WebKit:

* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::startScriptFetchInClient):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
* WebProcess/Storage/WebSWClientConnection.messages.in:

LayoutTests:

Add layout test coverage.

* http/tests/workers/service/registration-updateViaCache-all-expected.txt: Added.
* http/tests/workers/service/registration-updateViaCache-all.html: Added.
* http/tests/workers/service/registration-updateViaCache-none-expected.txt: Added.
* http/tests/workers/service/registration-updateViaCache-none.html: Added.
* http/tests/workers/service/resources/cacheable-script-worker.php: Added.

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

25 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/workers/service/registration-updateViaCache-all-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/workers/service/registration-updateViaCache-all.html [new file with mode: 0644]
LayoutTests/http/tests/workers/service/registration-updateViaCache-none-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/workers/service/registration-updateViaCache-none.html [new file with mode: 0644]
LayoutTests/http/tests/workers/service/resources/cacheable-script-worker.php [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/workers/Worker.cpp
Source/WebCore/workers/WorkerScriptLoader.cpp
Source/WebCore/workers/WorkerScriptLoader.h
Source/WebCore/workers/service/SWClientConnection.cpp
Source/WebCore/workers/service/SWClientConnection.h
Source/WebCore/workers/service/ServiceWorkerContainer.cpp
Source/WebCore/workers/service/ServiceWorkerContainer.h
Source/WebCore/workers/service/ServiceWorkerJob.cpp
Source/WebCore/workers/service/ServiceWorkerJob.h
Source/WebCore/workers/service/ServiceWorkerJobClient.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/SWServerRegistration.h
Source/WebKit/ChangeLog
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h
Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in

index 25a43a8..8d46ec9 100644 (file)
@@ -1,3 +1,18 @@
+2017-12-14  Chris Dumez  <cdumez@apple.com>
+
+        Service worker script fetching currently always uses the network cache
+        https://bugs.webkit.org/show_bug.cgi?id=180816
+
+        Reviewed by Alex Christensen.
+
+        Add layout test coverage.
+
+        * http/tests/workers/service/registration-updateViaCache-all-expected.txt: Added.
+        * http/tests/workers/service/registration-updateViaCache-all.html: Added.
+        * http/tests/workers/service/registration-updateViaCache-none-expected.txt: Added.
+        * http/tests/workers/service/registration-updateViaCache-none.html: Added.
+        * http/tests/workers/service/resources/cacheable-script-worker.php: Added.
+
 2017-12-14  Matt Lewis  <jlewis3@apple.com>
 
         Updated test expectations for imported/w3c/web-platform-tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/parsing.html.
diff --git a/LayoutTests/http/tests/workers/service/registration-updateViaCache-all-expected.txt b/LayoutTests/http/tests/workers/service/registration-updateViaCache-all-expected.txt
new file mode 100644 (file)
index 0000000..bf57996
--- /dev/null
@@ -0,0 +1,2 @@
+PASS: The worker script came from the network cache
+
diff --git a/LayoutTests/http/tests/workers/service/registration-updateViaCache-all.html b/LayoutTests/http/tests/workers/service/registration-updateViaCache-all.html
new file mode 100644 (file)
index 0000000..20f76b7
--- /dev/null
@@ -0,0 +1,43 @@
+<html>
+<head>
+<script src="resources/sw-test-pre.js"></script>
+</head>
+<body>
+<script>
+
+function getRandomIdFromWorker(worker)
+{
+    worker.postMessage("getRandomId");
+    return new Promise(function(resolve) {
+      navigator.serviceWorker.addEventListener('message', function(e) {
+            resolve(e.data);
+        });
+    });
+}
+
+async function test()
+{
+    try {
+        let registration = await navigator.serviceWorker.register("resources/cacheable-script-worker.php", { updateViaCache: "all" });
+        let worker1 = registration.installing;
+        await waitForState(worker1, "activated");
+        let randomId1 = await getRandomIdFromWorker(worker1);
+
+        await registration.update();
+        let worker2 = registration.installing;
+        await waitForState(worker2, "activated");
+        let randomId2 = await getRandomIdFromWorker(worker2);
+
+        if (randomId1 === randomId2)
+            log("PASS: The worker script came from the network cache");
+        else
+            log("FAIL: The worker script did not come from the network cache");
+    } catch(e) {
+        log("Got exception: " + e);
+    }
+    finishSWTest();
+}
+test();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/workers/service/registration-updateViaCache-none-expected.txt b/LayoutTests/http/tests/workers/service/registration-updateViaCache-none-expected.txt
new file mode 100644 (file)
index 0000000..1711a65
--- /dev/null
@@ -0,0 +1,2 @@
+PASS: The worker script did not come from the network cache
+
diff --git a/LayoutTests/http/tests/workers/service/registration-updateViaCache-none.html b/LayoutTests/http/tests/workers/service/registration-updateViaCache-none.html
new file mode 100644 (file)
index 0000000..1fd46fa
--- /dev/null
@@ -0,0 +1,43 @@
+<html>
+<head>
+<script src="resources/sw-test-pre.js"></script>
+</head>
+<body>
+<script>
+
+function getRandomIdFromWorker(worker)
+{
+    worker.postMessage("getRandomId");
+    return new Promise(function(resolve) {
+      navigator.serviceWorker.addEventListener('message', function(e) {
+            resolve(e.data);
+        });
+    });
+}
+
+async function test()
+{
+    try {
+        let registration = await navigator.serviceWorker.register("resources/cacheable-script-worker.php", { updateViaCache: "none" });
+        let worker1 = registration.installing;
+        await waitForState(worker1, "activated");
+        let randomId1 = await getRandomIdFromWorker(worker1);
+
+        await registration.update();
+        let worker2 = registration.installing;
+        await waitForState(worker2, "activated");
+        let randomId2 = await getRandomIdFromWorker(worker2);
+
+        if (randomId1 === randomId2)
+            log("FAIL: The worker script came from the network cache");
+        else
+            log("PASS: The worker script did not come from the network cache");
+    } catch(e) {
+        log("Got exception: " + e);
+    }
+    finishSWTest();
+}
+test();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/workers/service/resources/cacheable-script-worker.php b/LayoutTests/http/tests/workers/service/resources/cacheable-script-worker.php
new file mode 100644 (file)
index 0000000..051367c
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+    $max_age = 12 * 31 * 24 * 60 * 60; //one year
+    header('Cache-Control: public, max-age=' . $max_age);
+    header('Content-Type: text/javascript');
+
+    $randomId = '';
+    $charset = 'ABCDEFGHIKLMNOPQRSTUVWXYZ0123456789';
+    for ($i = 0; $i < 16; $i++)
+        $randomId .= $charset[rand(0, strlen($charset) - 1)];
+
+    echo 'let randomId = "' . $randomId . '";';
+?>
+
+self.addEventListener("message", function(e) {
+   e.source.postMessage(randomId);
+});
index 0161264..9c92717 100644 (file)
@@ -1,3 +1,40 @@
+2017-12-14  Chris Dumez  <cdumez@apple.com>
+
+        Service worker script fetching currently always uses the network cache
+        https://bugs.webkit.org/show_bug.cgi?id=180816
+
+        Reviewed by Alex Christensen.
+
+        Service worker script fetching currently always uses the network cache. This is incorrect as per:
+        - https://w3c.github.io/ServiceWorker/#update-algorithm (step 7.2)
+
+        Tests: http/tests/workers/service/registration-updateViaCache-all.html
+               http/tests/workers/service/registration-updateViaCache-none.html
+
+        * workers/Worker.cpp:
+        (WebCore::Worker::create):
+        * workers/WorkerScriptLoader.cpp:
+        (WebCore::WorkerScriptLoader::loadAsynchronously):
+        * workers/WorkerScriptLoader.h:
+        * workers/service/SWClientConnection.cpp:
+        (WebCore::SWClientConnection::startScriptFetchForServer):
+        * workers/service/SWClientConnection.h:
+        * workers/service/ServiceWorkerContainer.cpp:
+        (WebCore::ServiceWorkerContainer::startScriptFetchForJob):
+        * workers/service/ServiceWorkerContainer.h:
+        * workers/service/ServiceWorkerJob.cpp:
+        (WebCore::ServiceWorkerJob::startScriptFetch):
+        (WebCore::ServiceWorkerJob::fetchScriptWithContext):
+        * workers/service/ServiceWorkerJob.h:
+        * workers/service/ServiceWorkerJobClient.h:
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::startScriptFetch):
+        * workers/service/server/SWServer.h:
+        * workers/service/server/SWServerJobQueue.cpp:
+        (WebCore::SWServerJobQueue::runUpdateJob):
+        * workers/service/server/SWServerRegistration.h:
+        (WebCore::SWServerRegistration::lastUpdateTime const):
+
 2017-12-14  Simon Fraser  <simon.fraser@apple.com>
 
         Remove ColorSpaceDeviceRGB and most users of the obsolete deviceRGB colorspace
index 390ca2c..05f17d8 100644 (file)
@@ -98,7 +98,7 @@ ExceptionOr<Ref<Worker>> Worker::create(ScriptExecutionContext& context, JSC::Ru
 
     worker->m_scriptLoader = WorkerScriptLoader::create();
     auto contentSecurityPolicyEnforcement = shouldBypassMainWorldContentSecurityPolicy ? ContentSecurityPolicyEnforcement::DoNotEnforce : ContentSecurityPolicyEnforcement::EnforceChildSrcDirective;
-    worker->m_scriptLoader->loadAsynchronously(&context, scriptURL.releaseReturnValue(), FetchOptions::Mode::SameOrigin, contentSecurityPolicyEnforcement, worker->m_identifier, worker.ptr());
+    worker->m_scriptLoader->loadAsynchronously(&context, scriptURL.releaseReturnValue(), FetchOptions::Mode::SameOrigin, FetchOptions::Cache::Default, contentSecurityPolicyEnforcement, worker->m_identifier, worker.ptr());
     return WTFMove(worker);
 }
 
index 36db2f9..855bd86 100644 (file)
@@ -72,7 +72,7 @@ void WorkerScriptLoader::loadSynchronously(ScriptExecutionContext* scriptExecuti
     WorkerThreadableLoader::loadResourceSynchronously(workerGlobalScope, WTFMove(*request), *this, options);
 }
 
-void WorkerScriptLoader::loadAsynchronously(ScriptExecutionContext* scriptExecutionContext, const URL& url, FetchOptions::Mode mode, ContentSecurityPolicyEnforcement contentSecurityPolicyEnforcement, const String& initiatorIdentifier, WorkerScriptLoaderClient* client)
+void WorkerScriptLoader::loadAsynchronously(ScriptExecutionContext* scriptExecutionContext, const URL& url, FetchOptions::Mode mode, FetchOptions::Cache cachePolicy, ContentSecurityPolicyEnforcement contentSecurityPolicyEnforcement, const String& initiatorIdentifier, WorkerScriptLoaderClient* client)
 {
     ASSERT(client);
     ASSERT(scriptExecutionContext);
@@ -91,6 +91,7 @@ void WorkerScriptLoader::loadAsynchronously(ScriptExecutionContext* scriptExecut
     ThreadableLoaderOptions options;
     options.credentials = FetchOptions::Credentials::SameOrigin;
     options.mode = mode;
+    options.cache = cachePolicy;
     options.sendLoadCallbacks = SendCallbacks;
     options.contentSecurityPolicyEnforcement = contentSecurityPolicyEnforcement;
 #if ENABLE(SERVICE_WORKER)
index a86c574..c81f86c 100644 (file)
@@ -53,7 +53,7 @@ public:
     }
 
     void loadSynchronously(ScriptExecutionContext*, const URL&, FetchOptions::Mode, ContentSecurityPolicyEnforcement, const String& initiatorIdentifier);
-    void loadAsynchronously(ScriptExecutionContext*, const URL&, FetchOptions::Mode, ContentSecurityPolicyEnforcement, const String& initiatorIdentifier, WorkerScriptLoaderClient*);
+    void loadAsynchronously(ScriptExecutionContext*, const URL&, FetchOptions::Mode, FetchOptions::Cache, ContentSecurityPolicyEnforcement, const String& initiatorIdentifier, WorkerScriptLoaderClient*);
 
     void notifyError();
 
index 98a4229..8f6e5a5 100644 (file)
@@ -116,7 +116,7 @@ void SWClientConnection::unregistrationJobResolvedInServer(const ServiceWorkerJo
     });
 }
 
-void SWClientConnection::startScriptFetchForServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier)
+void SWClientConnection::startScriptFetchForServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, FetchOptions::Cache cachePolicy)
 {
     ASSERT(isMainThread());
 
@@ -131,8 +131,8 @@ void SWClientConnection::startScriptFetchForServer(const ServiceWorkerJobDataIde
         return;
     }
 
-    ScriptExecutionContext::postTaskTo(job->contextIdentifier(), [job](ScriptExecutionContext&) {
-        job->startScriptFetch();
+    ScriptExecutionContext::postTaskTo(job->contextIdentifier(), [job, cachePolicy](ScriptExecutionContext&) {
+        job->startScriptFetch(cachePolicy);
     });
 }
 
index 11c02ee..1c511f2 100644 (file)
@@ -89,7 +89,7 @@ protected:
     WEBCORE_EXPORT void jobRejectedInServer(const ServiceWorkerJobDataIdentifier&, const ExceptionData&);
     WEBCORE_EXPORT void registrationJobResolvedInServer(const ServiceWorkerJobDataIdentifier&, ServiceWorkerRegistrationData&&, ShouldNotifyWhenResolved);
     WEBCORE_EXPORT void unregistrationJobResolvedInServer(const ServiceWorkerJobDataIdentifier&, bool unregistrationResult);
-    WEBCORE_EXPORT void startScriptFetchForServer(const ServiceWorkerJobDataIdentifier&);
+    WEBCORE_EXPORT void startScriptFetchForServer(const ServiceWorkerJobDataIdentifier&, FetchOptions::Cache);
     WEBCORE_EXPORT void postMessageToServiceWorkerClient(DocumentIdentifier destinationContextIdentifier, Ref<SerializedScriptValue>&& message, ServiceWorkerData&& source, const String& sourceOrigin);
     WEBCORE_EXPORT void updateRegistrationState(ServiceWorkerRegistrationIdentifier, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerData>&);
     WEBCORE_EXPORT void updateWorkerState(ServiceWorkerIdentifier, ServiceWorkerState);
index 4ce585c..c9e1911 100644 (file)
@@ -431,7 +431,7 @@ void ServiceWorkerContainer::jobResolvedWithUnregistrationResult(ServiceWorkerJo
     });
 }
 
-void ServiceWorkerContainer::startScriptFetchForJob(ServiceWorkerJob& job)
+void ServiceWorkerContainer::startScriptFetchForJob(ServiceWorkerJob& job, FetchOptions::Cache cachePolicy)
 {
 #ifndef NDEBUG
     ASSERT(m_creationThread.ptr() == &Thread::current());
@@ -449,7 +449,7 @@ void ServiceWorkerContainer::startScriptFetchForJob(ServiceWorkerJob& job)
         return;
     }
 
-    job.fetchScriptWithContext(*context);
+    job.fetchScriptWithContext(*context, cachePolicy);
 }
 
 void ServiceWorkerContainer::jobFinishedLoadingScript(ServiceWorkerJob& job, const String& script)
index 7f7ce82..dc68439 100644 (file)
@@ -88,7 +88,7 @@ private:
     void jobFailedWithException(ServiceWorkerJob&, const Exception&) final;
     void jobResolvedWithRegistration(ServiceWorkerJob&, ServiceWorkerRegistrationData&&, ShouldNotifyWhenResolved) final;
     void jobResolvedWithUnregistrationResult(ServiceWorkerJob&, bool unregistrationResult) final;
-    void startScriptFetchForJob(ServiceWorkerJob&) final;
+    void startScriptFetchForJob(ServiceWorkerJob&, FetchOptions::Cache) final;
     void jobFinishedLoadingScript(ServiceWorkerJob&, const String&) final;
     void jobFailedLoadingScript(ServiceWorkerJob&, const ResourceError&, std::optional<Exception>&&) final;
 
index 4a881d7..d28494f 100644 (file)
@@ -77,22 +77,22 @@ void ServiceWorkerJob::resolvedWithUnregistrationResult(bool unregistrationResul
     m_client->jobResolvedWithUnregistrationResult(*this, unregistrationResult);
 }
 
-void ServiceWorkerJob::startScriptFetch()
+void ServiceWorkerJob::startScriptFetch(FetchOptions::Cache cachePolicy)
 {
     ASSERT(m_creationThread.ptr() == &Thread::current());
     ASSERT(!m_completed);
 
-    m_client->startScriptFetchForJob(*this);
+    m_client->startScriptFetchForJob(*this, cachePolicy);
 }
 
-void ServiceWorkerJob::fetchScriptWithContext(ScriptExecutionContext& context)
+void ServiceWorkerJob::fetchScriptWithContext(ScriptExecutionContext& context, FetchOptions::Cache cachePolicy)
 {
     ASSERT(m_creationThread.ptr() == &Thread::current());
     ASSERT(!m_completed);
 
     // FIXME: WorkerScriptLoader is the wrong loader class to use here, but there's nothing else better right now.
     m_scriptLoader = WorkerScriptLoader::create();
-    m_scriptLoader->loadAsynchronously(&context, m_jobData.scriptURL, FetchOptions::Mode::SameOrigin, ContentSecurityPolicyEnforcement::DoNotEnforce, "serviceWorkerScriptLoad:", this);
+    m_scriptLoader->loadAsynchronously(&context, m_jobData.scriptURL, FetchOptions::Mode::SameOrigin, cachePolicy, ContentSecurityPolicyEnforcement::DoNotEnforce, "serviceWorkerScriptLoad:", this);
 }
 
 void ServiceWorkerJob::didReceiveResponse(unsigned long, const ResourceResponse& response)
index 9c428e7..ea7a7a3 100644 (file)
@@ -58,7 +58,7 @@ public:
     void failedWithException(const Exception&);
     void resolvedWithRegistration(ServiceWorkerRegistrationData&&, ShouldNotifyWhenResolved);
     void resolvedWithUnregistrationResult(bool);
-    void startScriptFetch();
+    void startScriptFetch(FetchOptions::Cache);
 
     using Identifier = ServiceWorkerJobIdentifier;
     Identifier identifier() const { return m_jobData.identifier().jobIdentifier; }
@@ -66,7 +66,7 @@ public:
     ServiceWorkerJobData data() const { return m_jobData; }
     DeferredPromise& promise() { return m_promise.get(); }
 
-    void fetchScriptWithContext(ScriptExecutionContext&);
+    void fetchScriptWithContext(ScriptExecutionContext&, FetchOptions::Cache);
 
     const DocumentOrWorkerIdentifier& contextIdentifier() { return m_contextIdentifier; }
 
index f103b27..a4cda6c 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "FetchOptions.h"
 #include "ServiceWorkerTypes.h"
 
 namespace WebCore {
@@ -46,7 +47,7 @@ public:
     virtual void jobFailedWithException(ServiceWorkerJob&, const Exception&) = 0;
     virtual void jobResolvedWithRegistration(ServiceWorkerJob&, ServiceWorkerRegistrationData&&, ShouldNotifyWhenResolved) = 0;
     virtual void jobResolvedWithUnregistrationResult(ServiceWorkerJob&, bool unregistrationResult) = 0;
-    virtual void startScriptFetchForJob(ServiceWorkerJob&) = 0;
+    virtual void startScriptFetchForJob(ServiceWorkerJob&, FetchOptions::Cache) = 0;
     virtual void jobFinishedLoadingScript(ServiceWorkerJob&, const String&) = 0;
     virtual void jobFailedLoadingScript(ServiceWorkerJob&, const ResourceError&, std::optional<Exception>&&) = 0;
 
index a1b66d1..2ca63e5 100644 (file)
@@ -284,14 +284,14 @@ void SWServer::resolveUnregistrationJob(const ServiceWorkerJobData& jobData, con
     connection->resolveUnregistrationJobInClient(jobData.identifier(), registrationKey, unregistrationResult);
 }
 
-void SWServer::startScriptFetch(const ServiceWorkerJobData& jobData)
+void SWServer::startScriptFetch(const ServiceWorkerJobData& jobData, FetchOptions::Cache cachePolicy)
 {
     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)
         return;
 
-    connection->startScriptFetchInClient(jobData.identifier());
+    connection->startScriptFetchInClient(jobData.identifier(), cachePolicy);
 }
 
 void SWServer::scriptFetchFinished(Connection& connection, const ServiceWorkerFetchResult& result)
index 5c2e043..4e7c8c3 100644 (file)
@@ -101,7 +101,7 @@ public:
         virtual void rejectJobInClient(const ServiceWorkerJobDataIdentifier&, const ExceptionData&) = 0;
         virtual void resolveRegistrationJobInClient(const ServiceWorkerJobDataIdentifier&, const ServiceWorkerRegistrationData&, ShouldNotifyWhenResolved) = 0;
         virtual void resolveUnregistrationJobInClient(const ServiceWorkerJobDataIdentifier&, const ServiceWorkerRegistrationKey&, bool registrationResult) = 0;
-        virtual void startScriptFetchInClient(const ServiceWorkerJobDataIdentifier&) = 0;
+        virtual void startScriptFetchInClient(const ServiceWorkerJobDataIdentifier&, FetchOptions::Cache) = 0;
 
         struct RegistrationReadyRequest {
             SecurityOriginData topOrigin;
@@ -129,7 +129,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&);
+    void startScriptFetch(const ServiceWorkerJobData&, FetchOptions::Cache);
 
     void postTask(CrossThreadTask&&);
     void postTaskReply(CrossThreadTask&&);
index 65e8469..c906013 100644 (file)
@@ -307,7 +307,17 @@ void SWServerJobQueue::runUpdateJob(const ServiceWorkerJobData& job)
     if (job.type == ServiceWorkerJobType::Update && newestWorker && !equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()))
         return rejectCurrentJob(ExceptionData { TypeError, ASCIILiteral("Cannot update a service worker with a requested script URL whose newest worker has a different script URL") });
 
-    m_server.startScriptFetch(job);
+    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->lastUpdateTime() && (WallTime::now() - registration->lastUpdateTime()) > 86400_s)) {
+        cachePolicy = FetchOptions::Cache::NoCache;
+    }
+    m_server.startScriptFetch(job, cachePolicy);
 }
 
 void SWServerJobQueue::rejectCurrentJob(const ExceptionData& exceptionData)
index f14df5c..fb75698 100644 (file)
@@ -61,6 +61,8 @@ public:
     void setIsUninstalling(bool);
 
     void setLastUpdateTime(WallTime time) { m_lastUpdateTime = time; }
+    WallTime lastUpdateTime() const { return m_lastUpdateTime; }
+
     ServiceWorkerUpdateViaCache updateViaCache() const { return m_updateViaCache; }
 
     void updateRegistrationState(ServiceWorkerRegistrationState, SWServerWorker*);
index 801fabd..b0975d1 100644 (file)
@@ -1,5 +1,17 @@
 2017-12-14  Chris Dumez  <cdumez@apple.com>
 
+        Service worker script fetching currently always uses the network cache
+        https://bugs.webkit.org/show_bug.cgi?id=180816
+
+        Reviewed by Alex Christensen.
+
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::startScriptFetchInClient):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+        * WebProcess/Storage/WebSWClientConnection.messages.in:
+
+2017-12-14  Chris Dumez  <cdumez@apple.com>
+
         StorageProcess::deleteWebsiteData() should ensure there is a SWServer for the given sessionID
         https://bugs.webkit.org/show_bug.cgi?id=180784
 
index b3ebd98..2b8d065 100644 (file)
@@ -91,9 +91,9 @@ void WebSWServerConnection::resolveUnregistrationJobInClient(const ServiceWorker
     send(Messages::WebSWClientConnection::UnregistrationJobResolvedInServer(jobDataIdentifier, unregistrationResult));
 }
 
-void WebSWServerConnection::startScriptFetchInClient(const ServiceWorkerJobDataIdentifier& jobDataIdentifier)
+void WebSWServerConnection::startScriptFetchInClient(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, FetchOptions::Cache cachePolicy)
 {
-    send(Messages::WebSWClientConnection::StartScriptFetchForServer(jobDataIdentifier));
+    send(Messages::WebSWClientConnection::StartScriptFetchForServer(jobDataIdentifier, cachePolicy));
 }
 
 void WebSWServerConnection::updateRegistrationStateInClient(ServiceWorkerRegistrationIdentifier identifier, ServiceWorkerRegistrationState state, const std::optional<ServiceWorkerData>& serviceWorkerData)
index d69dd5f..072941b 100644 (file)
@@ -74,7 +74,7 @@ private:
     void rejectJobInClient(const WebCore::ServiceWorkerJobDataIdentifier&, const WebCore::ExceptionData&) final;
     void resolveRegistrationJobInClient(const WebCore::ServiceWorkerJobDataIdentifier&, const WebCore::ServiceWorkerRegistrationData&, WebCore::ShouldNotifyWhenResolved) final;
     void resolveUnregistrationJobInClient(const WebCore::ServiceWorkerJobDataIdentifier&, const WebCore::ServiceWorkerRegistrationKey&, bool unregistrationResult) final;
-    void startScriptFetchInClient(const WebCore::ServiceWorkerJobDataIdentifier&) final;
+    void startScriptFetchInClient(const WebCore::ServiceWorkerJobDataIdentifier&, WebCore::FetchOptions::Cache) final;
     void updateRegistrationStateInClient(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::ServiceWorkerRegistrationState, const std::optional<WebCore::ServiceWorkerData>&) final;
     void updateWorkerStateInClient(WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerState) final;
     void fireUpdateFoundEvent(WebCore::ServiceWorkerRegistrationIdentifier) final;
index 0b2d35f..339158f 100644 (file)
@@ -27,7 +27,7 @@ messages -> WebSWClientConnection {
     JobRejectedInServer(struct WebCore::ServiceWorkerJobDataIdentifier jobDataIdentifier, struct WebCore::ExceptionData exception)
     RegistrationJobResolvedInServer(struct WebCore::ServiceWorkerJobDataIdentifier jobDataIdentifier, struct WebCore::ServiceWorkerRegistrationData registration, enum WebCore::ShouldNotifyWhenResolved shouldNotifyWhenResolved)
     UnregistrationJobResolvedInServer(struct WebCore::ServiceWorkerJobDataIdentifier jobDataIdentifier, bool unregistrationResult)
-    StartScriptFetchForServer(struct WebCore::ServiceWorkerJobDataIdentifier jobDataIdentifier)
+    StartScriptFetchForServer(struct WebCore::ServiceWorkerJobDataIdentifier jobDataIdentifier, WebCore::FetchOptions::Cache cachePolicy)
     UpdateRegistrationState(WebCore::ServiceWorkerRegistrationIdentifier identifier, enum WebCore::ServiceWorkerRegistrationState state, std::optional<WebCore::ServiceWorkerData> serviceWorkerIdentifier)
     UpdateWorkerState(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, enum WebCore::ServiceWorkerState state)
     FireUpdateFoundEvent(WebCore::ServiceWorkerRegistrationIdentifier identifier)