summaryrefslogtreecommitdiff
path: root/ext/fetch/23_request.js
diff options
context:
space:
mode:
authorLeo Kettmeir <crowlkats@toaxl.com>2023-02-07 20:22:46 +0100
committerGitHub <noreply@github.com>2023-02-07 20:22:46 +0100
commitb4aa1530970f7b9cc4e6f2f27e077852c4e178d3 (patch)
tree3d008912affe8550692183bd2697a386db5e3c79 /ext/fetch/23_request.js
parent65500f36e870b4ada3996b06aa287e30177d21a3 (diff)
refactor: Use ES modules for internal runtime code (#17648)
This PR refactors all internal js files (except core) to be written as ES modules. `__bootstrap`has been mostly replaced with static imports in form in `internal:[path to file from repo root]`. To specify if files are ESM, an `esm` method has been added to `Extension`, similar to the `js` method. A new ModuleLoader called `InternalModuleLoader` has been added to enable the loading of internal specifiers, which is used in all situations except when a snapshot is only loaded, and not a new one is created from it. --------- Co-authored-by: Bartek IwaƄczuk <biwanczuk@gmail.com>
Diffstat (limited to 'ext/fetch/23_request.js')
-rw-r--r--ext/fetch/23_request.js1161
1 files changed, 584 insertions, 577 deletions
diff --git a/ext/fetch/23_request.js b/ext/fetch/23_request.js
index e266a7e44..1e8d5c1ec 100644
--- a/ext/fetch/23_request.js
+++ b/ext/fetch/23_request.js
@@ -8,657 +8,664 @@
/// <reference path="../web/06_streams_types.d.ts" />
/// <reference path="./lib.deno_fetch.d.ts" />
/// <reference lib="esnext" />
-"use strict";
-
-((window) => {
- const webidl = window.__bootstrap.webidl;
- const consoleInternal = window.__bootstrap.console;
- const { HTTP_TOKEN_CODE_POINT_RE, byteUpperCase } = window.__bootstrap.infra;
- const { URL } = window.__bootstrap.url;
- const { guardFromHeaders } = window.__bootstrap.headers;
- const { mixinBody, extractBody, InnerBody } = window.__bootstrap.fetchBody;
- const { getLocationHref } = window.__bootstrap.location;
- const { extractMimeType } = window.__bootstrap.mimesniff;
- const { blobFromObjectUrl } = window.__bootstrap.file;
- const {
- headersFromHeaderList,
- headerListFromHeaders,
- fillHeaders,
- getDecodeSplitHeader,
- } = window.__bootstrap.headers;
- const { HttpClientPrototype } = window.__bootstrap.fetch;
- const abortSignal = window.__bootstrap.abortSignal;
- const {
- ArrayPrototypeMap,
- ArrayPrototypeSlice,
- ArrayPrototypeSplice,
- ObjectKeys,
- ObjectPrototypeIsPrototypeOf,
- RegExpPrototypeTest,
- Symbol,
- SymbolFor,
- TypeError,
- } = window.__bootstrap.primordials;
-
- const _request = Symbol("request");
- const _headers = Symbol("headers");
- const _getHeaders = Symbol("get headers");
- const _headersCache = Symbol("headers cache");
- const _signal = Symbol("signal");
- const _mimeType = Symbol("mime type");
- const _body = Symbol("body");
- const _flash = Symbol("flash");
- const _url = Symbol("url");
- const _method = Symbol("method");
- /**
- * @param {(() => string)[]} urlList
- * @param {string[]} urlListProcessed
- */
- function processUrlList(urlList, urlListProcessed) {
- for (let i = 0; i < urlList.length; i++) {
- if (urlListProcessed[i] === undefined) {
- urlListProcessed[i] = urlList[i]();
- }
+import * as webidl from "internal:ext/webidl/00_webidl.js";
+import { createFilteredInspectProxy } from "internal:ext/console/02_console.js";
+import {
+ byteUpperCase,
+ HTTP_TOKEN_CODE_POINT_RE,
+} from "internal:ext/web/00_infra.js";
+import { URL } from "internal:ext/url/00_url.js";
+import {
+ extractBody,
+ InnerBody,
+ mixinBody,
+} from "internal:ext/fetch/22_body.js";
+import { getLocationHref } from "internal:ext/web/12_location.js";
+import { extractMimeType } from "internal:ext/web/01_mimesniff.js";
+import { blobFromObjectUrl } from "internal:ext/web/09_file.js";
+import {
+ fillHeaders,
+ getDecodeSplitHeader,
+ guardFromHeaders,
+ headerListFromHeaders,
+ headersFromHeaderList,
+} from "internal:ext/fetch/20_headers.js";
+import { HttpClientPrototype } from "internal:ext/fetch/22_http_client.js";
+import * as abortSignal from "internal:ext/web/03_abort_signal.js";
+const primordials = globalThis.__bootstrap.primordials;
+const {
+ ArrayPrototypeMap,
+ ArrayPrototypeSlice,
+ ArrayPrototypeSplice,
+ ObjectKeys,
+ ObjectPrototypeIsPrototypeOf,
+ RegExpPrototypeTest,
+ Symbol,
+ SymbolFor,
+ TypeError,
+} = primordials;
+
+const _request = Symbol("request");
+const _headers = Symbol("headers");
+const _getHeaders = Symbol("get headers");
+const _headersCache = Symbol("headers cache");
+const _signal = Symbol("signal");
+const _mimeType = Symbol("mime type");
+const _body = Symbol("body");
+const _flash = Symbol("flash");
+const _url = Symbol("url");
+const _method = Symbol("method");
+
+/**
+ * @param {(() => string)[]} urlList
+ * @param {string[]} urlListProcessed
+ */
+function processUrlList(urlList, urlListProcessed) {
+ for (let i = 0; i < urlList.length; i++) {
+ if (urlListProcessed[i] === undefined) {
+ urlListProcessed[i] = urlList[i]();
}
- return urlListProcessed;
}
+ return urlListProcessed;
+}
+
+/**
+ * @typedef InnerRequest
+ * @property {() => string} method
+ * @property {() => string} url
+ * @property {() => string} currentUrl
+ * @property {() => [string, string][]} headerList
+ * @property {null | typeof __window.bootstrap.fetchBody.InnerBody} body
+ * @property {"follow" | "error" | "manual"} redirectMode
+ * @property {number} redirectCount
+ * @property {(() => string)[]} urlList
+ * @property {string[]} urlListProcessed
+ * @property {number | null} clientRid NOTE: non standard extension for `Deno.HttpClient`.
+ * @property {Blob | null} blobUrlEntry
+ */
+
+/**
+ * @param {() => string} method
+ * @param {string | () => string} url
+ * @param {() => [string, string][]} headerList
+ * @param {typeof __window.bootstrap.fetchBody.InnerBody} body
+ * @param {boolean} maybeBlob
+ * @returns {InnerRequest}
+ */
+function newInnerRequest(method, url, headerList, body, maybeBlob) {
+ let blobUrlEntry = null;
+ if (maybeBlob && typeof url === "string" && url.startsWith("blob:")) {
+ blobUrlEntry = blobFromObjectUrl(url);
+ }
+ return {
+ methodInner: null,
+ get method() {
+ if (this.methodInner === null) {
+ try {
+ this.methodInner = method();
+ } catch {
+ throw new TypeError("cannot read method: request closed");
+ }
+ }
+ return this.methodInner;
+ },
+ set method(value) {
+ this.methodInner = value;
+ },
+ headerListInner: null,
+ get headerList() {
+ if (this.headerListInner === null) {
+ try {
+ this.headerListInner = headerList();
+ } catch {
+ throw new TypeError("cannot read headers: request closed");
+ }
+ }
+ return this.headerListInner;
+ },
+ set headerList(value) {
+ this.headerListInner = value;
+ },
+ body,
+ redirectMode: "follow",
+ redirectCount: 0,
+ urlList: [typeof url === "string" ? () => url : url],
+ urlListProcessed: [],
+ clientRid: null,
+ blobUrlEntry,
+ url() {
+ if (this.urlListProcessed[0] === undefined) {
+ try {
+ this.urlListProcessed[0] = this.urlList[0]();
+ } catch {
+ throw new TypeError("cannot read url: request closed");
+ }
+ }
+ return this.urlListProcessed[0];
+ },
+ currentUrl() {
+ const currentIndex = this.urlList.length - 1;
+ if (this.urlListProcessed[currentIndex] === undefined) {
+ try {
+ this.urlListProcessed[currentIndex] = this.urlList[currentIndex]();
+ } catch {
+ throw new TypeError("cannot read url: request closed");
+ }
+ }
+ return this.urlListProcessed[currentIndex];
+ },
+ };
+}
+
+/**
+ * https://fetch.spec.whatwg.org/#concept-request-clone
+ * @param {InnerRequest} request
+ * @param {boolean} skipBody
+ * @param {boolean} flash
+ * @returns {InnerRequest}
+ */
+function cloneInnerRequest(request, skipBody = false, flash = false) {
+ const headerList = ArrayPrototypeMap(
+ request.headerList,
+ (x) => [x[0], x[1]],
+ );
- /**
- * @typedef InnerRequest
- * @property {() => string} method
- * @property {() => string} url
- * @property {() => string} currentUrl
- * @property {() => [string, string][]} headerList
- * @property {null | typeof __window.bootstrap.fetchBody.InnerBody} body
- * @property {"follow" | "error" | "manual"} redirectMode
- * @property {number} redirectCount
- * @property {(() => string)[]} urlList
- * @property {string[]} urlListProcessed
- * @property {number | null} clientRid NOTE: non standard extension for `Deno.HttpClient`.
- * @property {Blob | null} blobUrlEntry
- */
+ let body = null;
+ if (request.body !== null && !skipBody) {
+ body = request.body.clone();
+ }
- /**
- * @param {() => string} method
- * @param {string | () => string} url
- * @param {() => [string, string][]} headerList
- * @param {typeof __window.bootstrap.fetchBody.InnerBody} body
- * @param {boolean} maybeBlob
- * @returns {InnerRequest}
- */
- function newInnerRequest(method, url, headerList, body, maybeBlob) {
- let blobUrlEntry = null;
- if (maybeBlob && typeof url === "string" && url.startsWith("blob:")) {
- blobUrlEntry = blobFromObjectUrl(url);
- }
+ if (flash) {
return {
- methodInner: null,
- get method() {
- if (this.methodInner === null) {
- try {
- this.methodInner = method();
- } catch {
- throw new TypeError("cannot read method: request closed");
- }
- }
- return this.methodInner;
- },
- set method(value) {
- this.methodInner = value;
- },
- headerListInner: null,
- get headerList() {
- if (this.headerListInner === null) {
- try {
- this.headerListInner = headerList();
- } catch {
- throw new TypeError("cannot read headers: request closed");
- }
- }
- return this.headerListInner;
- },
- set headerList(value) {
- this.headerListInner = value;
- },
body,
+ methodCb: request.methodCb,
+ urlCb: request.urlCb,
+ headerList: request.headerList,
+ streamRid: request.streamRid,
+ serverId: request.serverId,
redirectMode: "follow",
redirectCount: 0,
- urlList: [typeof url === "string" ? () => url : url],
- urlListProcessed: [],
- clientRid: null,
- blobUrlEntry,
- url() {
- if (this.urlListProcessed[0] === undefined) {
- try {
- this.urlListProcessed[0] = this.urlList[0]();
- } catch {
- throw new TypeError("cannot read url: request closed");
- }
- }
- return this.urlListProcessed[0];
- },
- currentUrl() {
- const currentIndex = this.urlList.length - 1;
- if (this.urlListProcessed[currentIndex] === undefined) {
- try {
- this.urlListProcessed[currentIndex] = this.urlList[currentIndex]();
- } catch {
- throw new TypeError("cannot read url: request closed");
- }
- }
- return this.urlListProcessed[currentIndex];
- },
};
}
- /**
- * https://fetch.spec.whatwg.org/#concept-request-clone
- * @param {InnerRequest} request
- * @param {boolean} skipBody
- * @param {boolean} flash
- * @returns {InnerRequest}
- */
- function cloneInnerRequest(request, skipBody = false, flash = false) {
- const headerList = ArrayPrototypeMap(
- request.headerList,
- (x) => [x[0], x[1]],
- );
-
- let body = null;
- if (request.body !== null && !skipBody) {
- body = request.body.clone();
- }
-
- if (flash) {
- return {
- body,
- methodCb: request.methodCb,
- urlCb: request.urlCb,
- headerList: request.headerList,
- streamRid: request.streamRid,
- serverId: request.serverId,
- redirectMode: "follow",
- redirectCount: 0,
- };
- }
-
- return {
- method: request.method,
- headerList,
- body,
- redirectMode: request.redirectMode,
- redirectCount: request.redirectCount,
- urlList: request.urlList,
- urlListProcessed: request.urlListProcessed,
- clientRid: request.clientRid,
- blobUrlEntry: request.blobUrlEntry,
- url() {
- if (this.urlListProcessed[0] === undefined) {
- try {
- this.urlListProcessed[0] = this.urlList[0]();
- } catch {
- throw new TypeError("cannot read url: request closed");
- }
+ return {
+ method: request.method,
+ headerList,
+ body,
+ redirectMode: request.redirectMode,
+ redirectCount: request.redirectCount,
+ urlList: request.urlList,
+ urlListProcessed: request.urlListProcessed,
+ clientRid: request.clientRid,
+ blobUrlEntry: request.blobUrlEntry,
+ url() {
+ if (this.urlListProcessed[0] === undefined) {
+ try {
+ this.urlListProcessed[0] = this.urlList[0]();
+ } catch {
+ throw new TypeError("cannot read url: request closed");
}
- return this.urlListProcessed[0];
- },
- currentUrl() {
- const currentIndex = this.urlList.length - 1;
- if (this.urlListProcessed[currentIndex] === undefined) {
- try {
- this.urlListProcessed[currentIndex] = this.urlList[currentIndex]();
- } catch {
- throw new TypeError("cannot read url: request closed");
- }
+ }
+ return this.urlListProcessed[0];
+ },
+ currentUrl() {
+ const currentIndex = this.urlList.length - 1;
+ if (this.urlListProcessed[currentIndex] === undefined) {
+ try {
+ this.urlListProcessed[currentIndex] = this.urlList[currentIndex]();
+ } catch {
+ throw new TypeError("cannot read url: request closed");
}
- return this.urlListProcessed[currentIndex];
- },
- };
+ }
+ return this.urlListProcessed[currentIndex];
+ },
+ };
+}
+
+/**
+ * @param {string} m
+ * @returns {boolean}
+ */
+function isKnownMethod(m) {
+ return (
+ m === "DELETE" ||
+ m === "GET" ||
+ m === "HEAD" ||
+ m === "OPTIONS" ||
+ m === "POST" ||
+ m === "PUT"
+ );
+}
+/**
+ * @param {string} m
+ * @returns {string}
+ */
+function validateAndNormalizeMethod(m) {
+ // Fast path for well-known methods
+ if (isKnownMethod(m)) {
+ return m;
}
- /**
- * @param {string} m
- * @returns {boolean}
- */
- function isKnownMethod(m) {
- return (
- m === "DELETE" ||
- m === "GET" ||
- m === "HEAD" ||
- m === "OPTIONS" ||
- m === "POST" ||
- m === "PUT"
- );
+ // Regular path
+ if (!RegExpPrototypeTest(HTTP_TOKEN_CODE_POINT_RE, m)) {
+ throw new TypeError("Method is not valid.");
}
- /**
- * @param {string} m
- * @returns {string}
- */
- function validateAndNormalizeMethod(m) {
- // Fast path for well-known methods
- if (isKnownMethod(m)) {
- return m;
+ const upperCase = byteUpperCase(m);
+ if (
+ upperCase === "CONNECT" || upperCase === "TRACE" || upperCase === "TRACK"
+ ) {
+ throw new TypeError("Method is forbidden.");
+ }
+ return upperCase;
+}
+
+class Request {
+ /** @type {InnerRequest} */
+ [_request];
+ /** @type {Headers} */
+ [_headersCache];
+ [_getHeaders];
+
+ /** @type {Headers} */
+ get [_headers]() {
+ if (this[_headersCache] === undefined) {
+ this[_headersCache] = this[_getHeaders]();
}
+ return this[_headersCache];
+ }
- // Regular path
- if (!RegExpPrototypeTest(HTTP_TOKEN_CODE_POINT_RE, m)) {
- throw new TypeError("Method is not valid.");
- }
- const upperCase = byteUpperCase(m);
- if (
- upperCase === "CONNECT" || upperCase === "TRACE" || upperCase === "TRACK"
- ) {
- throw new TypeError("Method is forbidden.");
+ set [_headers](value) {
+ this[_headersCache] = value;
+ }
+
+ /** @type {AbortSignal} */
+ [_signal];
+ get [_mimeType]() {
+ const values = getDecodeSplitHeader(
+ headerListFromHeaders(this[_headers]),
+ "Content-Type",
+ );
+ return extractMimeType(values);
+ }
+ get [_body]() {
+ if (this[_flash]) {
+ return this[_flash].body;
+ } else {
+ return this[_request].body;
}
- return upperCase;
}
- class Request {
+ /**
+ * https://fetch.spec.whatwg.org/#dom-request
+ * @param {RequestInfo} input
+ * @param {RequestInit} init
+ */
+ constructor(input, init = {}) {
+ const prefix = "Failed to construct 'Request'";
+ webidl.requiredArguments(arguments.length, 1, { prefix });
+ input = webidl.converters["RequestInfo_DOMString"](input, {
+ prefix,
+ context: "Argument 1",
+ });
+ init = webidl.converters["RequestInit"](init, {
+ prefix,
+ context: "Argument 2",
+ });
+
+ this[webidl.brand] = webidl.brand;
+
/** @type {InnerRequest} */
- [_request];
- /** @type {Headers} */
- [_headersCache];
- [_getHeaders];
-
- /** @type {Headers} */
- get [_headers]() {
- if (this[_headersCache] === undefined) {
- this[_headersCache] = this[_getHeaders]();
+ let request;
+ const baseURL = getLocationHref();
+
+ // 4.
+ let signal = null;
+
+ // 5.
+ if (typeof input === "string") {
+ const parsedURL = new URL(input, baseURL);
+ request = newInnerRequest(
+ () => "GET",
+ parsedURL.href,
+ () => [],
+ null,
+ true,
+ );
+ } else { // 6.
+ if (!ObjectPrototypeIsPrototypeOf(RequestPrototype, input)) {
+ throw new TypeError("Unreachable");
}
- return this[_headersCache];
+ const originalReq = input[_request];
+ // fold in of step 12 from below
+ request = cloneInnerRequest(originalReq, true);
+ request.redirectCount = 0; // reset to 0 - cloneInnerRequest copies the value
+ signal = input[_signal];
}
- set [_headers](value) {
- this[_headersCache] = value;
+ // 12. is folded into the else statement of step 6 above.
+
+ // 22.
+ if (init.redirect !== undefined) {
+ request.redirectMode = init.redirect;
}
- /** @type {AbortSignal} */
- [_signal];
- get [_mimeType]() {
- const values = getDecodeSplitHeader(
- headerListFromHeaders(this[_headers]),
- "Content-Type",
- );
- return extractMimeType(values);
+ // 25.
+ if (init.method !== undefined) {
+ let method = init.method;
+ method = validateAndNormalizeMethod(method);
+ request.method = method;
}
- get [_body]() {
- if (this[_flash]) {
- return this[_flash].body;
- } else {
- return this[_request].body;
- }
+
+ // 26.
+ if (init.signal !== undefined) {
+ signal = init.signal;
}
- /**
- * https://fetch.spec.whatwg.org/#dom-request
- * @param {RequestInfo} input
- * @param {RequestInit} init
- */
- constructor(input, init = {}) {
- const prefix = "Failed to construct 'Request'";
- webidl.requiredArguments(arguments.length, 1, { prefix });
- input = webidl.converters["RequestInfo_DOMString"](input, {
- prefix,
- context: "Argument 1",
- });
- init = webidl.converters["RequestInit"](init, {
- prefix,
- context: "Argument 2",
- });
-
- this[webidl.brand] = webidl.brand;
-
- /** @type {InnerRequest} */
- let request;
- const baseURL = getLocationHref();
-
- // 4.
- let signal = null;
-
- // 5.
- if (typeof input === "string") {
- const parsedURL = new URL(input, baseURL);
- request = newInnerRequest(
- () => "GET",
- parsedURL.href,
- () => [],
- null,
- true,
+ // NOTE: non standard extension. This handles Deno.HttpClient parameter
+ if (init.client !== undefined) {
+ if (
+ init.client !== null &&
+ !ObjectPrototypeIsPrototypeOf(HttpClientPrototype, init.client)
+ ) {
+ throw webidl.makeException(
+ TypeError,
+ "`client` must be a Deno.HttpClient",
+ { prefix, context: "Argument 2" },
);
- } else { // 6.
- if (!ObjectPrototypeIsPrototypeOf(RequestPrototype, input)) {
- throw new TypeError("Unreachable");
- }
- const originalReq = input[_request];
- // fold in of step 12 from below
- request = cloneInnerRequest(originalReq, true);
- request.redirectCount = 0; // reset to 0 - cloneInnerRequest copies the value
- signal = input[_signal];
}
+ request.clientRid = init.client?.rid ?? null;
+ }
- // 12. is folded into the else statement of step 6 above.
+ // 27.
+ this[_request] = request;
- // 22.
- if (init.redirect !== undefined) {
- request.redirectMode = init.redirect;
- }
+ // 28.
+ this[_signal] = abortSignal.newSignal();
- // 25.
- if (init.method !== undefined) {
- let method = init.method;
- method = validateAndNormalizeMethod(method);
- request.method = method;
- }
+ // 29.
+ if (signal !== null) {
+ abortSignal.follow(this[_signal], signal);
+ }
- // 26.
- if (init.signal !== undefined) {
- signal = init.signal;
- }
+ // 30.
+ this[_headers] = headersFromHeaderList(request.headerList, "request");
- // NOTE: non standard extension. This handles Deno.HttpClient parameter
- if (init.client !== undefined) {
- if (
- init.client !== null &&
- !ObjectPrototypeIsPrototypeOf(HttpClientPrototype, init.client)
- ) {
- throw webidl.makeException(
- TypeError,
- "`client` must be a Deno.HttpClient",
- { prefix, context: "Argument 2" },
- );
- }
- request.clientRid = init.client?.rid ?? null;
+ // 32.
+ if (ObjectKeys(init).length > 0) {
+ let headers = ArrayPrototypeSlice(
+ headerListFromHeaders(this[_headers]),
+ 0,
+ headerListFromHeaders(this[_headers]).length,
+ );
+ if (init.headers !== undefined) {
+ headers = init.headers;
}
+ ArrayPrototypeSplice(
+ headerListFromHeaders(this[_headers]),
+ 0,
+ headerListFromHeaders(this[_headers]).length,
+ );
+ fillHeaders(this[_headers], headers);
+ }
- // 27.
- this[_request] = request;
-
- // 28.
- this[_signal] = abortSignal.newSignal();
-
- // 29.
- if (signal !== null) {
- abortSignal.follow(this[_signal], signal);
- }
+ // 33.
+ let inputBody = null;
+ if (ObjectPrototypeIsPrototypeOf(RequestPrototype, input)) {
+ inputBody = input[_body];
+ }
- // 30.
- this[_headers] = headersFromHeaderList(request.headerList, "request");
+ // 34.
+ if (
+ (request.method === "GET" || request.method === "HEAD") &&
+ ((init.body !== undefined && init.body !== null) ||
+ inputBody !== null)
+ ) {
+ throw new TypeError("Request with GET/HEAD method cannot have body.");
+ }
- // 32.
- if (ObjectKeys(init).length > 0) {
- let headers = ArrayPrototypeSlice(
- headerListFromHeaders(this[_headers]),
- 0,
- headerListFromHeaders(this[_headers]).length,
- );
- if (init.headers !== undefined) {
- headers = init.headers;
- }
- ArrayPrototypeSplice(
- headerListFromHeaders(this[_headers]),
- 0,
- headerListFromHeaders(this[_headers]).length,
- );
- fillHeaders(this[_headers], headers);
- }
+ // 35.
+ let initBody = null;
- // 33.
- let inputBody = null;
- if (ObjectPrototypeIsPrototypeOf(RequestPrototype, input)) {
- inputBody = input[_body];
+ // 36.
+ if (init.body !== undefined && init.body !== null) {
+ const res = extractBody(init.body);
+ initBody = res.body;
+ if (res.contentType !== null && !this[_headers].has("content-type")) {
+ this[_headers].append("Content-Type", res.contentType);
}
+ }
- // 34.
- if (
- (request.method === "GET" || request.method === "HEAD") &&
- ((init.body !== undefined && init.body !== null) ||
- inputBody !== null)
- ) {
- throw new TypeError("Request with GET/HEAD method cannot have body.");
- }
+ // 37.
+ const inputOrInitBody = initBody ?? inputBody;
- // 35.
- let initBody = null;
+ // 39.
+ let finalBody = inputOrInitBody;
- // 36.
- if (init.body !== undefined && init.body !== null) {
- const res = extractBody(init.body);
- initBody = res.body;
- if (res.contentType !== null && !this[_headers].has("content-type")) {
- this[_headers].append("Content-Type", res.contentType);
- }
+ // 40.
+ if (initBody === null && inputBody !== null) {
+ if (input[_body] && input[_body].unusable()) {
+ throw new TypeError("Input request's body is unusable.");
}
+ finalBody = inputBody.createProxy();
+ }
- // 37.
- const inputOrInitBody = initBody ?? inputBody;
-
- // 39.
- let finalBody = inputOrInitBody;
-
- // 40.
- if (initBody === null && inputBody !== null) {
- if (input[_body] && input[_body].unusable()) {
- throw new TypeError("Input request's body is unusable.");
- }
- finalBody = inputBody.createProxy();
- }
+ // 41.
+ request.body = finalBody;
+ }
- // 41.
- request.body = finalBody;
+ get method() {
+ webidl.assertBranded(this, RequestPrototype);
+ if (this[_method]) {
+ return this[_method];
}
-
- get method() {
- webidl.assertBranded(this, RequestPrototype);
- if (this[_method]) {
- return this[_method];
- }
- if (this[_flash]) {
- this[_method] = this[_flash].methodCb();
- return this[_method];
- } else {
- this[_method] = this[_request].method;
- return this[_method];
- }
+ if (this[_flash]) {
+ this[_method] = this[_flash].methodCb();
+ return this[_method];
+ } else {
+ this[_method] = this[_request].method;
+ return this[_method];
}
+ }
- get url() {
- webidl.assertBranded(this, RequestPrototype);
- if (this[_url]) {
- return this[_url];
- }
-
- if (this[_flash]) {
- this[_url] = this[_flash].urlCb();
- return this[_url];
- } else {
- this[_url] = this[_request].url();
- return this[_url];
- }
+ get url() {
+ webidl.assertBranded(this, RequestPrototype);
+ if (this[_url]) {
+ return this[_url];
}
- get headers() {
- webidl.assertBranded(this, RequestPrototype);
- return this[_headers];
+ if (this[_flash]) {
+ this[_url] = this[_flash].urlCb();
+ return this[_url];
+ } else {
+ this[_url] = this[_request].url();
+ return this[_url];
}
+ }
- get redirect() {
- webidl.assertBranded(this, RequestPrototype);
- if (this[_flash]) {
- return this[_flash].redirectMode;
- }
- return this[_request].redirectMode;
- }
+ get headers() {
+ webidl.assertBranded(this, RequestPrototype);
+ return this[_headers];
+ }
- get signal() {
- webidl.assertBranded(this, RequestPrototype);
- return this[_signal];
+ get redirect() {
+ webidl.assertBranded(this, RequestPrototype);
+ if (this[_flash]) {
+ return this[_flash].redirectMode;
}
+ return this[_request].redirectMode;
+ }
- clone() {
- webidl.assertBranded(this, RequestPrototype);
- if (this[_body] && this[_body].unusable()) {
- throw new TypeError("Body is unusable.");
- }
- let newReq;
- if (this[_flash]) {
- newReq = cloneInnerRequest(this[_flash], false, true);
- } else {
- newReq = cloneInnerRequest(this[_request]);
- }
- const newSignal = abortSignal.newSignal();
+ get signal() {
+ webidl.assertBranded(this, RequestPrototype);
+ return this[_signal];
+ }
- if (this[_signal]) {
- abortSignal.follow(newSignal, this[_signal]);
- }
+ clone() {
+ webidl.assertBranded(this, RequestPrototype);
+ if (this[_body] && this[_body].unusable()) {
+ throw new TypeError("Body is unusable.");
+ }
+ let newReq;
+ if (this[_flash]) {
+ newReq = cloneInnerRequest(this[_flash], false, true);
+ } else {
+ newReq = cloneInnerRequest(this[_request]);
+ }
+ const newSignal = abortSignal.newSignal();
- if (this[_flash]) {
- return fromInnerRequest(
- newReq,
- newSignal,
- guardFromHeaders(this[_headers]),
- true,
- );
- }
+ if (this[_signal]) {
+ abortSignal.follow(newSignal, this[_signal]);
+ }
+ if (this[_flash]) {
return fromInnerRequest(
newReq,
newSignal,
guardFromHeaders(this[_headers]),
- false,
+ true,
);
}
- [SymbolFor("Deno.customInspect")](inspect) {
- return inspect(consoleInternal.createFilteredInspectProxy({
- object: this,
- evaluate: ObjectPrototypeIsPrototypeOf(RequestPrototype, this),
- keys: [
- "bodyUsed",
- "headers",
- "method",
- "redirect",
- "url",
- ],
- }));
- }
+ return fromInnerRequest(
+ newReq,
+ newSignal,
+ guardFromHeaders(this[_headers]),
+ false,
+ );
}
- webidl.configurePrototype(Request);
- const RequestPrototype = Request.prototype;
- mixinBody(RequestPrototype, _body, _mimeType);
-
- webidl.converters["Request"] = webidl.createInterfaceConverter(
- "Request",
- RequestPrototype,
- );
- webidl.converters["RequestInfo_DOMString"] = (V, opts) => {
- // Union for (Request or USVString)
- if (typeof V == "object") {
- if (ObjectPrototypeIsPrototypeOf(RequestPrototype, V)) {
- return webidl.converters["Request"](V, opts);
- }
- }
- // Passed to new URL(...) which implicitly converts DOMString -> USVString
- return webidl.converters["DOMString"](V, opts);
- };
- webidl.converters["RequestRedirect"] = webidl.createEnumConverter(
- "RequestRedirect",
- [
- "follow",
- "error",
- "manual",
- ],
- );
- webidl.converters["RequestInit"] = webidl.createDictionaryConverter(
- "RequestInit",
- [
- { key: "method", converter: webidl.converters["ByteString"] },
- { key: "headers", converter: webidl.converters["HeadersInit"] },
- {
- key: "body",
- converter: webidl.createNullableConverter(
- webidl.converters["BodyInit_DOMString"],
- ),
- },
- { key: "redirect", converter: webidl.converters["RequestRedirect"] },
- {
- key: "signal",
- converter: webidl.createNullableConverter(
- webidl.converters["AbortSignal"],
- ),
- },
- { key: "client", converter: webidl.converters.any },
- ],
- );
-
- /**
- * @param {Request} request
- * @returns {InnerRequest}
- */
- function toInnerRequest(request) {
- return request[_request];
+ [SymbolFor("Deno.customInspect")](inspect) {
+ return inspect(createFilteredInspectProxy({
+ object: this,
+ evaluate: ObjectPrototypeIsPrototypeOf(RequestPrototype, this),
+ keys: [
+ "bodyUsed",
+ "headers",
+ "method",
+ "redirect",
+ "url",
+ ],
+ }));
}
-
- /**
- * @param {InnerRequest} inner
- * @param {AbortSignal} signal
- * @param {"request" | "immutable" | "request-no-cors" | "response" | "none"} guard
- * @param {boolean} flash
- * @returns {Request}
- */
- function fromInnerRequest(inner, signal, guard, flash) {
- const request = webidl.createBranded(Request);
- if (flash) {
- request[_flash] = inner;
- } else {
- request[_request] = inner;
+}
+
+webidl.configurePrototype(Request);
+const RequestPrototype = Request.prototype;
+mixinBody(RequestPrototype, _body, _mimeType);
+
+webidl.converters["Request"] = webidl.createInterfaceConverter(
+ "Request",
+ RequestPrototype,
+);
+webidl.converters["RequestInfo_DOMString"] = (V, opts) => {
+ // Union for (Request or USVString)
+ if (typeof V == "object") {
+ if (ObjectPrototypeIsPrototypeOf(RequestPrototype, V)) {
+ return webidl.converters["Request"](V, opts);
}
- request[_signal] = signal;
- request[_getHeaders] = flash
- ? () => headersFromHeaderList(inner.headerList(), guard)
- : () => headersFromHeaderList(inner.headerList, guard);
- return request;
}
-
- /**
- * @param {number} serverId
- * @param {number} streamRid
- * @param {ReadableStream} body
- * @param {() => string} methodCb
- * @param {() => string} urlCb
- * @param {() => [string, string][]} headersCb
- * @returns {Request}
- */
- function fromFlashRequest(
- serverId,
- streamRid,
- body,
+ // Passed to new URL(...) which implicitly converts DOMString -> USVString
+ return webidl.converters["DOMString"](V, opts);
+};
+webidl.converters["RequestRedirect"] = webidl.createEnumConverter(
+ "RequestRedirect",
+ [
+ "follow",
+ "error",
+ "manual",
+ ],
+);
+webidl.converters["RequestInit"] = webidl.createDictionaryConverter(
+ "RequestInit",
+ [
+ { key: "method", converter: webidl.converters["ByteString"] },
+ { key: "headers", converter: webidl.converters["HeadersInit"] },
+ {
+ key: "body",
+ converter: webidl.createNullableConverter(
+ webidl.converters["BodyInit_DOMString"],
+ ),
+ },
+ { key: "redirect", converter: webidl.converters["RequestRedirect"] },
+ {
+ key: "signal",
+ converter: webidl.createNullableConverter(
+ webidl.converters["AbortSignal"],
+ ),
+ },
+ { key: "client", converter: webidl.converters.any },
+ ],
+);
+
+/**
+ * @param {Request} request
+ * @returns {InnerRequest}
+ */
+function toInnerRequest(request) {
+ return request[_request];
+}
+
+/**
+ * @param {InnerRequest} inner
+ * @param {AbortSignal} signal
+ * @param {"request" | "immutable" | "request-no-cors" | "response" | "none"} guard
+ * @param {boolean} flash
+ * @returns {Request}
+ */
+function fromInnerRequest(inner, signal, guard, flash) {
+ const request = webidl.createBranded(Request);
+ if (flash) {
+ request[_flash] = inner;
+ } else {
+ request[_request] = inner;
+ }
+ request[_signal] = signal;
+ request[_getHeaders] = flash
+ ? () => headersFromHeaderList(inner.headerList(), guard)
+ : () => headersFromHeaderList(inner.headerList, guard);
+ return request;
+}
+
+/**
+ * @param {number} serverId
+ * @param {number} streamRid
+ * @param {ReadableStream} body
+ * @param {() => string} methodCb
+ * @param {() => string} urlCb
+ * @param {() => [string, string][]} headersCb
+ * @returns {Request}
+ */
+function fromFlashRequest(
+ serverId,
+ streamRid,
+ body,
+ methodCb,
+ urlCb,
+ headersCb,
+) {
+ const request = webidl.createBranded(Request);
+ request[_flash] = {
+ body: body !== null ? new InnerBody(body) : null,
methodCb,
urlCb,
- headersCb,
- ) {
- const request = webidl.createBranded(Request);
- request[_flash] = {
- body: body !== null ? new InnerBody(body) : null,
- methodCb,
- urlCb,
- headerList: headersCb,
- streamRid,
- serverId,
- redirectMode: "follow",
- redirectCount: 0,
- };
- request[_getHeaders] = () => headersFromHeaderList(headersCb(), "request");
- return request;
- }
-
- window.__bootstrap.fetch ??= {};
- window.__bootstrap.fetch.Request = Request;
- window.__bootstrap.fetch.toInnerRequest = toInnerRequest;
- window.__bootstrap.fetch.fromFlashRequest = fromFlashRequest;
- window.__bootstrap.fetch.fromInnerRequest = fromInnerRequest;
- window.__bootstrap.fetch.newInnerRequest = newInnerRequest;
- window.__bootstrap.fetch.processUrlList = processUrlList;
- window.__bootstrap.fetch._flash = _flash;
-})(globalThis);
+ headerList: headersCb,
+ streamRid,
+ serverId,
+ redirectMode: "follow",
+ redirectCount: 0,
+ };
+ request[_getHeaders] = () => headersFromHeaderList(headersCb(), "request");
+ return request;
+}
+
+export {
+ _flash,
+ fromFlashRequest,
+ fromInnerRequest,
+ newInnerRequest,
+ processUrlList,
+ Request,
+ RequestPrototype,
+ toInnerRequest,
+};