1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

refactor(fetch/request): use callback for url and method (#15483)

This commit is contained in:
Leo Kettmeir 2022-08-17 16:29:26 +02:00 committed by GitHub
parent a2ab5eee01
commit 0b0843e4a5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 17 deletions

View file

@ -49,35 +49,62 @@
const _mimeType = Symbol("mime type"); const _mimeType = Symbol("mime type");
const _body = Symbol("body"); 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 * @typedef InnerRequest
* @property {string} method * @property {() => string} method
* @property {() => string} url * @property {() => string} url
* @property {() => string} currentUrl * @property {() => string} currentUrl
* @property {() => [string, string][]} headerList * @property {() => [string, string][]} headerList
* @property {null | typeof __window.bootstrap.fetchBody.InnerBody} body * @property {null | typeof __window.bootstrap.fetchBody.InnerBody} body
* @property {"follow" | "error" | "manual"} redirectMode * @property {"follow" | "error" | "manual"} redirectMode
* @property {number} redirectCount * @property {number} redirectCount
* @property {string[]} urlList * @property {(() => string)[]} urlList
* @property {string[]} urlListProcessed
* @property {number | null} clientRid NOTE: non standard extension for `Deno.HttpClient`. * @property {number | null} clientRid NOTE: non standard extension for `Deno.HttpClient`.
* @property {Blob | null} blobUrlEntry * @property {Blob | null} blobUrlEntry
*/ */
/** /**
* @param {string} method * @param {() => string} method
* @param {string} url * @param {string | () => string} url
* @param {() => [string, string][]} headerList * @param {() => [string, string][]} headerList
* @param {typeof __window.bootstrap.fetchBody.InnerBody} body * @param {typeof __window.bootstrap.fetchBody.InnerBody} body
* @param {boolean} maybeBlob * @param {boolean} maybeBlob
* @returns * @returns {InnerRequest}
*/ */
function newInnerRequest(method, url, headerList, body, maybeBlob) { function newInnerRequest(method, url, headerList, body, maybeBlob) {
let blobUrlEntry = null; let blobUrlEntry = null;
if (maybeBlob && url.startsWith("blob:")) { if (maybeBlob && typeof url === "string" && url.startsWith("blob:")) {
blobUrlEntry = blobFromObjectUrl(url); blobUrlEntry = blobFromObjectUrl(url);
} }
return { 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, headerListInner: null,
get headerList() { get headerList() {
if (this.headerListInner === null) { if (this.headerListInner === null) {
@ -95,14 +122,30 @@
body, body,
redirectMode: "follow", redirectMode: "follow",
redirectCount: 0, redirectCount: 0,
urlList: [url], urlList: [typeof url === "string" ? () => url : url],
urlListProcessed: [],
clientRid: null, clientRid: null,
blobUrlEntry, blobUrlEntry,
url() { 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() { 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, redirectMode: request.redirectMode,
redirectCount: request.redirectCount, redirectCount: request.redirectCount,
urlList: request.urlList, urlList: request.urlList,
urlListProcessed: request.urlListProcessed,
clientRid: request.clientRid, clientRid: request.clientRid,
blobUrlEntry: request.blobUrlEntry, blobUrlEntry: request.blobUrlEntry,
url() { 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() { 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. // 5.
if (typeof input === "string") { if (typeof input === "string") {
const parsedURL = new URL(input, baseURL); const parsedURL = new URL(input, baseURL);
request = newInnerRequest("GET", parsedURL.href, () => [], null, true); request = newInnerRequest(
() => "GET",
parsedURL.href,
() => [],
null,
true,
);
} else { // 6. } else { // 6.
if (!ObjectPrototypeIsPrototypeOf(RequestPrototype, input)) { if (!ObjectPrototypeIsPrototypeOf(RequestPrototype, input)) {
throw new TypeError("Unreachable"); throw new TypeError("Unreachable");
@ -489,4 +554,5 @@
window.__bootstrap.fetch.toInnerRequest = toInnerRequest; window.__bootstrap.fetch.toInnerRequest = toInnerRequest;
window.__bootstrap.fetch.fromInnerRequest = fromInnerRequest; window.__bootstrap.fetch.fromInnerRequest = fromInnerRequest;
window.__bootstrap.fetch.newInnerRequest = newInnerRequest; window.__bootstrap.fetch.newInnerRequest = newInnerRequest;
window.__bootstrap.fetch.processUrlList = processUrlList;
})(globalThis); })(globalThis);

View file

@ -28,6 +28,7 @@
nullBodyStatus, nullBodyStatus,
networkError, networkError,
abortedNetworkError, abortedNetworkError,
processUrlList,
} = window.__bootstrap.fetch; } = window.__bootstrap.fetch;
const abortSignal = window.__bootstrap.abortSignal; const abortSignal = window.__bootstrap.abortSignal;
const { const {
@ -295,6 +296,8 @@
} }
if (terminator.aborted) return abortedNetworkError(); if (terminator.aborted) return abortedNetworkError();
processUrlList(req.urlList, req.urlListProcessed);
/** @type {InnerResponse} */ /** @type {InnerResponse} */
const response = { const response = {
headerList: resp.headers, headerList: resp.headers,
@ -306,7 +309,7 @@
if (this.urlList.length == 0) return null; if (this.urlList.length == 0) return null;
return this.urlList[this.urlList.length - 1]; return this.urlList[this.urlList.length - 1];
}, },
urlList: req.urlList, urlList: req.urlListProcessed,
}; };
if (redirectStatus(resp.status)) { if (redirectStatus(resp.status)) {
switch (req.redirectMode) { switch (req.redirectMode) {
@ -339,7 +342,8 @@
if (recursive) return response; if (recursive) return response;
if (response.urlList.length === 0) { if (response.urlList.length === 0) {
response.urlList = [...new SafeArrayIterator(req.urlList)]; processUrlList(req.urlList, req.urlListProcessed);
response.urlList = [...new SafeArrayIterator(req.urlListProcessed)];
} }
return response; return response;
@ -407,7 +411,7 @@
const res = extractBody(request.body.source); const res = extractBody(request.body.source);
request.body = res.body; request.body = res.body;
} }
ArrayPrototypePush(request.urlList, locationURL.href); ArrayPrototypePush(request.urlList, () => locationURL.href);
return mainFetch(request, true, terminator); return mainFetch(request, true, terminator);
} }

View file

@ -124,7 +124,7 @@
} }
const innerRequest = newInnerRequest( const innerRequest = newInnerRequest(
method, () => method,
url, url,
() => ops.op_http_headers(streamRid), () => ops.op_http_headers(streamRid),
body !== null ? new InnerBody(body) : null, body !== null ? new InnerBody(body) : null,