summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/fetch/23_request.js92
-rw-r--r--ext/fetch/26_fetch.js10
-rw-r--r--ext/http/01_http.js2
3 files changed, 87 insertions, 17 deletions
diff --git a/ext/fetch/23_request.js b/ext/fetch/23_request.js
index cbc6a887b..63fc6a26e 100644
--- a/ext/fetch/23_request.js
+++ b/ext/fetch/23_request.js
@@ -50,34 +50,61 @@
const _body = Symbol("body");
/**
+ * @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;
+ }
+
+ /**
* @typedef InnerRequest
- * @property {string} method
+ * @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)[]} urlList
+ * @property {string[]} urlListProcessed
* @property {number | null} clientRid NOTE: non standard extension for `Deno.HttpClient`.
* @property {Blob | null} blobUrlEntry
*/
/**
- * @param {string} method
- * @param {string} url
+ * @param {() => string} method
+ * @param {string | () => string} url
* @param {() => [string, string][]} headerList
* @param {typeof __window.bootstrap.fetchBody.InnerBody} body
* @param {boolean} maybeBlob
- * @returns
+ * @returns {InnerRequest}
*/
function newInnerRequest(method, url, headerList, body, maybeBlob) {
let blobUrlEntry = null;
- if (maybeBlob && url.startsWith("blob:")) {
+ if (maybeBlob && typeof url === "string" && url.startsWith("blob:")) {
blobUrlEntry = blobFromObjectUrl(url);
}
return {
- method,
+ 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) {
@@ -95,14 +122,30 @@
body,
redirectMode: "follow",
redirectCount: 0,
- urlList: [url],
+ urlList: [typeof url === "string" ? () => url : url],
+ urlListProcessed: [],
clientRid: null,
blobUrlEntry,
url() {
- return this.urlList[0];
+ 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() {
- return this.urlList[this.urlList.length - 1];
+ 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];
},
};
}
@@ -130,13 +173,29 @@
redirectMode: request.redirectMode,
redirectCount: request.redirectCount,
urlList: request.urlList,
+ urlListProcessed: request.urlListProcessed,
clientRid: request.clientRid,
blobUrlEntry: request.blobUrlEntry,
url() {
- return this.urlList[0];
+ 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() {
- return this.urlList[this.urlList.length - 1];
+ 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];
},
};
}
@@ -239,7 +298,13 @@
// 5.
if (typeof input === "string") {
const parsedURL = new URL(input, baseURL);
- request = newInnerRequest("GET", parsedURL.href, () => [], null, true);
+ request = newInnerRequest(
+ () => "GET",
+ parsedURL.href,
+ () => [],
+ null,
+ true,
+ );
} else { // 6.
if (!ObjectPrototypeIsPrototypeOf(RequestPrototype, input)) {
throw new TypeError("Unreachable");
@@ -489,4 +554,5 @@
window.__bootstrap.fetch.toInnerRequest = toInnerRequest;
window.__bootstrap.fetch.fromInnerRequest = fromInnerRequest;
window.__bootstrap.fetch.newInnerRequest = newInnerRequest;
+ window.__bootstrap.fetch.processUrlList = processUrlList;
})(globalThis);
diff --git a/ext/fetch/26_fetch.js b/ext/fetch/26_fetch.js
index a069583a7..c980bc9b8 100644
--- a/ext/fetch/26_fetch.js
+++ b/ext/fetch/26_fetch.js
@@ -28,6 +28,7 @@
nullBodyStatus,
networkError,
abortedNetworkError,
+ processUrlList,
} = window.__bootstrap.fetch;
const abortSignal = window.__bootstrap.abortSignal;
const {
@@ -295,6 +296,8 @@
}
if (terminator.aborted) return abortedNetworkError();
+ processUrlList(req.urlList, req.urlListProcessed);
+
/** @type {InnerResponse} */
const response = {
headerList: resp.headers,
@@ -306,7 +309,7 @@
if (this.urlList.length == 0) return null;
return this.urlList[this.urlList.length - 1];
},
- urlList: req.urlList,
+ urlList: req.urlListProcessed,
};
if (redirectStatus(resp.status)) {
switch (req.redirectMode) {
@@ -339,7 +342,8 @@
if (recursive) return response;
if (response.urlList.length === 0) {
- response.urlList = [...new SafeArrayIterator(req.urlList)];
+ processUrlList(req.urlList, req.urlListProcessed);
+ response.urlList = [...new SafeArrayIterator(req.urlListProcessed)];
}
return response;
@@ -407,7 +411,7 @@
const res = extractBody(request.body.source);
request.body = res.body;
}
- ArrayPrototypePush(request.urlList, locationURL.href);
+ ArrayPrototypePush(request.urlList, () => locationURL.href);
return mainFetch(request, true, terminator);
}
diff --git a/ext/http/01_http.js b/ext/http/01_http.js
index 34457ab0b..7dfe86a75 100644
--- a/ext/http/01_http.js
+++ b/ext/http/01_http.js
@@ -124,7 +124,7 @@
}
const innerRequest = newInnerRequest(
- method,
+ () => method,
url,
() => ops.op_http_headers(streamRid),
body !== null ? new InnerBody(body) : null,