From 9272d185adc8b290b7cc2ad3f315c34c35131365 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Sat, 27 Jan 2024 09:16:09 -0500 Subject: [PATCH] LibWeb: Implement a slightly better ad-hoc Body::clone method Just creating a stream on the JS heap isn't enough, as we will later crash when trying to read from that stream as it hasn't been properly initialized. Instead, until we have teeing implemented (which is a rather huge part of the Streams spec), create streams using proper AOs that do initialize the stream. --- .../init-from-cloned-fetch-response.txt | 1 + .../init-from-cloned-fetch-response.html | 17 +++++++++++++++++ .../Fetch/Infrastructure/HTTP/Bodies.cpp | 18 ++++++++++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/Streams/init-from-cloned-fetch-response.txt create mode 100644 Tests/LibWeb/Text/input/Streams/init-from-cloned-fetch-response.html diff --git a/Tests/LibWeb/Text/expected/Streams/init-from-cloned-fetch-response.txt b/Tests/LibWeb/Text/expected/Streams/init-from-cloned-fetch-response.txt new file mode 100644 index 0000000000..8e5c87e46c --- /dev/null +++ b/Tests/LibWeb/Text/expected/Streams/init-from-cloned-fetch-response.txt @@ -0,0 +1 @@ +Was able to create a reader from a cloned Fetch response! diff --git a/Tests/LibWeb/Text/input/Streams/init-from-cloned-fetch-response.html b/Tests/LibWeb/Text/input/Streams/init-from-cloned-fetch-response.html new file mode 100644 index 0000000000..f61ad5fe5c --- /dev/null +++ b/Tests/LibWeb/Text/input/Streams/init-from-cloned-fetch-response.html @@ -0,0 +1,17 @@ + + diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Bodies.cpp b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Bodies.cpp index db13c8c7bd..85d4c443d7 100644 --- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Bodies.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Bodies.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include namespace Web::Fetch::Infrastructure { @@ -46,13 +48,25 @@ void Body::visit_edges(Cell::Visitor& visitor) // https://fetch.spec.whatwg.org/#concept-body-clone JS::NonnullGCPtr Body::clone(JS::Realm& realm) const { + HTML::TemporaryExecutionContext execution_context { Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes }; + // To clone a body body, run these steps: // FIXME: 1. Let « out1, out2 » be the result of teeing body’s stream. // FIXME: 2. Set body’s stream to out1. - auto out2 = realm.heap().allocate(realm, realm); + JS::GCPtr out2; + + Streams::StartAlgorithm start_algorithm = []() { return JS::js_undefined(); }; + Streams::PullAlgorithm pull_algorithm = [&realm]() { return WebIDL::create_resolved_promise(realm, JS::js_undefined()); }; + Streams::CancelAlgorithm cancel_algorithm = [&realm](auto) { return WebIDL::create_resolved_promise(realm, JS::js_undefined()); }; + + if (m_stream->controller()->has>()) { + out2 = Streams::create_readable_stream(realm, move(start_algorithm), move(pull_algorithm), move(cancel_algorithm)).release_value_but_fixme_should_propagate_errors(); + } else { + out2 = Streams::create_readable_byte_stream(realm, move(start_algorithm), move(pull_algorithm), move(cancel_algorithm)).release_value_but_fixme_should_propagate_errors(); + } // 3. Return a body whose stream is out2 and other members are copied from body. - return Body::create(realm.vm(), out2, m_source, m_length); + return Body::create(realm.vm(), *out2, m_source, m_length); } // https://fetch.spec.whatwg.org/#body-fully-read