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:
parent
843b5476ba
commit
8c8d15f161
5 changed files with 45 additions and 19 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
|
|
1
extensions/web/internal.d.ts
vendored
1
extensions/web/internal.d.ts
vendored
|
@ -84,6 +84,7 @@ declare namespace globalThis {
|
|||
declare var streams: {
|
||||
ReadableStream: typeof ReadableStream;
|
||||
isReadableStreamDisturbed(stream: ReadableStream): boolean;
|
||||
createProxy<T>(stream: ReadableStream<T>): ReadableStream<T>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
],
|
||||
|
|
Loading…
Reference in a new issue