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.
This commit is contained in:
parent
c8c3866101
commit
9272d185ad
Notes:
sideshowbarker
2024-07-17 06:51:48 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/9272d185ad Pull-request: https://github.com/SerenityOS/serenity/pull/22962 Issue: https://github.com/SerenityOS/serenity/issues/22960
3 changed files with 34 additions and 2 deletions
|
@ -0,0 +1 @@
|
|||
Was able to create a reader from a cloned Fetch response!
|
|
@ -0,0 +1,17 @@
|
|||
<script src="../include.js"></script>
|
||||
<script>
|
||||
asyncTest(async done => {
|
||||
fetch("./../basic.html", { mode: "no-cors" })
|
||||
.then(response => {
|
||||
const clonedResponse = response.clone();
|
||||
return clonedResponse.body;
|
||||
})
|
||||
.then(body => {
|
||||
const reader = body.getReader();
|
||||
reader.read();
|
||||
|
||||
println("Was able to create a reader from a cloned Fetch response!");
|
||||
done();
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -9,6 +9,8 @@
|
|||
#include <LibWeb/Fetch/BodyInit.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/Task.h>
|
||||
#include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
|
||||
#include <LibWeb/Streams/AbstractOperations.h>
|
||||
#include <LibWeb/WebIDL/Promise.h>
|
||||
|
||||
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> 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<Streams::ReadableStream>(realm, realm);
|
||||
JS::GCPtr<Streams::ReadableStream> 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<JS::NonnullGCPtr<Streams::ReadableStreamDefaultController>>()) {
|
||||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue