Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
- /fetch/api/request/request-init-stream-lazy.any.html - WPT Dashboard Interop Dashboard
- /fetch/api/request/request-init-stream-lazy.any.serviceworker.html - WPT Dashboard Interop Dashboard
- /fetch/api/request/request-init-stream-lazy.any.sharedworker.html - WPT Dashboard Interop Dashboard
- /fetch/api/request/request-init-stream-lazy.any.worker.html - WPT Dashboard Interop Dashboard
// META: global=window,worker
function streamWithText(text) {
return new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode(text));
controller.close();
},
});
}
promise_test(async () => {
const stream = streamWithText("hello");
const request = new Request("/", {
method: "POST", body: stream, duplex: "half",
});
assert_equals(request.body, stream);
assert_false(stream.locked);
assert_false(request.bodyUsed);
const reader = request.body.getReader();
assert_equals(new TextDecoder().decode((await reader.read()).value), "hello");
assert_true((await reader.read()).done);
assert_true(request.bodyUsed);
}, "Constructing a Request leaves its supplied stream available to a reader");
promise_test(async t => {
let pulls = 0;
const stream = new ReadableStream({
pull(controller) {
pulls++;
controller.enqueue(new TextEncoder().encode("hello"));
controller.close();
},
}, { highWaterMark: 0 });
const request = new Request("/", {
method: "POST", body: stream, duplex: "half",
});
await new Promise(resolve => t.step_timeout(resolve, 0));
assert_equals(pulls, 0);
assert_false(stream.locked);
assert_false(request.bodyUsed);
assert_equals(await request.text(), "hello");
assert_equals(pulls, 1);
}, "An unused Request does not pull from its supplied stream");
promise_test(async () => {
const request = new Request("/", {
method: "POST", body: streamWithText("hello"), duplex: "half",
});
const clone = request.clone();
assert_false(request.bodyUsed);
assert_false(clone.bodyUsed);
assert_array_equals(await Promise.all([request.text(), clone.text()]),
["hello", "hello"]);
}, "Cloning an unconsumed streaming Request leaves both bodies readable");
promise_test(async () => {
const request = new Request("/", {
method: "POST", body: streamWithText("hello"), duplex: "half",
});
const clone = request.clone();
assert_throws_js(TypeError, () => new Request(clone, { mode: "no-cors" }));
assert_false(clone.bodyUsed);
assert_array_equals(await Promise.all([request.text(), clone.text()]),
["hello", "hello"]);
}, "A cloned streaming Request retains the no-cors restriction");
promise_test(async t => {
let pulls = 0;
const stream = new ReadableStream({
pull(controller) {
pulls++;
controller.enqueue(new TextEncoder().encode("hello"));
},
}, { highWaterMark: 0 });
const input = new Request("/", {
method: "POST", body: stream, duplex: "half",
});
const request = new Request(input);
assert_true(input.bodyUsed);
assert_false(request.bodyUsed);
assert_false(request.body.locked);
await new Promise(resolve => t.step_timeout(resolve, 0));
assert_less_than_equal(pulls, 1, "an unread proxy must preserve backpressure");
const reader = request.body.getReader();
assert_equals(new TextDecoder().decode((await reader.read()).value), "hello");
await reader.cancel();
}, "Constructing from a streaming Request uses a proxy with backpressure");
promise_test(async () => {
const controller = new AbortController();
const request = new Request("/", {
method: "POST", body: streamWithText("hello"), duplex: "half",
signal: controller.signal,
});
controller.abort("unused");
assert_equals(await request.text(), "hello");
}, "Aborting an unused Request's signal does not consume or cancel its body");