diff --git a/Userland/Libraries/LibWeb/Fetch/BodyInit.cpp b/Userland/Libraries/LibWeb/Fetch/BodyInit.cpp index 9961de3827c..2e20fd75880 100644 --- a/Userland/Libraries/LibWeb/Fetch/BodyInit.cpp +++ b/Userland/Libraries/LibWeb/Fetch/BodyInit.cpp @@ -1,17 +1,19 @@ /* * Copyright (c) 2022-2023, Linus Groh - * Copyright (c) 2022-2023, Kenneth Myhra + * Copyright (c) 2022-2024, Kenneth Myhra * * SPDX-License-Identifier: BSD-2-Clause */ #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -60,7 +62,8 @@ WebIDL::ExceptionOr extract_body(JS::Realm& realm, // 5. Assert: stream is a ReadableStream object. VERIFY(stream); - // FIXME: 6. Let action be null. + // 6. Let action be null. + Function action; // 7. Let source be null. Infrastructure::Body::SourceType source {}; @@ -131,12 +134,36 @@ WebIDL::ExceptionOr extract_body(JS::Realm& realm, return {}; })); - // FIXME: 11. If source is a byte sequence, then set action to a step that returns source and length to source’s length. + // 11. If source is a byte sequence, then set action to a step that returns source and length to source’s length. // For now, do it synchronously. - if (source.has()) + if (source.has()) { + action = [source = MUST(ByteBuffer::copy(source.get()))]() mutable { + return move(source); + }; length = source.get().size(); + } - // FIXME: 12. If action is non-null, then run these steps in parallel: + // 12. If action is non-null, then run these steps in parallel: + if (action) { + Platform::EventLoopPlugin::the().deferred_invoke([&realm, stream, action = move(action)] { + HTML::TemporaryExecutionContext execution_context { Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes }; + + // 1. Run action. + auto bytes = action(); + + // Whenever one or more bytes are available and stream is not errored, enqueue the result of creating a + // Uint8Array from the available bytes into stream. + if (!bytes.is_empty() && !stream->is_errored()) { + auto array_buffer = JS::ArrayBuffer::create(stream->realm(), move(bytes)); + auto chunk = JS::Uint8Array::create(stream->realm(), array_buffer->byte_length(), *array_buffer); + + Streams::readable_stream_enqueue(*stream->controller(), chunk).release_value_but_fixme_should_propagate_errors(); + } + + // When running action is done, close stream. + stream->close(); + }); + } // 13. Let body be a body whose stream is stream, source is source, and length is length. auto body = Infrastructure::Body::create(vm, *stream, move(source), move(length));