diff --git a/Libraries/LibWeb/FileAPI/Blob.cpp b/Libraries/LibWeb/FileAPI/Blob.cpp index 8d4d383419c..8a39c066dc0 100644 --- a/Libraries/LibWeb/FileAPI/Blob.cpp +++ b/Libraries/LibWeb/FileAPI/Blob.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2022-2024, Kenneth Myhra - * Copyright (c) 2023, Shannon Booth + * Copyright (c) 2023-2025, Shannon Booth * * SPDX-License-Identifier: BSD-2-Clause */ @@ -357,7 +357,7 @@ GC::Ref Blob::get_stream() // FIXME: Spec bug: https://github.com/w3c/FileAPI/issues/206 // // We need to close the stream so that the stream will finish reading. - Streams::readable_stream_close(*stream); + stream->close(); })); } } diff --git a/Tests/LibWeb/Text/expected/wpt-import/fetch/api/abort/request.any.txt b/Tests/LibWeb/Text/expected/wpt-import/fetch/api/abort/request.any.txt new file mode 100644 index 00000000000..39fdf28b736 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/fetch/api/abort/request.any.txt @@ -0,0 +1,23 @@ +Harness status: OK + +Found 18 tests + +18 Pass +Pass Calling arrayBuffer() on an aborted request +Pass Aborting a request after calling arrayBuffer() +Pass Calling arrayBuffer() on an aborted consumed empty request +Pass Calling arrayBuffer() on an aborted consumed nonempty request +Pass Calling blob() on an aborted request +Pass Aborting a request after calling blob() +Pass Calling blob() on an aborted consumed empty request +Pass Calling blob() on an aborted consumed nonempty request +Pass Calling formData() on an aborted request +Pass Aborting a request after calling formData() +Pass Calling formData() on an aborted consumed nonempty request +Pass Calling json() on an aborted request +Pass Aborting a request after calling json() +Pass Calling json() on an aborted consumed nonempty request +Pass Calling text() on an aborted request +Pass Aborting a request after calling text() +Pass Calling text() on an aborted consumed empty request +Pass Calling text() on an aborted consumed nonempty request \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/fetch/api/response/response-consume.txt b/Tests/LibWeb/Text/expected/wpt-import/fetch/api/response/response-consume.txt index 020f549fc9a..36bc8a70440 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/fetch/api/response/response-consume.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/fetch/api/response/response-consume.txt @@ -2,8 +2,8 @@ Harness status: OK Found 40 tests -28 Pass -12 Fail +33 Pass +7 Fail Pass Consume response's body: from text to text Pass Consume response's body: from text to blob Pass Consume response's body: from text to arrayBuffer @@ -13,13 +13,13 @@ Fail Consume response's body: from text with correct multipart type to formData Pass Consume response's body: from text without correct multipart type to formData (error case) Pass Consume response's body: from text with correct urlencoded type to formData Pass Consume response's body: from text without correct urlencoded type to formData (error case) -Fail Consume response's body: from blob to blob -Fail Consume response's body: from blob to text -Fail Consume response's body: from blob to arrayBuffer -Fail Consume response's body: from blob to json +Pass Consume response's body: from blob to blob +Pass Consume response's body: from blob to text +Pass Consume response's body: from blob to arrayBuffer +Pass Consume response's body: from blob to json Fail Consume response's body: from blob with correct multipart type to formData Pass Consume response's body: from blob without correct multipart type to formData (error case) -Fail Consume response's body: from blob with correct urlencoded type to formData +Pass Consume response's body: from blob with correct urlencoded type to formData Pass Consume response's body: from blob without correct urlencoded type to formData (error case) Pass Consume response's body: from FormData to formData Pass Consume response's body: from FormData without correct type to formData (error case) diff --git a/Tests/LibWeb/Text/input/wpt-import/fetch/api/abort/request.any.html b/Tests/LibWeb/Text/input/wpt-import/fetch/api/abort/request.any.html new file mode 100644 index 00000000000..62298bef85d --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/fetch/api/abort/request.any.html @@ -0,0 +1,15 @@ + + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/fetch/api/abort/request.any.js b/Tests/LibWeb/Text/input/wpt-import/fetch/api/abort/request.any.js new file mode 100644 index 00000000000..dcc7803abe5 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/fetch/api/abort/request.any.js @@ -0,0 +1,85 @@ +// META: timeout=long +// META: global=window,worker + +const BODY_FUNCTION_AND_DATA = { + arrayBuffer: null, + blob: null, + formData: new FormData(), + json: new Blob(["{}"]), + text: null, +}; + +for (const [bodyFunction, body] of Object.entries(BODY_FUNCTION_AND_DATA)) { + promise_test(async () => { + const controller = new AbortController(); + const signal = controller.signal; + const request = new Request("../resources/data.json", { + method: "post", + signal, + body, + }); + + controller.abort(); + await request[bodyFunction](); + assert_true( + true, + `An aborted request should still be able to run ${bodyFunction}()` + ); + }, `Calling ${bodyFunction}() on an aborted request`); + + promise_test(async () => { + const controller = new AbortController(); + const signal = controller.signal; + const request = new Request("../resources/data.json", { + method: "post", + signal, + body, + }); + + const p = request[bodyFunction](); + controller.abort(); + await p; + assert_true( + true, + `An aborted request should still be able to run ${bodyFunction}()` + ); + }, `Aborting a request after calling ${bodyFunction}()`); + + if (!body) { + promise_test(async () => { + const controller = new AbortController(); + const signal = controller.signal; + const request = new Request("../resources/data.json", { + method: "post", + signal, + body, + }); + + // consuming happens synchronously, so don't wait + fetch(request).catch(() => {}); + + controller.abort(); + await request[bodyFunction](); + assert_true( + true, + `An aborted consumed request should still be able to run ${bodyFunction}() when empty` + ); + }, `Calling ${bodyFunction}() on an aborted consumed empty request`); + } + + promise_test(async t => { + const controller = new AbortController(); + const signal = controller.signal; + const request = new Request("../resources/data.json", { + method: "post", + signal, + body: body || new Blob(["foo"]), + }); + + // consuming happens synchronously, so don't wait + fetch(request).catch(() => {}); + + controller.abort(); + await promise_rejects_js(t, TypeError, request[bodyFunction]()); + }, `Calling ${bodyFunction}() on an aborted consumed nonempty request`); +}