summaryrefslogtreecommitdiff
path: root/ext/fetch
diff options
context:
space:
mode:
Diffstat (limited to 'ext/fetch')
-rw-r--r--ext/fetch/22_body.js16
-rw-r--r--ext/fetch/23_request.js77
-rw-r--r--ext/fetch/23_response.js20
3 files changed, 97 insertions, 16 deletions
diff --git a/ext/fetch/22_body.js b/ext/fetch/22_body.js
index 10ddb7603..a51cdc184 100644
--- a/ext/fetch/22_body.js
+++ b/ext/fetch/22_body.js
@@ -388,7 +388,10 @@
let source = null;
let length = null;
let contentType = null;
- if (ObjectPrototypeIsPrototypeOf(BlobPrototype, object)) {
+ if (typeof object === "string") {
+ source = object;
+ contentType = "text/plain;charset=UTF-8";
+ } else if (ObjectPrototypeIsPrototypeOf(BlobPrototype, object)) {
stream = object.stream();
source = object;
length = object.size;
@@ -424,24 +427,21 @@
// TODO(@satyarohith): not sure what primordial here.
source = object.toString();
contentType = "application/x-www-form-urlencoded;charset=UTF-8";
- } else if (typeof object === "string") {
- source = object;
- contentType = "text/plain;charset=UTF-8";
} else if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, object)) {
stream = object;
if (object.locked || isReadableStreamDisturbed(object)) {
throw new TypeError("ReadableStream is locked or disturbed");
}
}
- if (ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, source)) {
- stream = { body: source, consumed: false };
- length = source.byteLength;
- } else if (typeof source === "string") {
+ if (typeof source === "string") {
// WARNING: this deviates from spec (expects length to be set)
// https://fetch.spec.whatwg.org/#bodyinit > 7.
// no observable side-effect for users so far, but could change
stream = { body: source, consumed: false };
length = null; // NOTE: string length != byte length
+ } else if (ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, source)) {
+ stream = { body: source, consumed: false };
+ length = source.byteLength;
}
const body = new InnerBody(stream);
body.source = source;
diff --git a/ext/fetch/23_request.js b/ext/fetch/23_request.js
index 63fc6a26e..5221d5ca9 100644
--- a/ext/fetch/23_request.js
+++ b/ext/fetch/23_request.js
@@ -16,7 +16,7 @@
const { HTTP_TOKEN_CODE_POINT_RE, byteUpperCase } = window.__bootstrap.infra;
const { URL } = window.__bootstrap.url;
const { guardFromHeaders } = window.__bootstrap.headers;
- const { mixinBody, extractBody } = window.__bootstrap.fetchBody;
+ const { mixinBody, extractBody, InnerBody } = window.__bootstrap.fetchBody;
const { getLocationHref } = window.__bootstrap.location;
const { extractMimeType } = window.__bootstrap.mimesniff;
const { blobFromObjectUrl } = window.__bootstrap.file;
@@ -48,6 +48,9 @@
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
@@ -266,7 +269,11 @@
return extractMimeType(values);
}
get [_body]() {
- return this[_request].body;
+ if (this[_flash]) {
+ return this[_flash].body;
+ } else {
+ return this[_request].body;
+ }
}
/**
@@ -427,12 +434,31 @@
get method() {
webidl.assertBranded(this, RequestPrototype);
- return this[_request].method;
+ 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];
+ }
}
get url() {
webidl.assertBranded(this, RequestPrototype);
- return this[_request].url();
+ 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 headers() {
@@ -442,6 +468,9 @@
get redirect() {
webidl.assertBranded(this, RequestPrototype);
+ if (this[_flash]) {
+ return this[_flash].redirectMode;
+ }
return this[_request].redirectMode;
}
@@ -455,7 +484,12 @@
if (this[_body] && this[_body].unusable()) {
throw new TypeError("Body is unusable.");
}
- const newReq = cloneInnerRequest(this[_request]);
+ let newReq;
+ if (this[_flash]) {
+ newReq = cloneInnerRequest(this[_flash]);
+ } else {
+ newReq = cloneInnerRequest(this[_request]);
+ }
const newSignal = abortSignal.newSignal();
abortSignal.follow(newSignal, this[_signal]);
return fromInnerRequest(
@@ -549,10 +583,43 @@
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,
+ 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);
diff --git a/ext/fetch/23_response.js b/ext/fetch/23_response.js
index 226a751bd..3c19f963a 100644
--- a/ext/fetch/23_response.js
+++ b/ext/fetch/23_response.js
@@ -15,6 +15,9 @@
const { isProxy } = Deno.core;
const webidl = window.__bootstrap.webidl;
const consoleInternal = window.__bootstrap.console;
+ const {
+ byteLowerCase,
+ } = window.__bootstrap.infra;
const { HTTP_TAB_OR_SPACE, regexMatcher, serializeJSValueToJSONString } =
window.__bootstrap.infra;
const { extractBody, mixinBody } = window.__bootstrap.fetchBody;
@@ -185,7 +188,6 @@
// 4.
response[_response].statusMessage = init.statusText;
-
// 5.
/** @type {__bootstrap.headers.Headers} */
const headers = response[_headers];
@@ -200,10 +202,22 @@
"Response with null body status cannot have body",
);
}
+
const { body, contentType } = bodyWithType;
response[_response].body = body;
- if (contentType !== null && !headers.has("content-type")) {
- headers.append("Content-Type", contentType);
+
+ if (contentType !== null) {
+ let hasContentType = false;
+ const list = headerListFromHeaders(headers);
+ for (let i = 0; i < list.length; i++) {
+ if (byteLowerCase(list[i][0]) === "content-type") {
+ hasContentType = true;
+ break;
+ }
+ }
+ if (!hasContentType) {
+ ArrayPrototypePush(list, ["Content-Type", contentType]);
+ }
}
}
}