diff --git a/lib/web/fetch/request.js b/lib/web/fetch/request.js index 60626f06a92..d963986ce2d 100644 --- a/lib/web/fetch/request.js +++ b/lib/web/fetch/request.js @@ -38,6 +38,8 @@ const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { signal.removeEventListener('abort', abort) }) +const dependentControllerMap = new WeakMap() + function buildAbort (acRef) { return abort @@ -57,6 +59,21 @@ function buildAbort (acRef) { this.removeEventListener('abort', abort) ac.abort(this.reason) + + const controllerList = dependentControllerMap.get(ac.signal) + + if (controllerList !== undefined) { + if (controllerList.size !== 0) { + for (const ref of controllerList) { + const ctrl = ref.deref() + if (ctrl !== undefined) { + ctrl.abort(this.reason) + } + } + controllerList.clear() + } + dependentControllerMap.delete(ac.signal) + } } } } @@ -754,11 +771,16 @@ class Request { if (this.signal.aborted) { ac.abort(this.signal.reason) } else { + let list = dependentControllerMap.get(this.signal) + if (list === undefined) { + list = new Set() + dependentControllerMap.set(this.signal, list) + } + const acRef = new WeakRef(ac) + list.add(acRef) util.addAbortListener( - this.signal, - () => { - ac.abort(this.signal.reason) - } + ac.signal, + buildAbort(acRef) ) } diff --git a/test/wpt/status/fetch.status.json b/test/wpt/status/fetch.status.json index 62677d62025..b07564d9303 100644 --- a/test/wpt/status/fetch.status.json +++ b/test/wpt/status/fetch.status.json @@ -2,13 +2,11 @@ "api": { "abort": { "general.any.js": { - "note": "TODO(@KhafraDev): Clone aborts with original controller can probably be fixed", "fail": [ "Already aborted signal rejects immediately", "Underlying connection is closed when aborting after receiving response - no-cors", "Stream errors once aborted. Underlying connection closed.", - "Readable stream synchronously cancels with AbortError if aborted before reading", - "Clone aborts with original controller" + "Readable stream synchronously cancels with AbortError if aborted before reading" ] }, "cache.https.any.js": {