Diff
Modified: trunk/LayoutTests/ChangeLog (250851 => 250852)
--- trunk/LayoutTests/ChangeLog 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/LayoutTests/ChangeLog 2019-10-08 19:50:12 UTC (rev 250852)
@@ -1,3 +1,22 @@
+2019-10-08 Brady Eidson <beid...@apple.com>
+
+ Service Worker Fetch events should time out.
+ https://bugs.webkit.org/show_bug.cgi?id=202188
+
+ Reviewed by Alex Christensen.
+
+ * http/tests/workers/service/basic-timeout.https-expected.txt: Added.
+ * http/tests/workers/service/basic-timeout.https.html: Added.
+ * http/tests/workers/service/resources/basic-timeout-worker.js: Added.
+ (event.event.request.url.indexOf):
+ * http/tests/workers/service/resources/basic-timeout.js: Added.
+ (async.test.finishThisTest):
+ (async.test.try):
+ (async.test.try.checkSuccessAgain):
+ (async.test):
+ * http/tests/workers/service/resources/succeed-fallback-check.php: Added.
+ * http/tests/workers/service/resources/timeout-fallback.html: Added.
+
2019-10-08 Alexey Shvayka <shvaikal...@gmail.com>
Accept two values in the overflow shorthand
Added: trunk/LayoutTests/http/tests/workers/service/basic-timeout.https-expected.txt (0 => 250852)
--- trunk/LayoutTests/http/tests/workers/service/basic-timeout.https-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/basic-timeout.https-expected.txt 2019-10-08 19:50:12 UTC (rev 250852)
@@ -0,0 +1,14 @@
+
+URL 0 - https://127.0.0.1:8443/workers/service/resources/timeout-fallback.html
+Status code 0 - 200
+Source' header 0 - null
+URL 1 - https://127.0.0.1:8443/workers/service/resources/timeout-no-fallback.html
+Status code 1 - 404
+Source' header 1 - null
+URL 2 - https://127.0.0.1:8443/workers/service/resources/succeed-fallback-check.php
+Status code 2 - 200
+Source' header 2 - network
+URL 3 - https://127.0.0.1:8443/workers/service/resources/succeed-fallback-check.php
+Status code 3 - 200
+Source' header 3 - network
+
Added: trunk/LayoutTests/http/tests/workers/service/basic-timeout.https.html (0 => 250852)
--- trunk/LayoutTests/http/tests/workers/service/basic-timeout.https.html (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/basic-timeout.https.html 2019-10-08 19:50:12 UTC (rev 250852)
@@ -0,0 +1,9 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/workers/service/resources/basic-timeout-worker.js (0 => 250852)
--- trunk/LayoutTests/http/tests/workers/service/resources/basic-timeout-worker.js (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/resources/basic-timeout-worker.js 2019-10-08 19:50:12 UTC (rev 250852)
@@ -0,0 +1,6 @@
+self.addEventListener("fetch", (event) => {
+ if (event.request.url.indexOf("timeout") !== -1) {
+ while (1) { }
+ } else
+ event.respondWith(new Response(null, { status: 200, statusText: "Hello from service worker", headers: [["Source", "ServiceWorker"]] }));
+});
Added: trunk/LayoutTests/http/tests/workers/service/resources/basic-timeout.js (0 => 250852)
--- trunk/LayoutTests/http/tests/workers/service/resources/basic-timeout.js (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/resources/basic-timeout.js 2019-10-08 19:50:12 UTC (rev 250852)
@@ -0,0 +1,76 @@
+async function test()
+{
+ var urlResults = new Array;
+ var statusResults = new Array;
+ var headerResults = new Array;
+
+ function finishThisTest()
+ {
+ for (var i = 0; i < urlResults.length; ++i) {
+ log("URL " + i + " - " + urlResults[i]);
+ log("Status code " + i + " - " + statusResults[i]);
+ log("Source' header " + i + " - " + headerResults[i]);
+ }
+ finishSWTest();
+ }
+
+ try {
+ var frame = await interceptedFrame("resources/basic-timeout-worker.js", "/workers/service/resources/");
+ var fetch = frame.contentWindow.fetch;
+
+ if (window.testRunner)
+ testRunner.setServiceWorkerFetchTimeout(0);
+
+ // The following two fetches should time out immediately
+ fetch("timeout-fallback.html").then(function(response) {
+ urlResults[0] = response.url;
+ statusResults[0] = response.status;
+ headerResults[0] = response.headers.get("Source");
+ }, function(error) {
+ log(error);
+ });
+
+ fetch("timeout-no-fallback.html").then(function(response) {
+ urlResults[1] = response.url;
+ statusResults[1] = response.status;
+ headerResults[1] = response.headers.get("Source");
+ }, function(error) {
+ log(error);
+ });
+
+ if (window.testRunner)
+ testRunner.setServiceWorkerFetchTimeout(60);
+
+ // The service worker knows how to handle the following fetch *and* has 60 seconds to do so.
+ // But will be cancelled with the above fetches since we're terminating the service worker, and
+ // therefore it will then fallback to the network.
+ fetch("succeed-fallback-check.php").then(function(response) {
+ urlResults[2] = response.url;
+ statusResults[2] = response.status;
+ headerResults[2] = response.headers.get("Source");
+ setTimeout(checkSuccessAgain, 0);
+ }, function(error) {
+ log(error);
+ finishSWTest();
+ });
+
+ // Now we can fetch that same URL again, which *could* relaunch the service worker and handle it there, but for now this service worker registration is inert and fetches through it will go to the network instead.
+ // I'm leaving this in to cover future cases where we do relaunch the SW to handle it.
+ function checkSuccessAgain() {
+ fetch("succeed-fallback-check.php").then(function(response) {
+ urlResults[3] = response.url;
+ statusResults[3] = response.status;
+ headerResults[3] = response.headers.get("Source");
+ finishThisTest();
+ }, function(error) {
+ log(error);
+ finishSWTest();
+ });
+ }
+ } catch(e) {
+ log("Got exception: " + e);
+ finishSWTest();
+ }
+}
+
+test();
Added: trunk/LayoutTests/http/tests/workers/service/resources/succeed-fallback-check.php (0 => 250852)
--- trunk/LayoutTests/http/tests/workers/service/resources/succeed-fallback-check.php (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/resources/succeed-fallback-check.php 2019-10-08 19:50:12 UTC (rev 250852)
@@ -0,0 +1,3 @@
+<?php
+ header('Source: network');
+?>Success!
\ No newline at end of file
Added: trunk/LayoutTests/http/tests/workers/service/resources/timeout-fallback.html (0 => 250852)
--- trunk/LayoutTests/http/tests/workers/service/resources/timeout-fallback.html (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/resources/timeout-fallback.html 2019-10-08 19:50:12 UTC (rev 250852)
@@ -0,0 +1 @@
+Timeout resource fetched from network
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (250851 => 250852)
--- trunk/Source/WebCore/ChangeLog 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebCore/ChangeLog 2019-10-08 19:50:12 UTC (rev 250852)
@@ -1,3 +1,17 @@
+2019-10-08 Brady Eidson <beid...@apple.com>
+
+ Service Worker Fetch events should time out.
+ https://bugs.webkit.org/show_bug.cgi?id=202188
+
+ Reviewed by Alex Christensen.
+
+ Test: http/tests/workers/service/basic-timeout.https.html
+
+ * workers/service/server/SWServer.h:
+ * workers/service/server/SWServerWorker.h:
+ (WebCore::SWServerWorker::setHasTimedOutAnyFetchTasks):
+ (WebCore::SWServerWorker::hasTimedOutAnyFetchTasks const):
+
2019-10-08 Alexey Shvayka <shvaikal...@gmail.com>
Accept two values in the overflow shorthand
Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (250851 => 250852)
--- trunk/Source/WebCore/workers/service/server/SWServer.h 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h 2019-10-08 19:50:12 UTC (rev 250852)
@@ -148,7 +148,7 @@
void updateWorker(Connection&, const ServiceWorkerJobDataIdentifier&, SWServerRegistration&, const URL&, const String& script, const ContentSecurityPolicyResponseHeaders&, const String& referrerPolicy, WorkerType, HashMap<URL, ServiceWorkerContextData::ImportedScript>&&);
void terminateWorker(SWServerWorker&);
- void syncTerminateWorker(SWServerWorker&);
+ WEBCORE_EXPORT void syncTerminateWorker(SWServerWorker&);
void fireInstallEvent(SWServerWorker&);
void fireActivateEvent(SWServerWorker&);
Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.h (250851 => 250852)
--- trunk/Source/WebCore/workers/service/server/SWServerWorker.h 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.h 2019-10-08 19:50:12 UTC (rev 250852)
@@ -116,6 +116,9 @@
SWServerRegistration* registration() const;
+ void setHasTimedOutAnyFetchTasks() { m_hasTimedOutAnyFetchTasks = true; }
+ bool hasTimedOutAnyFetchTasks() const { return m_hasTimedOutAnyFetchTasks; }
+
private:
SWServerWorker(SWServer&, SWServerRegistration&, const URL&, const String& script, const ContentSecurityPolicyResponseHeaders&, String&& referrerPolicy, WorkerType, ServiceWorkerIdentifier, HashMap<URL, ServiceWorkerContextData::ImportedScript>&&);
@@ -136,6 +139,7 @@
Vector<Function<void(bool)>> m_whenActivatedHandlers;
HashMap<URL, ServiceWorkerContextData::ImportedScript> m_scriptResourceMap;
bool m_shouldSkipHandleFetch;
+ bool m_hasTimedOutAnyFetchTasks { false };
};
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (250851 => 250852)
--- trunk/Source/WebKit/ChangeLog 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/ChangeLog 2019-10-08 19:50:12 UTC (rev 250852)
@@ -1,3 +1,57 @@
+2019-10-08 Brady Eidson <beid...@apple.com>
+
+ Service Worker Fetch events should time out.
+ https://bugs.webkit.org/show_bug.cgi?id=202188
+
+ Reviewed by Alex Christensen.
+
+ When we start a fetch task in the server, we also start a timeout on that fetch task.
+
+ "Time out" means the fetch task must continue to make progress at the given frequency (once every 60 seconds by default)
+
+ If any given fetch task times out in a service worker instance, that instance loses the right to handle fetches.
+
+ * NetworkProcess/NetworkProcess.cpp:
+ (WebKit::NetworkProcess::setServiceWorkerFetchTimeoutForTesting):
+ (WebKit::NetworkProcess::resetServiceWorkerFetchTimeoutForTesting):
+ * NetworkProcess/NetworkProcess.h:
+ (WebKit::NetworkProcess::serviceWorkerFetchTimeout const):
+ * NetworkProcess/NetworkProcess.messages.in:
+
+ * NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
+ (WebKit::ServiceWorkerFetchTask::ServiceWorkerFetchTask):
+ (WebKit::ServiceWorkerFetchTask::didReceiveRedirectResponse):
+ (WebKit::ServiceWorkerFetchTask::didReceiveResponse):
+ (WebKit::ServiceWorkerFetchTask::didReceiveData):
+ (WebKit::ServiceWorkerFetchTask::didReceiveFormData):
+ (WebKit::ServiceWorkerFetchTask::didFinish):
+ (WebKit::ServiceWorkerFetchTask::didFail):
+ (WebKit::ServiceWorkerFetchTask::didNotHandle):
+ * NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h:
+ (WebKit::ServiceWorkerFetchTask::create):
+ (WebKit::ServiceWorkerFetchTask::serviceWorkerIdentifier const):
+ (WebKit::ServiceWorkerFetchTask::wasHandled const):
+ (WebKit::ServiceWorkerFetchTask::ServiceWorkerFetchTask): Deleted.
+
+ * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
+ (WebKit::WebSWServerConnection::startFetch):
+ * NetworkProcess/ServiceWorker/WebSWServerConnection.h:
+
+ * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+ (WebKit::WebSWServerToContextConnection::startFetch):
+ (WebKit::WebSWServerToContextConnection::fetchTaskTimedOut):
+ * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
+
+ * UIProcess/API/C/WKContext.cpp:
+ (WKContextSetServiceWorkerFetchTimeoutForTesting):
+ (WKContextResetServiceWorkerFetchTimeoutForTesting):
+ * UIProcess/API/C/WKContext.h:
+
+ * UIProcess/WebProcessPool.cpp:
+ (WebKit::WebProcessPool::setServiceWorkerTimeoutForTesting):
+ (WebKit::WebProcessPool::resetServiceWorkerTimeoutForTesting):
+ * UIProcess/WebProcessPool.h:
+
2019-10-08 Ross Kirsling <ross.kirsl...@sony.com>
Unreviewed. Restabilize non-unified build.
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (250851 => 250852)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2019-10-08 19:50:12 UTC (rev 250852)
@@ -2614,4 +2614,17 @@
return m_webProcessConnections.get(identifier);
}
+const Seconds NetworkProcess::defaultServiceWorkerFetchTimeout = 70_s;
+void NetworkProcess::setServiceWorkerFetchTimeoutForTesting(Seconds timeout, CompletionHandler<void()>&& completionHandler)
+{
+ m_serviceWorkerFetchTimeout = timeout;
+ completionHandler();
+}
+
+void NetworkProcess::resetServiceWorkerFetchTimeoutForTesting(CompletionHandler<void()>&& completionHandler)
+{
+ m_serviceWorkerFetchTimeout = defaultServiceWorkerFetchTimeout;
+ completionHandler();
+}
+
} // namespace WebKit
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (250851 => 250852)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2019-10-08 19:50:12 UTC (rev 250852)
@@ -344,6 +344,10 @@
NetworkConnectionToWebProcess* webProcessConnection(WebCore::ProcessIdentifier) const;
WebCore::MessagePortChannelRegistry& messagePortChannelRegistry() { return m_messagePortChannelRegistry; }
+ void setServiceWorkerFetchTimeoutForTesting(Seconds, CompletionHandler<void()>&&);
+ void resetServiceWorkerFetchTimeoutForTesting(CompletionHandler<void()>&&);
+ Seconds serviceWorkerFetchTimeout() const { return m_serviceWorkerFetchTimeout; }
+
private:
void platformInitializeNetworkProcess(const NetworkProcessCreationParameters&);
std::unique_ptr<WebCore::NetworkStorageSession> platformCreateDefaultStorageSession() const;
@@ -561,6 +565,9 @@
OptionSet<NetworkCache::CacheOption> m_cacheOptions;
WebCore::MessagePortChannelRegistry m_messagePortChannelRegistry;
+
+ static const Seconds defaultServiceWorkerFetchTimeout;
+ Seconds m_serviceWorkerFetchTimeout { defaultServiceWorkerFetchTimeout };
};
} // namespace WebKit
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (250851 => 250852)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2019-10-08 19:50:12 UTC (rev 250852)
@@ -164,4 +164,7 @@
SetAdClickAttributionConversionURLForTesting(PAL::SessionID sessionID, URL url) -> () Async
MarkAdClickAttributionsAsExpiredForTesting(PAL::SessionID sessionID) -> () Async
GetLocalStorageOriginDetails(PAL::SessionID sessionID) -> (Vector<WebKit::LocalStorageDatabaseTracker::OriginDetails> details) Async
+
+ SetServiceWorkerFetchTimeoutForTesting(Seconds seconds) -> () Synchronous
+ ResetServiceWorkerFetchTimeoutForTesting() -> () Synchronous
}
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp (250851 => 250852)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp 2019-10-08 19:50:12 UTC (rev 250852)
@@ -34,6 +34,8 @@
#include "Logging.h"
#include "ServiceWorkerClientFetchMessages.h"
#include "WebCoreArgumentCoders.h"
+#include "WebSWServerConnection.h"
+#include "WebSWServerToContextConnection.h"
#define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(m_sessionID.isAlwaysOnLoggingAllowed(), ServiceWorker, "%p - ServiceWorkerFetchTask::" fmt, this, ##__VA_ARGS__)
#define RELEASE_LOG_ERROR_IF_ALLOWED(fmt, ...) RELEASE_LOG_ERROR_IF(m_sessionID.isAlwaysOnLoggingAllowed(), ServiceWorker, "%p - ServiceWorkerFetchTask::" fmt, this, ##__VA_ARGS__)
@@ -42,45 +44,84 @@
namespace WebKit {
+ServiceWorkerFetchTask::ServiceWorkerFetchTask(PAL::SessionID sessionID, WebSWServerConnection& connection, WebSWServerToContextConnection& contextConnection, FetchIdentifier fetchIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, Seconds timeout)
+ : m_sessionID(sessionID)
+ , m_connection(makeWeakPtr(connection))
+ , m_contextConnection(contextConnection)
+ , m_identifier { connection.identifier(), fetchIdentifier }
+ , m_serviceWorkerIdentifier(serviceWorkerIdentifier)
+ , m_timeout(timeout)
+ , m_timeoutTimer(*this, &ServiceWorkerFetchTask::timeoutTimerFired)
+{
+ m_timeoutTimer.startOneShot(m_timeout);
+}
+
void ServiceWorkerFetchTask::didReceiveRedirectResponse(const ResourceResponse& response)
{
RELEASE_LOG_IF_ALLOWED("didReceiveRedirectResponse: %s", m_identifier.fetchIdentifier.loggingString().utf8().data());
- m_connection->send(Messages::ServiceWorkerClientFetch::DidReceiveRedirectResponse { response }, m_identifier.fetchIdentifier);
+ m_wasHandled = true;
+ if (m_connection)
+ m_connection->send(Messages::ServiceWorkerClientFetch::DidReceiveRedirectResponse { response }, m_identifier.fetchIdentifier);
}
void ServiceWorkerFetchTask::didReceiveResponse(const ResourceResponse& response, bool needsContinueDidReceiveResponseMessage)
{
- m_connection->send(Messages::ServiceWorkerClientFetch::DidReceiveResponse { response, needsContinueDidReceiveResponseMessage }, m_identifier.fetchIdentifier);
+ RELEASE_LOG_IF_ALLOWED("didReceiveResponse: %s", m_identifier.fetchIdentifier.loggingString().utf8().data());
+ m_wasHandled = true;
+ if (m_connection)
+ m_connection->send(Messages::ServiceWorkerClientFetch::DidReceiveResponse { response, needsContinueDidReceiveResponseMessage }, m_identifier.fetchIdentifier);
}
void ServiceWorkerFetchTask::didReceiveData(const IPC::DataReference& data, int64_t encodedDataLength)
{
- m_connection->send(Messages::ServiceWorkerClientFetch::DidReceiveData { data, encodedDataLength }, m_identifier.fetchIdentifier);
+ if (m_connection)
+ m_connection->send(Messages::ServiceWorkerClientFetch::DidReceiveData { data, encodedDataLength }, m_identifier.fetchIdentifier);
}
void ServiceWorkerFetchTask::didReceiveFormData(const IPC::FormDataReference& formData)
{
- m_connection->send(Messages::ServiceWorkerClientFetch::DidReceiveFormData { formData }, m_identifier.fetchIdentifier);
+ if (m_connection)
+ m_connection->send(Messages::ServiceWorkerClientFetch::DidReceiveFormData { formData }, m_identifier.fetchIdentifier);
}
void ServiceWorkerFetchTask::didFinish()
{
RELEASE_LOG_IF_ALLOWED("didFinishFetch: fetchIdentifier: %s", m_identifier.fetchIdentifier.loggingString().utf8().data());
- m_connection->send(Messages::ServiceWorkerClientFetch::DidFinish { }, m_identifier.fetchIdentifier);
+ m_timeoutTimer.stop();
+ if (!m_didReachTerminalState && m_connection)
+ m_connection->send(Messages::ServiceWorkerClientFetch::DidFinish { }, m_identifier.fetchIdentifier);
+ m_didReachTerminalState = true;
}
void ServiceWorkerFetchTask::didFail(const ResourceError& error)
{
RELEASE_LOG_ERROR_IF_ALLOWED("didFailFetch: fetchIdentifier: %s", m_identifier.fetchIdentifier.loggingString().utf8().data());
- m_connection->send(Messages::ServiceWorkerClientFetch::DidFail { error }, m_identifier.fetchIdentifier);
+ m_timeoutTimer.stop();
+ if (!m_didReachTerminalState && m_connection)
+ m_connection->send(Messages::ServiceWorkerClientFetch::DidFail { error }, m_identifier.fetchIdentifier);
+ m_didReachTerminalState = true;
}
void ServiceWorkerFetchTask::didNotHandle()
{
RELEASE_LOG_IF_ALLOWED("didNotHandleFetch: fetchIdentifier: %s", m_identifier.fetchIdentifier.loggingString().utf8().data());
- m_connection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, m_identifier.fetchIdentifier);
+ m_timeoutTimer.stop();
+ if (!m_didReachTerminalState && 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 });
+
+ m_contextConnection.fetchTaskTimedOut(*this);
+}
+
} // namespace WebKit
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h (250851 => 250852)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h 2019-10-08 19:50:12 UTC (rev 250852)
@@ -29,6 +29,7 @@
#include <WebCore/FetchIdentifier.h>
#include <WebCore/ServiceWorkerTypes.h>
+#include <WebCore/Timer.h>
#include <pal/SessionID.h>
#include <wtf/RefCounted.h>
@@ -46,10 +47,17 @@
namespace WebKit {
+class WebSWServerConnection;
+class WebSWServerToContextConnection;
+
class ServiceWorkerFetchTask : public RefCounted<ServiceWorkerFetchTask> {
public:
- static Ref<ServiceWorkerFetchTask> create(PAL::SessionID sessionID, Ref<IPC::Connection>&& connection, WebCore::SWServerConnectionIdentifier connectionIdentifier, WebCore::FetchIdentifier fetchIdentifier) { return adoptRef(*new ServiceWorkerFetchTask(sessionID, WTFMove(connection), connectionIdentifier, fetchIdentifier)); }
+ template<typename... Args> static Ref<ServiceWorkerFetchTask> create(Args&&... args)
+ {
+ return adoptRef(*new ServiceWorkerFetchTask(std::forward<Args>(args)...));
+ }
+ void didNotHandle();
void fail(const WebCore::ResourceError& error) { didFail(error); }
void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
@@ -67,13 +75,11 @@
};
const Identifier& identifier() const { return m_identifier; }
+ const WebCore::ServiceWorkerIdentifier& serviceWorkerIdentifier() const { return m_serviceWorkerIdentifier; }
+ bool wasHandled() const { return m_wasHandled; }
private:
- ServiceWorkerFetchTask(PAL::SessionID sessionID, Ref<IPC::Connection>&& connection, WebCore::SWServerConnectionIdentifier connectionIdentifier, WebCore::FetchIdentifier fetchIdentifier)
- : m_sessionID(sessionID)
- , m_connection(WTFMove(connection))
- , m_identifier { connectionIdentifier, fetchIdentifier }
- { }
+ ServiceWorkerFetchTask(PAL::SessionID, WebSWServerConnection&, WebSWServerToContextConnection&, WebCore::FetchIdentifier, WebCore::ServiceWorkerIdentifier, Seconds timeout);
void didReceiveRedirectResponse(const WebCore::ResourceResponse&);
void didReceiveResponse(const WebCore::ResourceResponse&, bool needsContinueDidReceiveResponseMessage);
@@ -81,11 +87,17 @@
void didReceiveFormData(const IPC::FormDataReference&);
void didFinish();
void didFail(const WebCore::ResourceError&);
- void didNotHandle();
+ void timeoutTimerFired();
PAL::SessionID m_sessionID;
- Ref<IPC::Connection> m_connection;
+ WeakPtr<WebSWServerConnection> m_connection;
+ WebSWServerToContextConnection& m_contextConnection;
Identifier m_identifier;
+ WebCore::ServiceWorkerIdentifier m_serviceWorkerIdentifier;
+ 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/WebSWServerConnection.cpp (250851 => 250852)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp 2019-10-08 19:50:12 UTC (rev 250852)
@@ -174,7 +174,7 @@
}
auto* worker = server().workerByID(serviceWorkerIdentifier);
- if (!worker) {
+ if (!worker || worker->hasTimedOutAnyFetchTasks()) {
m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, fetchIdentifier);
return;
}
@@ -188,9 +188,9 @@
if (contextConnection) {
SWSERVERCONNECTION_RELEASE_LOG_IF_ALLOWED("startFetch: Starting fetch %s via service worker %s", fetchIdentifier.loggingString().utf8().data(), serviceWorkerIdentifier.loggingString().utf8().data());
- static_cast<WebSWServerToContextConnection&>(*contextConnection).startFetch(sessionID(), m_contentConnection.get(), this->identifier(), fetchIdentifier, serviceWorkerIdentifier, request, options, formData, referrer);
+ static_cast<WebSWServerToContextConnection&>(*contextConnection).startFetch(sessionID(), *this, fetchIdentifier, serviceWorkerIdentifier, request, options, formData, referrer);
} else {
- SWSERVERCONNECTION_RELEASE_LOG_ERROR_IF_ALLOWED("startFetch: fetchIdentifier: %s DidNotHandle because failed to run service worker", fetchIdentifier.loggingString().utf8().data());
+ SWSERVERCONNECTION_RELEASE_LOG_ERROR_IF_ALLOWED("startFetch: fetchIdentifier: %s DidNotHandle because failed to run service worker, or service worker has had timed out fetch tasks", fetchIdentifier.loggingString().utf8().data());
m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, fetchIdentifier);
}
});
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h (250851 => 250852)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h 2019-10-08 19:50:12 UTC (rev 250852)
@@ -35,6 +35,7 @@
#include <WebCore/SWServer.h>
#include <pal/SessionID.h>
#include <wtf/HashMap.h>
+#include <wtf/WeakPtr.h>
namespace IPC {
class FormDataReference;
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp (250851 => 250852)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp 2019-10-08 19:50:12 UTC (rev 250852)
@@ -35,6 +35,7 @@
#include "ServiceWorkerFetchTaskMessages.h"
#include "WebCoreArgumentCoders.h"
#include "WebSWContextManagerConnectionMessages.h"
+#include "WebSWServerConnection.h"
#include <WebCore/SWServer.h>
#include <WebCore/ServiceWorkerContextData.h>
@@ -151,16 +152,18 @@
send(Messages::WebSWContextManagerConnection::TerminateProcess());
}
-void WebSWServerToContextConnection::startFetch(PAL::SessionID sessionID, Ref<IPC::Connection>&& contentConnection, WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier contentFetchIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, const ResourceRequest& request, const FetchOptions& options, const IPC::FormDataReference& data, const String& referrer)
+void WebSWServerToContextConnection::startFetch(PAL::SessionID sessionID, WebSWServerConnection& contentConnection, FetchIdentifier contentFetchIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, const ResourceRequest& request, const FetchOptions& options, const IPC::FormDataReference& data, const String& referrer)
{
+ auto serverConnectionIdentifier = contentConnection.identifier();
auto fetchIdentifier = FetchIdentifier::generate();
-
- m_ongoingFetches.add(fetchIdentifier, ServiceWorkerFetchTask::create(sessionID, WTFMove(contentConnection), serverConnectionIdentifier, contentFetchIdentifier));
- ASSERT(!m_ongoingFetchIdentifiers.contains({serverConnectionIdentifier, contentFetchIdentifier}));
- m_ongoingFetchIdentifiers.add({serverConnectionIdentifier, contentFetchIdentifier}, fetchIdentifier);
+ auto result = m_ongoingFetches.add(fetchIdentifier, ServiceWorkerFetchTask::create(sessionID, contentConnection, *this, contentFetchIdentifier, serviceWorkerIdentifier, m_networkProcess->serviceWorkerFetchTimeout()));
- send(Messages::WebSWContextManagerConnection::StartFetch { serverConnectionIdentifier, serviceWorkerIdentifier, fetchIdentifier, request, options, data, referrer });
+ ASSERT(!m_ongoingFetchIdentifiers.contains({ serverConnectionIdentifier, contentFetchIdentifier }));
+ m_ongoingFetchIdentifiers.add({ serverConnectionIdentifier, contentFetchIdentifier }, fetchIdentifier);
+
+ if (!send(Messages::WebSWContextManagerConnection::StartFetch { serverConnectionIdentifier, serviceWorkerIdentifier, fetchIdentifier, request, options, data, referrer }))
+ result.iterator->value->didNotHandle();
}
void WebSWServerToContextConnection::cancelFetch(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier contentFetchIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier)
@@ -204,6 +207,43 @@
}
}
+void WebSWServerToContextConnection::fetchTaskTimedOut(ServiceWorkerFetchTask& task)
+{
+ ASSERT(m_ongoingFetchIdentifiers.contains(task.identifier()));
+ auto takenIdentifier = m_ongoingFetchIdentifiers.take(task.identifier());
+
+ ASSERT(m_ongoingFetches.contains(takenIdentifier));
+ auto takenTask = m_ongoingFetches.take(takenIdentifier);
+ ASSERT(takenTask);
+ ASSERT(takenTask->ptr() == &task);
+
+ // Gather all other fetches in this service worker
+ HashSet<Ref<ServiceWorkerFetchTask>> otherFetches;
+ for (auto& fetchTask : m_ongoingFetches.values()) {
+ if (fetchTask->serviceWorkerIdentifier() == task.serviceWorkerIdentifier())
+ otherFetches.add(fetchTask.copyRef());
+ }
+
+ // Signal load failure for them
+ for (auto& fetchTask : otherFetches) {
+ if (fetchTask->wasHandled())
+ fetchTask->fail({ errorDomainWebKitInternal, 0, { }, "Service Worker context closed"_s });
+ else
+ fetchTask->didNotHandle();
+
+ auto identifier = m_ongoingFetchIdentifiers.take(fetchTask->identifier());
+ m_ongoingFetches.remove(identifier);
+ }
+
+ if (m_server) {
+ if (auto* worker = m_server->workerByID(task.serviceWorkerIdentifier())) {
+ worker->setHasTimedOutAnyFetchTasks();
+ if (worker->isRunning())
+ m_server->syncTerminateWorker(*worker);
+ }
+ }
+}
+
} // namespace WebKit
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h (250851 => 250852)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h 2019-10-08 19:50:12 UTC (rev 250852)
@@ -50,6 +50,7 @@
namespace WebKit {
class NetworkProcess;
+class WebSWServerConnection;
class WebSWServerToContextConnection : public WebCore::SWServerToContextConnection, public IPC::MessageSender, public IPC::MessageReceiver {
public:
@@ -63,7 +64,7 @@
void terminate();
- void startFetch(PAL::SessionID, Ref<IPC::Connection>&&, WebCore::SWServerConnectionIdentifier, WebCore::FetchIdentifier, WebCore::ServiceWorkerIdentifier, const WebCore::ResourceRequest&, const WebCore::FetchOptions&, const IPC::FormDataReference&, const String&);
+ void startFetch(PAL::SessionID, WebSWServerConnection&, WebCore::FetchIdentifier, WebCore::ServiceWorkerIdentifier, const WebCore::ResourceRequest&, const WebCore::FetchOptions&, const IPC::FormDataReference&, const String&);
void cancelFetch(WebCore::SWServerConnectionIdentifier, WebCore::FetchIdentifier, WebCore::ServiceWorkerIdentifier);
void continueDidReceiveFetchResponse(WebCore::SWServerConnectionIdentifier, WebCore::FetchIdentifier, WebCore::ServiceWorkerIdentifier);
@@ -72,6 +73,8 @@
void setThrottleState(bool isThrottleable);
bool isThrottleable() const { return m_isThrottleable; }
+ void fetchTaskTimedOut(ServiceWorkerFetchTask&);
+
private:
// IPC::MessageSender
IPC::Connection* messageSenderConnection() const final;
Modified: trunk/Source/WebKit/UIProcess/API/C/WKContext.cpp (250851 => 250852)
--- trunk/Source/WebKit/UIProcess/API/C/WKContext.cpp 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/UIProcess/API/C/WKContext.cpp 2019-10-08 19:50:12 UTC (rev 250852)
@@ -408,6 +408,16 @@
WebKit::toImpl(contextRef)->setCustomWebContentServiceBundleIdentifier(WebKit::toImpl(name)->string());
}
+void WKContextSetServiceWorkerFetchTimeoutForTesting(WKContextRef contextRef, double seconds)
+{
+ WebKit::toImpl(contextRef)->setServiceWorkerTimeoutForTesting((Seconds)seconds);
+}
+
+void WKContextResetServiceWorkerFetchTimeoutForTesting(WKContextRef contextRef)
+{
+ WebKit::toImpl(contextRef)->resetServiceWorkerTimeoutForTesting();
+}
+
void WKContextSetDiskCacheSpeculativeValidationEnabled(WKContextRef, bool)
{
}
Modified: trunk/Source/WebKit/UIProcess/API/C/WKContext.h (250851 => 250852)
--- trunk/Source/WebKit/UIProcess/API/C/WKContext.h 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/UIProcess/API/C/WKContext.h 2019-10-08 19:50:12 UTC (rev 250852)
@@ -170,6 +170,9 @@
WK_EXPORT void WKContextSetCustomWebContentServiceBundleIdentifier(WKContextRef contextRef, WKStringRef name);
+WK_EXPORT void WKContextSetServiceWorkerFetchTimeoutForTesting(WKContextRef contextRef, double seconds);
+WK_EXPORT void WKContextResetServiceWorkerFetchTimeoutForTesting(WKContextRef contextRef);
+
#ifdef __cplusplus
}
#endif
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (250851 => 250852)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2019-10-08 19:50:12 UTC (rev 250852)
@@ -1432,6 +1432,16 @@
completionHandler({ });
}
+void WebProcessPool::setServiceWorkerTimeoutForTesting(Seconds seconds)
+{
+ sendSyncToNetworkingProcess(Messages::NetworkProcess::SetServiceWorkerFetchTimeoutForTesting(seconds), Messages::NetworkProcess::SetServiceWorkerFetchTimeoutForTesting::Reply());
+}
+
+void WebProcessPool::resetServiceWorkerTimeoutForTesting()
+{
+ sendSyncToNetworkingProcess(Messages::NetworkProcess::ResetServiceWorkerFetchTimeoutForTesting(), Messages::NetworkProcess::ResetServiceWorkerFetchTimeoutForTesting::Reply());
+}
+
void WebProcessPool::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
{
m_alwaysUsesComplexTextCodePath = alwaysUseComplexText;
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (250851 => 250852)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.h 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h 2019-10-08 19:50:12 UTC (rev 250852)
@@ -257,6 +257,8 @@
ProcessID prewarmedProcessIdentifier();
void activePagesOriginsInWebProcessForTesting(ProcessID, CompletionHandler<void(Vector<String>&&)>&&);
bool networkProcessHasEntitlementForTesting(const String&);
+ void setServiceWorkerTimeoutForTesting(Seconds);
+ void resetServiceWorkerTimeoutForTesting();
WebPageGroup& defaultPageGroup() { return m_defaultPageGroup.get(); }
Modified: trunk/Tools/ChangeLog (250851 => 250852)
--- trunk/Tools/ChangeLog 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Tools/ChangeLog 2019-10-08 19:50:12 UTC (rev 250852)
@@ -1,3 +1,21 @@
+2019-10-08 Brady Eidson <beid...@apple.com>
+
+ Service Worker Fetch events should time out.
+ https://bugs.webkit.org/show_bug.cgi?id=202188
+
+ Reviewed by Alex Christensen.
+
+ * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+ * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+ (WTR::TestRunner::setServiceWorkerFetchTimeout):
+ * WebKitTestRunner/InjectedBundle/TestRunner.h:
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::resetStateToConsistentValues):
+ (WTR::TestController::setServiceWorkerFetchTimeoutForTesting):
+ * WebKitTestRunner/TestController.h:
+ * WebKitTestRunner/TestInvocation.cpp:
+ (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
2019-10-08 Matt Lewis <jlew...@apple.com>
Unreviewed, rolling out r250784.
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (250851 => 250852)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2019-10-08 19:50:12 UTC (rev 250852)
@@ -390,6 +390,8 @@
void sendDisplayConfigurationChangedMessageForTesting();
+ void setServiceWorkerFetchTimeout(double seconds);
+
// WebAuthN
void setWebAuthenticationMockConfiguration(object configuration);
void addTestKeyToKeychain(DOMString privateKeyBase64, DOMString attrLabel, DOMString applicationTagBase64);
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (250851 => 250852)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2019-10-08 19:50:12 UTC (rev 250852)
@@ -2628,6 +2628,13 @@
WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), nullptr, nullptr);
}
+void TestRunner::setServiceWorkerFetchTimeout(double seconds)
+{
+ WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SetServiceWorkerFetchTimeout"));
+ WKRetainPtr<WKDoubleRef> messageBody = adoptWK(WKDoubleCreate(seconds));
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
// WebAuthN
void TestRunner::setWebAuthenticationMockConfiguration(JSValueRef configurationValue)
{
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (250851 => 250852)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2019-10-08 19:50:12 UTC (rev 250852)
@@ -490,6 +490,8 @@
void sendDisplayConfigurationChangedMessageForTesting();
+ void setServiceWorkerFetchTimeout(double seconds);
+
// WebAuthN
void setWebAuthenticationMockConfiguration(JSValueRef);
// FIXME(189876)
Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (250851 => 250852)
--- trunk/Tools/WebKitTestRunner/TestController.cpp 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp 2019-10-08 19:50:12 UTC (rev 250852)
@@ -964,6 +964,8 @@
WKContextClearCachedCredentials(TestController::singleton().context());
+ WKContextResetServiceWorkerFetchTimeoutForTesting(TestController::singleton().context());
+
WKWebsiteDataStoreClearAllDeviceOrientationPermissions(TestController::websiteDataStore());
clearIndexedDatabases();
@@ -3614,6 +3616,11 @@
WKSendDisplayConfigurationChangedMessageForTesting(platformContext());
}
+void TestController::setServiceWorkerFetchTimeoutForTesting(double seconds)
+{
+ WKContextSetServiceWorkerFetchTimeoutForTesting(platformContext(), seconds);
+}
+
void TestController::setWebAuthenticationMockConfiguration(WKDictionaryRef configuration)
{
WKWebsiteDataStoreSetWebAuthenticationMockConfiguration(TestController::websiteDataStore(), configuration);
Modified: trunk/Tools/WebKitTestRunner/TestController.h (250851 => 250852)
--- trunk/Tools/WebKitTestRunner/TestController.h 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Tools/WebKitTestRunner/TestController.h 2019-10-08 19:50:12 UTC (rev 250852)
@@ -294,6 +294,8 @@
void sendDisplayConfigurationChangedMessageForTesting();
+ void setServiceWorkerFetchTimeoutForTesting(double seconds);
+
void setWebAuthenticationMockConfiguration(WKDictionaryRef);
void addTestKeyToKeychain(const String& privateKeyBase64, const String& attrLabel, const String& applicationTagBase64);
void cleanUpKeychain(const String& attrLabel, const String& applicationTagBase64);
Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (250851 => 250852)
--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2019-10-08 19:38:43 UTC (rev 250851)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2019-10-08 19:50:12 UTC (rev 250852)
@@ -1611,6 +1611,13 @@
return nullptr;
}
+ if (WKStringIsEqualToUTF8CString(messageName, "SetServiceWorkerFetchTimeout")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
+ WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
+ TestController::singleton().setServiceWorkerFetchTimeoutForTesting(WKDoubleGetValue(seconds));
+ return nullptr;
+ }
+
if (WKStringIsEqualToUTF8CString(messageName, "TerminateNetworkProcess")) {
ASSERT(!messageBody);
TestController::singleton().terminateNetworkProcess();