Title: [250985] trunk
Revision
250985
Author
you...@apple.com
Date
2019-10-10 12:52:04 -0700 (Thu, 10 Oct 2019)

Log Message

Do not timeout a load intercepted by service worker that receives a response
https://bugs.webkit.org/show_bug.cgi?id=202787

Reviewed by Chris Dumez.

Source/WebKit:

Stop making ServiceWorkerFetchTask ref counted since it is not needed and
can potentially make ServiceWorkerFetchTask oulive its WebSWServerToContextConnection member.

Stop the ServiceWorkerFetchTask timeout timer whenever receiving a response so that the load will not timeout in that case.
This ensures that a load that is starting in a service worker will not be failing.
Instead the load will go to network process.

Removed m_didReachTerminalState which is not needed as WebSWServerToContextConnection unregisters the ServiceWorkerFetchTask
as an IPC listener for all terminating messages.

* NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
(WebKit::ServiceWorkerFetchTask::didReceiveRedirectResponse):
(WebKit::ServiceWorkerFetchTask::didReceiveResponse):
(WebKit::ServiceWorkerFetchTask::didReceiveData):
(WebKit::ServiceWorkerFetchTask::didReceiveFormData):
(WebKit::ServiceWorkerFetchTask::didFinish):
(WebKit::ServiceWorkerFetchTask::didFail):
(WebKit::ServiceWorkerFetchTask::didNotHandle):
(WebKit::ServiceWorkerFetchTask::timeoutTimerFired):
* NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h:
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
(WebKit::WebSWServerToContextConnection::startFetch):
(WebKit::WebSWServerToContextConnection::fetchTaskTimedOut):
Use a Vector instead of a HasSet for performance reasons.
Update according fetch map using unique_ptr instead of Ref<>.
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:

LayoutTests:

* http/wpt/service-workers/fetch-timeout-worker.js: Added.
(async.doTest):
* http/wpt/service-workers/fetch-timeout.https-expected.txt: Added.
* http/wpt/service-workers/fetch-timeout.https.html: Added.
* http/wpt/service-workers/resources/lengthy-pass.py:
(main):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (250984 => 250985)


--- trunk/LayoutTests/ChangeLog	2019-10-10 19:49:27 UTC (rev 250984)
+++ trunk/LayoutTests/ChangeLog	2019-10-10 19:52:04 UTC (rev 250985)
@@ -1,3 +1,17 @@
+2019-10-10  Youenn Fablet  <you...@apple.com>
+
+        Do not timeout a load intercepted by service worker that receives a response
+        https://bugs.webkit.org/show_bug.cgi?id=202787
+
+        Reviewed by Chris Dumez.
+
+        * http/wpt/service-workers/fetch-timeout-worker.js: Added.
+        (async.doTest):
+        * http/wpt/service-workers/fetch-timeout.https-expected.txt: Added.
+        * http/wpt/service-workers/fetch-timeout.https.html: Added.
+        * http/wpt/service-workers/resources/lengthy-pass.py:
+        (main):
+
 2019-10-10  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         FontFaceSet's ready promise is not always resolved

Added: trunk/LayoutTests/http/wpt/service-workers/fetch-timeout-worker.js (0 => 250985)


--- trunk/LayoutTests/http/wpt/service-workers/fetch-timeout-worker.js	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/fetch-timeout-worker.js	2019-10-10 19:52:04 UTC (rev 250985)
@@ -0,0 +1,6 @@
+async function doTest(event)
+{
+    event.respondWith(fetch(event.request));
+}
+
+self.addEventListener("fetch", doTest);

Added: trunk/LayoutTests/http/wpt/service-workers/fetch-timeout.https-expected.txt (0 => 250985)


--- trunk/LayoutTests/http/wpt/service-workers/fetch-timeout.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/fetch-timeout.https-expected.txt	2019-10-10 19:52:04 UTC (rev 250985)
@@ -0,0 +1,4 @@
+
+PASS Setup worker 
+PASS Make sure a load that makes progress does not time out 
+

Added: trunk/LayoutTests/http/wpt/service-workers/fetch-timeout.https.html (0 => 250985)


--- trunk/LayoutTests/http/wpt/service-workers/fetch-timeout.https.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/fetch-timeout.https.html	2019-10-10 19:52:04 UTC (rev 250985)
@@ -0,0 +1,39 @@
+<html>
+<head>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+var scope = "resources";
+var activeWorker;
+
+promise_test(async (test) => {
+    var registration = await navigator.serviceWorker.register("fetch-timeout-worker.js", { scope : scope });
+    activeWorker = registration.active;
+    if (activeWorker)
+        return;
+    activeWorker = registration.installing;
+    return new Promise(resolve => {
+        activeWorker.addEventListener('statechange', () => {
+            if (activeWorker.state === "activated")
+                resolve();
+        });
+    });
+}, "Setup worker");
+
+promise_test(async (test) => {
+    const iframe = await with_iframe(scope);
+
+    if (window.testRunner)
+        testRunner.setServiceWorkerFetchTimeout(1);
+
+     const response = await iframe.contentWindow.fetch("/WebKit/service-workers/resources/lengthy-pass.py?delay=0.5");
+     const text = await response.text();
+     assert_equals(text, "document.body.innerHTML = 'PASS'");
+     iframe.remove(); 
+}, "Make sure a load that makes progress does not time out");
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/http/wpt/service-workers/resources/lengthy-pass.py (250984 => 250985)


--- trunk/LayoutTests/http/wpt/service-workers/resources/lengthy-pass.py	2019-10-10 19:49:27 UTC (rev 250984)
+++ trunk/LayoutTests/http/wpt/service-workers/resources/lengthy-pass.py	2019-10-10 19:52:04 UTC (rev 250985)
@@ -2,6 +2,9 @@
 
 def main(request, response):
     delay = 0.05
+    headers = []
+    if "delay" in request.GET:
+        delay = float(request.GET.first("delay"))
     response.headers.set("Content-type", "text/_javascript_")
     response.headers.append("Access-Control-Allow-Origin", "*")
     response.write_status_headers()

Modified: trunk/Source/WebKit/ChangeLog (250984 => 250985)


--- trunk/Source/WebKit/ChangeLog	2019-10-10 19:49:27 UTC (rev 250984)
+++ trunk/Source/WebKit/ChangeLog	2019-10-10 19:52:04 UTC (rev 250985)
@@ -1,3 +1,37 @@
+2019-10-10  Youenn Fablet  <you...@apple.com>
+
+        Do not timeout a load intercepted by service worker that receives a response
+        https://bugs.webkit.org/show_bug.cgi?id=202787
+
+        Reviewed by Chris Dumez.
+
+        Stop making ServiceWorkerFetchTask ref counted since it is not needed and
+        can potentially make ServiceWorkerFetchTask oulive its WebSWServerToContextConnection member.
+
+        Stop the ServiceWorkerFetchTask timeout timer whenever receiving a response so that the load will not timeout in that case.
+        This ensures that a load that is starting in a service worker will not be failing.
+        Instead the load will go to network process.
+
+        Removed m_didReachTerminalState which is not needed as WebSWServerToContextConnection unregisters the ServiceWorkerFetchTask
+        as an IPC listener for all terminating messages.
+
+        * NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
+        (WebKit::ServiceWorkerFetchTask::didReceiveRedirectResponse):
+        (WebKit::ServiceWorkerFetchTask::didReceiveResponse):
+        (WebKit::ServiceWorkerFetchTask::didReceiveData):
+        (WebKit::ServiceWorkerFetchTask::didReceiveFormData):
+        (WebKit::ServiceWorkerFetchTask::didFinish):
+        (WebKit::ServiceWorkerFetchTask::didFail):
+        (WebKit::ServiceWorkerFetchTask::didNotHandle):
+        (WebKit::ServiceWorkerFetchTask::timeoutTimerFired):
+        * NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h:
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+        (WebKit::WebSWServerToContextConnection::startFetch):
+        (WebKit::WebSWServerToContextConnection::fetchTaskTimedOut):
+        Use a Vector instead of a HasSet for performance reasons.
+        Update according fetch map using unique_ptr instead of Ref<>.
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
+
 2019-10-10  Rob Buis  <rb...@igalia.com>
 
         SpeculativeLoad should use CompletionHandler

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp (250984 => 250985)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp	2019-10-10 19:49:27 UTC (rev 250984)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp	2019-10-10 19:52:04 UTC (rev 250985)
@@ -59,6 +59,7 @@
 void ServiceWorkerFetchTask::didReceiveRedirectResponse(const ResourceResponse& response)
 {
     RELEASE_LOG_IF_ALLOWED("didReceiveRedirectResponse: %s", m_identifier.fetchIdentifier.loggingString().utf8().data());
+    m_timeoutTimer.stop();
     m_wasHandled = true;
     if (m_connection)
         m_connection->send(Messages::ServiceWorkerClientFetch::DidReceiveRedirectResponse { response }, m_identifier.fetchIdentifier);
@@ -67,6 +68,7 @@
 void ServiceWorkerFetchTask::didReceiveResponse(const ResourceResponse& response, bool needsContinueDidReceiveResponseMessage)
 {
     RELEASE_LOG_IF_ALLOWED("didReceiveResponse: %s", m_identifier.fetchIdentifier.loggingString().utf8().data());
+    m_timeoutTimer.stop();
     m_wasHandled = true;
     if (m_connection)
         m_connection->send(Messages::ServiceWorkerClientFetch::DidReceiveResponse { response, needsContinueDidReceiveResponseMessage }, m_identifier.fetchIdentifier);
@@ -74,6 +76,7 @@
 
 void ServiceWorkerFetchTask::didReceiveData(const IPC::DataReference& data, int64_t encodedDataLength)
 {
+    ASSERT(!m_timeoutTimer.isActive());
     if (m_connection)
         m_connection->send(Messages::ServiceWorkerClientFetch::DidReceiveData { data, encodedDataLength }, m_identifier.fetchIdentifier);
 }
@@ -80,6 +83,7 @@
 
 void ServiceWorkerFetchTask::didReceiveFormData(const IPC::FormDataReference& formData)
 {
+    ASSERT(!m_timeoutTimer.isActive());
     if (m_connection)
         m_connection->send(Messages::ServiceWorkerClientFetch::DidReceiveFormData { formData }, m_identifier.fetchIdentifier);
 }
@@ -86,11 +90,11 @@
 
 void ServiceWorkerFetchTask::didFinish()
 {
+    ASSERT(!m_timeoutTimer.isActive());
     RELEASE_LOG_IF_ALLOWED("didFinishFetch: fetchIdentifier: %s", m_identifier.fetchIdentifier.loggingString().utf8().data());
     m_timeoutTimer.stop();
-    if (!m_didReachTerminalState && m_connection)
+    if (m_connection)
         m_connection->send(Messages::ServiceWorkerClientFetch::DidFinish { }, m_identifier.fetchIdentifier);
-    m_didReachTerminalState = true;
 }
 
 void ServiceWorkerFetchTask::didFail(const ResourceError& error)
@@ -97,9 +101,8 @@
 {
     RELEASE_LOG_ERROR_IF_ALLOWED("didFailFetch: fetchIdentifier: %s", m_identifier.fetchIdentifier.loggingString().utf8().data());
     m_timeoutTimer.stop();
-    if (!m_didReachTerminalState && m_connection)
+    if (m_connection)
         m_connection->send(Messages::ServiceWorkerClientFetch::DidFail { error }, m_identifier.fetchIdentifier);
-    m_didReachTerminalState = true;
 }
 
 void ServiceWorkerFetchTask::didNotHandle()
@@ -106,19 +109,14 @@
 {
     RELEASE_LOG_IF_ALLOWED("didNotHandleFetch: fetchIdentifier: %s", m_identifier.fetchIdentifier.loggingString().utf8().data());
     m_timeoutTimer.stop();
-    if (!m_didReachTerminalState && m_connection)
+    if (m_connection)
         m_connection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, m_identifier.fetchIdentifier);
-    m_didReachTerminalState = true;
 }
 
 void ServiceWorkerFetchTask::timeoutTimerFired()
 {
     RELEASE_LOG_IF_ALLOWED("timeoutTimerFired: fetchIdentifier: %s", m_identifier.fetchIdentifier.loggingString().utf8().data());
-    if (!m_wasHandled)
-        didNotHandle();
-    else
-        didFail({ errorDomainWebKitInternal, 0, { }, "Service Worker fetch timed out"_s });
-
+    didNotHandle();
     m_contextConnection.fetchTaskTimedOut(*this);
 }
 

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h (250984 => 250985)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h	2019-10-10 19:49:27 UTC (rev 250984)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h	2019-10-10 19:52:04 UTC (rev 250985)
@@ -31,7 +31,6 @@
 #include <WebCore/ServiceWorkerTypes.h>
 #include <WebCore/Timer.h>
 #include <pal/SessionID.h>
-#include <wtf/RefCounted.h>
 
 namespace WebCore {
 class ResourceError;
@@ -50,12 +49,10 @@
 class WebSWServerConnection;
 class WebSWServerToContextConnection;
 
-class ServiceWorkerFetchTask : public RefCounted<ServiceWorkerFetchTask> {
+class ServiceWorkerFetchTask {
+    WTF_MAKE_FAST_ALLOCATED;
 public:
-    template<typename... Args> static Ref<ServiceWorkerFetchTask> create(Args&&... args)
-    {
-        return adoptRef(*new ServiceWorkerFetchTask(std::forward<Args>(args)...));
-    }
+    ServiceWorkerFetchTask(PAL::SessionID, WebSWServerConnection&, WebSWServerToContextConnection&, WebCore::FetchIdentifier, WebCore::ServiceWorkerIdentifier, Seconds timeout);
 
     void didNotHandle();
     void fail(const WebCore::ResourceError& error) { didFail(error); }
@@ -79,8 +76,6 @@
     bool wasHandled() const { return m_wasHandled; }
 
 private:
-    ServiceWorkerFetchTask(PAL::SessionID, WebSWServerConnection&, WebSWServerToContextConnection&, WebCore::FetchIdentifier, WebCore::ServiceWorkerIdentifier, Seconds timeout);
-
     void didReceiveRedirectResponse(const WebCore::ResourceResponse&);
     void didReceiveResponse(const WebCore::ResourceResponse&, bool needsContinueDidReceiveResponseMessage);
     void didReceiveData(const IPC::DataReference&, int64_t encodedDataLength);
@@ -97,7 +92,6 @@
     Seconds m_timeout;
     WebCore::Timer m_timeoutTimer;
     bool m_wasHandled { false };
-    bool m_didReachTerminalState { false };
 };
 
 inline bool operator==(const ServiceWorkerFetchTask::Identifier& a, const ServiceWorkerFetchTask::Identifier& b)

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp (250984 => 250985)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2019-10-10 19:49:27 UTC (rev 250984)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2019-10-10 19:52:04 UTC (rev 250985)
@@ -157,7 +157,7 @@
     auto serverConnectionIdentifier = contentConnection.identifier();
     auto fetchIdentifier = FetchIdentifier::generate();
 
-    auto result = m_ongoingFetches.add(fetchIdentifier, ServiceWorkerFetchTask::create(sessionID, contentConnection, *this, contentFetchIdentifier, serviceWorkerIdentifier, m_networkProcess->serviceWorkerFetchTimeout()));
+    auto result = m_ongoingFetches.add(fetchIdentifier, makeUnique<ServiceWorkerFetchTask>(sessionID, contentConnection, *this, contentFetchIdentifier, serviceWorkerIdentifier, m_networkProcess->serviceWorkerFetchTimeout()));
 
     ASSERT(!m_ongoingFetchIdentifiers.contains({ serverConnectionIdentifier, contentFetchIdentifier }));
     m_ongoingFetchIdentifiers.add({ serverConnectionIdentifier, contentFetchIdentifier }, fetchIdentifier);
@@ -215,17 +215,17 @@
     ASSERT(m_ongoingFetches.contains(takenIdentifier));
     auto takenTask = m_ongoingFetches.take(takenIdentifier);
     ASSERT(takenTask);
-    ASSERT(takenTask->ptr() == &task);
+    ASSERT(takenTask.get() == &task);
 
     // Gather all other fetches in this service worker
-    HashSet<Ref<ServiceWorkerFetchTask>> otherFetches;
+    Vector<ServiceWorkerFetchTask*> otherFetches;
     for (auto& fetchTask : m_ongoingFetches.values()) {
         if (fetchTask->serviceWorkerIdentifier() == task.serviceWorkerIdentifier())
-            otherFetches.add(fetchTask.copyRef());
+            otherFetches.append(fetchTask.get());
     }
 
     // Signal load failure for them
-    for (auto& fetchTask : otherFetches) {
+    for (auto* fetchTask : otherFetches) {
         if (fetchTask->wasHandled())
             fetchTask->fail({ errorDomainWebKitInternal, 0, { }, "Service Worker context closed"_s });
         else

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h (250984 => 250985)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h	2019-10-10 19:49:27 UTC (rev 250984)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h	2019-10-10 19:52:04 UTC (rev 250985)
@@ -103,7 +103,7 @@
     WeakPtr<WebCore::SWServer> m_server;
 
     HashMap<ServiceWorkerFetchTask::Identifier, WebCore::FetchIdentifier> m_ongoingFetchIdentifiers;
-    HashMap<WebCore::FetchIdentifier, Ref<ServiceWorkerFetchTask>> m_ongoingFetches;
+    HashMap<WebCore::FetchIdentifier, std::unique_ptr<ServiceWorkerFetchTask>> m_ongoingFetches;
     bool m_isThrottleable { true };
 }; // class WebSWServerToContextConnection
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to