Diff
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (226135 => 226136)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2017-12-19 20:46:48 UTC (rev 226135)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2017-12-19 21:22:22 UTC (rev 226136)
@@ -1,3 +1,14 @@
+2017-12-19 Chris Dumez <[email protected]>
+
+ Handle Fetch should wait for the service worker's state to become activated
+ https://bugs.webkit.org/show_bug.cgi?id=180959
+
+ Reviewed by Youenn Fablet.
+
+ Rebaseline WPT test that is now passing.
+
+ * web-platform-tests/service-workers/service-worker/fetch-waits-for-activate.https-expected.txt:
+
2017-12-19 Youenn Fablet <[email protected]>
Service Worker should not clean HTTP headers added by the application or by fetch specification before service worker interception
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-waits-for-activate.https-expected.txt (226135 => 226136)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-waits-for-activate.https-expected.txt 2017-12-19 20:46:48 UTC (rev 226135)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-waits-for-activate.https-expected.txt 2017-12-19 21:22:22 UTC (rev 226136)
@@ -1,4 +1,3 @@
+PASS Fetch events should wait for the activate event to complete.
-FAIL Fetch events should wait for the activate event to complete. assert_unreached: unexpected rejection: assert_equals: frame should not be loaded expected (undefined) undefined but got (object) Element node <iframe class="test-iframe" src="" Reached unreachable code
-
Modified: trunk/Source/WebCore/ChangeLog (226135 => 226136)
--- trunk/Source/WebCore/ChangeLog 2017-12-19 20:46:48 UTC (rev 226135)
+++ trunk/Source/WebCore/ChangeLog 2017-12-19 21:22:22 UTC (rev 226136)
@@ -1,3 +1,25 @@
+2017-12-19 Chris Dumez <[email protected]>
+
+ Handle Fetch should wait for the service worker's state to become activated
+ https://bugs.webkit.org/show_bug.cgi?id=180959
+
+ Reviewed by Youenn Fablet.
+
+ Handle Fetch should wait for the service worker's state to become activated when
+ it is currently activating.
+
+ Specification:
+ - https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm (Step 16)
+
+ No new tests, rebaselined existing test.
+
+ * workers/service/server/SWServerWorker.cpp:
+ (WebCore::SWServerWorker::~SWServerWorker):
+ (WebCore::SWServerWorker::whenActivated):
+ (WebCore::SWServerWorker::setState):
+ (WebCore::SWServerWorker::callWhenActivatedHandler):
+ * workers/service/server/SWServerWorker.h:
+
2017-12-19 Yusuke Suzuki <[email protected]>
[YARR] Yarr should return ErrorCode instead of error messages (const char*)
Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (226135 => 226136)
--- trunk/Source/WebCore/workers/service/server/SWServer.h 2017-12-19 20:46:48 UTC (rev 226135)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h 2017-12-19 21:22:22 UTC (rev 226136)
@@ -46,6 +46,7 @@
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/Threading.h>
#include <wtf/UniqueRef.h>
+#include <wtf/WeakPtr.h>
namespace WebCore {
@@ -74,6 +75,8 @@
using Identifier = SWServerConnectionIdentifier;
Identifier identifier() const { return m_identifier; }
+ auto& weakPtrFactory() { return m_weakFactory; }
+
WEBCORE_EXPORT void didResolveRegistrationPromise(const ServiceWorkerRegistrationKey&);
SWServerRegistration* doRegistrationMatching(const SecurityOriginData& topOrigin, const URL& clientURL) { return m_server.doRegistrationMatching(topOrigin, clientURL); }
void resolveRegistrationReadyRequests(SWServerRegistration&);
@@ -113,6 +116,7 @@
SWServer& m_server;
Identifier m_identifier;
+ WeakPtrFactory<Connection> m_weakFactory;
Vector<RegistrationReadyRequest> m_registrationReadyRequests;
};
Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp (226135 => 226136)
--- trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp 2017-12-19 20:46:48 UTC (rev 226135)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp 2017-12-19 21:22:22 UTC (rev 226136)
@@ -58,6 +58,8 @@
SWServerWorker::~SWServerWorker()
{
+ callWhenActivatedHandler(false);
+
auto taken = allWorkers().take(identifier());
ASSERT_UNUSED(taken, taken == this);
}
@@ -152,6 +154,30 @@
registration->tryActivate();
}
+void SWServerWorker::whenActivated(WTF::Function<void(bool)>&& handler)
+{
+ if (state() == ServiceWorkerState::Activated) {
+ handler(true);
+ return;
+ }
+ m_whenActivatedHandlers.append(WTFMove(handler));
+}
+
+void SWServerWorker::setState(ServiceWorkerState state)
+{
+ m_data.state = state;
+
+ if (state == ServiceWorkerState::Activated || state == ServiceWorkerState::Redundant)
+ callWhenActivatedHandler(state == ServiceWorkerState::Activated);
+}
+
+void SWServerWorker::callWhenActivatedHandler(bool success)
+{
+ auto whenActivatedHandlers = WTFMove(m_whenActivatedHandlers);
+ for (auto& handler : whenActivatedHandlers)
+ handler(success);
+}
+
} // namespace WebCore
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.h (226135 => 226136)
--- trunk/Source/WebCore/workers/service/server/SWServerWorker.h 2017-12-19 20:46:48 UTC (rev 226135)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.h 2017-12-19 21:22:22 UTC (rev 226136)
@@ -59,6 +59,8 @@
void terminate();
+ WEBCORE_EXPORT void whenActivated(WTF::Function<void(bool)>&&);
+
enum class State {
Running,
Terminating,
@@ -78,7 +80,7 @@
SWServerToContextConnectionIdentifier contextConnectionIdentifier() const { return m_contextConnectionIdentifier; }
ServiceWorkerState state() const { return m_data.state; }
- void setState(ServiceWorkerState state) { m_data.state = state; }
+ void setState(ServiceWorkerState);
bool hasPendingEvents() const { return m_hasPendingEvents; }
void setHasPendingEvents(bool);
@@ -104,6 +106,8 @@
private:
SWServerWorker(SWServer&, SWServerRegistration&, SWServerToContextConnectionIdentifier, const URL&, const String& script, WorkerType, ServiceWorkerIdentifier);
+ void callWhenActivatedHandler(bool success);
+
SWServer& m_server;
ServiceWorkerRegistrationKey m_registrationKey;
SWServerToContextConnectionIdentifier m_contextConnectionIdentifier;
@@ -113,6 +117,7 @@
State m_state { State::NotRunning };
mutable std::optional<ClientOrigin> m_origin;
bool m_isSkipWaitingFlagSet { false };
+ Vector<WTF::Function<void(bool)>> m_whenActivatedHandlers;
};
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (226135 => 226136)
--- trunk/Source/WebKit/ChangeLog 2017-12-19 20:46:48 UTC (rev 226135)
+++ trunk/Source/WebKit/ChangeLog 2017-12-19 21:22:22 UTC (rev 226136)
@@ -1,3 +1,19 @@
+2017-12-19 Chris Dumez <[email protected]>
+
+ Handle Fetch should wait for the service worker's state to become activated
+ https://bugs.webkit.org/show_bug.cgi?id=180959
+
+ Reviewed by Youenn Fablet.
+
+ Handle Fetch should wait for the service worker's state to become activated when
+ it is currently activating.
+
+ Specification:
+ - https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm (Step 16)
+
+ * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+ (WebKit::WebSWServerConnection::startFetch):
+
2017-12-19 Youenn Fablet <[email protected]>
Service Worker should not clean HTTP headers added by the application or by fetch specification before service worker interception
Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp (226135 => 226136)
--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp 2017-12-19 20:46:48 UTC (rev 226135)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp 2017-12-19 21:22:22 UTC (rev 226136)
@@ -128,13 +128,36 @@
void WebSWServerConnection::startFetch(uint64_t fetchIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, ResourceRequest&& request, FetchOptions&& options, IPC::FormDataReference&& formData, String&& referrer)
{
- // It's possible this specific worker cannot be re-run (e.g. its registration has been removed)
- server().runServiceWorkerIfNecessary(serviceWorkerIdentifier, [contentConnection = m_contentConnection.copyRef(), connectionIdentifier = identifier(), fetchIdentifier, serviceWorkerIdentifier = serviceWorkerIdentifier, request = WTFMove(request), options = WTFMove(options), formData = WTFMove(formData), referrer = WTFMove(referrer)](bool success, auto& contextConnection) {
- if (success)
- sendToContextProcess(contextConnection, Messages::WebSWContextManagerConnection::StartFetch { connectionIdentifier, fetchIdentifier, serviceWorkerIdentifier, request, options, formData, referrer });
- else
- contentConnection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, fetchIdentifier);
- });
+ auto* worker = server().workerByID(serviceWorkerIdentifier);
+ if (!worker) {
+ m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, fetchIdentifier);
+ return;
+ }
+
+ auto runServerWorkerAndStartFetch = [weakThis = makeWeakPtr(this), this, fetchIdentifier, serviceWorkerIdentifier, request = WTFMove(request), options = WTFMove(options), formData = WTFMove(formData), referrer = WTFMove(referrer)](bool success) mutable {
+ if (!weakThis)
+ return;
+
+ if (!success) {
+ m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, fetchIdentifier);
+ return;
+ }
+
+ server().runServiceWorkerIfNecessary(serviceWorkerIdentifier, [weakThis = WTFMove(weakThis), this, fetchIdentifier, serviceWorkerIdentifier, request = WTFMove(request), options = WTFMove(options), formData = WTFMove(formData), referrer = WTFMove(referrer)](bool success, auto& contextConnection) {
+ if (!weakThis)
+ return;
+
+ if (success)
+ sendToContextProcess(contextConnection, Messages::WebSWContextManagerConnection::StartFetch { identifier(), fetchIdentifier, serviceWorkerIdentifier, request, options, formData, referrer });
+ else
+ m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, fetchIdentifier);
+ });
+ };
+
+ if (worker->state() == ServiceWorkerState::Activating)
+ worker->whenActivated(WTFMove(runServerWorkerAndStartFetch));
+ else
+ runServerWorkerAndStartFetch(true);
}
void WebSWServerConnection::postMessageToServiceWorker(ServiceWorkerIdentifier destinationIdentifier, IPC::DataReference&& message, const ServiceWorkerOrClientIdentifier& sourceIdentifier)