https://bugs.webkit.org/show_bug.cgi?id=180983
Reviewed by Youenn Fablet.
LayoutTests/imported/w3c:
Rebaseline WPT tests now that more checks are passing.
* web-platform-tests/service-workers/service-worker/register-default-scope.https-expected.txt:
* web-platform-tests/service-workers/service-worker/registration-iframe.https-expected.txt:
* web-platform-tests/service-workers/service-worker/registration-security-error.https-expected.txt:
Source/WebCore:
scopeURL should start with the provided scriptURL, as per:
- https://w3c.github.io/ServiceWorker/#update (steps 7.8 to 7.18)
No new tests, rebaselined existing tests.
* platform/network/HTTPHeaderNames.in:
* workers/service/ServiceWorkerJob.cpp:
(WebCore::ServiceWorkerJob::didReceiveResponse):
LayoutTests:
Update WebKit tests due to new restrictions.
* http/tests/workers/service/basic-unregister.https-expected.txt:
* http/tests/workers/service/controller-change.html:
* http/tests/workers/service/resources/ServiceWorkerGlobalScope_getRegistration-worker.js:
(async.runTest):
* http/tests/workers/service/resources/ServiceWorkerGlobalScope_register-worker.js:
(async.runTest):
* http/tests/workers/service/resources/basic-fetch.js:
(async.test):
* http/tests/workers/service/resources/basic-register.js:
(async.test):
* http/tests/workers/service/resources/basic-unregister.js:
(async.test):
* http/tests/workers/service/resources/service-worker-fetch.js:
(async.test):
* http/tests/workers/service/resources/service-worker-getRegistration.js:
(async.test):
* http/tests/workers/service/resources/service-worker-importScript.js:
(async.test):
* http/tests/workers/service/resources/shift-reload-navigation.js:
(async.test):
* http/tests/workers/service/service-worker-clear.html:
* http/tests/workers/service/service-worker-crossorigin-fetch.html:
* http/tests/workers/service/service-worker-getRegistration-expected.txt:
* http/tests/workers/service/service-worker-request-with-body.https.html:
* http/tests/workers/service/serviceworker-idb.https.html:
* http/tests/workers/service/serviceworker-websocket.https.html:
* http/tests/workers/service/serviceworkerclients-get.https.html:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226141
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2017-12-19 Chris Dumez <cdumez@apple.com>
+
+ scopeURL should start with the provided scriptURL
+ https://bugs.webkit.org/show_bug.cgi?id=180983
+
+ Reviewed by Youenn Fablet.
+
+ Update WebKit tests due to new restrictions.
+
+ * http/tests/workers/service/basic-unregister.https-expected.txt:
+ * http/tests/workers/service/controller-change.html:
+ * http/tests/workers/service/resources/ServiceWorkerGlobalScope_getRegistration-worker.js:
+ (async.runTest):
+ * http/tests/workers/service/resources/ServiceWorkerGlobalScope_register-worker.js:
+ (async.runTest):
+ * http/tests/workers/service/resources/basic-fetch.js:
+ (async.test):
+ * http/tests/workers/service/resources/basic-register.js:
+ (async.test):
+ * http/tests/workers/service/resources/basic-unregister.js:
+ (async.test):
+ * http/tests/workers/service/resources/service-worker-fetch.js:
+ (async.test):
+ * http/tests/workers/service/resources/service-worker-getRegistration.js:
+ (async.test):
+ * http/tests/workers/service/resources/service-worker-importScript.js:
+ (async.test):
+ * http/tests/workers/service/resources/shift-reload-navigation.js:
+ (async.test):
+ * http/tests/workers/service/service-worker-clear.html:
+ * http/tests/workers/service/service-worker-crossorigin-fetch.html:
+ * http/tests/workers/service/service-worker-getRegistration-expected.txt:
+ * http/tests/workers/service/service-worker-request-with-body.https.html:
+ * http/tests/workers/service/serviceworker-idb.https.html:
+ * http/tests/workers/service/serviceworker-websocket.https.html:
+ * http/tests/workers/service/serviceworkerclients-get.https.html:
+
2017-12-19 Youenn Fablet <youenn@apple.com>
Service Worker should not clean HTTP headers added by the application or by fetch specification before service worker interception
<script>
async function startServiceWorker()
{
- var registration = await navigator.serviceWorker.register("resources/fetch-service-worker.js", { scope : "/"});
+ var registration = await navigator.serviceWorker.register("resources/fetch-service-worker.js", { scope : "/inspector/network/resources/"});
await new Promise(resolve => {
if (registration.active)
resolve();
var frame;
await new Promise(function(resolve) {
frame = document.createElement('iframe');
- frame.src = "/";
+ frame.src = "/inspector/network/resources/";
frame.onload = function() { resolve(frame); };
document.body.appendChild(frame);
});
PASS: There is initially no service worker registered for the origin
-PASS: registration scope is https://127.0.0.1:8443/
+PASS: registration scope is https://127.0.0.1:8443/workers/service/resources/
PASS: There is a service worker registered for the origin
PASS: Unregistration was successful
PASS: There is no service worker registered for the origin
}
async function test() {
- let scopeURL = "/";
+ let scopeURL = "/workers/service/resources/";
let registration = await registerAndWaitForActive("resources/updating-fetch-worker.php", scopeURL);
let frame = await withFrame(scopeURL);
initialController = frame.contentWindow.navigator.serviceWorker.controller;
async function runTest()
{
try {
- let r = await navigator.serviceWorker.register("empty-worker.js", { scope: "/test" });
+ let r = await navigator.serviceWorker.register("empty-worker.js", { scope: "/workers/service/resources/test" });
log("PASS: Registration succeeded");
- let retrievedRegistration = await navigator.serviceWorker.getRegistration("/test");
+ let retrievedRegistration = await navigator.serviceWorker.getRegistration("/workers/service/resources/test");
if (r === retrievedRegistration)
log("PASS: getRegistration() returned the right registration");
else
async function runTest()
{
try {
- let r = await navigator.serviceWorker.register("empty-worker.js", { scope: "/test", updateViaCache: "none" });
+ let r = await navigator.serviceWorker.register("empty-worker.js", { scope: "/workers/service/resources/test", updateViaCache: "none" });
log("PASS: Registration succeeded");
- if (r.scope == "http://127.0.0.1:8000/test")
+ if (r.scope == "http://127.0.0.1:8000/workers/service/resources/test")
log("PASS: registration object's scope is valid");
else
log("FAIL: registration object's scope is invalid, got: " + r.scope);
async function test()
{
try {
- var frame = await interceptedFrame("resources/basic-fetch-worker.js", "/");
+ var frame = await interceptedFrame("resources/basic-fetch-worker.js", "/workers/service/resources/");
var fetch = frame.contentWindow.fetch;
var response = await fetch("test1");
testRunner.setPrivateBrowsingEnabled(false);
try {
- r = await navigator.serviceWorker.register("resources/empty-worker.js", { scope: "/test", updateViaCache: "none" })
+ r = await navigator.serviceWorker.register("resources/empty-worker.js", { scope: "/workers/service/resources/test", updateViaCache: "none" })
log("Registered!");
- if (r.scope == "http://127.0.0.1:8000/test")
+ if (r.scope == "http://127.0.0.1:8000/workers/service/resources/test")
log("PASS: registration object's scope is valid");
else
log("FAIL: registration object's scope is invalid, got: " + r.scope);
else
log("FAIL: registration object's updateViaCache is invalid, got: " + r.updateViaCache);
- if (await internals.hasServiceWorkerRegistration("/test"))
+ if (await internals.hasServiceWorkerRegistration("/workers/service/resources/test"))
log("PASS: A service worker is now registered for this origin");
else
log("FAIL: No service worker is registered for this origin");
else
log("FAIL: There is initially a service worker registered for the origin");
- let registration = await navigator.serviceWorker.register("resources/basic-fetch-worker.js", { scope: "/" });
- if (registration.scope === "https://127.0.0.1:8443/")
+ let registration = await navigator.serviceWorker.register("resources/basic-fetch-worker.js", { scope: "/workers/service/resources/" });
+ if (registration.scope === "https://127.0.0.1:8443/workers/service/resources/")
log("PASS: registration scope is " + registration.scope);
else
log("FAIL: registration scope is " + registration.scope);
- if (await internals.hasServiceWorkerRegistration(self.origin))
+ if (await internals.hasServiceWorkerRegistration("https://127.0.0.1:8443/workers/service/resources/"))
log("PASS: There is a service worker registered for the origin");
else
log("FAIL: There is no service worker registered for the origin");
async function test()
{
try {
- var frame = await interceptedFrame("resources/service-worker-fetch-worker.js", "/");
+ var frame = await interceptedFrame("resources/service-worker-fetch-worker.js", "/workers/service/resources/");
var fetch = frame.contentWindow.fetch;
var response = await fetch("status");
{
try {
log("Registering service worker 0");
- var newRegistration0 = await navigator.serviceWorker.register("resources/service-worker-getRegistration-worker.js", { scope: "/test1" });
+ var newRegistration0 = await navigator.serviceWorker.register("resources/service-worker-getRegistration-worker.js", { scope: "/workers/service/resources/test1" });
log("Service worker 0 registered with scope " + newRegistration0.scope);
var registration0 = await navigator.serviceWorker.getRegistration();
checkRegistration(registration0, undefined, "registration0");
- var registration1 = await navigator.serviceWorker.getRegistration("/test1");
+ var registration1 = await navigator.serviceWorker.getRegistration("/workers/service/resources/test1");
checkRegistration(registration1, newRegistration0, "registration1");
- var registration2 = await navigator.serviceWorker.getRegistration("/test");
+ var registration2 = await navigator.serviceWorker.getRegistration("/workers/service/resources/test");
checkRegistration(registration2, undefined, "registration2");
- var registration3 = await navigator.serviceWorker.getRegistration("/test1/test2/test3");
+ var registration3 = await navigator.serviceWorker.getRegistration("/workers/service/resources/test1/test2/test3");
checkRegistration(registration3, newRegistration0, "registration3");
log("Registering service worker 1");
- var newRegistration1 = await navigator.serviceWorker.register("resources/service-worker-getRegistration-worker.js", { scope: "/test1/test2" });
+ var newRegistration1 = await navigator.serviceWorker.register("resources/service-worker-getRegistration-worker.js", { scope: "/workers/service/resources/test1/test2" });
log("Service worker 1 registered with scope " + newRegistration1.scope);
log("Registering service worker 2");
- var newRegistration2 = await navigator.serviceWorker.register("resources/service-worker-getRegistration-worker.js", { scope: "./" });
+ var newRegistration2 = await navigator.serviceWorker.register("resources/service-worker-getRegistration-worker.js", { scope: "/workers/service/resources/" });
log("Service worker 2 registered with scope " + newRegistration2.scope);
- var registration4 = await navigator.serviceWorker.getRegistration("/test1/test2");
+ var registration4 = await navigator.serviceWorker.getRegistration("/workers/service/resources/test1/test2");
checkRegistration(registration4, newRegistration1, "registration4");
- var registration5 = await navigator.serviceWorker.getRegistration("/test1/test2-test3");
+ var registration5 = await navigator.serviceWorker.getRegistration("/workers/service/resources/test1/test2-test3");
checkRegistration(registration5, newRegistration1, "registration5");
- var registration6 = await navigator.serviceWorker.getRegistration();
+ var registration6 = await navigator.serviceWorker.getRegistration("/workers/service/resources/");
checkRegistration(registration6, newRegistration2, "registration6");
- var registration7 = await navigator.serviceWorker.getRegistration("");
+ var registration7 = await navigator.serviceWorker.getRegistration("/workers/service/resources/");
checkRegistration(registration7, newRegistration2, "registration7");
- var registration8 = await navigator.serviceWorker.getRegistration("foo");
+ var registration8 = await navigator.serviceWorker.getRegistration("/workers/service/resources/foo");
checkRegistration(registration8, newRegistration2, "registration8");
- var registration9 = await navigator.serviceWorker.getRegistration("/foo");
- checkRegistration(registration9, undefined, "registration9");
-
await newRegistration1.unregister();
- var registration10 = await navigator.serviceWorker.getRegistration("/test1/test2");
- checkRegistration(registration10, newRegistration0, "registration10");
+ var registration9 = await navigator.serviceWorker.getRegistration("/workers/service/resources/test1/test2");
+ checkRegistration(registration9, newRegistration0, "registration9");
} catch(e) {
log("Got exception: " + e);
}
await navigator.serviceWorker.register("resources/service-worker-importScript-worker.js", { });
log("Registered service worker");
- var frame = await interceptedFrame("resources/service-worker-fetch-worker.js", "/");
+ var frame = await interceptedFrame("resources/service-worker-fetch-worker.js", "/workers/service/resources/");
var fetch = frame.contentWindow.fetch;
var response = await fetch("status");
log("Status is " + response.statusText);
log("PASS: Fetch failed as expected with: " + e);
}
- var frame = await interceptedFrame("resources/service-worker-crossorigin-fetch-worker.js", "/");
+ var frame = await interceptedFrame("resources/service-worker-crossorigin-fetch-worker.js", "/workers/service/resources/");
var response = await frame.contentWindow.fetch("http://localhost:8080/resources/square100.png.fromserviceworker");
var buffer = await response.arrayBuffer();
var hasRegistration = await internals.hasServiceWorkerRegistration("");
log(hasRegistration ? "FAIL: Got registration" : "PASS: No registration");
- await navigator.serviceWorker.register("resources/service-worker-fetch-worker.js", { scope: "./" });
+ await navigator.serviceWorker.register("resources/service-worker-fetch-worker.js");
- var hasRegistration = await internals.hasServiceWorkerRegistration("");
+ var hasRegistration = await internals.hasServiceWorkerRegistration("/workers/service/resources/");
log(hasRegistration ? "PASS: Got registration" : "FAIL: No registration");
} catch(e) {
log("Got exception: " + e);
var frame;
promise_test(async test => {
- frame = await interceptedFrame("resources/service-worker-crossorigin-fetch-worker.js", "/");
+ frame = await interceptedFrame("resources/service-worker-crossorigin-fetch-worker.js", "/workers/service/resources/");
}, "Registering service worker and controlled frame");
promise_test(async test => {
Registering service worker 0
-Service worker 0 registered with scope http://127.0.0.1:8000/test1
+Service worker 0 registered with scope http://127.0.0.1:8000/workers/service/resources/test1
PASS: registration0 is as expected
PASS: registration1 is as expected
PASS: registration2 is as expected
PASS: registration3 is as expected
Registering service worker 1
-Service worker 1 registered with scope http://127.0.0.1:8000/test1/test2
+Service worker 1 registered with scope http://127.0.0.1:8000/workers/service/resources/test1/test2
Registering service worker 2
-Service worker 2 registered with scope http://127.0.0.1:8000/workers/service/
+Service worker 2 registered with scope http://127.0.0.1:8000/workers/service/resources/
PASS: registration4 is as expected
PASS: registration5 is as expected
PASS: registration6 is as expected
PASS: registration7 is as expected
PASS: registration8 is as expected
PASS: registration9 is as expected
-PASS: registration10 is as expected
var fetch;
promise_test(async (test) => {
- var frame = await interceptedFrame("resources/service-worker-request-with-body-worker.js", "/");
+ var frame = await interceptedFrame("resources/service-worker-request-with-body-worker.js", "/workers/service/resources/");
fetch = frame.contentWindow.fetch;
}, "Setup test");
<body>
<script>
var activeWorker;
-var scope = "whatever fits your IDB needs";
+var scope = "/workers/service/resources/IDB/";
promise_test(async (test) => {
var registration = await navigator.serviceWorker.getRegistration(scope);
<body>
<script>
var activeWorker;
-var scope = "wanna my sockets";
+var scope = "/workers/service/resources/WebSocket/";
promise_test(async (test) => {
var registration = await navigator.serviceWorker.getRegistration(scope);
}));
});
- var registration = await navigator.serviceWorker.register("resources/serviceworkerclients-get-worker.js", { scope : "/noone" });
+ var registration = await navigator.serviceWorker.register("resources/serviceworkerclients-get-worker.js", { scope : "/workers/service/resources/noone" });
var worker = registration.installing;
if (!worker)
worker = registration.active;
<script src="/resources/testharnessreport.js"></script>
<script>
promise_test(async (test) => {
- return navigator.serviceWorker.register("check-service-worker-header.py", { scope: "/" })
+ return navigator.serviceWorker.register("check-service-worker-header.py")
}, "Testing loading service worker script with the correct Service-Worker header");
</script>
2017-12-19 Chris Dumez <cdumez@apple.com>
+ scopeURL should start with the provided scriptURL
+ https://bugs.webkit.org/show_bug.cgi?id=180983
+
+ Reviewed by Youenn Fablet.
+
+ Rebaseline WPT tests now that more checks are passing.
+
+ * web-platform-tests/service-workers/service-worker/register-default-scope.https-expected.txt:
+ * web-platform-tests/service-workers/service-worker/registration-iframe.https-expected.txt:
+ * web-platform-tests/service-workers/service-worker/registration-security-error.https-expected.txt:
+
+2017-12-19 Chris Dumez <cdumez@apple.com>
+
Handle Fetch should wait for the service worker's state to become activated
https://bugs.webkit.org/show_bug.cgi?id=180959
PASS default scope
PASS undefined scope
-FAIL null scope assert_unreached: register should fail Reached unreachable code
+PASS null scope
-
PASS register method should use the "relevant global object" to parse its scriptURL and scope - normal case
PASS register method should use the "relevant global object" to parse its scriptURL and scope - error case
-FAIL A scope url should start with the given script url assert_unreached: unexpected rejection: assert_unreached: register() should reject Reached unreachable code Reached unreachable code
+PASS A scope url should start with the given script url
FAIL Registering same scope as the script directory without the last slash assert_unreached: Should have rejected: Registering same scope as the script directory without the last slash should fail with SecurityError. Reached unreachable code
-FAIL Registration scope outside the script directory assert_unreached: Should have rejected: Registration scope outside the script directory should fail with SecurityError. Reached unreachable code
+PASS Registration scope outside the script directory
PASS Registering scope outside domain
PASS Registering script outside domain
FAIL Registering redirected script assert_throws: Registration of redirected script should fail. function "function () { throw e }" threw object "TypeError: Script URL https://localhost:9443/service-workers/service-worker/resources/redirect.py?Redirect=%2Fservice-workers%2Fservice-worker%2Fresources%2Fregistration-worker.js fetch resulted in error: Redirections are not allowed" that is not a DOMException SecurityError: property "code" is equal to undefined, expected 18
-FAIL Scope including parent-reference and not under the script directory assert_unreached: Should have rejected: Scope not under the script directory should be rejected. Reached unreachable code
-FAIL Script URL including consecutive slashes assert_unreached: Should have rejected: Consecutive slashes in the script url should not be unified. Reached unreachable code
+PASS Scope including parent-reference and not under the script directory
+PASS Script URL including consecutive slashes
FAIL Script URL is same-origin filesystem: URL assert_throws: Registering a script which has same-origin filesystem: URL should fail with SecurityError. function "function () { throw e }" threw object "TypeError: serviceWorker.register() must be called with a script URL whose protocol is either HTTP or HTTPS" that is not a DOMException SecurityError: property "code" is equal to undefined, expected 18
+2017-12-19 Chris Dumez <cdumez@apple.com>
+
+ scopeURL should start with the provided scriptURL
+ https://bugs.webkit.org/show_bug.cgi?id=180983
+
+ Reviewed by Youenn Fablet.
+
+ scopeURL should start with the provided scriptURL, as per:
+ - https://w3c.github.io/ServiceWorker/#update (steps 7.8 to 7.18)
+
+ No new tests, rebaselined existing tests.
+
+ * platform/network/HTTPHeaderNames.in:
+ * workers/service/ServiceWorkerJob.cpp:
+ (WebCore::ServiceWorkerJob::didReceiveResponse):
+
2017-12-19 Zalan Bujtas <zalan@apple.com>
[RenderTreeBuilder] Move finding-the-parent/creating-wrapper logic from RenderTableSection::addChild to RenderTreeBuilder
Sec-WebSocket-Protocol
Sec-WebSocket-Version
Server
+Service-Worker-Allowed
Set-Cookie
Set-Cookie2
TE
#if ENABLE(SERVICE_WORKER)
+#include "HTTPHeaderNames.h"
#include "JSDOMPromiseDeferred.h"
#include "MIMETypeRegistry.h"
#include "ResourceError.h"
m_client->jobFailedLoadingScript(*this, WTFMove(error), WTFMove(exception));
m_scriptLoader = nullptr;
}
+ String serviceWorkerAllowed = response.httpHeaderField(HTTPHeaderName::ServiceWorkerAllowed);
+ String maxScopeString;
+ if (serviceWorkerAllowed.isNull()) {
+ String path = m_jobData.scriptURL.path();
+ // Last part of the path is the script's filename.
+ maxScopeString = path.substring(0, path.reverseFind('/'));
+ } else {
+ auto maxScope = URL(m_jobData.scriptURL, serviceWorkerAllowed);
+ maxScopeString = maxScope.path();
+ }
+ String scopeString = m_jobData.scopeURL.path();
+ if (!scopeString.startsWith(maxScopeString)) {
+ Exception exception { SecurityError, ASCIILiteral("Scope URL should start with the given script URL") };
+ ResourceError error { errorDomainWebKitInternal, 0, response.url(), ASCIILiteral("Scope URL should start with the given script URL") };
+ m_client->jobFailedLoadingScript(*this, WTFMove(error), WTFMove(exception));
+ m_scriptLoader = nullptr;
+ }
}
void ServiceWorkerJob::notifyFinished()