зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1737692 [wpt PR 31378] - Fetch: Plumb request initiator through passthrough service workers., a=testonly
Automatic update from web-platform-tests Fetch: Plumb request initiator through passthrough service workers. This CL contains essentially two changes: 1. The request initiator origin is plumbed through service workers that do `fetch(evt.request)`. In addition to plumbing, this requires changes to how we validate navigation requests in the CorsURLLoaderFactory. 2. Tracks the original destination of a request passed through a service worker. This is then used in the network service to force SameSite=Lax cookies to treat the request as a main frame navigation where appropriate. For more detailed information about these changes please see the internal design doc at: https://docs.google.com/document/d/1KZscujuV7bCFEnzJW-0DaCPU-I40RJimQKoCcI0umTQ/edit?usp=sharing In addition, there is some discussion of these features in the following spec issues: https://github.com/whatwg/fetch/issues/1321 https://github.com/whatwg/fetch/issues/1327 The test includes WPT tests that verify navigation headers and SameSite cookies. Note, chrome has a couple expected failures in the SameSite cookie tests because of the "lax-allowing-unsafe" intervention that is currently enabled. See: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/TestExpectations;l=4635;drc=e8133cbf2469adb99c6610483ab78bcfb8cc4c76 Bug: 1115847,1241188 Change-Id: I7e236fa20aeabb705aef40fcf8d5c36da6d2798c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3115917 Reviewed-by: Matt Menke <mmenke@chromium.org> Reviewed-by: Yutaka Hirano <yhirano@chromium.org> Reviewed-by: Nasko Oskov <nasko@chromium.org> Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org> Commit-Queue: Ben Kelly <wanderview@chromium.org> Cr-Commit-Position: refs/heads/main@{#936029} -- wpt-commits: cd0951f4268af579e9e26913fbefea1684c67f2d wpt-pr: 31378
This commit is contained in:
Родитель
8564d47e49
Коммит
c1eb2fc596
|
@ -0,0 +1,558 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Service Worker: Navigation Post Request Origin Header</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/get-host-info.sub.js"></script>
|
||||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
const script = new URL('./resources/fetch-rewrite-worker.js', self.location);
|
||||
const base = './resources/navigation-headers-server.py';
|
||||
const scope = base + '?with-sw';
|
||||
let registration;
|
||||
|
||||
async function post_and_get_headers(t, form_host, method, swaction) {
|
||||
if (swaction === 'navpreload') {
|
||||
assert_true('navigationPreload' in registration,
|
||||
'navigation preload must be supported');
|
||||
}
|
||||
let target_string;
|
||||
if (swaction === 'no-sw') {
|
||||
target_string = base + '?no-sw';
|
||||
} else if (swaction === 'fallback') {
|
||||
target_string = `${scope}&ignore`;
|
||||
} else {
|
||||
target_string = `${scope}&${swaction}`;
|
||||
}
|
||||
const target = new URL(target_string, self.location);
|
||||
|
||||
let popup_url_path;
|
||||
if (method === 'GET') {
|
||||
popup_url_path = './resources/location-setter.html';
|
||||
} else if (method === 'POST') {
|
||||
popup_url_path = './resources/form-poster.html';
|
||||
}
|
||||
|
||||
const popup_url = new URL(popup_url_path, self.location);
|
||||
const tmp_params = new URLSearchParams();
|
||||
tmp_params.set('target', encodeURIComponent(target));
|
||||
popup_url.hostname = form_host;
|
||||
popup_url.search = tmp_params.toString();
|
||||
|
||||
const message_promise = new Promise(resolve => {
|
||||
self.addEventListener('message', evt => {
|
||||
resolve(evt.data);
|
||||
});
|
||||
});
|
||||
|
||||
const frame = await with_iframe(popup_url);
|
||||
t.add_cleanup(() => frame.remove());
|
||||
|
||||
return await message_promise;
|
||||
}
|
||||
|
||||
const SAME_ORIGIN = new URL(self.location.origin);
|
||||
const SAME_SITE = new URL(get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
const CROSS_SITE = new URL(get_host_info().HTTPS_NOTSAMESITE_ORIGIN);
|
||||
|
||||
promise_test(async t => {
|
||||
registration = await service_worker_unregister_and_register(t, script, scope);
|
||||
await wait_for_state(t, registration.installing, 'activated');
|
||||
if (registration.navigationPreload)
|
||||
await registration.navigationPreload.enable();
|
||||
}, 'Setup service worker');
|
||||
|
||||
//
|
||||
// Origin and referer headers
|
||||
//
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'GET',
|
||||
'no-sw');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, SAME_ORIGIN.href, 'referer header');
|
||||
}, 'GET Navigation, same-origin with no service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'POST',
|
||||
'no-sw');
|
||||
assert_equals(result.origin, SAME_ORIGIN.origin, 'origin header');
|
||||
assert_equals(result.referer, SAME_ORIGIN.href, 'referer header');
|
||||
}, 'POST Navigation, same-origin with no service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'GET',
|
||||
'passthrough');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, SAME_ORIGIN.href, 'referer header');
|
||||
}, 'GET Navigation, same-origin with passthrough service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'POST',
|
||||
'passthrough');
|
||||
assert_equals(result.origin, SAME_ORIGIN.origin, 'origin header');
|
||||
assert_equals(result.referer, SAME_ORIGIN.href, 'referer header');
|
||||
}, 'POST Navigation, same-origin with passthrough service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'GET',
|
||||
'fallback');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, SAME_ORIGIN.href, 'referer header');
|
||||
}, 'GET Navigation, same-origin with fallback service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'POST',
|
||||
'fallback');
|
||||
assert_equals(result.origin, SAME_ORIGIN.origin, 'origin header');
|
||||
assert_equals(result.referer, SAME_ORIGIN.href, 'referer header');
|
||||
}, 'POST Navigation, same-origin with fallback service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'GET',
|
||||
'navpreload');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, SAME_ORIGIN.href, 'referer header');
|
||||
}, 'GET Navigation, same-origin with navpreload service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
// There is no POST test for navpreload since the feature only supports GET
|
||||
// requests.
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'GET',
|
||||
'change-request');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, script.href, 'referer header');
|
||||
}, 'GET Navigation, same-origin with service worker that changes the ' +
|
||||
'request sets correct origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'POST',
|
||||
'change-request');
|
||||
assert_equals(result.origin, SAME_ORIGIN.origin, 'origin header');
|
||||
assert_equals(result.referer, script.href, 'referer header');
|
||||
}, 'POST Navigation, same-origin with service worker that changes the ' +
|
||||
'request sets correct origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'GET',
|
||||
'no-sw');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, SAME_SITE.href, 'referer header');
|
||||
}, 'GET Navigation, same-site with no service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'POST',
|
||||
'no-sw');
|
||||
assert_equals(result.origin, SAME_SITE.origin, 'origin header');
|
||||
assert_equals(result.referer, SAME_SITE.href, 'referer header');
|
||||
}, 'POST Navigation, same-site with no service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'GET',
|
||||
'passthrough');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, SAME_SITE.href, 'referer header');
|
||||
}, 'GET Navigation, same-site with passthrough service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'POST',
|
||||
'passthrough');
|
||||
assert_equals(result.origin, SAME_SITE.origin, 'origin header');
|
||||
assert_equals(result.referer, SAME_SITE.href, 'referer header');
|
||||
}, 'POST Navigation, same-site with passthrough service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'GET',
|
||||
'fallback');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, SAME_SITE.href, 'referer header');
|
||||
}, 'GET Navigation, same-site with fallback service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'POST',
|
||||
'fallback');
|
||||
assert_equals(result.origin, SAME_SITE.origin, 'origin header');
|
||||
assert_equals(result.referer, SAME_SITE.href, 'referer header');
|
||||
}, 'POST Navigation, same-site with fallback service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'GET',
|
||||
'navpreload');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, SAME_SITE.href, 'referer header');
|
||||
}, 'GET Navigation, same-site with navpreload service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
// There is no POST test for navpreload since the feature only supports GET
|
||||
// requests.
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'GET',
|
||||
'change-request');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, script.href, 'referer header');
|
||||
}, 'GET Navigation, same-site with service worker that changes the ' +
|
||||
'request sets correct origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'POST',
|
||||
'change-request');
|
||||
assert_equals(result.origin, SAME_ORIGIN.origin, 'origin header');
|
||||
assert_equals(result.referer, script.href, 'referer header');
|
||||
}, 'POST Navigation, same-site with service worker that changes the ' +
|
||||
'request sets correct origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'GET',
|
||||
'no-sw');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, CROSS_SITE.href, 'referer header');
|
||||
}, 'GET Navigation, cross-site with no service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'POST',
|
||||
'no-sw');
|
||||
assert_equals(result.origin, CROSS_SITE.origin, 'origin header');
|
||||
assert_equals(result.referer, CROSS_SITE.href, 'referer header');
|
||||
}, 'POST Navigation, cross-site with no service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'GET',
|
||||
'passthrough');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, CROSS_SITE.href, 'referer header');
|
||||
}, 'GET Navigation, cross-site with passthrough service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'POST',
|
||||
'passthrough');
|
||||
assert_equals(result.origin, CROSS_SITE.origin, 'origin header');
|
||||
assert_equals(result.referer, CROSS_SITE.href, 'referer header');
|
||||
}, 'POST Navigation, cross-site with passthrough service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'GET',
|
||||
'fallback');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, CROSS_SITE.href, 'referer header');
|
||||
}, 'GET Navigation, cross-site with fallback service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'POST',
|
||||
'fallback');
|
||||
assert_equals(result.origin, CROSS_SITE.origin, 'origin header');
|
||||
assert_equals(result.referer, CROSS_SITE.href, 'referer header');
|
||||
}, 'POST Navigation, cross-site with fallback service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'GET',
|
||||
'navpreload');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, CROSS_SITE.href, 'referer header');
|
||||
}, 'GET Navigation, cross-site with navpreload service worker sets correct ' +
|
||||
'origin and referer headers.');
|
||||
|
||||
// There is no POST test for navpreload since the feature only supports GET
|
||||
// requests.
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'GET',
|
||||
'change-request');
|
||||
assert_equals(result.origin, 'not set', 'origin header');
|
||||
assert_equals(result.referer, script.href, 'referer header');
|
||||
}, 'GET Navigation, cross-site with service worker that changes the ' +
|
||||
'request sets correct origin and referer headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'POST',
|
||||
'change-request');
|
||||
assert_equals(result.origin, SAME_ORIGIN.origin, 'origin header');
|
||||
assert_equals(result.referer, script.href, 'referer header');
|
||||
}, 'POST Navigation, cross-site with service worker that changes the ' +
|
||||
'request sets correct origin and referer headers.');
|
||||
|
||||
//
|
||||
// Sec-Fetch-* Headers (separated since not all browsers implement them)
|
||||
//
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'GET',
|
||||
'no-sw');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, same-origin with no service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'POST',
|
||||
'no-sw');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'POST Navigation, same-origin with no service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'GET',
|
||||
'passthrough');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'empty', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, same-origin with passthrough service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'POST',
|
||||
'passthrough');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'empty', 'sec-fetch-dest header');
|
||||
}, 'POST Navigation, same-origin with passthrough service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'GET',
|
||||
'fallback');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, same-origin with fallback service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'POST',
|
||||
'fallback');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'POST Navigation, same-origin with fallback service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'GET',
|
||||
'navpreload');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, same-origin with navpreload service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
// There is no POST test for navpreload since the feature only supports GET
|
||||
// requests.
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'GET',
|
||||
'change-request');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'same-origin', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'empty', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, same-origin with service worker that changes the ' +
|
||||
'request sets correct sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_ORIGIN.hostname, 'POST',
|
||||
'change-request');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'same-origin', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'empty', 'sec-fetch-dest header');
|
||||
}, 'POST Navigation, same-origin with service worker that changes the ' +
|
||||
'request sets correct sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'GET',
|
||||
'no-sw');
|
||||
assert_equals(result['sec-fetch-site'], 'same-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, same-site with no service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'POST',
|
||||
'no-sw');
|
||||
assert_equals(result['sec-fetch-site'], 'same-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'POST Navigation, same-site with no service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'GET',
|
||||
'passthrough');
|
||||
assert_equals(result['sec-fetch-site'], 'same-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'empty', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, same-site with passthrough service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'POST',
|
||||
'passthrough');
|
||||
assert_equals(result['sec-fetch-site'], 'same-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'empty', 'sec-fetch-dest header');
|
||||
}, 'POST Navigation, same-site with passthrough service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'GET',
|
||||
'fallback');
|
||||
assert_equals(result['sec-fetch-site'], 'same-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, same-site with fallback service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'POST',
|
||||
'fallback');
|
||||
assert_equals(result['sec-fetch-site'], 'same-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'POST Navigation, same-site with fallback service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'GET',
|
||||
'navpreload');
|
||||
assert_equals(result['sec-fetch-site'], 'same-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, same-site with navpreload service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
// There is no POST test for navpreload since the feature only supports GET
|
||||
// requests.
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'GET',
|
||||
'change-request');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'same-origin', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'empty', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, same-site with service worker that changes the ' +
|
||||
'request sets correct sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, SAME_SITE.hostname, 'POST',
|
||||
'change-request');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'same-origin', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'empty', 'sec-fetch-dest header');
|
||||
}, 'POST Navigation, same-site with service worker that changes the ' +
|
||||
'request sets correct sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'GET',
|
||||
'no-sw');
|
||||
assert_equals(result['sec-fetch-site'], 'cross-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, cross-site with no service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'POST',
|
||||
'no-sw');
|
||||
assert_equals(result['sec-fetch-site'], 'cross-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'POST Navigation, cross-site with no service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'GET',
|
||||
'passthrough');
|
||||
assert_equals(result['sec-fetch-site'], 'cross-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'empty', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, cross-site with passthrough service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'POST',
|
||||
'passthrough');
|
||||
assert_equals(result['sec-fetch-site'], 'cross-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'empty', 'sec-fetch-dest header');
|
||||
}, 'POST Navigation, cross-site with passthrough service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'GET',
|
||||
'fallback');
|
||||
assert_equals(result['sec-fetch-site'], 'cross-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, cross-site with fallback service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'POST',
|
||||
'fallback');
|
||||
assert_equals(result['sec-fetch-site'], 'cross-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'POST Navigation, cross-site with fallback service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'GET',
|
||||
'navpreload');
|
||||
assert_equals(result['sec-fetch-site'], 'cross-site', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'navigate', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'iframe', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, cross-site with navpreload service worker sets correct ' +
|
||||
'sec-fetch headers.');
|
||||
|
||||
// There is no POST test for navpreload since the feature only supports GET
|
||||
// requests.
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'GET',
|
||||
'change-request');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'same-origin', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'empty', 'sec-fetch-dest header');
|
||||
}, 'GET Navigation, cross-site with service worker that changes the ' +
|
||||
'request sets correct sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
const result = await post_and_get_headers(t, CROSS_SITE.hostname, 'POST',
|
||||
'change-request');
|
||||
assert_equals(result['sec-fetch-site'], 'same-origin', 'sec-fetch-site header');
|
||||
assert_equals(result['sec-fetch-mode'], 'same-origin', 'sec-fetch-mode header');
|
||||
assert_equals(result['sec-fetch-dest'], 'empty', 'sec-fetch-dest header');
|
||||
}, 'POST Navigation, cross-site with service worker that changes the ' +
|
||||
'request sets correct sec-fetch headers.');
|
||||
|
||||
promise_test(async t => {
|
||||
await registration.unregister();
|
||||
}, 'Cleanup service worker');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -90,8 +90,12 @@ self.addEventListener('fetch', function(event) {
|
|||
var request = event.request;
|
||||
if (url) {
|
||||
request = new Request(url, init);
|
||||
} else if (params['change-request']) {
|
||||
request = new Request(request, init);
|
||||
}
|
||||
fetch(request).then(function(response) {
|
||||
const response_promise = params['navpreload'] ? event.preloadResponse
|
||||
: fetch(request);
|
||||
response_promise.then(function(response) {
|
||||
var expectedType = params['expected_type'];
|
||||
if (expectedType && response.type !== expectedType) {
|
||||
// Resolve a JSON object with a failure instead of rejecting
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Content-Type: text/javascript
|
||||
Service-Worker-Allowed: /
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<meta name="referrer" content="origin">
|
||||
<form method="POST" id="form"></form>
|
||||
<script>
|
||||
function onLoad() {
|
||||
const params = new URLSearchParams(self.location.search);
|
||||
const form = document.getElementById('form');
|
||||
form.action = decodeURIComponent(params.get('target'));
|
||||
form.submit();
|
||||
}
|
||||
self.addEventListener('load', onLoad);
|
||||
</script>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<meta name="referrer" content="origin">
|
||||
<script>
|
||||
function onLoad() {
|
||||
const params = new URLSearchParams(self.location.search);
|
||||
const target = decodeURIComponent(params.get('target'));
|
||||
self.location = target;
|
||||
}
|
||||
self.addEventListener('load', onLoad);
|
||||
</script>
|
|
@ -0,0 +1,19 @@
|
|||
def main(request, response):
|
||||
response.status = (200, b"OK")
|
||||
response.headers.set(b"Content-Type", b"text/html")
|
||||
return b"""
|
||||
<script>
|
||||
self.addEventListener('load', evt => {
|
||||
self.parent.postMessage({
|
||||
origin: '%s',
|
||||
referer: '%s',
|
||||
'sec-fetch-site': '%s',
|
||||
'sec-fetch-mode': '%s',
|
||||
'sec-fetch-dest': '%s',
|
||||
});
|
||||
});
|
||||
</script>""" % (request.headers.get(
|
||||
b"origin", b"not set"), request.headers.get(b"referer", b"not set"),
|
||||
request.headers.get(b"sec-fetch-site", b"not set"),
|
||||
request.headers.get(b"sec-fetch-mode", b"not set"),
|
||||
request.headers.get(b"sec-fetch-dest", b"not set"))
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8"/>
|
||||
<script>
|
||||
async function onLoad() {
|
||||
const scope = self.origin + '/cookies/resources/postToParent.py?with-sw';
|
||||
const script = './fetch-rewrite-worker.js';
|
||||
const reg = await navigator.serviceWorker.register(script, { scope: scope });
|
||||
await new Promise(resolve => {
|
||||
const worker = reg.installing;
|
||||
worker.addEventListener('statechange', evt => {
|
||||
if (worker.state === 'activated') {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
if (reg.navigationPreload) {
|
||||
await reg.navigationPreload.enable();
|
||||
}
|
||||
window.opener.postMessage({ type: 'SW-REGISTERED' }, '*');
|
||||
}
|
||||
self.addEventListener('load', onLoad);
|
||||
</script>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8"/>
|
||||
<script>
|
||||
async function onLoad() {
|
||||
const scope = self.origin + '/cookies/resources/postToParent.py?with-sw';
|
||||
const reg = await navigator.serviceWorker.getRegistration(scope);
|
||||
await reg.unregister();
|
||||
window.opener.postMessage({ type: 'SW-UNREGISTERED' }, '*');
|
||||
}
|
||||
self.addEventListener('load', onLoad);
|
||||
</script>
|
|
@ -0,0 +1,215 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Service Worker: Same-site cookie behavior</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/get-host-info.sub.js"></script>
|
||||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
||||
<script src="/cookies/resources/cookie-helper.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
async function unregister_service_worker(origin) {
|
||||
const w = window.open(origin +
|
||||
'/service-workers/service-worker/resources/same-site-cookies-unregister.html');
|
||||
try {
|
||||
await wait_for_message('SW-UNREGISTERED');
|
||||
} finally {
|
||||
w.close();
|
||||
}
|
||||
}
|
||||
|
||||
async function register_service_worker(origin) {
|
||||
const w = window.open(origin +
|
||||
'/service-workers/service-worker/resources/same-site-cookies-register.html');
|
||||
try {
|
||||
await wait_for_message('SW-REGISTERED');
|
||||
} finally {
|
||||
w.close();
|
||||
}
|
||||
}
|
||||
|
||||
async function run_test(t, origin, navaction, swaction, expected) {
|
||||
const value = 'COOKIE_VALUE';
|
||||
await resetSameSiteCookies(origin, value);
|
||||
if (swaction === 'navpreload') {
|
||||
assert_true('navigationPreload' in ServiceWorkerRegistration.prototype,
|
||||
'navigation preload must be supported');
|
||||
}
|
||||
const sw_param = swaction === 'no-sw' ? 'no-sw' : 'with-sw';
|
||||
let action_param = '';
|
||||
if (swaction === 'fallback') {
|
||||
action_param = '&ignore';
|
||||
} else if (swaction !== 'no-sw') {
|
||||
action_param = '&' + swaction;
|
||||
}
|
||||
const navpreload_param = swaction === 'navpreload' ? '&navpreload' : '';
|
||||
const change_request_param = swaction === 'change-request' ? '&change-request' : '';
|
||||
const target_string = origin + `/cookies/resources/postToParent.py?` +
|
||||
`${sw_param}${action_param}`
|
||||
const target_url = new URL(target_string);
|
||||
if (navaction === 'window.open') {
|
||||
const w = window.open(target_url);
|
||||
t.add_cleanup(() => w.close());
|
||||
} else if (navaction === 'form post') {
|
||||
const poster_url =
|
||||
`./resources/form-poster.html?target=${encodeURIComponent(target_url)}`;
|
||||
const w = window.open(poster_url);
|
||||
t.add_cleanup(() => w.close());
|
||||
}
|
||||
const result = await wait_for_message('COOKIES');
|
||||
verifySameSiteCookieState(expected, value, result.data,
|
||||
DomSameSiteStatus.SAME_SITE);
|
||||
}
|
||||
|
||||
promise_test(async t => {
|
||||
await register_service_worker(self.origin);
|
||||
await register_service_worker(SECURE_SUBDOMAIN_ORIGIN);
|
||||
await register_service_worker(SECURE_CROSS_SITE_ORIGIN);
|
||||
}, 'Setup service workers');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, self.origin, 'window.open', 'no-sw',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-origin, window.open with no service worker');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, self.origin, 'window.open', 'fallback',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-origin, window.open with fallback');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, self.origin, 'window.open', 'passthrough',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-origin, window.open with passthrough');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, self.origin, 'window.open', 'change-request',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-origin, window.open with change-request');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, self.origin, 'window.open', 'navpreload',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-origin, window.open with navpreload');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_SUBDOMAIN_ORIGIN, 'window.open', 'no-sw',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-site, window.open with no service worker');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_SUBDOMAIN_ORIGIN, 'window.open', 'fallback',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-site, window.open with fallback');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_SUBDOMAIN_ORIGIN, 'window.open', 'passthrough',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-site, window.open with passthrough');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_SUBDOMAIN_ORIGIN, 'window.open', 'change-request',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-site, window.open with change-request');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_SUBDOMAIN_ORIGIN, 'window.open', 'navpreload',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-site, window.open with navpreload');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_CROSS_SITE_ORIGIN, 'window.open', 'no-sw',
|
||||
SameSiteStatus.LAX);
|
||||
}, 'cross-site, window.open with no service worker');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_CROSS_SITE_ORIGIN, 'window.open', 'fallback',
|
||||
SameSiteStatus.LAX);
|
||||
}, 'cross-site, window.open with fallback');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_CROSS_SITE_ORIGIN, 'window.open', 'passthrough',
|
||||
SameSiteStatus.LAX);
|
||||
}, 'cross-site, window.open with passthrough');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_CROSS_SITE_ORIGIN, 'window.open', 'change-request',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'cross-site, window.open with change-request');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_CROSS_SITE_ORIGIN, 'window.open', 'navpreload',
|
||||
SameSiteStatus.LAX);
|
||||
}, 'cross-site, window.open with navpreload');
|
||||
|
||||
//
|
||||
// Form POST tests
|
||||
//
|
||||
promise_test(t => {
|
||||
return run_test(t, self.origin, 'form post', 'no-sw', SameSiteStatus.STRICT);
|
||||
}, 'same-origin, form post with no service worker');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, self.origin, 'form post', 'fallback',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-origin, form post with fallback');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, self.origin, 'form post', 'passthrough',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-origin, form post with passthrough');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, self.origin, 'form post', 'change-request',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-origin, form post with change-request');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_SUBDOMAIN_ORIGIN, 'form post', 'no-sw',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-site, form post with no service worker');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_SUBDOMAIN_ORIGIN, 'form post', 'fallback',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-site, form post with fallback');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_SUBDOMAIN_ORIGIN, 'form post', 'passthrough',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-site, form post with passthrough');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_SUBDOMAIN_ORIGIN, 'form post', 'change-request',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'same-site, form post with change-request');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_CROSS_SITE_ORIGIN, 'form post', 'no-sw',
|
||||
SameSiteStatus.CROSS_SITE);
|
||||
}, 'cross-site, form post with no service worker');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_CROSS_SITE_ORIGIN, 'form post', 'fallback',
|
||||
SameSiteStatus.CROSS_SITE);
|
||||
}, 'cross-site, form post with fallback');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_CROSS_SITE_ORIGIN, 'form post', 'passthrough',
|
||||
SameSiteStatus.CROSS_SITE);
|
||||
}, 'cross-site, form post with passthrough');
|
||||
|
||||
promise_test(t => {
|
||||
return run_test(t, SECURE_CROSS_SITE_ORIGIN, 'form post', 'change-request',
|
||||
SameSiteStatus.STRICT);
|
||||
}, 'cross-site, form post with change-request');
|
||||
|
||||
promise_test(async t => {
|
||||
await unregister_service_worker(self.origin);
|
||||
await unregister_service_worker(SECURE_SUBDOMAIN_ORIGIN);
|
||||
await unregister_service_worker(SECURE_CROSS_SITE_ORIGIN);
|
||||
}, 'Cleanup service workers');
|
||||
|
||||
</script>
|
||||
</body>
|
Загрузка…
Ссылка в новой задаче