Skip to content

Commit

Permalink
Update encoded/decoded body length for service-worker responses
Browse files Browse the repository at this point in the history
Instead of relying on the network, count the bytes as they
come in and use the sum as the metric, only for service-worker
responses.

Corresponds to the relevant spec change:
https://w3c.github.io/ServiceWorker/#dom-fetchevent-respondwith
(search for "encoded size")
and to proposed spec change:
whatwg/fetch#1556

Bug: 925239
Change-Id: I7d47c4febef61a89128cc50003f9f2058f3c1270
  • Loading branch information
noamr authored and chromium-wpt-export-bot committed Dec 12, 2022
1 parent 3b6b8de commit 4bb2793
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 0 deletions.
55 changes: 55 additions & 0 deletions service-workers/service-worker/resource-timing-bodySize.https.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<script src="/common/utils.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
const {REMOTE_ORIGIN} = get_host_info();

/*
This test does the following:
- Loads a service worker
- Loads an iframe in the service worker's scope
- The service worker tries to fetch a resource which is either:
- constructed inside the service worker
- fetched from a different URL ny the service worker
- Streamed from a differend URL by the service worker
- Passes through
- By default the RT entry should have encoded/decoded body size. except for
the case where the response is an opaque pass-through.
*/
function test_scenario({tao, mode, name}) {
promise_test(async (t) => {
const uid = token();
const worker_url = `resources/fetch-response.js?uid=${uid}`;
const scope = `resources/fetch-response.html?uid=${uid}`;
const iframe = document.createElement('iframe');
const path = name === "passthrough" ? `element-timing/resources/TAOImage.py?origin=*&tao=${
tao === "pass" ? "wildcard" : "none"})}` : name;

iframe.src = `${scope}&path=${encodeURIComponent(
`${mode === "same-origin" ? "" : REMOTE_ORIGIN}/${path}`)}&mode=${mode}`;
const registration = await service_worker_unregister_and_register(t, worker_url, scope);
t.add_cleanup(() => registration.unregister());
t.add_cleanup(() => iframe.remove());
await wait_for_state(t, registration.installing, 'activated');
const waitForMessage = new Promise(resolve =>
window.addEventListener('message', ({data}) => resolve(data)));
document.body.appendChild(iframe);
const {buffer, entry} = await waitForMessage;
const expectPass = name !== "passthrough" || mode !== "no-cors";
assert_equals(buffer.byteLength, expectPass ? entry.decodedBodySize : 0);
assert_equals(buffer.byteLength, expectPass ? entry.encodedBodySize : 0);
}, `Response body size: ${name}, ${mode}, TAO ${tao}`);
}
for (const mode of ["cors", "no-cors", "same-origin"]) {
for (const tao of ["pass", "fail"])
for (const name of ['constructed', 'forward', 'stream', 'passthrough']) {
test_scenario({tao, mode, name});
}
}

</script>
29 changes: 29 additions & 0 deletions service-workers/service-worker/resources/fetch-response.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<meta charset="utf-8">

<script>
const params =new URLSearchParams(location.search);
const mode = params.get("mode") || "cors";
const path = params.get('path');
const bufferPromise =
new Promise(resolve =>
fetch(path, {mode})
.then(response => resolve(response.arrayBuffer()))
.catch(() => resolve(new Uint8Array())));

const entryPromise = new Promise(resolve => {
new PerformanceObserver(entries => {
const byName = entries.getEntriesByType("resource").find(e => e.name.includes(path));
if (byName)
resolve(byName);
}).observe({entryTypes: ["resource"]});
});

Promise.all([bufferPromise, entryPromise]).then(([buffer, entry]) => {
parent.postMessage({
buffer,
entry: entry.toJSON(),
}, '*');
});

</script>
35 changes: 35 additions & 0 deletions service-workers/service-worker/resources/fetch-response.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
self.addEventListener('fetch', event => {
const path = event.request.url.match(/\/(?<name>[^\/]+)$/);
switch (path?.groups?.name) {
case 'constructed':
event.respondWith(new Response(new Uint8Array([1, 2, 3])));
break;
case 'forward':
event.respondWith(fetch('/common/text-plain.txt'));
break;
case 'stream':
event.respondWith((async() => {
const res = await fetch('/common/text-plain.txt');
const body = await res.body;
const reader = await body.getReader();
const stream = new ReadableStream({
async start(controller) {
while (true) {
const {done, value} = await reader.read();
if (done)
break;

controller.enqueue(value);
}
controller.close();
reader.releaseLock();
}
});
return new Response(stream);
})());
break;
default:
event.respondWith(fetch(event.request));
break;
}
});

0 comments on commit 4bb2793

Please sign in to comment.