From cc3e2b9b1a7ccd6c671bc0b3813cf7e2b0d88b5c Mon Sep 17 00:00:00 2001 From: Marcos Casagrande Date: Sat, 8 Oct 2022 22:08:47 +0200 Subject: [PATCH] fix(ext/fetch): reject immediately on aborted signal (#16190) Enabled the following test: https://github.com/web-platform-tests/wpt/blob/edc428e8e229429acd723efc7a6d41010c94fc41/fetch/api/abort/general.any.js#L185-L201 --- ext/fetch/22_body.js | 49 ++++++++++++++++++-------------------- ext/web/06_streams.js | 1 + tools/wpt/expectation.json | 18 ++------------ 3 files changed, 26 insertions(+), 42 deletions(-) diff --git a/ext/fetch/22_body.js b/ext/fetch/22_body.js index 429b56ae1d..b230c353ec 100644 --- a/ext/fetch/22_body.js +++ b/ext/fetch/22_body.js @@ -31,6 +31,7 @@ readableStreamClose, readableStreamDisturb, readableStreamCollectIntoUint8Array, + readableStreamThrowIfErrored, createProxy, ReadableStreamPrototype, } = globalThis.__bootstrap.streams; @@ -41,7 +42,6 @@ JSONParse, ObjectDefineProperties, ObjectPrototypeIsPrototypeOf, - PromiseResolve, TypedArrayPrototypeSlice, TypeError, Uint8Array, @@ -147,6 +147,7 @@ this.streamOrStatic, ) ) { + readableStreamThrowIfErrored(this.stream); return readableStreamCollectIntoUint8Array(this.stream); } else { this.streamOrStatic.consumed = true; @@ -222,11 +223,17 @@ * @returns {void} */ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) { - function consumeBody(object) { - if (object[bodySymbol] !== null) { - return object[bodySymbol].consume(); - } - return PromiseResolve(new Uint8Array()); + async function consumeBody(object, type) { + webidl.assertBranded(object, prototype); + + const body = object[bodySymbol] !== null + ? await object[bodySymbol].consume() + : new Uint8Array(); + + const mimeType = type === "Blob" || type === "FormData" + ? object[mimeTypeSymbol] + : null; + return packageData(body, type, mimeType); } /** @type {PropertyDescriptorMap} */ @@ -262,10 +269,8 @@ }, arrayBuffer: { /** @returns {Promise} */ - value: async function arrayBuffer() { - webidl.assertBranded(this, prototype); - const body = await consumeBody(this); - return packageData(body, "ArrayBuffer"); + value: function arrayBuffer() { + return consumeBody(this, "ArrayBuffer"); }, writable: true, configurable: true, @@ -273,10 +278,8 @@ }, blob: { /** @returns {Promise} */ - value: async function blob() { - webidl.assertBranded(this, prototype); - const body = await consumeBody(this); - return packageData(body, "Blob", this[mimeTypeSymbol]); + value: function blob() { + return consumeBody(this, "Blob"); }, writable: true, configurable: true, @@ -284,10 +287,8 @@ }, formData: { /** @returns {Promise} */ - value: async function formData() { - webidl.assertBranded(this, prototype); - const body = await consumeBody(this); - return packageData(body, "FormData", this[mimeTypeSymbol]); + value: function formData() { + return consumeBody(this, "FormData"); }, writable: true, configurable: true, @@ -295,10 +296,8 @@ }, json: { /** @returns {Promise} */ - value: async function json() { - webidl.assertBranded(this, prototype); - const body = await consumeBody(this); - return packageData(body, "JSON"); + value: function json() { + return consumeBody(this, "JSON"); }, writable: true, configurable: true, @@ -306,10 +305,8 @@ }, text: { /** @returns {Promise} */ - value: async function text() { - webidl.assertBranded(this, prototype); - const body = await consumeBody(this); - return packageData(body, "text"); + value: function text() { + return consumeBody(this, "text"); }, writable: true, configurable: true, diff --git a/ext/web/06_streams.js b/ext/web/06_streams.js index ba422b71dd..76e31503f7 100644 --- a/ext/web/06_streams.js +++ b/ext/web/06_streams.js @@ -6057,6 +6057,7 @@ readableStreamForRidUnrefable, readableStreamForRidUnrefableRef, readableStreamForRidUnrefableUnref, + readableStreamThrowIfErrored, getReadableStreamResourceBacking, Deferred, // Exposed in global runtime scope diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 5c15084b89..828eb079d7 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -3209,24 +3209,10 @@ "WorkerGlobalScope interface: calling fetch(RequestInfo, optional RequestInit) on self with too few arguments must throw TypeError" ], "abort": { - "general.any.html": [ - "response.arrayBuffer() rejects if already aborted", - "response.blob() rejects if already aborted", - "response.formData() rejects if already aborted", - "response.json() rejects if already aborted", - "response.text() rejects if already aborted", - "Call text() twice on aborted response" - ], - "general.any.worker.html": [ - "response.arrayBuffer() rejects if already aborted", - "response.blob() rejects if already aborted", - "response.formData() rejects if already aborted", - "response.json() rejects if already aborted", - "response.text() rejects if already aborted", - "Call text() twice on aborted response" - ], "request.any.html": true, "request.any.worker.html": true, + "general.any.html": true, + "general.any.worker.html": true, "cache.https.any.html": false, "cache.https.any.worker.html": false }