<!DOCTYPE html>
<meta name=timeout content=long>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/utils.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<body>
<script>
const worker = 'resources/fetch-event-test-worker.js';
const method = 'POST';
const duplex = 'half';
function createBody(t) {
const rs = new ReadableStream({start(c) {
c.enqueue('i a');
c.enqueue('m the request');
step_timeout(t.step_func(() => {
c.enqueue(' body');
c.close();
}, 10));
}});
return rs.pipeThrough(new TextEncoderStream());
}
promise_test(async t => {
const scope = 'resources/';
const registration =
await service_worker_unregister_and_register(t, worker, scope);
await wait_for_state(t, registration.installing, 'activated');
// This will happen after all other tests
promise_test(t => {
return registration.unregister();
}, 'restore global state');
}, 'global setup');
// Test that the service worker can read FetchEvent#body when it is made from
// a ReadableStream. It responds with request body it read.
promise_test(async t => {
const body = createBody(t);
// Set page_url to "?ignore" so the service worker falls back to network
// for the main resource request, and add a suffix to avoid colliding
// with other tests.
const page_url = `resources/simple.html?ignore&id=${token()}`;
const frame = await with_iframe(page_url);
t.add_cleanup(() => { frame.remove(); });
const response = await frame.contentWindow.fetch('simple.html?request-body', {
method, body, duplex});
assert_equals(response.status, 200, 'status');
const text = await response.text();
assert_equals(text, 'i am the request body', 'body');
}, 'The streaming request body is readable in the service worker.');
// Network fallback
promise_test(async t => {
const body = createBody(t);
// Set page_url to "?ignore" so the service worker falls back to network
// for the main resource request, and add a suffix to avoid colliding
// with other tests.
const page_url = `resources/simple.html?ignore&id=${token()}`;
const frame = await with_iframe(page_url);
t.add_cleanup(() => { frame.remove(); });
// Add "?ignore" so that the service worker falls back to
// echo-content.h2.py.
const echo_url = '/fetch/api/resources/echo-content.h2.py?ignore';
const response =
await frame.contentWindow.fetch(echo_url, { method, body, duplex});
assert_equals(response.status, 200, 'status');
const text = await response.text();
assert_equals(text, 'i am the request body', 'body');
}, 'Network fallback for streaming upload.');
// When the streaming body is used in the service worker, network fallback
// fails.
promise_test(async t => {
const body = createBody(t);
// Set page_url to "?ignore" so the service worker falls back to network
// for the main resource request, and add a suffix to avoid colliding
// with other tests.
const page_url = `resources/simple.html?ignore&id=${token()}`;
const frame = await with_iframe(page_url);
t.add_cleanup(() => { frame.remove(); });
const echo_url = '/fetch/api/resources/echo-content.h2.py?use-and-ignore';
const w = frame.contentWindow;
await promise_rejects_js(t, w.TypeError, w.fetch(echo_url, {
method, body, duplex}));
}, 'When the streaming request body is used, network fallback fails.');
// When the streaming body is used by clone() in the service worker, network
// fallback succeeds.
promise_test(async t => {
const body = createBody(t);
// Set page_url to "?ignore" so the service worker falls back to network
// for the main resource request, and add a suffix to avoid colliding
// with other tests.
const page_url = `resources/simple.html?ignore&id=${token()}`;
const frame = await with_iframe(page_url);
t.add_cleanup(() => { frame.remove(); });
// Add "?clone-and-ignore" so that the service worker falls back to
// echo-content.h2.py.
const echo_url = '/fetch/api/resources/echo-content.h2.py?clone-and-ignore';
const response = await frame.contentWindow.fetch(echo_url, {
method, body, duplex});
assert_equals(response.status, 200, 'status');
const text = await response.text();
assert_equals(text, 'i am the request body', 'body');
}, 'Running clone() in the service worker does not prevent network fallback.');
</script>
</body>