Diff
Modified: branches/safari-605-branch/LayoutTests/ChangeLog (227383 => 227384)
--- branches/safari-605-branch/LayoutTests/ChangeLog 2018-01-23 04:08:13 UTC (rev 227383)
+++ branches/safari-605-branch/LayoutTests/ChangeLog 2018-01-23 04:08:19 UTC (rev 227384)
@@ -1,5 +1,22 @@
2018-01-22 Jason Marcell <[email protected]>
+ Cherry-pick r227348. rdar://problem/36746180
+
+ 2018-01-22 Youenn Fablet <[email protected]>
+
+ Safari Tech Preview can't use GitHub login at forums.swift.org
+ https://bugs.webkit.org/show_bug.cgi?id=181908
+ <rdar://problem/36715111>
+
+ Reviewed by Chris Dumez.
+
+ * http/wpt/service-workers/navigation-redirect-worker.js: Added.
+ (async):
+ * http/wpt/service-workers/navigation-redirect.https-expected.txt: Added.
+ * http/wpt/service-workers/navigation-redirect.https.html: Added.
+
+2018-01-22 Jason Marcell <[email protected]>
+
Cherry-pick r227174. rdar://problem/36723030
2018-01-18 Chris Dumez <[email protected]>
Added: branches/safari-605-branch/LayoutTests/http/wpt/service-workers/navigation-redirect-worker.js (0 => 227384)
--- branches/safari-605-branch/LayoutTests/http/wpt/service-workers/navigation-redirect-worker.js (rev 0)
+++ branches/safari-605-branch/LayoutTests/http/wpt/service-workers/navigation-redirect-worker.js 2018-01-23 04:08:19 UTC (rev 227384)
@@ -0,0 +1,11 @@
+addEventListener("fetch", async (e) => {
+ if (e.request.url.indexOf("navigation-redirect-frame1.html") !== -1) {
+ //e.respondWith(new Response(self.registration.scope));
+ e.respondWith(Response.redirect("resources/navigation-redirect-frame2.html"));
+ return;
+ }
+ if (e.request.url.indexOf("navigation-redirect-frame2.html") !== -1) {
+ e.respondWith(new Response(self.registration.scope));
+ return;
+ }
+});
Added: branches/safari-605-branch/LayoutTests/http/wpt/service-workers/navigation-redirect.https-expected.txt (0 => 227384)
--- branches/safari-605-branch/LayoutTests/http/wpt/service-workers/navigation-redirect.https-expected.txt (rev 0)
+++ branches/safari-605-branch/LayoutTests/http/wpt/service-workers/navigation-redirect.https-expected.txt 2018-01-23 04:08:19 UTC (rev 227384)
@@ -0,0 +1,7 @@
+
+PASS Setup worker 1
+PASS Frame redirecting to an unregistered scope
+PASS Setup worker 2
+PASS Frame redirecting to a registered scope
+PASS Clean-up
+
Added: branches/safari-605-branch/LayoutTests/http/wpt/service-workers/navigation-redirect.https.html (0 => 227384)
--- branches/safari-605-branch/LayoutTests/http/wpt/service-workers/navigation-redirect.https.html (rev 0)
+++ branches/safari-605-branch/LayoutTests/http/wpt/service-workers/navigation-redirect.https.html 2018-01-23 04:08:19 UTC (rev 227384)
@@ -0,0 +1,66 @@
+<html>
+<head>
+<title>Service Worker Fetch Event</title>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+var scope1 = "resources/navigation-redirect-frame1.html";
+var scope2 = "resources/navigation-redirect-frame2.html";
+var registration1;
+var registration2;
+
+function withFrame(url)
+{
+ return new Promise((resolve) => {
+ let frame = document.createElement('iframe');
+ frame.src = ""
+ frame._onload_ = function() { resolve(frame); };
+ document.body.appendChild(frame);
+ });
+}
+
+async function registerServiceWorker(scope)
+{
+ var registration = await navigator.serviceWorker.register("navigation-redirect-worker.js", { scope : scope });
+ var activeWorker = registration.active;
+ if (activeWorker)
+ return;
+ activeWorker = registration.installing;
+ return new Promise(resolve => {
+ activeWorker.addEventListener('statechange', () => {
+ if (activeWorker.state === "activated")
+ resolve(registration);
+ });
+ });
+}
+
+promise_test(async (test) => {
+ registration1 = await registerServiceWorker(scope1);
+}, "Setup worker 1");
+
+promise_test(async (test) => {
+ var frame = await withFrame(scope1);
+ assert_equals(frame.contentWindow.navigator.serviceWorker.controller, null);
+ frame.remove();
+}, "Frame redirecting to an unregistered scope");
+
+promise_test(async (test) => {
+ registration2 = await registerServiceWorker(scope2);
+}, "Setup worker 2");
+
+promise_test(async (test) => {
+ var frame = await withFrame(scope1);
+ assert_true(frame.contentWindow.navigator.serviceWorker.controller !== null);
+ frame.remove();
+}, "Frame redirecting to a registered scope");
+
+promise_test(async (test) => {
+ registration1.unregister();
+ registration2.unregister();
+}, "Clean-up");
+
+</script>
+</body>
+</html>
Modified: branches/safari-605-branch/Source/WebCore/ChangeLog (227383 => 227384)
--- branches/safari-605-branch/Source/WebCore/ChangeLog 2018-01-23 04:08:13 UTC (rev 227383)
+++ branches/safari-605-branch/Source/WebCore/ChangeLog 2018-01-23 04:08:19 UTC (rev 227384)
@@ -1,5 +1,33 @@
2018-01-22 Jason Marcell <[email protected]>
+ Cherry-pick r227348. rdar://problem/36746180
+
+ 2018-01-22 Youenn Fablet <[email protected]>
+
+ Safari Tech Preview can't use GitHub login at forums.swift.org
+ https://bugs.webkit.org/show_bug.cgi?id=181908
+ <rdar://problem/36715111>
+
+ Reviewed by Chris Dumez.
+
+ Test: http/wpt/service-workers/navigation-redirect.https.html
+
+ For subresource loads, redirections will not change who is in charge of continuing the load (service worker or network process).
+ For navigation loads, we need to match the registration for every redirection since this is using the Manual redirect mode.
+ This allows starting the load with a service worker and finishing the load with another service worker, which will become the controller.
+
+ Implement this by wrapping the registration matching of an URL within DocumentLoader::matchRegistration.
+ Use that method in DocumentLoader::redirectReceived.
+
+ * loader/DocumentLoader.cpp:
+ (WebCore::DocumentLoader::matchRegistration):
+ (WebCore::doRegistrationsMatch):
+ (WebCore::DocumentLoader::redirectReceived):
+ (WebCore::DocumentLoader::startLoadingMainResource):
+ * loader/DocumentLoader.h:
+
+2018-01-22 Jason Marcell <[email protected]>
+
Cherry-pick r227213. rdar://problem/36722644
2018-01-19 Jonathan Bedard <[email protected]>
Modified: branches/safari-605-branch/Source/WebCore/loader/DocumentLoader.cpp (227383 => 227384)
--- branches/safari-605-branch/Source/WebCore/loader/DocumentLoader.cpp 2018-01-23 04:08:13 UTC (rev 227383)
+++ branches/safari-605-branch/Source/WebCore/loader/DocumentLoader.cpp 2018-01-23 04:08:19 UTC (rev 227384)
@@ -482,10 +482,70 @@
startDataLoadTimer();
}
+#if ENABLE(SERVICE_WORKER)
+void DocumentLoader::matchRegistration(const URL& url, SWClientConnection::RegistrationCallback&& callback)
+{
+ auto shouldTryLoadingThroughServiceWorker = !frameLoader()->isReloadingFromOrigin() && m_frame->page() && RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled() && SchemeRegistry::canServiceWorkersHandleURLScheme(url.protocol().toStringWithoutCopying());
+ if (!shouldTryLoadingThroughServiceWorker) {
+ callback(std::nullopt);
+ return;
+ }
+
+ auto origin = (!m_frame->isMainFrame() && m_frame->document()) ? makeRef(m_frame->document()->topOrigin()) : SecurityOrigin::create(url);
+ auto sessionID = m_frame->page()->sessionID();
+ auto& provider = ServiceWorkerProvider::singleton();
+ if (!provider.mayHaveServiceWorkerRegisteredForOrigin(sessionID, origin)) {
+ callback(std::nullopt);
+ return;
+ }
+
+ auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(sessionID);
+ connection.matchRegistration(origin, url, WTFMove(callback));
+}
+
+static inline bool areRegistrationsEqual(const std::optional<ServiceWorkerRegistrationData>& a, const std::optional<ServiceWorkerRegistrationData>& b)
+{
+ if (!a)
+ return !b;
+ if (!b)
+ return false;
+ return a->identifier == b->identifier;
+}
+#endif
+
void DocumentLoader::redirectReceived(CachedResource& resource, ResourceRequest&& request, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
{
ASSERT_UNUSED(resource, &resource == m_mainResource);
+#if ENABLE(SERVICE_WORKER)
+ willSendRequest(WTFMove(request), redirectResponse, [completionHandler = WTFMove(completionHandler), protectedThis = makeRef(*this), this] (auto&& request) mutable {
+ if (request.isNull() || !m_mainDocumentError.isNull() || !m_frame) {
+ completionHandler({ });
+ return;
+ }
+ auto url = ""
+ matchRegistration(url, [request = WTFMove(request), completionHandler = WTFMove(completionHandler), protectedThis = WTFMove(protectedThis), this] (auto&& registrationData) mutable {
+ if (!m_mainDocumentError.isNull() || !m_frame) {
+ completionHandler({ });
+ return;
+ }
+
+ if (areRegistrationsEqual(m_serviceWorkerRegistrationData, registrationData)) {
+ completionHandler(WTFMove(request));
+ return;
+ }
+
+ // Service worker registration changed, we need to cancel the current load to restart a new one.
+ clearMainResource();
+ completionHandler({ });
+
+ m_serviceWorkerRegistrationData = WTFMove(registrationData);
+ loadMainResource(WTFMove(request));
+ return;
+ });
+ });
+#else
willSendRequest(WTFMove(request), redirectResponse, WTFMove(completionHandler));
+#endif
}
void DocumentLoader::willSendRequest(ResourceRequest&& newRequest, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
@@ -1586,26 +1646,17 @@
#if ENABLE(SERVICE_WORKER)
// FIXME: Implement local URL interception by getting the service worker of the parent.
- auto tryLoadingThroughServiceWorker = !frameLoader()->isReloadingFromOrigin() && m_frame->page() && RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled() && SchemeRegistry::canServiceWorkersHandleURLScheme(request.url().protocol().toStringWithoutCopying());
- if (tryLoadingThroughServiceWorker) {
- auto origin = (!m_frame->isMainFrame() && m_frame->document()) ? makeRef(m_frame->document()->topOrigin()) : SecurityOrigin::create(request.url());
- auto sessionID = m_frame->page()->sessionID();
- auto& provider = ServiceWorkerProvider::singleton();
- if (provider.mayHaveServiceWorkerRegisteredForOrigin(sessionID, origin)) {
- auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(sessionID);
- auto url = ""
- connection.matchRegistration(origin, url, [request = WTFMove(request), protectedThis = WTFMove(protectedThis), this] (auto&& registrationData) mutable {
- if (!m_mainDocumentError.isNull() || !m_frame)
- return;
+ auto url = ""
+ matchRegistration(url, [request = WTFMove(request), protectedThis = WTFMove(protectedThis), this] (auto&& registrationData) mutable {
+ if (!m_mainDocumentError.isNull() || !m_frame)
+ return;
- m_serviceWorkerRegistrationData = WTFMove(registrationData);
- loadMainResource(WTFMove(request));
- });
- return;
- }
- }
+ m_serviceWorkerRegistrationData = WTFMove(registrationData);
+ loadMainResource(WTFMove(request));
+ });
+#else
+ loadMainResource(WTFMove(request));
#endif
- loadMainResource(WTFMove(request));
});
}
Modified: branches/safari-605-branch/Source/WebCore/loader/DocumentLoader.h (227383 => 227384)
--- branches/safari-605-branch/Source/WebCore/loader/DocumentLoader.h 2018-01-23 04:08:13 UTC (rev 227383)
+++ branches/safari-605-branch/Source/WebCore/loader/DocumentLoader.h 2018-01-23 04:08:19 UTC (rev 227384)
@@ -320,6 +320,10 @@
private:
Document* document() const;
+#if ENABLE(SERVICE_WORKER)
+ void matchRegistration(const URL&, CompletionHandler<void(std::optional<ServiceWorkerRegistrationData>&&)>&&);
+#endif
+
void loadMainResource(ResourceRequest&&);
void setRequest(const ResourceRequest&);