1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-29 16:30:56 -05:00

fix(fetch): proxy body for requests created from other requests (#11093)

Additionally, if the existing `Request`'s body is disturbed, the Request creation
should fail.

This change also updates the step numbers in the Request constructor to match
whatwg/fetch#1249.
This commit is contained in:
Andreu Botella 2021-06-23 16:00:23 +02:00 committed by Ryan Dahl
parent 843b5476ba
commit 8c8d15f161
5 changed files with 45 additions and 19 deletions

View file

@ -19,7 +19,7 @@
const { parseFormData, formDataFromEntries, encodeFormData } =
globalThis.__bootstrap.formData;
const mimesniff = globalThis.__bootstrap.mimesniff;
const { isReadableStreamDisturbed, errorReadableStream } =
const { isReadableStreamDisturbed, errorReadableStream, createProxy } =
globalThis.__bootstrap.streams;
class InnerBody {
@ -133,6 +133,23 @@
second.length = this.length;
return second;
}
/**
* @returns {InnerBody}
*/
createProxy() {
let proxyStreamOrStatic;
if (this.streamOrStatic instanceof ReadableStream) {
proxyStreamOrStatic = createProxy(this.streamOrStatic);
} else {
proxyStreamOrStatic = { ...this.streamOrStatic };
this.streamOrStatic.consumed = true;
}
const proxy = new InnerBody(proxyStreamOrStatic);
proxy.source = this.source;
proxy.length = this.length;
return proxy;
}
}
/**

View file

@ -257,14 +257,16 @@
// 28.
this[_signal] = abortSignal.newSignal();
// 29.
if (signal !== null) {
abortSignal.follow(this[_signal], signal);
}
// 29.
// 30.
this[_headers] = headersFromHeaderList(request.headerList, "request");
// 31.
// 32.
if (Object.keys(init).length > 0) {
let headers = headerListFromHeaders(this[_headers]).slice(
0,
@ -280,13 +282,13 @@
fillHeaders(this[_headers], headers);
}
// 32.
// 33.
let inputBody = null;
if (input instanceof Request) {
inputBody = input[_body];
}
// 33.
// 34.
if (
(request.method === "GET" || request.method === "HEAD") &&
((init.body !== undefined && init.body !== null) ||
@ -295,10 +297,10 @@
throw new TypeError("Request with GET/HEAD method cannot have body.");
}
// 34.
// 35.
let initBody = null;
// 35.
// 36.
if (init.body !== undefined && init.body !== null) {
const res = extractBody(init.body);
initBody = res.body;
@ -307,20 +309,22 @@
}
}
// 36.
// 37.
const inputOrInitBody = initBody ?? inputBody;
// 38.
const finalBody = inputOrInitBody;
// 39.
// TODO(lucacasonato): implement this step. Is it needed?
let finalBody = inputOrInitBody;
// 40.
request.body = finalBody;
if (initBody === null && inputBody !== null) {
if (input[_body] && input[_body].unusable()) {
throw new TypeError("Input request's body is unusable.");
}
finalBody = inputBody.createProxy();
}
// 41.
// TODO(lucacasonato): Extranious? https://github.com/whatwg/fetch/issues/1249
request.body = finalBody;
}
get method() {

View file

@ -4246,6 +4246,13 @@
webidl.configurePrototype(WritableStreamDefaultController);
/**
* @param {ReadableStream} stream
*/
function createProxy(stream) {
return stream.pipeThrough(new TransformStream());
}
webidl.converters.ReadableStream = webidl
.createInterfaceConverter("ReadableStream", ReadableStream);
webidl.converters.WritableStream = webidl
@ -4403,6 +4410,7 @@
// Non-Public
isReadableStreamDisturbed,
errorReadableStream,
createProxy,
// Exposed in global runtime scope
ByteLengthQueuingStrategy,
CountQueuingStrategy,

View file

@ -84,6 +84,7 @@ declare namespace globalThis {
declare var streams: {
ReadableStream: typeof ReadableStream;
isReadableStreamDisturbed(stream: ReadableStream): boolean;
createProxy<T>(stream: ReadableStream<T>): ReadableStream<T>;
};
}
}

View file

@ -696,11 +696,7 @@
"api": {
"request": {
"request-init-002.any.html": true,
"request-init-stream.any.html": [
"Constructing a Request with a Request on which body.getReader() is called",
"Constructing a Request with a Request on which body.getReader().read() is called",
"Constructing a Request with a Request on which read() and releaseLock() are called"
],
"request-init-stream.any.html": true,
"request-consume-empty.any.html": [
"Consume empty FormData request body as text"
],