summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsher Gomez <ashersaupingomez@gmail.com>2024-05-23 10:27:58 +1000
committerGitHub <noreply@github.com>2024-05-23 00:27:58 +0000
commit8a636d0600dc7000d1e12b2fc4f4f46ecd70164a (patch)
treea568fcac6b658e041f15da3b62953a5b812433f6
parentf5d0c4b1ea39e34e2e068264f18021a4f7412479 (diff)
feat(ext/fetch): `Request.bytes()` and `Response.bytes()` (#23823)
Closes #23790
-rw-r--r--cli/tsc/dts/lib.dom.d.ts2
-rw-r--r--cli/tsc/dts/lib.webworker.d.ts2
-rw-r--r--ext/fetch/22_body.js13
-rw-r--r--ext/fetch/lib.deno_fetch.d.ts4
-rw-r--r--tests/specs/run/045_proxy/proxy_test.ts2
-rw-r--r--tests/testdata/fmt/with_config/subdir/a.ts12
-rw-r--r--tests/unit/fetch_test.ts33
-rw-r--r--tests/unit/http_test.ts8
-rw-r--r--tests/unit/serve_test.ts17
-rw-r--r--tests/unit/worker_test.ts2
-rw-r--r--tests/unit_node/http_test.ts2
-rw-r--r--tests/wpt/runner/expectation.json24
m---------tests/wpt/suite0
13 files changed, 74 insertions, 47 deletions
diff --git a/cli/tsc/dts/lib.dom.d.ts b/cli/tsc/dts/lib.dom.d.ts
index 5d4aa12e9..f0af1798c 100644
--- a/cli/tsc/dts/lib.dom.d.ts
+++ b/cli/tsc/dts/lib.dom.d.ts
@@ -3156,6 +3156,8 @@ interface Body {
arrayBuffer(): Promise<ArrayBuffer>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/blob) */
blob(): Promise<Blob>;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bytes) */
+ bytes(): Promise<Uint8Array>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/formData) */
formData(): Promise<FormData>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/json) */
diff --git a/cli/tsc/dts/lib.webworker.d.ts b/cli/tsc/dts/lib.webworker.d.ts
index 150ad5da7..7ffd63c4b 100644
--- a/cli/tsc/dts/lib.webworker.d.ts
+++ b/cli/tsc/dts/lib.webworker.d.ts
@@ -1029,6 +1029,8 @@ interface Body {
arrayBuffer(): Promise<ArrayBuffer>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/blob) */
blob(): Promise<Blob>;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bytes) */
+ bytes(): Promise<Uint8Array>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/formData) */
formData(): Promise<FormData>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/json) */
diff --git a/ext/fetch/22_body.js b/ext/fetch/22_body.js
index e16fd4c54..e9d493658 100644
--- a/ext/fetch/22_body.js
+++ b/ext/fetch/22_body.js
@@ -296,6 +296,15 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
configurable: true,
enumerable: true,
},
+ bytes: {
+ /** @returns {Promise<Uint8Array>} */
+ value: function bytes() {
+ return consumeBody(this, "bytes");
+ },
+ writable: true,
+ configurable: true,
+ enumerable: true,
+ },
formData: {
/** @returns {Promise<FormData>} */
value: function formData() {
@@ -330,7 +339,7 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
/**
* https://fetch.spec.whatwg.org/#concept-body-package-data
* @param {Uint8Array | string} bytes
- * @param {"ArrayBuffer" | "Blob" | "FormData" | "JSON" | "text"} type
+ * @param {"ArrayBuffer" | "Blob" | "FormData" | "JSON" | "text" | "bytes"} type
* @param {MimeType | null} [mimeType]
*/
function packageData(bytes, type, mimeType) {
@@ -341,6 +350,8 @@ function packageData(bytes, type, mimeType) {
return new Blob([bytes], {
type: mimeType !== null ? mimesniff.serializeMimeType(mimeType) : "",
});
+ case "bytes":
+ return chunkToU8(bytes);
case "FormData": {
if (mimeType !== null) {
const essence = mimesniff.essence(mimeType);
diff --git a/ext/fetch/lib.deno_fetch.d.ts b/ext/fetch/lib.deno_fetch.d.ts
index 4eb303e68..c27313903 100644
--- a/ext/fetch/lib.deno_fetch.d.ts
+++ b/ext/fetch/lib.deno_fetch.d.ts
@@ -59,6 +59,10 @@ declare interface Body {
*/
blob(): Promise<Blob>;
/** Takes a `Response` stream and reads it to completion. It returns a promise
+ * that resolves with a `Uint8Array`.
+ */
+ bytes(): Promise<Uint8Array>;
+ /** Takes a `Response` stream and reads it to completion. It returns a promise
* that resolves with a `FormData` object.
*/
formData(): Promise<FormData>;
diff --git a/tests/specs/run/045_proxy/proxy_test.ts b/tests/specs/run/045_proxy/proxy_test.ts
index d3386f0d7..582b0e638 100644
--- a/tests/specs/run/045_proxy/proxy_test.ts
+++ b/tests/specs/run/045_proxy/proxy_test.ts
@@ -23,7 +23,7 @@ async function handler(req: Request): Promise<Response> {
method: req.method,
headers: headers,
});
- return new Response(new Uint8Array(await resp.arrayBuffer()), {
+ return new Response(await resp.bytes(), {
status: resp.status,
headers: resp.headers,
});
diff --git a/tests/testdata/fmt/with_config/subdir/a.ts b/tests/testdata/fmt/with_config/subdir/a.ts
index 5474b3aa3..14f22d1b2 100644
--- a/tests/testdata/fmt/with_config/subdir/a.ts
+++ b/tests/testdata/fmt/with_config/subdir/a.ts
@@ -22,15 +22,11 @@ Deno.test(
.statusText,
)
const u8a =
- new Uint8Array(
- await response
- .arrayBuffer(),
- )
+ await response
+ .bytes()
const u8a1 =
- new Uint8Array(
- await response1
- .arrayBuffer(),
- )
+ await response1
+ .bytes()
for (
let i = 0;
i <
diff --git a/tests/unit/fetch_test.ts b/tests/unit/fetch_test.ts
index 3202d40fa..4176f39ac 100644
--- a/tests/unit/fetch_test.ts
+++ b/tests/unit/fetch_test.ts
@@ -243,8 +243,8 @@ Deno.test({ permissions: { net: true } }, async function responseClone() {
assert(response !== response1);
assertEquals(response.status, response1.status);
assertEquals(response.statusText, response1.statusText);
- const u8a = new Uint8Array(await response.arrayBuffer());
- const u8a1 = new Uint8Array(await response1.arrayBuffer());
+ const u8a = await response.bytes();
+ const u8a1 = await response1.bytes();
for (let i = 0; i < u8a.byteLength; i++) {
assertEquals(u8a[i], u8a1[i]);
}
@@ -675,7 +675,7 @@ Deno.test(
["Foo", "Bar"],
],
});
- await response.arrayBuffer();
+ await response.body?.cancel();
assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2");
@@ -709,7 +709,7 @@ Deno.test(
["Accept-Language", "en-US"],
],
});
- await response.arrayBuffer();
+ await response.body?.cancel();
assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2");
@@ -743,7 +743,7 @@ Deno.test(
],
body,
});
- await response.arrayBuffer();
+ await response.body?.cancel();
assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2");
@@ -782,7 +782,7 @@ Deno.test(
],
body,
});
- await response.arrayBuffer();
+ await response.body?.cancel();
assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2");
@@ -816,7 +816,7 @@ Deno.test(
["Content-Length", "10"],
],
});
- await response.arrayBuffer();
+ await response.body?.cancel();
assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2");
@@ -847,7 +847,7 @@ Deno.test(
["Transfer-Encoding", "chunked"],
],
});
- await response.arrayBuffer();
+ await response.body?.cancel();
assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2");
@@ -933,7 +933,7 @@ Deno.test(function responseRedirectTakeURLObjectAsParameter() {
Deno.test(async function responseWithoutBody() {
const response = new Response();
- assertEquals(await response.arrayBuffer(), new ArrayBuffer(0));
+ assertEquals(await response.bytes(), new Uint8Array(0));
const blob = await response.blob();
assertEquals(blob.size, 0);
assertEquals(await blob.arrayBuffer(), new ArrayBuffer(0));
@@ -1214,7 +1214,7 @@ Deno.test(
],
body: stream.readable,
});
- await response.arrayBuffer();
+ await response.body?.cancel();
assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2");
@@ -1793,10 +1793,9 @@ Deno.test(
const listener = invalidServer(addr, body);
const response = await fetch(`http://${addr}/`);
- const res = await response.arrayBuffer();
+ const res = await response.bytes();
const buf = new TextEncoder().encode(data);
- assertEquals(res.byteLength, buf.byteLength);
- assertEquals(new Uint8Array(res), buf);
+ assertEquals(res, buf);
listener.close();
},
@@ -1850,10 +1849,10 @@ Deno.test(
// If content-length < totalLength, a maximum of content-length bytes
// should be returned.
- const res = await response.arrayBuffer();
+ const res = await response.bytes();
const buf = new TextEncoder().encode(data);
assertEquals(res.byteLength, contentLength);
- assertEquals(new Uint8Array(res), buf.subarray(contentLength));
+ assertEquals(res, buf.subarray(contentLength));
listener.close();
},
@@ -2029,7 +2028,7 @@ Deno.test(
Deno.test("Request with subarray TypedArray body", async () => {
const body = new Uint8Array([1, 2, 3, 4, 5]).subarray(1);
const req = new Request("https://example.com", { method: "POST", body });
- const actual = new Uint8Array(await req.arrayBuffer());
+ const actual = await req.bytes();
const expected = new Uint8Array([2, 3, 4, 5]);
assertEquals(actual, expected);
});
@@ -2037,7 +2036,7 @@ Deno.test("Request with subarray TypedArray body", async () => {
Deno.test("Response with subarray TypedArray body", async () => {
const body = new Uint8Array([1, 2, 3, 4, 5]).subarray(1);
const req = new Response(body);
- const actual = new Uint8Array(await req.arrayBuffer());
+ const actual = await req.bytes();
const expected = new Uint8Array([2, 3, 4, 5]);
assertEquals(actual, expected);
});
diff --git a/tests/unit/http_test.ts b/tests/unit/http_test.ts
index 607f2fc6e..f4fa62fa6 100644
--- a/tests/unit/http_test.ts
+++ b/tests/unit/http_test.ts
@@ -239,7 +239,7 @@ Deno.test(
headers: { "connection": "close" },
});
- await resp.arrayBuffer();
+ await resp.body?.cancel();
await promise;
},
);
@@ -963,7 +963,7 @@ Deno.test(
await respondWith(new Response(f.readable, { status: 200 }));
})();
const resp = await fetch(`http://127.0.0.1:${listenPort}/`);
- const body = await resp.arrayBuffer();
+ const body = await resp.bytes();
assertEquals(body.byteLength, 70 * 1024);
await promise;
httpConn!.close();
@@ -1293,8 +1293,8 @@ Deno.test(
const resp = await fetch(`http://localhost:${listenPort}/`);
assertEquals(resp.status, 200);
- const body = await resp.arrayBuffer();
- assertEquals(new Uint8Array(body), new Uint8Array([128]));
+ const body = await resp.bytes();
+ assertEquals(body, new Uint8Array([128]));
await promise;
httpConn!.close();
diff --git a/tests/unit/serve_test.ts b/tests/unit/serve_test.ts
index 74628ace1..f7f01076b 100644
--- a/tests/unit/serve_test.ts
+++ b/tests/unit/serve_test.ts
@@ -340,7 +340,7 @@ Deno.test(
});
const resp = await fetch(`http://localhost:${servePort}`);
- dataPromise = resp.arrayBuffer();
+ dataPromise = resp.bytes();
}
assertEquals((await dataPromise).byteLength, 1048576);
@@ -358,7 +358,7 @@ Deno.test(
const [_, data] = await Promise.all([
server.shutdown(),
- resp.arrayBuffer(),
+ resp.bytes(),
]);
assertEquals(data.byteLength, 1048576);
@@ -1861,13 +1861,12 @@ Deno.test(
signal: ac.signal,
});
const response = await fetch(`http://localhost:${servePort}/`);
- const body = await response.arrayBuffer();
+ const body = await response.bytes();
assertEquals(1024 * 1024, body.byteLength);
- const buffer = new Uint8Array(body);
for (let i = 0; i < 256; i++) {
assertEquals(
i,
- buffer[i * 4096],
+ body[i * 4096],
`sentinel mismatch at index ${i * 4096}`,
);
}
@@ -2078,8 +2077,8 @@ Deno.test(
await deferred.promise;
assertEquals(resp.status, 200);
- const body = await resp.arrayBuffer();
- assertEquals(new Uint8Array(body), new Uint8Array([128]));
+ const body = await resp.bytes();
+ assertEquals(body, new Uint8Array([128]));
ac.abort();
await server.finished;
@@ -2694,7 +2693,7 @@ for (const testCase of compressionTestCases) {
headers: testCase.in as HeadersInit,
});
await deferred.promise;
- const body = await resp.arrayBuffer();
+ const body = await resp.bytes();
if (testCase.expect == null) {
assertEquals(body.byteLength, testCase.length);
assertEquals(
@@ -2731,7 +2730,7 @@ Deno.test(
const server = Deno.serve({
handler: async (request) => {
assertEquals(
- new Uint8Array(await request.arrayBuffer()),
+ await request.bytes(),
makeTempData(70 * 1024),
);
deferred.resolve();
diff --git a/tests/unit/worker_test.ts b/tests/unit/worker_test.ts
index 33e25f70e..a66eb69a9 100644
--- a/tests/unit/worker_test.ts
+++ b/tests/unit/worker_test.ts
@@ -689,7 +689,7 @@ Deno.test({
assert(worker);
const response = await fetch("http://localhost:4506");
- assert(await response.arrayBuffer());
+ assert(await response.bytes());
worker.terminate();
},
});
diff --git a/tests/unit_node/http_test.ts b/tests/unit_node/http_test.ts
index c57027549..0518d935b 100644
--- a/tests/unit_node/http_test.ts
+++ b/tests/unit_node/http_test.ts
@@ -174,7 +174,7 @@ Deno.test("[node/http] server can respond with 101, 204, 205, 304 status", async
// deno-lint-ignore no-explicit-any
`http://127.0.0.1:${(server.address() as any).port}/`,
);
- await res.arrayBuffer();
+ await res.body?.cancel();
assertEquals(res.status, status);
server.close(() => resolve());
});
diff --git a/tests/wpt/runner/expectation.json b/tests/wpt/runner/expectation.json
index 1f2dfa684..e3f2ac972 100644
--- a/tests/wpt/runner/expectation.json
+++ b/tests/wpt/runner/expectation.json
@@ -7153,6 +7153,12 @@
"response": {
"json.any.html": true,
"json.any.worker.html": true,
+ "response-blob-realm.any.html": [
+ "realm of the Uint8Array from Response bytes()"
+ ],
+ "response-blob-realm.any.worker.html": [
+ "realm of the Uint8Array from Response bytes()"
+ ],
"response-init-001.any.html": true,
"response-init-001.any.worker.html": true,
"response-init-002.any.html": true,
@@ -8148,7 +8154,11 @@
"HTTP/1.1 200 ",
"HTTP/1.1 999 DOES IT MATTER "
],
- "resources-with-0x00-in-header.window.html": false
+ "resources-with-0x00-in-header.window.html": [
+ "Expect network error for script with 0x00 in a header",
+ "Expect network error for frame navigation to resource with 0x00 in a header",
+ "Expect network error for image with 0x00 in a header"
+ ]
},
"range": {
"general.any.html": [
@@ -12825,8 +12835,6 @@
"eventsource-onopen.any.worker.html": true,
"eventsource-prototype.any.html": true,
"eventsource-prototype.any.worker.html": true,
- "eventsource-request-cancellation.window.any.html": false,
- "eventsource-request-cancellation.window.any.worker.html": false,
"eventsource-url.any.html": true,
"eventsource-url.any.worker.html": true,
"format-bom-2.any.html": true,
@@ -12883,6 +12891,12 @@
"eventsource-constructor-stringify.window.html": false,
"eventsource-cross-origin.window.html": false,
"eventsource-reconnect.window.html": false,
- "request-status-error.window.html": false
+ "request-status-error.window.html": false,
+ "eventsource-constructor-empty-url.any.serviceworker.html": false,
+ "eventsource-constructor-empty-url.any.sharedworker.html": false,
+ "eventsource-constructor-url-bogus.any.serviceworker.html": false,
+ "eventsource-constructor-url-bogus.any.sharedworker.html": false,
+ "request-credentials.window.html": false,
+ "request-redirect.window.html": false
}
-}
+} \ No newline at end of file
diff --git a/tests/wpt/suite b/tests/wpt/suite
-Subproject 5e8f71d73049d4fca2a8cbc62d40e821400f162
+Subproject 915d40b37fbd3554548d5cbec9f335f329ccc94