LibGC+Everywhere: Factor out a LibGC from LibJS

Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:

 * JS::NonnullGCPtr -> GC::Ref
 * JS::GCPtr -> GC::Ptr
 * JS::HeapFunction -> GC::Function
 * JS::CellImpl -> GC::Cell
 * JS::Handle -> GC::Root
This commit is contained in:
Shannon Booth 2024-11-15 04:01:23 +13:00 committed by Andreas Kling
parent ce23efc5f6
commit f87041bf3a
Notes: github-actions[bot] 2024-11-15 13:50:17 +00:00
1722 changed files with 9939 additions and 9906 deletions

View file

@ -38,7 +38,7 @@ bool BodyMixin::is_unusable() const
}
// https://fetch.spec.whatwg.org/#dom-body-body
JS::GCPtr<Streams::ReadableStream> BodyMixin::body() const
GC::Ptr<Streams::ReadableStream> BodyMixin::body() const
{
// The body getter steps are to return null if thiss body is null; otherwise thiss bodys stream.
auto const& body = body_impl();
@ -54,7 +54,7 @@ bool BodyMixin::body_used() const
}
// https://fetch.spec.whatwg.org/#dom-body-arraybuffer
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> BodyMixin::array_buffer() const
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> BodyMixin::array_buffer() const
{
auto& vm = Bindings::main_thread_vm();
auto& realm = *vm.current_realm();
@ -64,7 +64,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> BodyMixin::array_buffer()
}
// https://fetch.spec.whatwg.org/#dom-body-blob
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> BodyMixin::blob() const
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> BodyMixin::blob() const
{
auto& vm = Bindings::main_thread_vm();
auto& realm = *vm.current_realm();
@ -74,7 +74,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> BodyMixin::blob() const
}
// https://fetch.spec.whatwg.org/#dom-body-bytes
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> BodyMixin::bytes() const
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> BodyMixin::bytes() const
{
auto& vm = Bindings::main_thread_vm();
auto& realm = *vm.current_realm();
@ -84,7 +84,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> BodyMixin::bytes() const
}
// https://fetch.spec.whatwg.org/#dom-body-formdata
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> BodyMixin::form_data() const
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> BodyMixin::form_data() const
{
auto& vm = Bindings::main_thread_vm();
auto& realm = *vm.current_realm();
@ -94,7 +94,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> BodyMixin::form_data() co
}
// https://fetch.spec.whatwg.org/#dom-body-json
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> BodyMixin::json() const
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> BodyMixin::json() const
{
auto& vm = Bindings::main_thread_vm();
auto& realm = *vm.current_realm();
@ -104,7 +104,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> BodyMixin::json() const
}
// https://fetch.spec.whatwg.org/#dom-body-text
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> BodyMixin::text() const
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> BodyMixin::text() const
{
auto& vm = Bindings::main_thread_vm();
auto& realm = *vm.current_realm();
@ -174,7 +174,7 @@ WebIDL::ExceptionOr<JS::Value> package_data(JS::Realm& realm, ByteBuffer bytes,
}
// https://fetch.spec.whatwg.org/#concept-body-consume-body
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> consume_body(JS::Realm& realm, BodyMixin const& object, PackageDataType type)
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> consume_body(JS::Realm& realm, BodyMixin const& object, PackageDataType type)
{
// 1. If object is unusable, then return a promise rejected with a TypeError.
if (object.is_unusable()) {
@ -186,8 +186,8 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> consume_body(JS::Realm& r
auto promise = WebIDL::create_promise(realm);
// 3. Let errorSteps given error be to reject promise with error.
// NOTE: `promise` and `realm` is protected by JS::HeapFunction.
auto error_steps = JS::create_heap_function(realm.heap(), [promise, &realm](JS::Value error) {
// NOTE: `promise` and `realm` is protected by GC::HeapFunction.
auto error_steps = GC::create_function(realm.heap(), [promise, &realm](JS::Value error) {
// AD-HOC: An execution context is required for Promise's reject function.
HTML::TemporaryExecutionContext execution_context { realm };
WebIDL::reject_promise(realm, promise, error);
@ -195,9 +195,9 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> consume_body(JS::Realm& r
// 4. Let successSteps given a byte sequence data be to resolve promise with the result of running convertBytesToJSValue
// with data. If that threw an exception, then run errorSteps with that exception.
// NOTE: `promise`, `realm` and `object` is protected by JS::HeapFunction.
// NOTE: `promise`, `realm` and `object` is protected by GC::HeapFunction.
// FIXME: Refactor this to the new version of the spec introduced with https://github.com/whatwg/fetch/commit/464326e8eb6a602122c030cd40042480a3c0e265
auto success_steps = JS::create_heap_function(realm.heap(), [promise, &realm, &object, type](ByteBuffer data) {
auto success_steps = GC::create_function(realm.heap(), [promise, &realm, &object, type](ByteBuffer data) {
auto& vm = realm.vm();
// AD-HOC: An execution context is required for Promise's reject function and JSON.parse.
@ -224,7 +224,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> consume_body(JS::Realm& r
}
// 6. Otherwise, fully read objects body given successSteps, errorSteps, and objects relevant global object.
else {
body->fully_read(realm, success_steps, error_steps, JS::NonnullGCPtr { HTML::relevant_global_object(object.as_platform_object()) });
body->fully_read(realm, success_steps, error_steps, GC::Ref { HTML::relevant_global_object(object.as_platform_object()) });
}
// 7. Return promise.

View file

@ -8,8 +8,8 @@
#pragma once
#include <AK/Forward.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Forward.h>
namespace Web::Fetch {
@ -29,25 +29,25 @@ public:
virtual ~BodyMixin();
virtual Optional<MimeSniff::MimeType> mime_type_impl() const = 0;
virtual JS::GCPtr<Infrastructure::Body> body_impl() = 0;
virtual JS::GCPtr<Infrastructure::Body const> body_impl() const = 0;
virtual GC::Ptr<Infrastructure::Body> body_impl() = 0;
virtual GC::Ptr<Infrastructure::Body const> body_impl() const = 0;
virtual Bindings::PlatformObject& as_platform_object() = 0;
virtual Bindings::PlatformObject const& as_platform_object() const = 0;
[[nodiscard]] bool is_unusable() const;
[[nodiscard]] JS::GCPtr<Streams::ReadableStream> body() const;
[[nodiscard]] GC::Ptr<Streams::ReadableStream> body() const;
[[nodiscard]] bool body_used() const;
// JS API functions
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> array_buffer() const;
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> blob() const;
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> bytes() const;
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> form_data() const;
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> json() const;
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> text() const;
[[nodiscard]] WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> array_buffer() const;
[[nodiscard]] WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> blob() const;
[[nodiscard]] WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> bytes() const;
[[nodiscard]] WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> form_data() const;
[[nodiscard]] WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> json() const;
[[nodiscard]] WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> text() const;
};
[[nodiscard]] WebIDL::ExceptionOr<JS::Value> package_data(JS::Realm&, ByteBuffer, PackageDataType, Optional<MimeSniff::MimeType> const&);
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> consume_body(JS::Realm&, BodyMixin const&, PackageDataType);
[[nodiscard]] WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> consume_body(JS::Realm&, BodyMixin const&, PackageDataType);
}

View file

@ -26,7 +26,7 @@ namespace Web::Fetch {
WebIDL::ExceptionOr<Infrastructure::BodyWithType> safely_extract_body(JS::Realm& realm, BodyInitOrReadableBytes const& object)
{
// 1. If object is a ReadableStream object, then:
if (auto const* stream = object.get_pointer<JS::Handle<Streams::ReadableStream>>()) {
if (auto const* stream = object.get_pointer<GC::Root<Streams::ReadableStream>>()) {
// 1. Assert: object is neither disturbed nor locked.
VERIFY(!((*stream)->is_disturbed() || (*stream)->is_locked()));
}
@ -43,14 +43,14 @@ WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm& realm,
auto& vm = realm.vm();
// 1. Let stream be null.
JS::GCPtr<Streams::ReadableStream> stream;
GC::Ptr<Streams::ReadableStream> stream;
// 2. If object is a ReadableStream object, then set stream to object.
if (auto const* stream_handle = object.get_pointer<JS::Handle<Streams::ReadableStream>>()) {
if (auto const* stream_handle = object.get_pointer<GC::Root<Streams::ReadableStream>>()) {
stream = const_cast<Streams::ReadableStream*>(stream_handle->cell());
}
// 3. Otherwise, if object is a Blob object, set stream to the result of running objects get stream.
else if (auto const* blob_handle = object.get_pointer<JS::Handle<FileAPI::Blob>>()) {
else if (auto const* blob_handle = object.get_pointer<GC::Root<FileAPI::Blob>>()) {
stream = blob_handle->cell()->get_stream();
}
// 4. Otherwise, set stream to a new ReadableStream object, and set up stream with byte reading support.
@ -76,7 +76,7 @@ WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm& realm,
// 10. Switch on object.
TRY(object.visit(
[&](JS::Handle<FileAPI::Blob> const& blob) -> WebIDL::ExceptionOr<void> {
[&](GC::Root<FileAPI::Blob> const& blob) -> WebIDL::ExceptionOr<void> {
// Set source to object.
source = blob;
// Set length to objects size.
@ -91,12 +91,12 @@ WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm& realm,
source = MUST(ByteBuffer::copy(bytes));
return {};
},
[&](JS::Handle<WebIDL::BufferSource> const& buffer_source) -> WebIDL::ExceptionOr<void> {
[&](GC::Root<WebIDL::BufferSource> const& buffer_source) -> WebIDL::ExceptionOr<void> {
// Set source to a copy of the bytes held by object.
source = MUST(WebIDL::get_buffer_source_copy(*buffer_source->raw_object()));
return {};
},
[&](JS::Handle<XHR::FormData> const& form_data) -> WebIDL::ExceptionOr<void> {
[&](GC::Root<XHR::FormData> const& form_data) -> WebIDL::ExceptionOr<void> {
// Set action to this step: run the multipart/form-data encoding algorithm, with objects entry list and UTF-8.
auto serialized_form_data = MUST(HTML::serialize_to_multipart_form_data(form_data->entry_list()));
// Set source to object.
@ -106,7 +106,7 @@ WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm& realm,
type = MUST(ByteBuffer::copy(MUST(String::formatted("multipart/form-data; boundary={}"sv, serialized_form_data.boundary)).bytes()));
return {};
},
[&](JS::Handle<DOMURL::URLSearchParams> const& url_search_params) -> WebIDL::ExceptionOr<void> {
[&](GC::Root<DOMURL::URLSearchParams> const& url_search_params) -> WebIDL::ExceptionOr<void> {
// Set source to the result of running the application/x-www-form-urlencoded serializer with objects list.
auto search_params_string = url_search_params->to_string();
source = MUST(ByteBuffer::copy(search_params_string.bytes()));
@ -122,7 +122,7 @@ WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm& realm,
type = MUST(ByteBuffer::copy("text/plain;charset=UTF-8"sv.bytes()));
return {};
},
[&](JS::Handle<Streams::ReadableStream> const& stream) -> WebIDL::ExceptionOr<void> {
[&](GC::Root<Streams::ReadableStream> const& stream) -> WebIDL::ExceptionOr<void> {
// If keepalive is true, then throw a TypeError.
if (keepalive)
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot extract body from stream when keepalive is set"sv };
@ -145,7 +145,7 @@ WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm& realm,
// 12. If action is non-null, then run these steps in parallel:
if (action) {
Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, stream, action = move(action)] {
Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(realm.heap(), [&realm, stream, action = move(action)] {
HTML::TemporaryExecutionContext execution_context { realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
// 1. Run action.

View file

@ -14,9 +14,9 @@
namespace Web::Fetch {
// https://fetch.spec.whatwg.org/#bodyinit
using BodyInit = Variant<JS::Handle<Streams::ReadableStream>, JS::Handle<FileAPI::Blob>, JS::Handle<WebIDL::BufferSource>, JS::Handle<XHR::FormData>, JS::Handle<DOMURL::URLSearchParams>, String>;
using BodyInit = Variant<GC::Root<Streams::ReadableStream>, GC::Root<FileAPI::Blob>, GC::Root<WebIDL::BufferSource>, GC::Root<XHR::FormData>, GC::Root<DOMURL::URLSearchParams>, String>;
using BodyInitOrReadableBytes = Variant<JS::Handle<Streams::ReadableStream>, JS::Handle<FileAPI::Blob>, JS::Handle<WebIDL::BufferSource>, JS::Handle<XHR::FormData>, JS::Handle<DOMURL::URLSearchParams>, String, ReadonlyBytes>;
using BodyInitOrReadableBytes = Variant<GC::Root<Streams::ReadableStream>, GC::Root<FileAPI::Blob>, GC::Root<WebIDL::BufferSource>, GC::Root<XHR::FormData>, GC::Root<DOMURL::URLSearchParams>, String, ReadonlyBytes>;
WebIDL::ExceptionOr<Infrastructure::BodyWithType> safely_extract_body(JS::Realm&, BodyInitOrReadableBytes const&);
WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm&, BodyInitOrReadableBytes const&, bool keepalive = false);

View file

@ -25,7 +25,7 @@
namespace Web::Fetch {
// https://fetch.spec.whatwg.org/#dom-global-fetch
JS::NonnullGCPtr<WebIDL::Promise> fetch(JS::VM& vm, RequestInfo const& input, RequestInit const& init)
GC::Ref<WebIDL::Promise> fetch(JS::VM& vm, RequestInfo const& input, RequestInit const& init)
{
auto& realm = *vm.current_realm();
@ -61,7 +61,7 @@ JS::NonnullGCPtr<WebIDL::Promise> fetch(JS::VM& vm, RequestInfo const& input, Re
(void)global_object;
// 7. Let responseObject be null.
JS::GCPtr<Response> response_object;
GC::Ptr<Response> response_object;
// 8. Let relevantRealm be thiss relevant Realm.
// NOTE: This assumes that the running execution context is for the fetch() function call.
@ -73,14 +73,14 @@ JS::NonnullGCPtr<WebIDL::Promise> fetch(JS::VM& vm, RequestInfo const& input, Re
auto locally_aborted = Fetching::RefCountedFlag::create(false);
// 10. Let controller be null.
JS::GCPtr<Infrastructure::FetchController> controller;
GC::Ptr<Infrastructure::FetchController> controller;
// NOTE: Step 11 is done out of order so that the controller is non-null when we capture the GCPtr by copy in the abort algorithm lambda.
// This is not observable, AFAICT.
// 12. Set controller to the result of calling fetch given request and processResponse given response being these
// steps:
auto process_response = [locally_aborted, promise_capability, request, response_object, &relevant_realm](JS::NonnullGCPtr<Infrastructure::Response> response) mutable {
auto process_response = [locally_aborted, promise_capability, request, response_object, &relevant_realm](GC::Ref<Infrastructure::Response> response) mutable {
// 1. If locallyAborted is true, then abort these steps.
if (locally_aborted->value())
return;
@ -153,7 +153,7 @@ JS::NonnullGCPtr<WebIDL::Promise> fetch(JS::VM& vm, RequestInfo const& input, Re
}
// https://fetch.spec.whatwg.org/#abort-fetch
void abort_fetch(JS::Realm& realm, WebIDL::Promise const& promise, JS::NonnullGCPtr<Infrastructure::Request> request, JS::GCPtr<Response> response_object, JS::Value error)
void abort_fetch(JS::Realm& realm, WebIDL::Promise const& promise, GC::Ref<Infrastructure::Request> request, GC::Ptr<Response> response_object, JS::Value error)
{
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Aborting fetch with: request @ {}, error = {}", request.ptr(), error);
@ -162,7 +162,7 @@ void abort_fetch(JS::Realm& realm, WebIDL::Promise const& promise, JS::NonnullGC
WebIDL::reject_promise(realm, promise, error);
// 2. If requests body is non-null and is readable, then cancel requests body with error.
if (auto* body = request->body().get_pointer<JS::NonnullGCPtr<Infrastructure::Body>>(); body != nullptr && (*body)->stream()->is_readable()) {
if (auto* body = request->body().get_pointer<GC::Ref<Infrastructure::Body>>(); body != nullptr && (*body)->stream()->is_readable()) {
// TODO: Implement cancelling streams
(void)error;
}

View file

@ -7,14 +7,14 @@
#pragma once
#include <AK/Forward.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Fetch/Request.h>
#include <LibWeb/WebIDL/Promise.h>
namespace Web::Fetch {
JS::NonnullGCPtr<WebIDL::Promise> fetch(JS::VM&, RequestInfo const& input, RequestInit const& init = {});
void abort_fetch(JS::Realm&, WebIDL::Promise const&, JS::NonnullGCPtr<Infrastructure::Request>, JS::GCPtr<Response>, JS::Value error);
GC::Ref<WebIDL::Promise> fetch(JS::VM&, RequestInfo const& input, RequestInit const& init = {});
void abort_fetch(JS::Realm&, WebIDL::Promise const&, GC::Ref<Infrastructure::Request>, GC::Ptr<Response>, JS::Value error);
}

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Heap/HeapFunction.h>
#include <LibGC/Function.h>
#include <LibWeb/Bindings/ExceptionOrUtils.h>
#include <LibWeb/Fetch/Fetching/FetchedDataReceiver.h>
#include <LibWeb/Fetch/Infrastructure/FetchParams.h>
@ -16,9 +16,9 @@
namespace Web::Fetch::Fetching {
JS_DEFINE_ALLOCATOR(FetchedDataReceiver);
GC_DEFINE_ALLOCATOR(FetchedDataReceiver);
FetchedDataReceiver::FetchedDataReceiver(JS::NonnullGCPtr<Infrastructure::FetchParams const> fetch_params, JS::NonnullGCPtr<Streams::ReadableStream> stream)
FetchedDataReceiver::FetchedDataReceiver(GC::Ref<Infrastructure::FetchParams const> fetch_params, GC::Ref<Streams::ReadableStream> stream)
: m_fetch_params(fetch_params)
, m_stream(stream)
{
@ -34,7 +34,7 @@ void FetchedDataReceiver::visit_edges(Visitor& visitor)
visitor.visit(m_pending_promise);
}
void FetchedDataReceiver::set_pending_promise(JS::NonnullGCPtr<WebIDL::Promise> promise)
void FetchedDataReceiver::set_pending_promise(GC::Ref<WebIDL::Promise> promise)
{
auto had_pending_promise = m_pending_promise != nullptr;
m_pending_promise = promise;
@ -63,8 +63,8 @@ void FetchedDataReceiver::on_data_received(ReadonlyBytes bytes)
// 3. Queue a fetch task to run the following steps, with fetchParamss task destination.
Infrastructure::queue_fetch_task(
m_fetch_params->controller(),
m_fetch_params->task_destination().get<JS::NonnullGCPtr<JS::Object>>(),
JS::create_heap_function(heap(), [this, bytes = MUST(ByteBuffer::copy(bytes))]() mutable {
m_fetch_params->task_destination().get<GC::Ref<JS::Object>>(),
GC::create_function(heap(), [this, bytes = MUST(ByteBuffer::copy(bytes))]() mutable {
HTML::TemporaryExecutionContext execution_context { m_stream->realm(), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
// 1. Pull from bytes buffer into stream.

View file

@ -7,30 +7,30 @@
#pragma once
#include <AK/ByteBuffer.h>
#include <LibGC/CellAllocator.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/CellAllocator.h>
#include <LibWeb/Forward.h>
namespace Web::Fetch::Fetching {
class FetchedDataReceiver final : public JS::Cell {
JS_CELL(FetchedDataReceiver, JS::Cell);
JS_DECLARE_ALLOCATOR(FetchedDataReceiver);
GC_CELL(FetchedDataReceiver, JS::Cell);
GC_DECLARE_ALLOCATOR(FetchedDataReceiver);
public:
virtual ~FetchedDataReceiver() override;
void set_pending_promise(JS::NonnullGCPtr<WebIDL::Promise>);
void set_pending_promise(GC::Ref<WebIDL::Promise>);
void on_data_received(ReadonlyBytes);
private:
FetchedDataReceiver(JS::NonnullGCPtr<Infrastructure::FetchParams const>, JS::NonnullGCPtr<Streams::ReadableStream>);
FetchedDataReceiver(GC::Ref<Infrastructure::FetchParams const>, GC::Ref<Streams::ReadableStream>);
virtual void visit_edges(Visitor& visitor) override;
JS::NonnullGCPtr<Infrastructure::FetchParams const> m_fetch_params;
JS::NonnullGCPtr<Streams::ReadableStream> m_stream;
JS::GCPtr<WebIDL::Promise> m_pending_promise;
GC::Ref<Infrastructure::FetchParams const> m_fetch_params;
GC::Ref<Streams::ReadableStream> m_stream;
GC::Ptr<WebIDL::Promise> m_pending_promise;
ByteBuffer m_buffer;
};

View file

@ -73,7 +73,7 @@ bool g_http_cache_enabled;
})
// https://fetch.spec.whatwg.org/#concept-fetch
WebIDL::ExceptionOr<JS::NonnullGCPtr<Infrastructure::FetchController>> fetch(JS::Realm& realm, Infrastructure::Request& request, Infrastructure::FetchAlgorithms const& algorithms, UseParallelQueue use_parallel_queue)
WebIDL::ExceptionOr<GC::Ref<Infrastructure::FetchController>> fetch(JS::Realm& realm, Infrastructure::Request& request, Infrastructure::FetchAlgorithms const& algorithms, UseParallelQueue use_parallel_queue)
{
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'fetch' with: request @ {}", &request);
@ -83,7 +83,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Infrastructure::FetchController>> fetch(JS:
VERIFY(request.mode() == Infrastructure::Request::Mode::Navigate || !algorithms.process_early_hints_response());
// 2. Let taskDestination be null.
JS::GCPtr<JS::Object> task_destination;
GC::Ptr<JS::Object> task_destination;
// 3. Let crossOriginIsolatedCapability be false.
auto cross_origin_isolated_capability = HTML::CanUseCrossOriginIsolatedAPIs::No;
@ -147,7 +147,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Infrastructure::FetchController>> fetch(JS:
// - requests mode is "same-origin", "cors", or "no-cors"
&& (request.mode() == Infrastructure::Request::Mode::SameOrigin || request.mode() == Infrastructure::Request::Mode::CORS || request.mode() == Infrastructure::Request::Mode::NoCORS)
// - requests window is an environment settings object
&& request.window().has<JS::GCPtr<HTML::EnvironmentSettingsObject>>()
&& request.window().has<GC::Ptr<HTML::EnvironmentSettingsObject>>()
// - requests method is `GET`
&& StringView { request.method() }.equals_ignoring_ascii_case("GET"sv)
// - requests unsafe-request flag is not set or requests header list is empty
@ -157,7 +157,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Infrastructure::FetchController>> fetch(JS:
// 2. Let onPreloadedResponseAvailable be an algorithm that runs the following step given a response
// response: set fetchParamss preloaded response candidate to response.
auto on_preloaded_response_available = JS::create_heap_function(realm.heap(), [fetch_params](JS::NonnullGCPtr<Infrastructure::Response> response) {
auto on_preloaded_response_available = GC::create_function(realm.heap(), [fetch_params](GC::Ref<Infrastructure::Response> response) {
fetch_params->set_preloaded_response_candidate(response);
});
@ -265,7 +265,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Infrastructure::FetchController>> fetch(JS:
}
// https://fetch.spec.whatwg.org/#concept-main-fetch
WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, Recursive recursive)
WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, Recursive recursive)
{
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'main fetch' with: fetch_params @ {}", &fetch_params);
@ -275,7 +275,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm& realm, Inf
auto request = fetch_params.request();
// 2. Let response be null.
JS::GCPtr<Infrastructure::Response> response;
GC::Ptr<Infrastructure::Response> response;
// 3. If requests local-URLs-only flag is set and requests current URL is not local, then set response to a
// network error.
@ -333,21 +333,21 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm& realm, Inf
request->current_url().set_scheme("https"_string);
}
auto get_response = JS::create_heap_function(vm.heap(), [&realm, &vm, &fetch_params, request]() -> WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> {
auto get_response = GC::create_function(vm.heap(), [&realm, &vm, &fetch_params, request]() -> WebIDL::ExceptionOr<GC::Ref<PendingResponse>> {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'main fetch' get_response() function");
// -> fetchParamss preloaded response candidate is not null
if (!fetch_params.preloaded_response_candidate().has<Empty>()) {
// 1. Wait until fetchParamss preloaded response candidate is not "pending".
HTML::main_thread_event_loop().spin_until(JS::create_heap_function(vm.heap(), [&] {
HTML::main_thread_event_loop().spin_until(GC::create_function(vm.heap(), [&] {
return !fetch_params.preloaded_response_candidate().has<Infrastructure::FetchParams::PreloadedResponseCandidatePendingTag>();
}));
// 2. Assert: fetchParamss preloaded response candidate is a response.
VERIFY(fetch_params.preloaded_response_candidate().has<JS::NonnullGCPtr<Infrastructure::Response>>());
VERIFY(fetch_params.preloaded_response_candidate().has<GC::Ref<Infrastructure::Response>>());
// 3. Return fetchParamss preloaded response candidate.
return PendingResponse::create(vm, request, fetch_params.preloaded_response_candidate().get<JS::NonnullGCPtr<Infrastructure::Response>>());
return PendingResponse::create(vm, request, fetch_params.preloaded_response_candidate().get<GC::Ref<Infrastructure::Response>>());
}
// -> requests current URLs origin is same origin with requests origin, and requests response tainting
// is "basic"
@ -406,7 +406,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm& realm, Inf
// 2. Let corsWithPreflightResponse be the result of running HTTP fetch given fetchParams and true.
auto cors_with_preflight_response = TRY(http_fetch(realm, fetch_params, MakeCORSPreflight::Yes));
cors_with_preflight_response->when_loaded([returned_pending_response](JS::NonnullGCPtr<Infrastructure::Response> cors_with_preflight_response) {
cors_with_preflight_response->when_loaded([returned_pending_response](GC::Ref<Infrastructure::Response> cors_with_preflight_response) {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'main fetch' cors_with_preflight_response load callback");
// 3. If corsWithPreflightResponse is a network error, then clear cache entries using request.
if (cors_with_preflight_response->is_network_error()) {
@ -441,7 +441,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm& realm, Inf
}
// 11. If recursive is false, then run the remaining steps in parallel.
Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&realm, &vm, &fetch_params, request, response, get_response] {
Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(realm.heap(), [&realm, &vm, &fetch_params, request, response, get_response] {
// 12. If response is null, then set response to the result of running the steps corresponding to the first
// matching statement:
auto pending_response = PendingResponse::create(vm, request, Infrastructure::Response::create(vm));
@ -451,7 +451,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm& realm, Inf
return;
pending_response = pending_response_or_error.release_value();
}
pending_response->when_loaded([&realm, &vm, &fetch_params, request, response, response_was_null = !response](JS::NonnullGCPtr<Infrastructure::Response> resolved_response) mutable {
pending_response->when_loaded([&realm, &vm, &fetch_params, request, response, response_was_null = !response](GC::Ref<Infrastructure::Response> resolved_response) mutable {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'main fetch' pending_response load callback");
if (response_was_null)
response = resolved_response;
@ -480,7 +480,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm& realm, Inf
// 2. Set response to the following filtered response with response as its internal response, depending
// on requests response tainting:
response = [&]() -> JS::NonnullGCPtr<Infrastructure::Response> {
response = [&]() -> GC::Ref<Infrastructure::Response> {
switch (request->response_tainting()) {
// -> "basic"
case Infrastructure::Request::ResponseTainting::Basic:
@ -503,7 +503,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm& realm, Inf
// 15. Let internalResponse be response, if response is a network error, and responses internal response
// otherwise.
auto internal_response = response->is_network_error()
? JS::NonnullGCPtr { *response }
? GC::Ref { *response }
: static_cast<Infrastructure::FilteredResponse&>(*response).internal_response();
// 16. If internalResponses URL list is empty, then set it to a clone of requests URL list.
@ -557,7 +557,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm& realm, Inf
if (!request->integrity_metadata().is_empty()) {
// 1. Let processBodyError be this step: run fetch response handover given fetchParams and a network
// error.
auto process_body_error = JS::create_heap_function(vm.heap(), [&realm, &vm, &fetch_params](JS::Value) {
auto process_body_error = GC::create_function(vm.heap(), [&realm, &vm, &fetch_params](JS::Value) {
fetch_response_handover(realm, fetch_params, Infrastructure::Response::network_error(vm, "Response body could not be processed"sv));
});
@ -568,7 +568,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm& realm, Inf
}
// 3. Let processBody given bytes be these steps:
auto process_body = JS::create_heap_function(vm.heap(), [&realm, request, response, &fetch_params, process_body_error = move(process_body_error)](ByteBuffer bytes) {
auto process_body = GC::create_function(vm.heap(), [&realm, request, response, &fetch_params, process_body_error = move(process_body_error)](ByteBuffer bytes) {
// 1. If bytes do not match requests integrity metadata, then run processBodyError and abort these steps.
if (!TRY_OR_IGNORE(SRI::do_bytes_match_metadata_list(bytes, request->integrity_metadata()))) {
process_body_error->function()({});
@ -592,7 +592,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm& realm, Inf
});
}));
return JS::GCPtr<PendingResponse> {};
return GC::Ptr<PendingResponse> {};
}
// https://fetch.spec.whatwg.org/#fetch-finale
@ -677,7 +677,7 @@ void fetch_response_handover(JS::Realm& realm, Infrastructure::FetchParams const
});
// 4. Let processResponseEndOfBodyTask be the following steps:
auto process_response_end_of_body_task = JS::create_heap_function(vm.heap(), [&fetch_params, &response] {
auto process_response_end_of_body_task = GC::create_function(vm.heap(), [&fetch_params, &response] {
// 1. Set fetchParamss requests done flag.
fetch_params.request()->set_done(true);
@ -690,7 +690,7 @@ void fetch_response_handover(JS::Realm& realm, Infrastructure::FetchParams const
// object is fetchParamss task destination, then run fetchParamss controllers report timing steps
// given fetchParamss requests clients global object.
auto client = fetch_params.request()->client();
auto const* task_destination_global_object = fetch_params.task_destination().get_pointer<JS::NonnullGCPtr<JS::Object>>();
auto const* task_destination_global_object = fetch_params.task_destination().get_pointer<GC::Ref<JS::Object>>();
if (client != nullptr && task_destination_global_object != nullptr) {
if (fetch_params.request()->initiator_type().has_value() && &client->global_object() == task_destination_global_object->ptr())
fetch_params.controller()->report_timing(client->global_object());
@ -698,25 +698,25 @@ void fetch_response_handover(JS::Realm& realm, Infrastructure::FetchParams const
});
// FIXME: Handle 'parallel queue' task destination
auto task_destination = fetch_params.task_destination().get<JS::NonnullGCPtr<JS::Object>>();
auto task_destination = fetch_params.task_destination().get<GC::Ref<JS::Object>>();
// 5. Queue a fetch task to run processResponseEndOfBodyTask with fetchParamss task destination.
Infrastructure::queue_fetch_task(fetch_params.controller(), task_destination, move(process_response_end_of_body_task));
};
// FIXME: Handle 'parallel queue' task destination
auto task_destination = fetch_params.task_destination().get<JS::NonnullGCPtr<JS::Object>>();
auto task_destination = fetch_params.task_destination().get<GC::Ref<JS::Object>>();
// 4. If fetchParamss process response is non-null, then queue a fetch task to run fetchParamss process response
// given response, with fetchParamss task destination.
if (fetch_params.algorithms()->process_response()) {
Infrastructure::queue_fetch_task(fetch_params.controller(), task_destination, JS::create_heap_function(vm.heap(), [&fetch_params, &response]() {
Infrastructure::queue_fetch_task(fetch_params.controller(), task_destination, GC::create_function(vm.heap(), [&fetch_params, &response]() {
fetch_params.algorithms()->process_response()(response);
}));
}
// 5. Let internalResponse be response, if response is a network error; otherwise responses internal response.
auto internal_response = response.is_network_error() ? JS::NonnullGCPtr { response } : response.unsafe_response();
auto internal_response = response.is_network_error() ? GC::Ref { response } : response.unsafe_response();
// 6. If internalResponses body is null, then run processResponseEndOfBody.
if (!internal_response->body()) {
@ -730,14 +730,14 @@ void fetch_response_handover(JS::Realm& realm, Infrastructure::FetchParams const
auto transform_stream = realm.create<Streams::TransformStream>(realm);
// 2. Let identityTransformAlgorithm be an algorithm which, given chunk, enqueues chunk in transformStream.
auto identity_transform_algorithm = JS::create_heap_function(realm.heap(), [&realm, transform_stream](JS::Value chunk) -> JS::NonnullGCPtr<WebIDL::Promise> {
auto identity_transform_algorithm = GC::create_function(realm.heap(), [&realm, transform_stream](JS::Value chunk) -> GC::Ref<WebIDL::Promise> {
MUST(Streams::transform_stream_default_controller_enqueue(*transform_stream->controller(), chunk));
return WebIDL::create_resolved_promise(realm, JS::js_undefined());
});
// 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm and flushAlgorithm set
// to processResponseEndOfBody.
auto flush_algorithm = JS::create_heap_function(realm.heap(), [&realm, process_response_end_of_body]() -> JS::NonnullGCPtr<WebIDL::Promise> {
auto flush_algorithm = GC::create_function(realm.heap(), [&realm, process_response_end_of_body]() -> GC::Ref<WebIDL::Promise> {
process_response_end_of_body();
return WebIDL::create_resolved_promise(realm, JS::js_undefined());
});
@ -753,20 +753,20 @@ void fetch_response_handover(JS::Realm& realm, Infrastructure::FetchParams const
if (fetch_params.algorithms()->process_response_consume_body()) {
// 1. Let processBody given nullOrBytes be this step: run fetchParamss process response consume body given
// response and nullOrBytes.
auto process_body = JS::create_heap_function(vm.heap(), [&fetch_params, &response](ByteBuffer null_or_bytes) {
auto process_body = GC::create_function(vm.heap(), [&fetch_params, &response](ByteBuffer null_or_bytes) {
(fetch_params.algorithms()->process_response_consume_body())(response, null_or_bytes);
});
// 2. Let processBodyError be this step: run fetchParamss process response consume body given response and
// failure.
auto process_body_error = JS::create_heap_function(vm.heap(), [&fetch_params, &response](JS::Value) {
auto process_body_error = GC::create_function(vm.heap(), [&fetch_params, &response](JS::Value) {
(fetch_params.algorithms()->process_response_consume_body())(response, Infrastructure::FetchAlgorithms::ConsumeBodyFailureTag {});
});
// 3. If internalResponse's body is null, then queue a fetch task to run processBody given null, with
// fetchParamss task destination.
if (!internal_response->body()) {
Infrastructure::queue_fetch_task(fetch_params.controller(), task_destination, JS::create_heap_function(vm.heap(), [process_body = move(process_body)]() {
Infrastructure::queue_fetch_task(fetch_params.controller(), task_destination, GC::create_function(vm.heap(), [process_body = move(process_body)]() {
process_body->function()({});
}));
}
@ -779,7 +779,7 @@ void fetch_response_handover(JS::Realm& realm, Infrastructure::FetchParams const
}
// https://fetch.spec.whatwg.org/#concept-scheme-fetch
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> scheme_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params)
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params)
{
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'scheme fetch' with: fetch_params @ {}", &fetch_params);
@ -939,7 +939,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> scheme_fetch(JS::Realm& r
}
// https://fetch.spec.whatwg.org/#concept-http-fetch
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, MakeCORSPreflight make_cors_preflight)
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, MakeCORSPreflight make_cors_preflight)
{
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP fetch' with: fetch_params @ {}, make_cors_preflight = {}",
&fetch_params, make_cors_preflight == MakeCORSPreflight::Yes ? "Yes"sv : "No"sv);
@ -950,8 +950,8 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& rea
auto request = fetch_params.request();
// 2. Let response and internalResponse be null.
JS::GCPtr<Infrastructure::Response> response;
JS::GCPtr<Infrastructure::Response> internal_response;
GC::Ptr<Infrastructure::Response> response;
GC::Ptr<Infrastructure::Response> internal_response;
// 3. If requests service-workers mode is "all", then:
if (request->service_workers_mode() == Infrastructure::Request::ServiceWorkersMode::All) {
@ -987,7 +987,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& rea
// 3. Set internalResponse to response, if response is not a filtered response; otherwise to responses
// internal response.
internal_response = !is<Infrastructure::FilteredResponse>(*response)
? JS::NonnullGCPtr { *response }
? GC::Ref { *response }
: static_cast<Infrastructure::FilteredResponse const&>(*response).internal_response();
// 4. If one of the following is true
@ -1008,7 +1008,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& rea
}
}
JS::GCPtr<PendingResponse> pending_actual_response;
GC::Ptr<PendingResponse> pending_actual_response;
auto returned_pending_response = PendingResponse::create(vm, request);
@ -1019,7 +1019,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& rea
// CORS-preflight fetch which, if successful, populates the cache. The purpose of the CORS-preflight
// fetch is to ensure the fetched resource is familiar with the CORS protocol. The cache is there to
// minimize the number of CORS-preflight fetches.
JS::GCPtr<PendingResponse> pending_preflight_response;
GC::Ptr<PendingResponse> pending_preflight_response;
if (make_cors_preflight == MakeCORSPreflight::Yes && (
// - There is no method cache entry match for requests method using request, and either requests
// method is not a CORS-safelisted method or requests use-CORS-preflight flag is set.
@ -1035,7 +1035,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& rea
// NOTE: Step 2 is performed in pending_preflight_response's load callback below.
}
auto fetch_main_content = [request = JS::make_handle(request), realm = JS::make_handle(realm), fetch_params = JS::make_handle(fetch_params)]() -> WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> {
auto fetch_main_content = [request = GC::make_root(request), realm = GC::make_root(realm), fetch_params = GC::make_root(fetch_params)]() -> WebIDL::ExceptionOr<GC::Ref<PendingResponse>> {
// 2. If requests redirect mode is "follow", then set requests service-workers mode to "none".
// NOTE: Redirects coming from the network (as opposed to from a service worker) are not to be exposed to a
// service worker.
@ -1048,7 +1048,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& rea
if (pending_preflight_response) {
pending_actual_response = PendingResponse::create(vm, request);
pending_preflight_response->when_loaded([returned_pending_response, pending_actual_response, fetch_main_content = move(fetch_main_content)](JS::NonnullGCPtr<Infrastructure::Response> preflight_response) {
pending_preflight_response->when_loaded([returned_pending_response, pending_actual_response, fetch_main_content = move(fetch_main_content)](GC::Ref<Infrastructure::Response> preflight_response) {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP fetch' pending_preflight_response load callback");
// 2. If preflightResponse is a network error, then return preflightResponse.
@ -1058,7 +1058,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& rea
}
auto pending_main_content_response = TRY_OR_IGNORE(fetch_main_content());
pending_main_content_response->when_loaded([pending_actual_response](JS::NonnullGCPtr<Infrastructure::Response> main_content_response) {
pending_main_content_response->when_loaded([pending_actual_response](GC::Ref<Infrastructure::Response> main_content_response) {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP fetch' pending_main_content_response load callback");
pending_actual_response->resolve(main_content_response);
});
@ -1070,7 +1070,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& rea
pending_actual_response = PendingResponse::create(vm, request, Infrastructure::Response::create(vm));
}
pending_actual_response->when_loaded([&realm, &vm, &fetch_params, request, response, internal_response, returned_pending_response, response_was_null = !response](JS::NonnullGCPtr<Infrastructure::Response> resolved_actual_response) mutable {
pending_actual_response->when_loaded([&realm, &vm, &fetch_params, request, response, internal_response, returned_pending_response, response_was_null = !response](GC::Ref<Infrastructure::Response> resolved_actual_response) mutable {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP fetch' pending_actual_response load callback");
if (response_was_null) {
response = internal_response = resolved_actual_response;
@ -1102,7 +1102,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& rea
return;
}
JS::GCPtr<PendingResponse> inner_pending_response;
GC::Ptr<PendingResponse> inner_pending_response;
// 6. If internalResponses status is a redirect status:
if (Infrastructure::is_redirect_status(internal_response->status())) {
@ -1143,7 +1143,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& rea
}
if (inner_pending_response) {
inner_pending_response->when_loaded([returned_pending_response](JS::NonnullGCPtr<Infrastructure::Response> response) {
inner_pending_response->when_loaded([returned_pending_response](GC::Ref<Infrastructure::Response> response) {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP fetch' inner_pending_response load callback");
returned_pending_response->resolve(response);
});
@ -1158,7 +1158,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& rea
}
// https://fetch.spec.whatwg.org/#concept-http-redirect-fetch
WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> http_redirect_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, Infrastructure::Response& response)
WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> http_redirect_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, Infrastructure::Response& response)
{
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP-redirect fetch' with: fetch_params @ {}, response = {}", &fetch_params, &response);
@ -1170,7 +1170,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> http_redirect_fetch(JS::Realm& r
// 2. Let internalResponse be response, if response is not a filtered response; otherwise responses internal
// response.
auto internal_response = !is<Infrastructure::FilteredResponse>(response)
? JS::NonnullGCPtr { response }
? GC::Ref { response }
: static_cast<Infrastructure::FilteredResponse const&>(response).internal_response();
// 3. Let locationURL be internalResponses location URL given requests current URLs fragment.
@ -1215,7 +1215,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> http_redirect_fetch(JS::Realm& r
// return a network error.
if (internal_response->status() != 303
&& !request->body().has<Empty>()
&& request->body().get<JS::NonnullGCPtr<Infrastructure::Body>>()->source().has<Empty>()) {
&& request->body().get<GC::Ref<Infrastructure::Body>>()->source().has<Empty>()) {
return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request has body but no body source"sv));
}
@ -1257,11 +1257,11 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> http_redirect_fetch(JS::Realm& r
// requests bodys source.
// NOTE: requests bodys sources nullity has already been checked.
if (!request->body().has<Empty>()) {
auto const& source = request->body().get<JS::NonnullGCPtr<Infrastructure::Body>>()->source();
auto const& source = request->body().get<GC::Ref<Infrastructure::Body>>()->source();
// NOTE: BodyInitOrReadableBytes is a superset of Body::SourceType
auto converted_source = source.has<ByteBuffer>()
? BodyInitOrReadableBytes { source.get<ByteBuffer>() }
: BodyInitOrReadableBytes { source.get<JS::Handle<FileAPI::Blob>>() };
: BodyInitOrReadableBytes { source.get<GC::Root<FileAPI::Blob>>() };
auto [body, _] = TRY(safely_extract_body(realm, converted_source));
request->set_body(move(body));
}
@ -1305,7 +1305,7 @@ WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> http_redirect_fetch(JS::Realm& r
class CachePartition : public RefCounted<CachePartition> {
public:
// https://httpwg.org/specs/rfc9111.html#constructing.responses.from.caches
JS::GCPtr<Infrastructure::Response> select_response(URL::URL const& url, ReadonlyBytes method, Vector<Infrastructure::Header> const& headers, Vector<JS::GCPtr<Infrastructure::Response>>& initial_set_of_stored_responses) const
GC::Ptr<Infrastructure::Response> select_response(URL::URL const& url, ReadonlyBytes method, Vector<Infrastructure::Header> const& headers, Vector<GC::Ptr<Infrastructure::Response>>& initial_set_of_stored_responses) const
{
// When presented with a request, a cache MUST NOT reuse a stored response unless:
@ -1357,7 +1357,7 @@ public:
}
// https://httpwg.org/specs/rfc9111.html#freshening.responses
void freshen_stored_responses_upon_validation(Infrastructure::Response const& response, Vector<JS::GCPtr<Infrastructure::Response>>& initial_set_of_stored_responses)
void freshen_stored_responses_upon_validation(Infrastructure::Response const& response, Vector<GC::Ptr<Infrastructure::Response>>& initial_set_of_stored_responses)
{
// When a cache receives a 304 (Not Modified) response, it needs to identify stored
// responses that are suitable for updating with the new information provided, and then do so.
@ -1538,7 +1538,7 @@ private:
return true;
}
HashMap<URL::URL, JS::GCPtr<Infrastructure::Response>> m_cache;
HashMap<URL::URL, GC::Ptr<Infrastructure::Response>> m_cache;
};
class HTTPCache {
@ -1578,7 +1578,7 @@ static RefPtr<CachePartition> determine_the_http_cache_partition(Infrastructure:
}
// https://fetch.spec.whatwg.org/#concept-http-network-or-cache-fetch
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, IsAuthenticationFetch is_authentication_fetch, IsNewConnectionFetch is_new_connection_fetch)
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_network_or_cache_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, IsAuthenticationFetch is_authentication_fetch, IsNewConnectionFetch is_new_connection_fetch)
{
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP-network-or-cache fetch' with: fetch_params @ {}, is_authentication_fetch = {}, is_new_connection_fetch = {}",
&fetch_params, is_authentication_fetch == IsAuthenticationFetch::Yes ? "Yes"sv : "No"sv, is_new_connection_fetch == IsNewConnectionFetch::Yes ? "Yes"sv : "No"sv);
@ -1589,17 +1589,17 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
auto request = fetch_params.request();
// 2. Let httpFetchParams be null.
JS::GCPtr<Infrastructure::FetchParams const> http_fetch_params;
GC::Ptr<Infrastructure::FetchParams const> http_fetch_params;
// 3. Let httpRequest be null.
JS::GCPtr<Infrastructure::Request> http_request;
GC::Ptr<Infrastructure::Request> http_request;
// 4. Let response be null.
JS::GCPtr<Infrastructure::Response> response;
GC::Ptr<Infrastructure::Response> response;
// 5. Let storedResponse be null.
JS::GCPtr<Infrastructure::Response> stored_response;
Vector<JS::GCPtr<Infrastructure::Response>> initial_set_of_stored_responses;
GC::Ptr<Infrastructure::Response> stored_response;
Vector<GC::Ptr<Infrastructure::Response>> initial_set_of_stored_responses;
// 6. Let httpCache be null.
// (Typeless until we actually implement it, needed for checks below)
@ -1666,8 +1666,8 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
include_credentials = IncludeCredentials::No;
// 5. Let contentLength be httpRequests bodys length, if httpRequests body is non-null; otherwise null.
auto content_length = http_request->body().has<JS::NonnullGCPtr<Infrastructure::Body>>()
? http_request->body().get<JS::NonnullGCPtr<Infrastructure::Body>>()->length()
auto content_length = http_request->body().has<GC::Ref<Infrastructure::Body>>()
? http_request->body().get<GC::Ref<Infrastructure::Body>>()->length()
: Optional<u64> {};
// 6. Let contentLengthHeaderValue be null.
@ -1702,7 +1702,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
auto& group = http_request->client()->fetch_group();
// 3. Let inflightRecords be the set of fetch records in group whose requests keepalive is true and done flag is unset.
Vector<JS::NonnullGCPtr<Infrastructure::FetchRecord>> in_flight_records;
Vector<GC::Ref<Infrastructure::FetchRecord>> in_flight_records;
for (auto const& fetch_record : group) {
if (fetch_record->request()->keepalive() && !fetch_record->request()->done())
in_flight_records.append(fetch_record);
@ -1717,7 +1717,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
inflight_keep_alive_bytes += in_flight_request->body().visit(
[](Empty) -> u64 { return 0; },
[](ByteBuffer const& buffer) -> u64 { return buffer.size(); },
[](JS::NonnullGCPtr<Infrastructure::Body> body) -> u64 {
[](GC::Ref<Infrastructure::Body> body) -> u64 {
return body->length().has_value() ? body->length().value() : 0;
});
}
@ -1921,7 +1921,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
revalidate_request->set_service_workers_mode(Infrastructure::Request::ServiceWorkersMode::None);
// 7. In parallel, run main fetch given a new fetch params whose request is revalidateRequest.
Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(realm.heap(), [&vm, &realm, revalidate_request, fetch_params = JS::NonnullGCPtr(fetch_params)] {
Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(realm.heap(), [&vm, &realm, revalidate_request, fetch_params = GC::Ref(fetch_params)] {
(void)main_fetch(realm, Infrastructure::FetchParams::create(vm, revalidate_request, fetch_params->timing_info()));
}));
}
@ -1960,7 +1960,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
if (aborted)
return PendingResponse::create(vm, request, Infrastructure::Response::appropriate_network_error(vm, fetch_params));
JS::GCPtr<PendingResponse> pending_forward_response;
GC::Ptr<PendingResponse> pending_forward_response;
// 10. If response is null, then:
if (!response) {
@ -1977,7 +1977,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
auto returned_pending_response = PendingResponse::create(vm, request);
pending_forward_response->when_loaded([&realm, &vm, &fetch_params, request, response, stored_response, initial_set_of_stored_responses, http_request, returned_pending_response, is_authentication_fetch, is_new_connection_fetch, revalidating_flag, include_credentials, response_was_null = !response, http_cache](JS::NonnullGCPtr<Infrastructure::Response> resolved_forward_response) mutable {
pending_forward_response->when_loaded([&realm, &vm, &fetch_params, request, response, stored_response, initial_set_of_stored_responses, http_request, returned_pending_response, is_authentication_fetch, is_new_connection_fetch, revalidating_flag, include_credentials, response_was_null = !response, http_cache](GC::Ref<Infrastructure::Response> resolved_forward_response) mutable {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP-network-or-cache fetch' pending_forward_response load callback");
if (response_was_null) {
auto forward_response = resolved_forward_response;
@ -2040,7 +2040,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
if (response->status() == 401
&& http_request->response_tainting() != Infrastructure::Request::ResponseTainting::CORS
&& include_credentials == IncludeCredentials::Yes
&& request->window().has<JS::GCPtr<HTML::EnvironmentSettingsObject>>()
&& request->window().has<GC::Ptr<HTML::EnvironmentSettingsObject>>()
// AD-HOC: Require at least one WWW-Authenticate header to be set before automatically retrying an authenticated
// request (see rule 1 below). See: https://github.com/whatwg/fetch/issues/1766
&& request->header_list()->contains("WWW-Authenticate"sv.bytes())) {
@ -2050,17 +2050,17 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
// 2. If requests body is non-null, then:
if (!request->body().has<Empty>()) {
// 1. If requests bodys source is null, then return a network error.
if (request->body().get<JS::NonnullGCPtr<Infrastructure::Body>>()->source().has<Empty>()) {
if (request->body().get<GC::Ref<Infrastructure::Body>>()->source().has<Empty>()) {
returned_pending_response->resolve(Infrastructure::Response::network_error(vm, "Request has body but no body source"_string));
return;
}
// 2. Set requests body to the body of the result of safely extracting requests bodys source.
auto const& source = request->body().get<JS::NonnullGCPtr<Infrastructure::Body>>()->source();
auto const& source = request->body().get<GC::Ref<Infrastructure::Body>>()->source();
// NOTE: BodyInitOrReadableBytes is a superset of Body::SourceType
auto converted_source = source.has<ByteBuffer>()
? BodyInitOrReadableBytes { source.get<ByteBuffer>() }
: BodyInitOrReadableBytes { source.get<JS::Handle<FileAPI::Blob>>() };
: BodyInitOrReadableBytes { source.get<GC::Root<FileAPI::Blob>>() };
auto [body, _] = TRY_OR_IGNORE(safely_extract_body(realm, converted_source));
request->set_body(move(body));
}
@ -2090,7 +2090,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
inner_pending_response = TRY_OR_IGNORE(http_network_or_cache_fetch(realm, fetch_params, IsAuthenticationFetch::Yes));
}
inner_pending_response->when_loaded([&realm, &vm, &fetch_params, request, returned_pending_response, is_authentication_fetch, is_new_connection_fetch](JS::NonnullGCPtr<Infrastructure::Response> response) {
inner_pending_response->when_loaded([&realm, &vm, &fetch_params, request, returned_pending_response, is_authentication_fetch, is_new_connection_fetch](GC::Ref<Infrastructure::Response> response) {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'HTTP network-or-cache fetch' inner_pending_response load callback");
// 15. If responses status is 407, then:
if (response->status() == 407) {
@ -2127,7 +2127,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
// - isNewConnectionFetch is false
&& is_new_connection_fetch == IsNewConnectionFetch::No
// - requests body is null, or requests body is non-null and requests bodys source is non-null
&& (request->body().has<Empty>() || !request->body().get<JS::NonnullGCPtr<Infrastructure::Body>>()->source().has<Empty>())
&& (request->body().has<Empty>() || !request->body().get<GC::Ref<Infrastructure::Body>>()->source().has<Empty>())
// then:
) {
// 1. If fetchParams is canceled, then return the appropriate network error for fetchParams.
@ -2140,7 +2140,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
inner_pending_response = TRY_OR_IGNORE(http_network_or_cache_fetch(realm, fetch_params, is_authentication_fetch, IsNewConnectionFetch::Yes));
}
inner_pending_response->when_loaded([returned_pending_response, is_authentication_fetch](JS::NonnullGCPtr<Infrastructure::Response> response) {
inner_pending_response->when_loaded([returned_pending_response, is_authentication_fetch](GC::Ref<Infrastructure::Response> response) {
// 17. If isAuthenticationFetch is true, then create an authentication entry for request and the given
// realm.
if (is_authentication_fetch == IsAuthenticationFetch::Yes) {
@ -2183,7 +2183,7 @@ static void log_response(auto const& status_code, auto const& headers, auto cons
// https://fetch.spec.whatwg.org/#concept-http-network-fetch
// Drop-in replacement for 'HTTP-network fetch', but obviously non-standard :^)
// It also handles file:// URLs since those can also go through ResourceLoader.
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_loader_file_or_http_network_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, IncludeCredentials include_credentials, IsNewConnectionFetch is_new_connection_fetch)
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> nonstandard_resource_loader_file_or_http_network_fetch(JS::Realm& realm, Infrastructure::FetchParams const& fetch_params, IncludeCredentials include_credentials, IsNewConnectionFetch is_new_connection_fetch)
{
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'non-standard HTTP-network fetch' with: fetch_params @ {}", &fetch_params);
@ -2206,13 +2206,13 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
for (auto const& header : *request->header_list())
load_request.set_header(ByteString::copy(header.name), ByteString::copy(header.value));
if (auto const* body = request->body().get_pointer<JS::NonnullGCPtr<Infrastructure::Body>>()) {
if (auto const* body = request->body().get_pointer<GC::Ref<Infrastructure::Body>>()) {
TRY((*body)->source().visit(
[&](ByteBuffer const& byte_buffer) -> WebIDL::ExceptionOr<void> {
load_request.set_body(TRY_OR_THROW_OOM(vm, ByteBuffer::copy(byte_buffer)));
return {};
},
[&](JS::Handle<FileAPI::Blob> const& blob_handle) -> WebIDL::ExceptionOr<void> {
[&](GC::Root<FileAPI::Blob> const& blob_handle) -> WebIDL::ExceptionOr<void> {
load_request.set_body(TRY_OR_THROW_OOM(vm, ByteBuffer::copy(blob_handle->raw_bytes())));
return {};
},
@ -2240,7 +2240,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
auto fetched_data_receiver = realm.create<FetchedDataReceiver>(fetch_params, stream);
// 10. Let pullAlgorithm be the followings steps:
auto pull_algorithm = JS::create_heap_function(realm.heap(), [&realm, fetched_data_receiver]() {
auto pull_algorithm = GC::create_function(realm.heap(), [&realm, fetched_data_receiver]() {
// 1. Let promise be a new promise.
auto promise = WebIDL::create_promise(realm);
@ -2253,7 +2253,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
});
// 11. Let cancelAlgorithm be an algorithm that aborts fetchParamss controller with reason, given reason.
auto cancel_algorithm = JS::create_heap_function(realm.heap(), [&realm, &fetch_params](JS::Value reason) {
auto cancel_algorithm = GC::create_function(realm.heap(), [&realm, &fetch_params](JS::Value reason) {
fetch_params.controller()->abort(realm, reason);
return WebIDL::create_resolved_promise(realm, JS::js_undefined());
});
@ -2261,7 +2261,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
// 13. Set up stream with byte reading support with pullAlgorithm set to pullAlgorithm, cancelAlgorithm set to cancelAlgorithm.
Streams::set_up_readable_stream_controller_with_byte_reading_support(stream, pull_algorithm, cancel_algorithm);
auto on_headers_received = JS::create_heap_function(vm.heap(), [&vm, request, pending_response, stream](HTTP::HeaderMap const& response_headers, Optional<u32> status_code, Optional<String> const& reason_phrase) {
auto on_headers_received = GC::create_function(vm.heap(), [&vm, request, pending_response, stream](HTTP::HeaderMap const& response_headers, Optional<u32> status_code, Optional<String> const& reason_phrase) {
(void)request;
if (pending_response->is_resolved()) {
// RequestServer will send us the response headers twice, the second time being for HTTP trailers. This
@ -2298,7 +2298,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
// 16. Run these steps in parallel:
// FIXME: 1. Run these steps, but abort when fetchParams is canceled:
auto on_data_received = JS::create_heap_function(vm.heap(), [fetched_data_receiver](ReadonlyBytes bytes) {
auto on_data_received = GC::create_function(vm.heap(), [fetched_data_receiver](ReadonlyBytes bytes) {
// 1. If one or more bytes have been transmitted from responses message body, then:
if (!bytes.is_empty()) {
// 1. Let bytes be the transmitted bytes.
@ -2317,7 +2317,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
}
});
auto on_complete = JS::create_heap_function(vm.heap(), [&vm, &realm, pending_response, stream](bool success, Optional<StringView> error_message) {
auto on_complete = GC::create_function(vm.heap(), [&vm, &realm, pending_response, stream](bool success, Optional<StringView> error_message) {
HTML::TemporaryExecutionContext execution_context { realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
// 16.1.1.2. Otherwise, if the bytes transmission for responses message body is done normally and stream is readable,
@ -2340,7 +2340,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
ResourceLoader::the().load_unbuffered(load_request, on_headers_received, on_data_received, on_complete);
} else {
auto on_load_success = JS::create_heap_function(vm.heap(), [&realm, &vm, request, pending_response](ReadonlyBytes data, HTTP::HeaderMap const& response_headers, Optional<u32> status_code, Optional<String> const& reason_phrase) {
auto on_load_success = GC::create_function(vm.heap(), [&realm, &vm, request, pending_response](ReadonlyBytes data, HTTP::HeaderMap const& response_headers, Optional<u32> status_code, Optional<String> const& reason_phrase) {
(void)request;
dbgln_if(WEB_FETCH_DEBUG, "Fetch: ResourceLoader load for '{}' complete", request->url());
if constexpr (WEB_FETCH_DEBUG)
@ -2360,7 +2360,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
pending_response->resolve(response);
});
auto on_load_error = JS::create_heap_function(vm.heap(), [&realm, &vm, request, pending_response](ByteString const& error, Optional<u32> status_code, Optional<String> const& reason_phrase, ReadonlyBytes data, HTTP::HeaderMap const& response_headers) {
auto on_load_error = GC::create_function(vm.heap(), [&realm, &vm, request, pending_response](ByteString const& error, Optional<u32> status_code, Optional<String> const& reason_phrase, ReadonlyBytes data, HTTP::HeaderMap const& response_headers) {
(void)request;
dbgln_if(WEB_FETCH_DEBUG, "Fetch: ResourceLoader load for '{}' failed: {} (status {})", request->url(), error, status_code.value_or(0));
if constexpr (WEB_FETCH_DEBUG)
@ -2392,7 +2392,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
}
// https://fetch.spec.whatwg.org/#cors-preflight-fetch-0
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> cors_preflight_fetch(JS::Realm& realm, Infrastructure::Request& request)
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> cors_preflight_fetch(JS::Realm& realm, Infrastructure::Request& request)
{
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'CORS-preflight fetch' with request @ {}", &request);
@ -2455,7 +2455,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> cors_preflight_fetch(JS::
auto preflight_response = TRY(http_network_or_cache_fetch(realm, fetch_params));
preflight_response->when_loaded([&vm, &request, returned_pending_response](JS::NonnullGCPtr<Infrastructure::Response> response) {
preflight_response->when_loaded([&vm, &request, returned_pending_response](GC::Ref<Infrastructure::Response> response) {
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'CORS-preflight fetch' preflight_response load callback");
// 7. If a CORS check for request and response returns success and responses status is an ok status, then:

View file

@ -8,8 +8,8 @@
#pragma once
#include <AK/Forward.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Forward.h>
namespace Web::Fetch::Fetching {
@ -38,15 +38,15 @@ constexpr auto keepalive_maximum_size = 64 * KiB;
ENUMERATE_BOOL_PARAMS
#undef __ENUMERATE_BOOL_PARAM
WebIDL::ExceptionOr<JS::NonnullGCPtr<Infrastructure::FetchController>> fetch(JS::Realm&, Infrastructure::Request&, Infrastructure::FetchAlgorithms const&, UseParallelQueue use_parallel_queue = UseParallelQueue::No);
WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm&, Infrastructure::FetchParams const&, Recursive recursive = Recursive::No);
WebIDL::ExceptionOr<GC::Ref<Infrastructure::FetchController>> fetch(JS::Realm&, Infrastructure::Request&, Infrastructure::FetchAlgorithms const&, UseParallelQueue use_parallel_queue = UseParallelQueue::No);
WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm&, Infrastructure::FetchParams const&, Recursive recursive = Recursive::No);
void fetch_response_handover(JS::Realm&, Infrastructure::FetchParams const&, Infrastructure::Response&);
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> scheme_fetch(JS::Realm&, Infrastructure::FetchParams const&);
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm&, Infrastructure::FetchParams const&, MakeCORSPreflight make_cors_preflight = MakeCORSPreflight::No);
WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> http_redirect_fetch(JS::Realm&, Infrastructure::FetchParams const&, Infrastructure::Response&);
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fetch(JS::Realm&, Infrastructure::FetchParams const&, IsAuthenticationFetch is_authentication_fetch = IsAuthenticationFetch::No, IsNewConnectionFetch is_new_connection_fetch = IsNewConnectionFetch::No);
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_loader_file_or_http_network_fetch(JS::Realm&, Infrastructure::FetchParams const&, IncludeCredentials include_credentials = IncludeCredentials::No, IsNewConnectionFetch is_new_connection_fetch = IsNewConnectionFetch::No);
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> cors_preflight_fetch(JS::Realm&, Infrastructure::Request&);
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm&, Infrastructure::FetchParams const&);
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_fetch(JS::Realm&, Infrastructure::FetchParams const&, MakeCORSPreflight make_cors_preflight = MakeCORSPreflight::No);
WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> http_redirect_fetch(JS::Realm&, Infrastructure::FetchParams const&, Infrastructure::Response&);
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_network_or_cache_fetch(JS::Realm&, Infrastructure::FetchParams const&, IsAuthenticationFetch is_authentication_fetch = IsAuthenticationFetch::No, IsNewConnectionFetch is_new_connection_fetch = IsNewConnectionFetch::No);
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> nonstandard_resource_loader_file_or_http_network_fetch(JS::Realm&, Infrastructure::FetchParams const&, IncludeCredentials include_credentials = IncludeCredentials::No, IsNewConnectionFetch is_new_connection_fetch = IsNewConnectionFetch::No);
WebIDL::ExceptionOr<GC::Ref<PendingResponse>> cors_preflight_fetch(JS::Realm&, Infrastructure::Request&);
void set_sec_fetch_dest_header(Infrastructure::Request&);
void set_sec_fetch_mode_header(Infrastructure::Request&);
void set_sec_fetch_site_header(Infrastructure::Request&);

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Heap/Heap.h>
#include <LibGC/Heap.h>
#include <LibJS/Runtime/VM.h>
#include <LibWeb/Fetch/Fetching/PendingResponse.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h>
@ -12,19 +12,19 @@
namespace Web::Fetch::Fetching {
JS_DEFINE_ALLOCATOR(PendingResponse);
GC_DEFINE_ALLOCATOR(PendingResponse);
JS::NonnullGCPtr<PendingResponse> PendingResponse::create(JS::VM& vm, JS::NonnullGCPtr<Infrastructure::Request> request)
GC::Ref<PendingResponse> PendingResponse::create(JS::VM& vm, GC::Ref<Infrastructure::Request> request)
{
return vm.heap().allocate<PendingResponse>(request);
}
JS::NonnullGCPtr<PendingResponse> PendingResponse::create(JS::VM& vm, JS::NonnullGCPtr<Infrastructure::Request> request, JS::NonnullGCPtr<Infrastructure::Response> response)
GC::Ref<PendingResponse> PendingResponse::create(JS::VM& vm, GC::Ref<Infrastructure::Request> request, GC::Ref<Infrastructure::Response> response)
{
return vm.heap().allocate<PendingResponse>(request, response);
}
PendingResponse::PendingResponse(JS::NonnullGCPtr<Infrastructure::Request> request, JS::GCPtr<Infrastructure::Response> response)
PendingResponse::PendingResponse(GC::Ref<Infrastructure::Request> request, GC::Ptr<Infrastructure::Response> response)
: m_request(request)
, m_response(response)
{
@ -42,12 +42,12 @@ void PendingResponse::visit_edges(JS::Cell::Visitor& visitor)
void PendingResponse::when_loaded(Callback callback)
{
VERIFY(!m_callback);
m_callback = JS::create_heap_function(heap(), move(callback));
m_callback = GC::create_function(heap(), move(callback));
if (m_response)
run_callback();
}
void PendingResponse::resolve(JS::NonnullGCPtr<Infrastructure::Response> response)
void PendingResponse::resolve(GC::Ref<Infrastructure::Response> response)
{
VERIFY(!m_response);
m_response = response;
@ -59,7 +59,7 @@ void PendingResponse::run_callback()
{
VERIFY(m_callback);
VERIFY(m_response);
Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(heap(), [this] {
Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(heap(), [this] {
VERIFY(m_callback);
VERIFY(m_response);
m_callback->function()(*m_response);

View file

@ -6,9 +6,9 @@
#pragma once
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h>
namespace Web::Fetch::Fetching {
@ -18,29 +18,29 @@ namespace Web::Fetch::Fetching {
// of the Fetch spec - we run 'in parallel' as a deferred_invoke(), which is still on the main thread;
// therefore we use callbacks to run portions of the spec that require waiting for an HTTP load.
class PendingResponse : public JS::Cell {
JS_CELL(PendingResponse, JS::Cell);
JS_DECLARE_ALLOCATOR(PendingResponse);
GC_CELL(PendingResponse, JS::Cell);
GC_DECLARE_ALLOCATOR(PendingResponse);
public:
using Callback = Function<void(JS::NonnullGCPtr<Infrastructure::Response>)>;
using Callback = Function<void(GC::Ref<Infrastructure::Response>)>;
[[nodiscard]] static JS::NonnullGCPtr<PendingResponse> create(JS::VM&, JS::NonnullGCPtr<Infrastructure::Request>);
[[nodiscard]] static JS::NonnullGCPtr<PendingResponse> create(JS::VM&, JS::NonnullGCPtr<Infrastructure::Request>, JS::NonnullGCPtr<Infrastructure::Response>);
[[nodiscard]] static GC::Ref<PendingResponse> create(JS::VM&, GC::Ref<Infrastructure::Request>);
[[nodiscard]] static GC::Ref<PendingResponse> create(JS::VM&, GC::Ref<Infrastructure::Request>, GC::Ref<Infrastructure::Response>);
void when_loaded(Callback);
void resolve(JS::NonnullGCPtr<Infrastructure::Response>);
void resolve(GC::Ref<Infrastructure::Response>);
bool is_resolved() const { return m_response != nullptr; }
private:
PendingResponse(JS::NonnullGCPtr<Infrastructure::Request>, JS::GCPtr<Infrastructure::Response> = {});
PendingResponse(GC::Ref<Infrastructure::Request>, GC::Ptr<Infrastructure::Response> = {});
virtual void visit_edges(JS::Cell::Visitor&) override;
void run_callback();
JS::GCPtr<JS::HeapFunction<void(JS::NonnullGCPtr<Infrastructure::Response>)>> m_callback;
JS::NonnullGCPtr<Infrastructure::Request> m_request;
JS::GCPtr<Infrastructure::Response> m_response;
GC::Ptr<GC::Function<void(GC::Ref<Infrastructure::Response>)>> m_callback;
GC::Ref<Infrastructure::Request> m_request;
GC::Ptr<Infrastructure::Response> m_response;
};
}

View file

@ -12,10 +12,10 @@
namespace Web::Fetch {
JS_DEFINE_ALLOCATOR(Headers);
GC_DEFINE_ALLOCATOR(Headers);
// https://fetch.spec.whatwg.org/#dom-headers
WebIDL::ExceptionOr<JS::NonnullGCPtr<Headers>> Headers::construct_impl(JS::Realm& realm, Optional<HeadersInit> const& init)
WebIDL::ExceptionOr<GC::Ref<Headers>> Headers::construct_impl(JS::Realm& realm, Optional<HeadersInit> const& init)
{
auto& vm = realm.vm();
@ -32,7 +32,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Headers>> Headers::construct_impl(JS::Realm
return headers;
}
Headers::Headers(JS::Realm& realm, JS::NonnullGCPtr<Infrastructure::HeaderList> header_list)
Headers::Headers(JS::Realm& realm, GC::Ref<Infrastructure::HeaderList> header_list)
: PlatformObject(realm)
, m_header_list(header_list)
{

View file

@ -10,8 +10,8 @@
#include <AK/String.h>
#include <AK/Variant.h>
#include <AK/Vector.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
@ -23,7 +23,7 @@ using HeadersInit = Variant<Vector<Vector<String>>, OrderedHashMap<String, Strin
// https://fetch.spec.whatwg.org/#headers-class
class Headers final : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(Headers, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(Headers);
GC_DECLARE_ALLOCATOR(Headers);
public:
enum class Guard {
@ -34,12 +34,12 @@ public:
None,
};
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Headers>> construct_impl(JS::Realm& realm, Optional<HeadersInit> const& init);
static WebIDL::ExceptionOr<GC::Ref<Headers>> construct_impl(JS::Realm& realm, Optional<HeadersInit> const& init);
virtual ~Headers() override;
[[nodiscard]] JS::NonnullGCPtr<Infrastructure::HeaderList> header_list() const { return m_header_list; }
void set_header_list(JS::NonnullGCPtr<Infrastructure::HeaderList> header_list) { m_header_list = header_list; }
[[nodiscard]] GC::Ref<Infrastructure::HeaderList> header_list() const { return m_header_list; }
void set_header_list(GC::Ref<Infrastructure::HeaderList> header_list) { m_header_list = header_list; }
[[nodiscard]] Guard guard() const { return m_guard; }
void set_guard(Guard guard) { m_guard = guard; }
@ -61,7 +61,7 @@ public:
private:
friend class HeadersIterator;
Headers(JS::Realm&, JS::NonnullGCPtr<Infrastructure::HeaderList>);
Headers(JS::Realm&, GC::Ref<Infrastructure::HeaderList>);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(JS::Cell::Visitor&) override;
@ -71,7 +71,7 @@ private:
// https://fetch.spec.whatwg.org/#concept-headers-header-list
// A Headers object has an associated header list (a header list), which is initially empty.
JS::NonnullGCPtr<Infrastructure::HeaderList> m_header_list;
GC::Ref<Infrastructure::HeaderList> m_header_list;
// https://fetch.spec.whatwg.org/#concept-headers-guard
// A Headers object also has an associated guard, which is a headers guard. A headers guard is "immutable", "request", "request-no-cors", "response" or "none".

View file

@ -23,9 +23,9 @@ void Intrinsics::create_web_prototype_and_constructor<HeadersIteratorPrototype>(
namespace Web::Fetch {
JS_DEFINE_ALLOCATOR(HeadersIterator);
GC_DEFINE_ALLOCATOR(HeadersIterator);
JS::NonnullGCPtr<HeadersIterator> HeadersIterator::create(Headers const& headers, JS::Object::PropertyKind iteration_kind)
GC::Ref<HeadersIterator> HeadersIterator::create(Headers const& headers, JS::Object::PropertyKind iteration_kind)
{
return headers.realm().create<HeadersIterator>(headers, iteration_kind);
}
@ -52,7 +52,7 @@ void HeadersIterator::visit_edges(JS::Cell::Visitor& visitor)
}
// https://webidl.spec.whatwg.org/#es-iterable, Step 2
JS::NonnullGCPtr<JS::Object> HeadersIterator::next()
GC::Ref<JS::Object> HeadersIterator::next()
{
// The value pairs to iterate over are the return value of running sort and combine with thiss header list.
auto value_pairs_to_iterate_over = [&]() {

View file

@ -6,7 +6,7 @@
#pragma once
#include <LibJS/Heap/GCPtr.h>
#include <LibGC/Ptr.h>
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/Fetch/Headers.h>
@ -14,14 +14,14 @@ namespace Web::Fetch {
class HeadersIterator final : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(HeadersIterator, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(HeadersIterator);
GC_DECLARE_ALLOCATOR(HeadersIterator);
public:
[[nodiscard]] static JS::NonnullGCPtr<HeadersIterator> create(Headers const&, JS::Object::PropertyKind iteration_kind);
[[nodiscard]] static GC::Ref<HeadersIterator> create(Headers const&, JS::Object::PropertyKind iteration_kind);
virtual ~HeadersIterator() override;
JS::NonnullGCPtr<JS::Object> next();
GC::Ref<JS::Object> next();
private:
virtual void initialize(JS::Realm&) override;
@ -29,7 +29,7 @@ private:
HeadersIterator(Headers const&, JS::Object::PropertyKind iteration_kind);
JS::NonnullGCPtr<Headers const> m_headers;
GC::Ref<Headers const> m_headers;
JS::Object::PropertyKind m_iteration_kind;
size_t m_index { 0 };
};

View file

@ -4,17 +4,17 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Heap/Heap.h>
#include <LibGC/Heap.h>
#include <LibJS/Runtime/VM.h>
#include <LibWeb/Fetch/Infrastructure/ConnectionTimingInfo.h>
namespace Web::Fetch::Infrastructure {
JS_DEFINE_ALLOCATOR(ConnectionTimingInfo);
GC_DEFINE_ALLOCATOR(ConnectionTimingInfo);
ConnectionTimingInfo::ConnectionTimingInfo() = default;
JS::NonnullGCPtr<ConnectionTimingInfo> ConnectionTimingInfo::create(JS::VM& vm)
GC::Ref<ConnectionTimingInfo> ConnectionTimingInfo::create(JS::VM& vm)
{
return vm.heap().allocate<ConnectionTimingInfo>();
}

View file

@ -7,19 +7,19 @@
#pragma once
#include <AK/ByteBuffer.h>
#include <LibGC/Ptr.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/HighResolutionTime/DOMHighResTimeStamp.h>
namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#connection-timing-info
class ConnectionTimingInfo : public JS::Cell {
JS_CELL(ConnectionTimingInfo, JS::Cell);
JS_DECLARE_ALLOCATOR(ConnectionTimingInfo);
GC_CELL(ConnectionTimingInfo, JS::Cell);
GC_DECLARE_ALLOCATOR(ConnectionTimingInfo);
public:
[[nodiscard]] static JS::NonnullGCPtr<ConnectionTimingInfo> create(JS::VM&);
[[nodiscard]] static GC::Ref<ConnectionTimingInfo> create(JS::VM&);
[[nodiscard]] HighResolutionTime::DOMHighResTimeStamp domain_lookup_start_time() const { return m_domain_lookup_start_time; }
void set_domain_lookup_start_time(HighResolutionTime::DOMHighResTimeStamp domain_lookup_start_time) { m_domain_lookup_start_time = domain_lookup_start_time; }

View file

@ -4,22 +4,22 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Heap/Heap.h>
#include <LibGC/Heap.h>
#include <LibJS/Runtime/VM.h>
#include <LibWeb/Fetch/Infrastructure/FetchAlgorithms.h>
namespace Web::Fetch::Infrastructure {
JS_DEFINE_ALLOCATOR(FetchAlgorithms);
GC_DEFINE_ALLOCATOR(FetchAlgorithms);
JS::NonnullGCPtr<FetchAlgorithms> FetchAlgorithms::create(JS::VM& vm, Input input)
GC::Ref<FetchAlgorithms> FetchAlgorithms::create(JS::VM& vm, Input input)
{
auto process_request_body_chunk_length = JS::create_heap_function(vm.heap(), move(input.process_request_body_chunk_length));
auto process_request_end_of_body = JS::create_heap_function(vm.heap(), move(input.process_request_end_of_body));
auto process_early_hints_response = JS::create_heap_function(vm.heap(), move(input.process_early_hints_response));
auto process_response = JS::create_heap_function(vm.heap(), move(input.process_response));
auto process_response_end_of_body = JS::create_heap_function(vm.heap(), move(input.process_response_end_of_body));
auto process_response_consume_body = JS::create_heap_function(vm.heap(), move(input.process_response_consume_body));
auto process_request_body_chunk_length = GC::create_function(vm.heap(), move(input.process_request_body_chunk_length));
auto process_request_end_of_body = GC::create_function(vm.heap(), move(input.process_request_end_of_body));
auto process_early_hints_response = GC::create_function(vm.heap(), move(input.process_early_hints_response));
auto process_response = GC::create_function(vm.heap(), move(input.process_response));
auto process_response_end_of_body = GC::create_function(vm.heap(), move(input.process_response_end_of_body));
auto process_response_consume_body = GC::create_function(vm.heap(), move(input.process_response_consume_body));
return vm.heap().allocate<FetchAlgorithms>(
process_request_body_chunk_length,
process_request_end_of_body,

View file

@ -7,17 +7,17 @@
#pragma once
#include <AK/Optional.h>
#include <LibGC/Function.h>
#include <LibGC/Ptr.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibJS/Heap/HeapFunction.h>
#include <LibWeb/Forward.h>
namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#fetch-elsewhere-fetch
class FetchAlgorithms : public JS::Cell {
JS_CELL(FetchAlgorithms, JS::Cell);
JS_DECLARE_ALLOCATOR(FetchAlgorithms);
GC_CELL(FetchAlgorithms, JS::Cell);
GC_DECLARE_ALLOCATOR(FetchAlgorithms);
public:
struct ConsumeBodyFailureTag { };
@ -25,17 +25,17 @@ public:
using ProcessRequestBodyChunkLengthFunction = Function<void(u64)>;
using ProcessRequestEndOfBodyFunction = Function<void()>;
using ProcessEarlyHintsResponseFunction = Function<void(JS::NonnullGCPtr<Infrastructure::Response>)>;
using ProcessResponseFunction = Function<void(JS::NonnullGCPtr<Infrastructure::Response>)>;
using ProcessResponseEndOfBodyFunction = Function<void(JS::NonnullGCPtr<Infrastructure::Response>)>;
using ProcessResponseConsumeBodyFunction = Function<void(JS::NonnullGCPtr<Infrastructure::Response>, BodyBytes)>;
using ProcessEarlyHintsResponseFunction = Function<void(GC::Ref<Infrastructure::Response>)>;
using ProcessResponseFunction = Function<void(GC::Ref<Infrastructure::Response>)>;
using ProcessResponseEndOfBodyFunction = Function<void(GC::Ref<Infrastructure::Response>)>;
using ProcessResponseConsumeBodyFunction = Function<void(GC::Ref<Infrastructure::Response>, BodyBytes)>;
using ProcessRequestBodyChunkLengthHeapFunction = JS::NonnullGCPtr<JS::HeapFunction<ProcessRequestBodyChunkLengthFunction::FunctionType>>;
using ProcessRequestEndOfBodyHeapFunction = JS::NonnullGCPtr<JS::HeapFunction<ProcessRequestEndOfBodyFunction::FunctionType>>;
using ProcessEarlyHintsResponseHeapFunction = JS::NonnullGCPtr<JS::HeapFunction<ProcessEarlyHintsResponseFunction::FunctionType>>;
using ProcessResponseHeapFunction = JS::NonnullGCPtr<JS::HeapFunction<ProcessResponseFunction::FunctionType>>;
using ProcessResponseEndOfBodyHeapFunction = JS::NonnullGCPtr<JS::HeapFunction<ProcessResponseEndOfBodyFunction::FunctionType>>;
using ProcessResponseConsumeBodyHeapFunction = JS::NonnullGCPtr<JS::HeapFunction<ProcessResponseConsumeBodyFunction::FunctionType>>;
using ProcessRequestBodyChunkLengthHeapFunction = GC::Ref<GC::Function<ProcessRequestBodyChunkLengthFunction::FunctionType>>;
using ProcessRequestEndOfBodyHeapFunction = GC::Ref<GC::Function<ProcessRequestEndOfBodyFunction::FunctionType>>;
using ProcessEarlyHintsResponseHeapFunction = GC::Ref<GC::Function<ProcessEarlyHintsResponseFunction::FunctionType>>;
using ProcessResponseHeapFunction = GC::Ref<GC::Function<ProcessResponseFunction::FunctionType>>;
using ProcessResponseEndOfBodyHeapFunction = GC::Ref<GC::Function<ProcessResponseEndOfBodyFunction::FunctionType>>;
using ProcessResponseConsumeBodyHeapFunction = GC::Ref<GC::Function<ProcessResponseConsumeBodyFunction::FunctionType>>;
struct Input {
ProcessRequestBodyChunkLengthFunction process_request_body_chunk_length;
@ -46,7 +46,7 @@ public:
ProcessResponseConsumeBodyFunction process_response_consume_body;
};
[[nodiscard]] static JS::NonnullGCPtr<FetchAlgorithms> create(JS::VM&, Input);
[[nodiscard]] static GC::Ref<FetchAlgorithms> create(JS::VM&, Input);
ProcessRequestBodyChunkLengthFunction const& process_request_body_chunk_length() const { return m_process_request_body_chunk_length->function(); }
ProcessRequestEndOfBodyFunction const& process_request_end_of_body() const { return m_process_request_end_of_body->function(); }

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Heap/Heap.h>
#include <LibGC/Heap.h>
#include <LibJS/Runtime/VM.h>
#include <LibWeb/Fetch/Infrastructure/FetchAlgorithms.h>
#include <LibWeb/Fetch/Infrastructure/FetchController.h>
@ -14,11 +14,11 @@
namespace Web::Fetch::Infrastructure {
JS_DEFINE_ALLOCATOR(FetchController);
GC_DEFINE_ALLOCATOR(FetchController);
FetchController::FetchController() = default;
JS::NonnullGCPtr<FetchController> FetchController::create(JS::VM& vm)
GC::Ref<FetchController> FetchController::create(JS::VM& vm)
{
return vm.heap().allocate<FetchController>();
}
@ -34,12 +34,12 @@ void FetchController::visit_edges(JS::Cell::Visitor& visitor)
void FetchController::set_report_timing_steps(Function<void(JS::Object const&)> report_timing_steps)
{
m_report_timing_steps = JS::create_heap_function(vm().heap(), move(report_timing_steps));
m_report_timing_steps = GC::create_function(vm().heap(), move(report_timing_steps));
}
void FetchController::set_next_manual_redirect_steps(Function<void()> next_manual_redirect_steps)
{
m_next_manual_redirect_steps = JS::create_heap_function(vm().heap(), move(next_manual_redirect_steps));
m_next_manual_redirect_steps = GC::create_function(vm().heap(), move(next_manual_redirect_steps));
}
// https://fetch.spec.whatwg.org/#finalize-and-report-timing
@ -63,7 +63,7 @@ void FetchController::process_next_manual_redirect() const
}
// https://fetch.spec.whatwg.org/#extract-full-timing-info
JS::NonnullGCPtr<FetchTimingInfo> FetchController::extract_full_timing_info() const
GC::Ref<FetchTimingInfo> FetchController::extract_full_timing_info() const
{
// 1. Assert: thiss full timing info is not null.
VERIFY(m_full_timing_info);

View file

@ -8,10 +8,10 @@
#include <AK/Badge.h>
#include <AK/HashMap.h>
#include <LibGC/Function.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibJS/Heap/HeapFunction.h>
#include <LibJS/Runtime/VM.h>
#include <LibWeb/Fetch/Infrastructure/FetchTimingInfo.h>
#include <LibWeb/Forward.h>
@ -21,8 +21,8 @@ namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#fetch-controller
class FetchController : public JS::Cell {
JS_CELL(FetchController, JS::Cell);
JS_DECLARE_ALLOCATOR(FetchController);
GC_CELL(FetchController, JS::Cell);
GC_DECLARE_ALLOCATOR(FetchController);
public:
enum class State {
@ -31,9 +31,9 @@ public:
Aborted,
};
[[nodiscard]] static JS::NonnullGCPtr<FetchController> create(JS::VM&);
[[nodiscard]] static GC::Ref<FetchController> create(JS::VM&);
void set_full_timing_info(JS::NonnullGCPtr<FetchTimingInfo> full_timing_info) { m_full_timing_info = full_timing_info; }
void set_full_timing_info(GC::Ref<FetchTimingInfo> full_timing_info) { m_full_timing_info = full_timing_info; }
void set_report_timing_steps(Function<void(JS::Object const&)> report_timing_steps);
void set_next_manual_redirect_steps(Function<void()> next_manual_redirect_steps);
@ -41,11 +41,11 @@ public:
void report_timing(JS::Object const&) const;
void process_next_manual_redirect() const;
[[nodiscard]] JS::NonnullGCPtr<FetchTimingInfo> extract_full_timing_info() const;
[[nodiscard]] GC::Ref<FetchTimingInfo> extract_full_timing_info() const;
void abort(JS::Realm&, Optional<JS::Value>);
void terminate();
void set_fetch_params(Badge<FetchParams>, JS::NonnullGCPtr<FetchParams> fetch_params) { m_fetch_params = fetch_params; }
void set_fetch_params(Badge<FetchParams>, GC::Ref<FetchParams> fetch_params) { m_fetch_params = fetch_params; }
void stop_fetch();
@ -66,12 +66,12 @@ private:
// https://fetch.spec.whatwg.org/#fetch-controller-full-timing-info
// full timing info (default null)
// Null or a fetch timing info.
JS::GCPtr<FetchTimingInfo> m_full_timing_info;
GC::Ptr<FetchTimingInfo> m_full_timing_info;
// https://fetch.spec.whatwg.org/#fetch-controller-report-timing-steps
// report timing steps (default null)
// Null or an algorithm accepting a global object.
JS::GCPtr<JS::HeapFunction<void(JS::Object const&)>> m_report_timing_steps;
GC::Ptr<GC::Function<void(JS::Object const&)>> m_report_timing_steps;
// https://fetch.spec.whatwg.org/#fetch-controller-report-timing-steps
// FIXME: serialized abort reason (default null)
@ -80,9 +80,9 @@ private:
// https://fetch.spec.whatwg.org/#fetch-controller-next-manual-redirect-steps
// next manual redirect steps (default null)
// Null or an algorithm accepting nothing.
JS::GCPtr<JS::HeapFunction<void()>> m_next_manual_redirect_steps;
GC::Ptr<GC::Function<void()>> m_next_manual_redirect_steps;
JS::GCPtr<FetchParams> m_fetch_params;
GC::Ptr<FetchParams> m_fetch_params;
HashMap<u64, HTML::TaskID> m_ongoing_fetch_tasks;
u64 m_next_fetch_task_id { 0 };

View file

@ -4,16 +4,16 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Heap/Heap.h>
#include <LibGC/Heap.h>
#include <LibJS/Runtime/VM.h>
#include <LibWeb/Fetch/Infrastructure/FetchParams.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h>
namespace Web::Fetch::Infrastructure {
JS_DEFINE_ALLOCATOR(FetchParams);
GC_DEFINE_ALLOCATOR(FetchParams);
FetchParams::FetchParams(JS::NonnullGCPtr<Request> request, JS::NonnullGCPtr<FetchAlgorithms> algorithms, JS::NonnullGCPtr<FetchController> controller, JS::NonnullGCPtr<FetchTimingInfo> timing_info)
FetchParams::FetchParams(GC::Ref<Request> request, GC::Ref<FetchAlgorithms> algorithms, GC::Ref<FetchController> controller, GC::Ref<FetchTimingInfo> timing_info)
: m_request(request)
, m_algorithms(algorithms)
, m_controller(controller)
@ -22,7 +22,7 @@ FetchParams::FetchParams(JS::NonnullGCPtr<Request> request, JS::NonnullGCPtr<Fet
m_controller->set_fetch_params({}, *this);
}
JS::NonnullGCPtr<FetchParams> FetchParams::create(JS::VM& vm, JS::NonnullGCPtr<Request> request, JS::NonnullGCPtr<FetchTimingInfo> timing_info)
GC::Ref<FetchParams> FetchParams::create(JS::VM& vm, GC::Ref<Request> request, GC::Ref<FetchTimingInfo> timing_info)
{
auto algorithms = Infrastructure::FetchAlgorithms::create(vm, {});
auto controller = Infrastructure::FetchController::create(vm);
@ -36,10 +36,10 @@ void FetchParams::visit_edges(JS::Cell::Visitor& visitor)
visitor.visit(m_algorithms);
visitor.visit(m_controller);
visitor.visit(m_timing_info);
if (m_task_destination.has<JS::NonnullGCPtr<JS::Object>>())
visitor.visit(m_task_destination.get<JS::NonnullGCPtr<JS::Object>>());
if (m_preloaded_response_candidate.has<JS::NonnullGCPtr<Response>>())
visitor.visit(m_preloaded_response_candidate.get<JS::NonnullGCPtr<Response>>());
if (m_task_destination.has<GC::Ref<JS::Object>>())
visitor.visit(m_task_destination.get<GC::Ref<JS::Object>>());
if (m_preloaded_response_candidate.has<GC::Ref<Response>>())
visitor.visit(m_preloaded_response_candidate.get<GC::Ref<Response>>());
}
// https://fetch.spec.whatwg.org/#fetch-params-aborted

View file

@ -7,9 +7,9 @@
#pragma once
#include <AK/Forward.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Fetch/Infrastructure/FetchAlgorithms.h>
#include <LibWeb/Fetch/Infrastructure/FetchController.h>
#include <LibWeb/Fetch/Infrastructure/FetchTimingInfo.h>
@ -20,21 +20,21 @@ namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#fetch-params
class FetchParams : public JS::Cell {
JS_CELL(FetchParams, JS::Cell);
JS_DECLARE_ALLOCATOR(FetchParams);
GC_CELL(FetchParams, JS::Cell);
GC_DECLARE_ALLOCATOR(FetchParams);
public:
struct PreloadedResponseCandidatePendingTag { };
using PreloadedResponseCandidate = Variant<Empty, PreloadedResponseCandidatePendingTag, JS::NonnullGCPtr<Response>>;
using PreloadedResponseCandidate = Variant<Empty, PreloadedResponseCandidatePendingTag, GC::Ref<Response>>;
[[nodiscard]] static JS::NonnullGCPtr<FetchParams> create(JS::VM&, JS::NonnullGCPtr<Request>, JS::NonnullGCPtr<FetchTimingInfo>);
[[nodiscard]] static GC::Ref<FetchParams> create(JS::VM&, GC::Ref<Request>, GC::Ref<FetchTimingInfo>);
[[nodiscard]] JS::NonnullGCPtr<Request> request() const { return m_request; }
[[nodiscard]] JS::NonnullGCPtr<FetchController> controller() const { return m_controller; }
[[nodiscard]] JS::NonnullGCPtr<FetchTimingInfo> timing_info() const { return m_timing_info; }
[[nodiscard]] GC::Ref<Request> request() const { return m_request; }
[[nodiscard]] GC::Ref<FetchController> controller() const { return m_controller; }
[[nodiscard]] GC::Ref<FetchTimingInfo> timing_info() const { return m_timing_info; }
[[nodiscard]] JS::NonnullGCPtr<FetchAlgorithms const> algorithms() const { return m_algorithms; }
void set_algorithms(JS::NonnullGCPtr<FetchAlgorithms const> algorithms) { m_algorithms = algorithms; }
[[nodiscard]] GC::Ref<FetchAlgorithms const> algorithms() const { return m_algorithms; }
void set_algorithms(GC::Ref<FetchAlgorithms const> algorithms) { m_algorithms = algorithms; }
[[nodiscard]] TaskDestination& task_destination() { return m_task_destination; }
[[nodiscard]] TaskDestination const& task_destination() const { return m_task_destination; }
@ -51,14 +51,14 @@ public:
[[nodiscard]] bool is_canceled() const;
private:
FetchParams(JS::NonnullGCPtr<Request>, JS::NonnullGCPtr<FetchAlgorithms>, JS::NonnullGCPtr<FetchController>, JS::NonnullGCPtr<FetchTimingInfo>);
FetchParams(GC::Ref<Request>, GC::Ref<FetchAlgorithms>, GC::Ref<FetchController>, GC::Ref<FetchTimingInfo>);
virtual void visit_edges(JS::Cell::Visitor&) override;
// https://fetch.spec.whatwg.org/#fetch-params-request
// request
// A request.
JS::NonnullGCPtr<Request> m_request;
GC::Ref<Request> m_request;
// https://fetch.spec.whatwg.org/#fetch-params-process-request-body
// process request body chunk length (default null)
@ -73,7 +73,7 @@ private:
// https://fetch.spec.whatwg.org/#fetch-params-process-response-consume-body
// process response consume body (default null)
// Null or an algorithm.
JS::NonnullGCPtr<FetchAlgorithms const> m_algorithms;
GC::Ref<FetchAlgorithms const> m_algorithms;
// https://fetch.spec.whatwg.org/#fetch-params-task-destination
// task destination (default null)
@ -88,12 +88,12 @@ private:
// https://fetch.spec.whatwg.org/#fetch-params-controller
// controller (default a new fetch controller)
// A fetch controller.
JS::NonnullGCPtr<FetchController> m_controller;
GC::Ref<FetchController> m_controller;
// https://fetch.spec.whatwg.org/#fetch-params-timing-info
// timing info
// A fetch timing info.
JS::NonnullGCPtr<FetchTimingInfo> m_timing_info;
GC::Ref<FetchTimingInfo> m_timing_info;
// https://fetch.spec.whatwg.org/#fetch-params-preloaded-response-candidate
// preloaded response candidate (default null)

View file

@ -8,24 +8,24 @@
namespace Web::Fetch::Infrastructure {
JS_DEFINE_ALLOCATOR(FetchRecord);
GC_DEFINE_ALLOCATOR(FetchRecord);
JS::NonnullGCPtr<FetchRecord> FetchRecord::create(JS::VM& vm, JS::NonnullGCPtr<Infrastructure::Request> request)
GC::Ref<FetchRecord> FetchRecord::create(JS::VM& vm, GC::Ref<Infrastructure::Request> request)
{
return vm.heap().allocate<FetchRecord>(request);
}
JS::NonnullGCPtr<FetchRecord> FetchRecord::create(JS::VM& vm, JS::NonnullGCPtr<Infrastructure::Request> request, JS::GCPtr<Fetch::Infrastructure::FetchController> fetch_controller)
GC::Ref<FetchRecord> FetchRecord::create(JS::VM& vm, GC::Ref<Infrastructure::Request> request, GC::Ptr<Fetch::Infrastructure::FetchController> fetch_controller)
{
return vm.heap().allocate<FetchRecord>(request, fetch_controller);
}
FetchRecord::FetchRecord(JS::NonnullGCPtr<Infrastructure::Request> request)
FetchRecord::FetchRecord(GC::Ref<Infrastructure::Request> request)
: m_request(request)
{
}
FetchRecord::FetchRecord(JS::NonnullGCPtr<Infrastructure::Request> request, JS::GCPtr<Fetch::Infrastructure::FetchController> fetch_controller)
FetchRecord::FetchRecord(GC::Ref<Infrastructure::Request> request, GC::Ptr<Fetch::Infrastructure::FetchController> fetch_controller)
: m_request(request)
, m_fetch_controller(fetch_controller)
{

View file

@ -13,32 +13,32 @@ namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#concept-fetch-record
class FetchRecord : public JS::Cell {
JS_CELL(FetchRecord, JS::Cell);
JS_DECLARE_ALLOCATOR(FetchRecord);
GC_CELL(FetchRecord, JS::Cell);
GC_DECLARE_ALLOCATOR(FetchRecord);
public:
[[nodiscard]] static JS::NonnullGCPtr<FetchRecord> create(JS::VM&, JS::NonnullGCPtr<Infrastructure::Request>);
[[nodiscard]] static JS::NonnullGCPtr<FetchRecord> create(JS::VM&, JS::NonnullGCPtr<Infrastructure::Request>, JS::GCPtr<FetchController>);
[[nodiscard]] static GC::Ref<FetchRecord> create(JS::VM&, GC::Ref<Infrastructure::Request>);
[[nodiscard]] static GC::Ref<FetchRecord> create(JS::VM&, GC::Ref<Infrastructure::Request>, GC::Ptr<FetchController>);
[[nodiscard]] JS::NonnullGCPtr<Infrastructure::Request> request() const { return m_request; }
void set_request(JS::NonnullGCPtr<Infrastructure::Request> request) { m_request = request; }
[[nodiscard]] GC::Ref<Infrastructure::Request> request() const { return m_request; }
void set_request(GC::Ref<Infrastructure::Request> request) { m_request = request; }
[[nodiscard]] JS::GCPtr<FetchController> fetch_controller() const { return m_fetch_controller; }
void set_fetch_controller(JS::GCPtr<FetchController> fetch_controller) { m_fetch_controller = fetch_controller; }
[[nodiscard]] GC::Ptr<FetchController> fetch_controller() const { return m_fetch_controller; }
void set_fetch_controller(GC::Ptr<FetchController> fetch_controller) { m_fetch_controller = fetch_controller; }
private:
explicit FetchRecord(JS::NonnullGCPtr<Infrastructure::Request>);
FetchRecord(JS::NonnullGCPtr<Infrastructure::Request>, JS::GCPtr<FetchController>);
explicit FetchRecord(GC::Ref<Infrastructure::Request>);
FetchRecord(GC::Ref<Infrastructure::Request>, GC::Ptr<FetchController>);
virtual void visit_edges(Visitor&) override;
// https://fetch.spec.whatwg.org/#concept-request
// A fetch record has an associated request (a request)
JS::NonnullGCPtr<Infrastructure::Request> m_request;
GC::Ref<Infrastructure::Request> m_request;
// https://fetch.spec.whatwg.org/#fetch-controller
// A fetch record has an associated controller (a fetch controller or null)
JS::GCPtr<FetchController> m_fetch_controller { nullptr };
GC::Ptr<FetchController> m_fetch_controller { nullptr };
};
}

View file

@ -4,17 +4,17 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Heap/Heap.h>
#include <LibGC/Heap.h>
#include <LibJS/Runtime/VM.h>
#include <LibWeb/Fetch/Infrastructure/FetchTimingInfo.h>
namespace Web::Fetch::Infrastructure {
JS_DEFINE_ALLOCATOR(FetchTimingInfo);
GC_DEFINE_ALLOCATOR(FetchTimingInfo);
FetchTimingInfo::FetchTimingInfo() = default;
JS::NonnullGCPtr<FetchTimingInfo> FetchTimingInfo::create(JS::VM& vm)
GC::Ref<FetchTimingInfo> FetchTimingInfo::create(JS::VM& vm)
{
return vm.heap().allocate<FetchTimingInfo>();
}
@ -26,7 +26,7 @@ void FetchTimingInfo::visit_edges(JS::Cell::Visitor& visitor)
}
// https://fetch.spec.whatwg.org/#create-an-opaque-timing-info
JS::NonnullGCPtr<FetchTimingInfo> create_opaque_timing_info(JS::VM& vm, FetchTimingInfo const& timing_info)
GC::Ref<FetchTimingInfo> create_opaque_timing_info(JS::VM& vm, FetchTimingInfo const& timing_info)
{
// To create an opaque timing info, given a fetch timing info timingInfo, return a new fetch timing info whose
// start time and post-redirect start time are timingInfos start time.

View file

@ -8,9 +8,9 @@
#include <AK/String.h>
#include <AK/Vector.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Fetch/Infrastructure/ConnectionTimingInfo.h>
#include <LibWeb/HighResolutionTime/DOMHighResTimeStamp.h>
@ -18,11 +18,11 @@ namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#fetch-timing-info
class FetchTimingInfo : public JS::Cell {
JS_CELL(FetchTimingInfo, JS::Cell);
JS_DECLARE_ALLOCATOR(FetchTimingInfo);
GC_CELL(FetchTimingInfo, JS::Cell);
GC_DECLARE_ALLOCATOR(FetchTimingInfo);
public:
[[nodiscard]] static JS::NonnullGCPtr<FetchTimingInfo> create(JS::VM&);
[[nodiscard]] static GC::Ref<FetchTimingInfo> create(JS::VM&);
[[nodiscard]] HighResolutionTime::DOMHighResTimeStamp start_time() const { return m_start_time; }
void set_start_time(HighResolutionTime::DOMHighResTimeStamp start_time) { m_start_time = start_time; }
@ -48,8 +48,8 @@ public:
[[nodiscard]] HighResolutionTime::DOMHighResTimeStamp end_time() const { return m_end_time; }
void set_end_time(HighResolutionTime::DOMHighResTimeStamp end_time) { m_end_time = end_time; }
[[nodiscard]] JS::GCPtr<ConnectionTimingInfo> final_connection_timing_info() const { return m_final_connection_timing_info; }
void set_final_connection_timing_info(JS::GCPtr<ConnectionTimingInfo> final_connection_timing_info) { m_final_connection_timing_info = final_connection_timing_info; }
[[nodiscard]] GC::Ptr<ConnectionTimingInfo> final_connection_timing_info() const { return m_final_connection_timing_info; }
void set_final_connection_timing_info(GC::Ptr<ConnectionTimingInfo> final_connection_timing_info) { m_final_connection_timing_info = final_connection_timing_info; }
[[nodiscard]] Vector<String>& server_timing_headers() { return m_server_timing_headers; }
[[nodiscard]] Vector<String> const& server_timing_headers() const { return m_server_timing_headers; }
@ -106,7 +106,7 @@ private:
// https://fetch.spec.whatwg.org/#fetch-timing-info-final-connection-timing-info
// final connection timing info (default null)
// Null or a connection timing info.
JS::GCPtr<ConnectionTimingInfo> m_final_connection_timing_info;
GC::Ptr<ConnectionTimingInfo> m_final_connection_timing_info;
// https://fetch.spec.whatwg.org/#fetch-timing-info-server-timing-headers
// server-timing headers (default « »)
@ -119,6 +119,6 @@ private:
bool m_render_blocking { false };
};
JS::NonnullGCPtr<FetchTimingInfo> create_opaque_timing_info(JS::VM&, FetchTimingInfo const& timing_info);
GC::Ref<FetchTimingInfo> create_opaque_timing_info(JS::VM&, FetchTimingInfo const& timing_info);
}

View file

@ -16,24 +16,24 @@
namespace Web::Fetch::Infrastructure {
JS_DEFINE_ALLOCATOR(Body);
GC_DEFINE_ALLOCATOR(Body);
JS::NonnullGCPtr<Body> Body::create(JS::VM& vm, JS::NonnullGCPtr<Streams::ReadableStream> stream)
GC::Ref<Body> Body::create(JS::VM& vm, GC::Ref<Streams::ReadableStream> stream)
{
return vm.heap().allocate<Body>(stream);
}
JS::NonnullGCPtr<Body> Body::create(JS::VM& vm, JS::NonnullGCPtr<Streams::ReadableStream> stream, SourceType source, Optional<u64> length)
GC::Ref<Body> Body::create(JS::VM& vm, GC::Ref<Streams::ReadableStream> stream, SourceType source, Optional<u64> length)
{
return vm.heap().allocate<Body>(stream, source, length);
}
Body::Body(JS::NonnullGCPtr<Streams::ReadableStream> stream)
Body::Body(GC::Ref<Streams::ReadableStream> stream)
: m_stream(move(stream))
{
}
Body::Body(JS::NonnullGCPtr<Streams::ReadableStream> stream, SourceType source, Optional<u64> length)
Body::Body(GC::Ref<Streams::ReadableStream> stream, SourceType source, Optional<u64> length)
: m_stream(move(stream))
, m_source(move(source))
, m_length(move(length))
@ -47,7 +47,7 @@ void Body::visit_edges(Cell::Visitor& visitor)
}
// https://fetch.spec.whatwg.org/#concept-body-clone
JS::NonnullGCPtr<Body> Body::clone(JS::Realm& realm)
GC::Ref<Body> Body::clone(JS::Realm& realm)
{
HTML::TemporaryExecutionContext execution_context { realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
@ -68,21 +68,21 @@ void Body::fully_read(JS::Realm& realm, Web::Fetch::Infrastructure::Body::Proces
// FIXME: 1. If taskDestination is null, then set taskDestination to the result of starting a new parallel queue.
// FIXME: Handle 'parallel queue' task destination
VERIFY(!task_destination.has<Empty>());
auto task_destination_object = task_destination.get<JS::NonnullGCPtr<JS::Object>>();
auto task_destination_object = task_destination.get<GC::Ref<JS::Object>>();
// 2. Let successSteps given a byte sequence bytes be to queue a fetch task to run processBody given bytes, with taskDestination.
auto success_steps = [&realm, process_body, task_destination_object = task_destination_object](ReadonlyBytes bytes) -> ErrorOr<void> {
// Make a copy of the bytes, as the source of the bytes may disappear between the time the task is queued and executed.
auto bytes_copy = TRY(ByteBuffer::copy(bytes));
queue_fetch_task(*task_destination_object, JS::create_heap_function(realm.heap(), [process_body, bytes_copy = move(bytes_copy)]() mutable {
queue_fetch_task(*task_destination_object, GC::create_function(realm.heap(), [process_body, bytes_copy = move(bytes_copy)]() mutable {
process_body->function()(move(bytes_copy));
}));
return {};
};
// 3. Let errorSteps optionally given an exception exception be to queue a fetch task to run processBodyError given exception, with taskDestination.
auto error_steps = [&realm, process_body_error, task_destination_object](JS::GCPtr<WebIDL::DOMException> exception) {
queue_fetch_task(*task_destination_object, JS::create_heap_function(realm.heap(), [process_body_error, exception]() {
auto error_steps = [&realm, process_body_error, task_destination_object](GC::Ptr<WebIDL::DOMException> exception) {
queue_fetch_task(*task_destination_object, GC::create_function(realm.heap(), [process_body_error, exception]() {
process_body_error->function()(exception);
}));
};
@ -95,7 +95,7 @@ void Body::fully_read(JS::Realm& realm, Web::Fetch::Infrastructure::Body::Proces
if (auto result = success_steps(byte_buffer); result.is_error())
error_steps(WebIDL::UnknownError::create(realm, "Out-of-memory"_string));
},
[&](JS::Handle<FileAPI::Blob> const& blob) {
[&](GC::Root<FileAPI::Blob> const& blob) {
if (auto result = success_steps(blob->raw_bytes()); result.is_error())
error_steps(WebIDL::UnknownError::create(realm, "Out-of-memory"_string));
},
@ -109,7 +109,7 @@ void Body::incrementally_read(ProcessBodyChunkCallback process_body_chunk, Proce
{
HTML::TemporaryExecutionContext const execution_context { m_stream->realm(), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
VERIFY(task_destination.has<JS::NonnullGCPtr<JS::Object>>());
VERIFY(task_destination.has<GC::Ref<JS::Object>>());
// FIXME: 1. If taskDestination is null, then set taskDestination to the result of starting a new parallel queue.
// FIXME: Handle 'parallel queue' task destination
@ -118,11 +118,11 @@ void Body::incrementally_read(ProcessBodyChunkCallback process_body_chunk, Proce
auto reader = MUST(Streams::acquire_readable_stream_default_reader(m_stream));
// 3. Perform the incrementally-read loop given reader, taskDestination, processBodyChunk, processEndOfBody, and processBodyError.
incrementally_read_loop(reader, task_destination.get<JS::NonnullGCPtr<JS::Object>>(), process_body_chunk, process_end_of_body, process_body_error);
incrementally_read_loop(reader, task_destination.get<GC::Ref<JS::Object>>(), process_body_chunk, process_end_of_body, process_body_error);
}
// https://fetch.spec.whatwg.org/#incrementally-read-loop
void Body::incrementally_read_loop(Streams::ReadableStreamDefaultReader& reader, JS::NonnullGCPtr<JS::Object> task_destination, ProcessBodyChunkCallback process_body_chunk, ProcessEndOfBodyCallback process_end_of_body, ProcessBodyErrorCallback process_body_error)
void Body::incrementally_read_loop(Streams::ReadableStreamDefaultReader& reader, GC::Ref<JS::Object> task_destination, ProcessBodyChunkCallback process_body_chunk, ProcessEndOfBodyCallback process_end_of_body, ProcessBodyErrorCallback process_body_error)
{
auto& realm = reader.realm();
@ -134,7 +134,7 @@ void Body::incrementally_read_loop(Streams::ReadableStreamDefaultReader& reader,
}
// https://fetch.spec.whatwg.org/#byte-sequence-as-a-body
WebIDL::ExceptionOr<JS::NonnullGCPtr<Body>> byte_sequence_as_body(JS::Realm& realm, ReadonlyBytes bytes)
WebIDL::ExceptionOr<GC::Ref<Body>> byte_sequence_as_body(JS::Realm& realm, ReadonlyBytes bytes)
{
// To get a byte sequence bytes as a body, return the body of the result of safely extracting bytes.
auto [body, _] = TRY(safely_extract_body(realm, bytes));

View file

@ -11,8 +11,8 @@
#include <AK/NonnullRefPtr.h>
#include <AK/Optional.h>
#include <AK/Variant.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibJS/Heap/Handle.h>
#include <LibGC/Ptr.h>
#include <LibGC/Root.h>
#include <LibWeb/Fetch/Infrastructure/Task.h>
#include <LibWeb/FileAPI/Blob.h>
#include <LibWeb/Streams/ReadableStream.h>
@ -22,43 +22,43 @@ namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#concept-body
class Body final : public JS::Cell {
JS_CELL(Body, JS::Cell);
JS_DECLARE_ALLOCATOR(Body);
GC_CELL(Body, JS::Cell);
GC_DECLARE_ALLOCATOR(Body);
public:
using SourceType = Variant<Empty, ByteBuffer, JS::Handle<FileAPI::Blob>>;
using SourceType = Variant<Empty, ByteBuffer, GC::Root<FileAPI::Blob>>;
// processBody must be an algorithm accepting a byte sequence.
using ProcessBodyCallback = JS::NonnullGCPtr<JS::HeapFunction<void(ByteBuffer)>>;
using ProcessBodyCallback = GC::Ref<GC::Function<void(ByteBuffer)>>;
// processBodyError must be an algorithm optionally accepting an exception.
using ProcessBodyErrorCallback = JS::NonnullGCPtr<JS::HeapFunction<void(JS::Value)>>;
using ProcessBodyErrorCallback = GC::Ref<GC::Function<void(JS::Value)>>;
// processBodyChunk must be an algorithm accepting a byte sequence.
using ProcessBodyChunkCallback = JS::NonnullGCPtr<JS::HeapFunction<void(ByteBuffer)>>;
using ProcessBodyChunkCallback = GC::Ref<GC::Function<void(ByteBuffer)>>;
// processEndOfBody must be an algorithm accepting no arguments
using ProcessEndOfBodyCallback = JS::NonnullGCPtr<JS::HeapFunction<void()>>;
using ProcessEndOfBodyCallback = GC::Ref<GC::Function<void()>>;
[[nodiscard]] static JS::NonnullGCPtr<Body> create(JS::VM&, JS::NonnullGCPtr<Streams::ReadableStream>);
[[nodiscard]] static JS::NonnullGCPtr<Body> create(JS::VM&, JS::NonnullGCPtr<Streams::ReadableStream>, SourceType, Optional<u64>);
[[nodiscard]] static GC::Ref<Body> create(JS::VM&, GC::Ref<Streams::ReadableStream>);
[[nodiscard]] static GC::Ref<Body> create(JS::VM&, GC::Ref<Streams::ReadableStream>, SourceType, Optional<u64>);
[[nodiscard]] JS::NonnullGCPtr<Streams::ReadableStream> stream() const { return *m_stream; }
void set_stream(JS::NonnullGCPtr<Streams::ReadableStream> value) { m_stream = value; }
[[nodiscard]] GC::Ref<Streams::ReadableStream> stream() const { return *m_stream; }
void set_stream(GC::Ref<Streams::ReadableStream> value) { m_stream = value; }
[[nodiscard]] SourceType const& source() const { return m_source; }
[[nodiscard]] Optional<u64> const& length() const { return m_length; }
[[nodiscard]] JS::NonnullGCPtr<Body> clone(JS::Realm&);
[[nodiscard]] GC::Ref<Body> clone(JS::Realm&);
void fully_read(JS::Realm&, ProcessBodyCallback process_body, ProcessBodyErrorCallback process_body_error, TaskDestination task_destination) const;
void incrementally_read(ProcessBodyChunkCallback process_body_chunk, ProcessEndOfBodyCallback process_end_of_body, ProcessBodyErrorCallback process_body_error, TaskDestination task_destination);
void incrementally_read_loop(Streams::ReadableStreamDefaultReader& reader, JS::NonnullGCPtr<JS::Object> task_destination, ProcessBodyChunkCallback process_body_chunk, ProcessEndOfBodyCallback process_end_of_body, ProcessBodyErrorCallback process_body_error);
void incrementally_read_loop(Streams::ReadableStreamDefaultReader& reader, GC::Ref<JS::Object> task_destination, ProcessBodyChunkCallback process_body_chunk, ProcessEndOfBodyCallback process_end_of_body, ProcessBodyErrorCallback process_body_error);
virtual void visit_edges(JS::Cell::Visitor&) override;
private:
explicit Body(JS::NonnullGCPtr<Streams::ReadableStream>);
Body(JS::NonnullGCPtr<Streams::ReadableStream>, SourceType, Optional<u64>);
explicit Body(GC::Ref<Streams::ReadableStream>);
Body(GC::Ref<Streams::ReadableStream>, SourceType, Optional<u64>);
// https://fetch.spec.whatwg.org/#concept-body-stream
// A stream (a ReadableStream object).
JS::NonnullGCPtr<Streams::ReadableStream> m_stream;
GC::Ref<Streams::ReadableStream> m_stream;
// https://fetch.spec.whatwg.org/#concept-body-source
// A source (null, a byte sequence, a Blob object, or a FormData object), initially null.
@ -72,10 +72,10 @@ private:
// https://fetch.spec.whatwg.org/#body-with-type
// A body with type is a tuple that consists of a body (a body) and a type (a header value or null).
struct BodyWithType {
JS::NonnullGCPtr<Body> body;
GC::Ref<Body> body;
Optional<ByteBuffer> type;
};
WebIDL::ExceptionOr<JS::NonnullGCPtr<Body>> byte_sequence_as_body(JS::Realm&, ReadonlyBytes);
WebIDL::ExceptionOr<GC::Ref<Body>> byte_sequence_as_body(JS::Realm&, ReadonlyBytes);
}

View file

@ -12,7 +12,7 @@
#include <AK/QuickSort.h>
#include <AK/ScopeGuard.h>
#include <AK/StringUtils.h>
#include <LibJS/Heap/Heap.h>
#include <LibGC/Heap.h>
#include <LibJS/Runtime/VM.h>
#include <LibRegex/Regex.h>
#include <LibTextCodec/Decoder.h>
@ -26,7 +26,7 @@
namespace Web::Fetch::Infrastructure {
JS_DEFINE_ALLOCATOR(HeaderList);
GC_DEFINE_ALLOCATOR(HeaderList);
template<typename T>
requires(IsSameIgnoringCV<T, u8>) struct CaseInsensitiveBytesTraits : public Traits<Span<T>> {
@ -58,7 +58,7 @@ Header Header::from_string_pair(StringView name, StringView value)
};
}
JS::NonnullGCPtr<HeaderList> HeaderList::create(JS::VM& vm)
GC::Ref<HeaderList> HeaderList::create(JS::VM& vm)
{
return vm.heap().allocate<HeaderList>();
}

View file

@ -13,10 +13,10 @@
#include <AK/Optional.h>
#include <AK/String.h>
#include <AK/Vector.h>
#include <LibGC/Heap.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibJS/Heap/Heap.h>
#include <LibWeb/MimeSniff/MimeType.h>
namespace Web::Fetch::Infrastructure {
@ -36,8 +36,8 @@ struct Header {
class HeaderList final
: public JS::Cell
, public Vector<Header> {
JS_CELL(HeaderList, JS::Cell);
JS_DECLARE_ALLOCATOR(HeaderList);
GC_CELL(HeaderList, JS::Cell);
GC_DECLARE_ALLOCATOR(HeaderList);
public:
using Vector::begin;
@ -45,7 +45,7 @@ public:
using Vector::end;
using Vector::is_empty;
[[nodiscard]] static JS::NonnullGCPtr<HeaderList> create(JS::VM&);
[[nodiscard]] static GC::Ref<HeaderList> create(JS::VM&);
[[nodiscard]] bool contains(ReadonlyBytes) const;
[[nodiscard]] Optional<ByteBuffer> get(ReadonlyBytes) const;

View file

@ -5,7 +5,7 @@
*/
#include <AK/Array.h>
#include <LibJS/Heap/Heap.h>
#include <LibGC/Heap.h>
#include <LibJS/Runtime/Realm.h>
#include <LibWeb/DOMURL/DOMURL.h>
#include <LibWeb/Fetch/Fetching/PendingResponse.h>
@ -13,9 +13,9 @@
namespace Web::Fetch::Infrastructure {
JS_DEFINE_ALLOCATOR(Request);
GC_DEFINE_ALLOCATOR(Request);
Request::Request(JS::NonnullGCPtr<HeaderList> header_list)
Request::Request(GC::Ref<HeaderList> header_list)
: m_header_list(header_list)
{
}
@ -26,16 +26,16 @@ void Request::visit_edges(JS::Cell::Visitor& visitor)
visitor.visit(m_header_list);
visitor.visit(m_client);
m_body.visit(
[&](JS::NonnullGCPtr<Body>& body) { visitor.visit(body); },
[&](GC::Ref<Body>& body) { visitor.visit(body); },
[](auto&) {});
visitor.visit(m_reserved_client);
m_window.visit(
[&](JS::GCPtr<HTML::EnvironmentSettingsObject> const& value) { visitor.visit(value); },
[&](GC::Ptr<HTML::EnvironmentSettingsObject> const& value) { visitor.visit(value); },
[](auto const&) {});
visitor.visit(m_pending_responses);
}
JS::NonnullGCPtr<Request> Request::create(JS::VM& vm)
GC::Ref<Request> Request::create(JS::VM& vm)
{
return vm.heap().allocate<Request>(HeaderList::create(vm));
}
@ -205,7 +205,7 @@ ByteBuffer Request::byte_serialize_origin() const
}
// https://fetch.spec.whatwg.org/#concept-request-clone
JS::NonnullGCPtr<Request> Request::clone(JS::Realm& realm) const
GC::Ref<Request> Request::clone(JS::Realm& realm) const
{
// To clone a request request, run these steps:
auto& vm = realm.vm();
@ -253,7 +253,7 @@ JS::NonnullGCPtr<Request> Request::clone(JS::Realm& realm) const
new_request->set_buffer_policy(m_buffer_policy);
// 2. If requests body is non-null, set newRequests body to the result of cloning requests body.
if (auto const* body = m_body.get_pointer<JS::NonnullGCPtr<Body>>())
if (auto const* body = m_body.get_pointer<GC::Ref<Body>>())
new_request->set_body((*body)->clone(realm));
// 3. Return newRequest.

View file

@ -14,9 +14,9 @@
#include <AK/String.h>
#include <AK/Variant.h>
#include <AK/Vector.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibURL/Origin.h>
#include <LibURL/URL.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h>
@ -28,8 +28,8 @@ namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#concept-request
class Request final : public JS::Cell {
JS_CELL(Request, JS::Cell);
JS_DECLARE_ALLOCATOR(Request);
GC_CELL(Request, JS::Cell);
GC_DECLARE_ALLOCATOR(Request);
public:
enum class CacheMode {
@ -169,14 +169,14 @@ public:
// Members are implementation-defined
struct InternalPriority { };
using BodyType = Variant<Empty, ByteBuffer, JS::NonnullGCPtr<Body>>;
using BodyType = Variant<Empty, ByteBuffer, GC::Ref<Body>>;
using OriginType = Variant<Origin, URL::Origin>;
using PolicyContainerType = Variant<PolicyContainer, HTML::PolicyContainer>;
using ReferrerType = Variant<Referrer, URL::URL>;
using ReservedClientType = JS::GCPtr<HTML::Environment>;
using WindowType = Variant<Window, JS::GCPtr<HTML::EnvironmentSettingsObject>>;
using ReservedClientType = GC::Ptr<HTML::Environment>;
using WindowType = Variant<Window, GC::Ptr<HTML::EnvironmentSettingsObject>>;
[[nodiscard]] static JS::NonnullGCPtr<Request> create(JS::VM&);
[[nodiscard]] static GC::Ref<Request> create(JS::VM&);
[[nodiscard]] ReadonlyBytes method() const { return m_method; }
void set_method(ByteBuffer method) { m_method = move(method); }
@ -184,8 +184,8 @@ public:
[[nodiscard]] bool local_urls_only() const { return m_local_urls_only; }
void set_local_urls_only(bool local_urls_only) { m_local_urls_only = local_urls_only; }
[[nodiscard]] JS::NonnullGCPtr<HeaderList> header_list() const { return m_header_list; }
void set_header_list(JS::NonnullGCPtr<HeaderList> header_list) { m_header_list = header_list; }
[[nodiscard]] GC::Ref<HeaderList> header_list() const { return m_header_list; }
void set_header_list(GC::Ref<HeaderList> header_list) { m_header_list = header_list; }
[[nodiscard]] bool unsafe_request() const { return m_unsafe_request; }
void set_unsafe_request(bool unsafe_request) { m_unsafe_request = unsafe_request; }
@ -194,8 +194,8 @@ public:
[[nodiscard]] BodyType& body() { return m_body; }
void set_body(BodyType body) { m_body = move(body); }
[[nodiscard]] JS::GCPtr<HTML::EnvironmentSettingsObject const> client() const { return m_client; }
[[nodiscard]] JS::GCPtr<HTML::EnvironmentSettingsObject> client() { return m_client; }
[[nodiscard]] GC::Ptr<HTML::EnvironmentSettingsObject const> client() const { return m_client; }
[[nodiscard]] GC::Ptr<HTML::EnvironmentSettingsObject> client() { return m_client; }
void set_client(HTML::EnvironmentSettingsObject* client) { m_client = client; }
[[nodiscard]] ReservedClientType const& reserved_client() const { return m_reserved_client; }
@ -313,7 +313,7 @@ public:
[[nodiscard]] String serialize_origin() const;
[[nodiscard]] ByteBuffer byte_serialize_origin() const;
[[nodiscard]] JS::NonnullGCPtr<Request> clone(JS::Realm&) const;
[[nodiscard]] GC::Ref<Request> clone(JS::Realm&) const;
void add_range_header(u64 first, Optional<u64> const& last);
void add_origin_header();
@ -321,13 +321,13 @@ public:
[[nodiscard]] bool cross_origin_embedder_policy_allows_credentials() const;
// Non-standard
void add_pending_response(Badge<Fetching::PendingResponse>, JS::NonnullGCPtr<Fetching::PendingResponse> pending_response)
void add_pending_response(Badge<Fetching::PendingResponse>, GC::Ref<Fetching::PendingResponse> pending_response)
{
VERIFY(!m_pending_responses.contains_slow(pending_response));
m_pending_responses.append(pending_response);
}
void remove_pending_response(Badge<Fetching::PendingResponse>, JS::NonnullGCPtr<Fetching::PendingResponse> pending_response)
void remove_pending_response(Badge<Fetching::PendingResponse>, GC::Ref<Fetching::PendingResponse> pending_response)
{
m_pending_responses.remove_first_matching([&](auto gc_ptr) { return gc_ptr == pending_response; });
}
@ -336,7 +336,7 @@ public:
void set_buffer_policy(BufferPolicy buffer_policy) { m_buffer_policy = buffer_policy; }
private:
explicit Request(JS::NonnullGCPtr<HeaderList>);
explicit Request(GC::Ref<HeaderList>);
virtual void visit_edges(JS::Cell::Visitor&) override;
@ -350,7 +350,7 @@ private:
// https://fetch.spec.whatwg.org/#concept-request-header-list
// A request has an associated header list (a header list). Unless stated otherwise it is empty.
JS::NonnullGCPtr<HeaderList> m_header_list;
GC::Ref<HeaderList> m_header_list;
// https://fetch.spec.whatwg.org/#unsafe-request-flag
// A request has an associated unsafe-request flag. Unless stated otherwise it is unset.
@ -362,7 +362,7 @@ private:
// https://fetch.spec.whatwg.org/#concept-request-client
// A request has an associated client (null or an environment settings object).
JS::GCPtr<HTML::EnvironmentSettingsObject> m_client;
GC::Ptr<HTML::EnvironmentSettingsObject> m_client;
// https://fetch.spec.whatwg.org/#concept-request-reserved-client
// A request has an associated reserved client (null, an environment, or an environment settings object). Unless
@ -524,7 +524,7 @@ private:
bool m_timing_allow_failed { false };
// Non-standard
Vector<JS::NonnullGCPtr<Fetching::PendingResponse>> m_pending_responses;
Vector<GC::Ref<Fetching::PendingResponse>> m_pending_responses;
BufferPolicy m_buffer_policy { BufferPolicy::BufferResponse };
};

View file

@ -6,7 +6,7 @@
#include <AK/Debug.h>
#include <AK/TypeCasts.h>
#include <LibJS/Heap/Heap.h>
#include <LibGC/Heap.h>
#include <LibJS/Runtime/Completion.h>
#include <LibJS/Runtime/VM.h>
#include <LibWeb/Bindings/MainThreadVM.h>
@ -17,13 +17,13 @@
namespace Web::Fetch::Infrastructure {
JS_DEFINE_ALLOCATOR(Response);
JS_DEFINE_ALLOCATOR(BasicFilteredResponse);
JS_DEFINE_ALLOCATOR(CORSFilteredResponse);
JS_DEFINE_ALLOCATOR(OpaqueFilteredResponse);
JS_DEFINE_ALLOCATOR(OpaqueRedirectFilteredResponse);
GC_DEFINE_ALLOCATOR(Response);
GC_DEFINE_ALLOCATOR(BasicFilteredResponse);
GC_DEFINE_ALLOCATOR(CORSFilteredResponse);
GC_DEFINE_ALLOCATOR(OpaqueFilteredResponse);
GC_DEFINE_ALLOCATOR(OpaqueRedirectFilteredResponse);
Response::Response(JS::NonnullGCPtr<HeaderList> header_list)
Response::Response(GC::Ref<HeaderList> header_list)
: m_header_list(header_list)
, m_response_time(UnixDateTime::now())
{
@ -36,7 +36,7 @@ void Response::visit_edges(JS::Cell::Visitor& visitor)
visitor.visit(m_body);
}
JS::NonnullGCPtr<Response> Response::create(JS::VM& vm)
GC::Ref<Response> Response::create(JS::VM& vm)
{
return vm.heap().allocate<Response>(HeaderList::create(vm));
}
@ -45,14 +45,14 @@ JS::NonnullGCPtr<Response> Response::create(JS::VM& vm)
// A network error is a response whose status is always 0, status message is always
// the empty byte sequence, header list is always empty, and body is always null.
JS::NonnullGCPtr<Response> Response::aborted_network_error(JS::VM& vm)
GC::Ref<Response> Response::aborted_network_error(JS::VM& vm)
{
auto response = network_error(vm, "Fetch has been aborted"sv);
response->set_aborted(true);
return response;
}
JS::NonnullGCPtr<Response> Response::network_error(JS::VM& vm, Variant<String, StringView> message)
GC::Ref<Response> Response::network_error(JS::VM& vm, Variant<String, StringView> message)
{
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Creating network error response with message: {}", message.visit([](auto const& s) -> StringView { return s; }));
auto response = Response::create(vm);
@ -64,7 +64,7 @@ JS::NonnullGCPtr<Response> Response::network_error(JS::VM& vm, Variant<String, S
}
// https://fetch.spec.whatwg.org/#appropriate-network-error
JS::NonnullGCPtr<Response> Response::appropriate_network_error(JS::VM& vm, FetchParams const& fetch_params)
GC::Ref<Response> Response::appropriate_network_error(JS::VM& vm, FetchParams const& fetch_params)
{
// 1. Assert: fetchParams is canceled.
VERIFY(fetch_params.is_canceled());
@ -147,7 +147,7 @@ ErrorOr<Optional<URL::URL>> Response::location_url(Optional<String> const& reque
}
// https://fetch.spec.whatwg.org/#concept-response-clone
JS::NonnullGCPtr<Response> Response::clone(JS::Realm& realm) const
GC::Ref<Response> Response::clone(JS::Realm& realm) const
{
// To clone a response response, run these steps:
auto& vm = realm.vm();
@ -192,7 +192,7 @@ JS::NonnullGCPtr<Response> Response::clone(JS::Realm& realm) const
}
// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#unsafe-response
JS::NonnullGCPtr<Response> Response::unsafe_response()
GC::Ref<Response> Response::unsafe_response()
{
// A response's unsafe response is its internal response if it has one, and the response itself otherwise.
if (is<FilteredResponse>(this))
@ -334,7 +334,7 @@ Optional<StringView> Response::network_error_message() const
return m_network_error_message->visit([](auto const& s) -> StringView { return s; });
}
FilteredResponse::FilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list)
FilteredResponse::FilteredResponse(GC::Ref<Response> internal_response, GC::Ref<HeaderList> header_list)
: Response(header_list)
, m_internal_response(internal_response)
{
@ -350,7 +350,7 @@ void FilteredResponse::visit_edges(JS::Cell::Visitor& visitor)
visitor.visit(m_internal_response);
}
JS::NonnullGCPtr<BasicFilteredResponse> BasicFilteredResponse::create(JS::VM& vm, JS::NonnullGCPtr<Response> internal_response)
GC::Ref<BasicFilteredResponse> BasicFilteredResponse::create(JS::VM& vm, GC::Ref<Response> internal_response)
{
// A basic filtered response is a filtered response whose type is "basic" and header list excludes
// any headers in internal responses header list whose name is a forbidden response-header name.
@ -363,7 +363,7 @@ JS::NonnullGCPtr<BasicFilteredResponse> BasicFilteredResponse::create(JS::VM& vm
return vm.heap().allocate<BasicFilteredResponse>(internal_response, header_list);
}
BasicFilteredResponse::BasicFilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list)
BasicFilteredResponse::BasicFilteredResponse(GC::Ref<Response> internal_response, GC::Ref<HeaderList> header_list)
: FilteredResponse(internal_response, header_list)
, m_header_list(header_list)
{
@ -375,7 +375,7 @@ void BasicFilteredResponse::visit_edges(JS::Cell::Visitor& visitor)
visitor.visit(m_header_list);
}
JS::NonnullGCPtr<CORSFilteredResponse> CORSFilteredResponse::create(JS::VM& vm, JS::NonnullGCPtr<Response> internal_response)
GC::Ref<CORSFilteredResponse> CORSFilteredResponse::create(JS::VM& vm, GC::Ref<Response> internal_response)
{
// A CORS filtered response is a filtered response whose type is "cors" and header list excludes
// any headers in internal responses header list whose name is not a CORS-safelisted response-header
@ -393,7 +393,7 @@ JS::NonnullGCPtr<CORSFilteredResponse> CORSFilteredResponse::create(JS::VM& vm,
return vm.heap().allocate<CORSFilteredResponse>(internal_response, header_list);
}
CORSFilteredResponse::CORSFilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list)
CORSFilteredResponse::CORSFilteredResponse(GC::Ref<Response> internal_response, GC::Ref<HeaderList> header_list)
: FilteredResponse(internal_response, header_list)
, m_header_list(header_list)
{
@ -405,14 +405,14 @@ void CORSFilteredResponse::visit_edges(JS::Cell::Visitor& visitor)
visitor.visit(m_header_list);
}
JS::NonnullGCPtr<OpaqueFilteredResponse> OpaqueFilteredResponse::create(JS::VM& vm, JS::NonnullGCPtr<Response> internal_response)
GC::Ref<OpaqueFilteredResponse> OpaqueFilteredResponse::create(JS::VM& vm, GC::Ref<Response> internal_response)
{
// An opaque filtered response is a filtered response whose type is "opaque", URL list is the empty list,
// status is 0, status message is the empty byte sequence, header list is empty, and body is null.
return vm.heap().allocate<OpaqueFilteredResponse>(internal_response, HeaderList::create(vm));
}
OpaqueFilteredResponse::OpaqueFilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list)
OpaqueFilteredResponse::OpaqueFilteredResponse(GC::Ref<Response> internal_response, GC::Ref<HeaderList> header_list)
: FilteredResponse(internal_response, header_list)
, m_header_list(header_list)
{
@ -425,14 +425,14 @@ void OpaqueFilteredResponse::visit_edges(JS::Cell::Visitor& visitor)
visitor.visit(m_body);
}
JS::NonnullGCPtr<OpaqueRedirectFilteredResponse> OpaqueRedirectFilteredResponse::create(JS::VM& vm, JS::NonnullGCPtr<Response> internal_response)
GC::Ref<OpaqueRedirectFilteredResponse> OpaqueRedirectFilteredResponse::create(JS::VM& vm, GC::Ref<Response> internal_response)
{
// An opaque-redirect filtered response is a filtered response whose type is "opaqueredirect",
// status is 0, status message is the empty byte sequence, header list is empty, and body is null.
return vm.heap().allocate<OpaqueRedirectFilteredResponse>(internal_response, HeaderList::create(vm));
}
OpaqueRedirectFilteredResponse::OpaqueRedirectFilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list)
OpaqueRedirectFilteredResponse::OpaqueRedirectFilteredResponse(GC::Ref<Response> internal_response, GC::Ref<HeaderList> header_list)
: FilteredResponse(internal_response, header_list)
, m_header_list(header_list)
{

View file

@ -12,9 +12,9 @@
#include <AK/Optional.h>
#include <AK/Time.h>
#include <AK/Vector.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibURL/URL.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h>
@ -24,8 +24,8 @@ namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#concept-response
class Response : public JS::Cell {
JS_CELL(Response, JS::Cell);
JS_DECLARE_ALLOCATOR(Response);
GC_CELL(Response, JS::Cell);
GC_DECLARE_ALLOCATOR(Response);
public:
enum class CacheState {
@ -56,10 +56,10 @@ public:
bool operator==(BodyInfo const&) const = default;
};
[[nodiscard]] static JS::NonnullGCPtr<Response> create(JS::VM&);
[[nodiscard]] static JS::NonnullGCPtr<Response> aborted_network_error(JS::VM&);
[[nodiscard]] static JS::NonnullGCPtr<Response> network_error(JS::VM&, Variant<String, StringView> message);
[[nodiscard]] static JS::NonnullGCPtr<Response> appropriate_network_error(JS::VM&, FetchParams const&);
[[nodiscard]] static GC::Ref<Response> create(JS::VM&);
[[nodiscard]] static GC::Ref<Response> aborted_network_error(JS::VM&);
[[nodiscard]] static GC::Ref<Response> network_error(JS::VM&, Variant<String, StringView> message);
[[nodiscard]] static GC::Ref<Response> appropriate_network_error(JS::VM&, FetchParams const&);
virtual ~Response() = default;
@ -79,12 +79,12 @@ public:
[[nodiscard]] virtual ReadonlyBytes status_message() const { return m_status_message; }
void set_status_message(ByteBuffer status_message) { m_status_message = move(status_message); }
[[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const { return m_header_list; }
void set_header_list(JS::NonnullGCPtr<HeaderList> header_list) { m_header_list = header_list; }
[[nodiscard]] virtual GC::Ref<HeaderList> header_list() const { return m_header_list; }
void set_header_list(GC::Ref<HeaderList> header_list) { m_header_list = header_list; }
[[nodiscard]] virtual JS::GCPtr<Body> const& body() const { return m_body; }
[[nodiscard]] virtual JS::GCPtr<Body>& body() { return m_body; }
void set_body(JS::GCPtr<Body> body) { m_body = move(body); }
[[nodiscard]] virtual GC::Ptr<Body> const& body() const { return m_body; }
[[nodiscard]] virtual GC::Ptr<Body>& body() { return m_body; }
void set_body(GC::Ptr<Body> body) { m_body = move(body); }
[[nodiscard]] virtual Optional<CacheState> const& cache_state() const { return m_cache_state; }
void set_cache_state(Optional<CacheState> cache_state) { m_cache_state = move(cache_state); }
@ -113,9 +113,9 @@ public:
[[nodiscard]] Optional<URL::URL const&> url() const;
[[nodiscard]] ErrorOr<Optional<URL::URL>> location_url(Optional<String> const& request_fragment) const;
[[nodiscard]] JS::NonnullGCPtr<Response> clone(JS::Realm&) const;
[[nodiscard]] GC::Ref<Response> clone(JS::Realm&) const;
[[nodiscard]] JS::NonnullGCPtr<Response> unsafe_response();
[[nodiscard]] GC::Ref<Response> unsafe_response();
[[nodiscard]] bool is_cors_cross_origin() const;
@ -127,7 +127,7 @@ public:
[[nodiscard]] Optional<StringView> network_error_message() const;
protected:
explicit Response(JS::NonnullGCPtr<HeaderList>);
explicit Response(GC::Ref<HeaderList>);
virtual void visit_edges(JS::Cell::Visitor&) override;
@ -154,11 +154,11 @@ private:
// https://fetch.spec.whatwg.org/#concept-response-header-list
// A response has an associated header list (a header list). Unless stated otherwise it is empty.
JS::NonnullGCPtr<HeaderList> m_header_list;
GC::Ref<HeaderList> m_header_list;
// https://fetch.spec.whatwg.org/#concept-response-body
// A response has an associated body (null or a body). Unless stated otherwise it is null.
JS::GCPtr<Body> m_body;
GC::Ptr<Body> m_body;
// https://fetch.spec.whatwg.org/#concept-response-cache-state
// A response has an associated cache state (the empty string, "local", or "validated"). Unless stated otherwise, it is the empty string.
@ -209,10 +209,10 @@ public:
// https://fetch.spec.whatwg.org/#concept-filtered-response
class FilteredResponse : public Response {
JS_CELL(FilteredResponse, Response);
GC_CELL(FilteredResponse, Response);
public:
FilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>);
FilteredResponse(GC::Ref<Response>, GC::Ref<HeaderList>);
virtual ~FilteredResponse() = 0;
[[nodiscard]] virtual Type type() const override { return m_internal_response->type(); }
@ -221,9 +221,9 @@ public:
[[nodiscard]] virtual Vector<URL::URL>& url_list() override { return m_internal_response->url_list(); }
[[nodiscard]] virtual Status status() const override { return m_internal_response->status(); }
[[nodiscard]] virtual ReadonlyBytes status_message() const override { return m_internal_response->status_message(); }
[[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_internal_response->header_list(); }
[[nodiscard]] virtual JS::GCPtr<Body> const& body() const override { return m_internal_response->body(); }
[[nodiscard]] virtual JS::GCPtr<Body>& body() override { return m_internal_response->body(); }
[[nodiscard]] virtual GC::Ref<HeaderList> header_list() const override { return m_internal_response->header_list(); }
[[nodiscard]] virtual GC::Ptr<Body> const& body() const override { return m_internal_response->body(); }
[[nodiscard]] virtual GC::Ptr<Body>& body() override { return m_internal_response->body(); }
[[nodiscard]] virtual Optional<CacheState> const& cache_state() const override { return m_internal_response->cache_state(); }
[[nodiscard]] virtual Vector<ByteBuffer> const& cors_exposed_header_name_list() const override { return m_internal_response->cors_exposed_header_name_list(); }
[[nodiscard]] virtual bool range_requested() const override { return m_internal_response->range_requested(); }
@ -231,102 +231,102 @@ public:
[[nodiscard]] virtual bool timing_allow_passed() const override { return m_internal_response->timing_allow_passed(); }
[[nodiscard]] virtual BodyInfo const& body_info() const override { return m_internal_response->body_info(); }
[[nodiscard]] JS::NonnullGCPtr<Response> internal_response() const { return m_internal_response; }
[[nodiscard]] GC::Ref<Response> internal_response() const { return m_internal_response; }
protected:
virtual void visit_edges(JS::Cell::Visitor&) override;
private:
// https://fetch.spec.whatwg.org/#concept-internal-response
JS::NonnullGCPtr<Response> m_internal_response;
GC::Ref<Response> m_internal_response;
};
// https://fetch.spec.whatwg.org/#concept-filtered-response-basic
class BasicFilteredResponse final : public FilteredResponse {
JS_CELL(BasicFilteredResponse, FilteredResponse);
JS_DECLARE_ALLOCATOR(BasicFilteredResponse);
GC_CELL(BasicFilteredResponse, FilteredResponse);
GC_DECLARE_ALLOCATOR(BasicFilteredResponse);
public:
[[nodiscard]] static JS::NonnullGCPtr<BasicFilteredResponse> create(JS::VM&, JS::NonnullGCPtr<Response>);
[[nodiscard]] static GC::Ref<BasicFilteredResponse> create(JS::VM&, GC::Ref<Response>);
[[nodiscard]] virtual Type type() const override { return Type::Basic; }
[[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_header_list; }
[[nodiscard]] virtual GC::Ref<HeaderList> header_list() const override { return m_header_list; }
private:
BasicFilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>);
BasicFilteredResponse(GC::Ref<Response>, GC::Ref<HeaderList>);
virtual void visit_edges(JS::Cell::Visitor&) override;
JS::NonnullGCPtr<HeaderList> m_header_list;
GC::Ref<HeaderList> m_header_list;
};
// https://fetch.spec.whatwg.org/#concept-filtered-response-cors
class CORSFilteredResponse final : public FilteredResponse {
JS_CELL(CORSFilteredResponse, FilteredResponse);
JS_DECLARE_ALLOCATOR(CORSFilteredResponse);
GC_CELL(CORSFilteredResponse, FilteredResponse);
GC_DECLARE_ALLOCATOR(CORSFilteredResponse);
public:
[[nodiscard]] static JS::NonnullGCPtr<CORSFilteredResponse> create(JS::VM&, JS::NonnullGCPtr<Response>);
[[nodiscard]] static GC::Ref<CORSFilteredResponse> create(JS::VM&, GC::Ref<Response>);
[[nodiscard]] virtual Type type() const override { return Type::CORS; }
[[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_header_list; }
[[nodiscard]] virtual GC::Ref<HeaderList> header_list() const override { return m_header_list; }
private:
CORSFilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>);
CORSFilteredResponse(GC::Ref<Response>, GC::Ref<HeaderList>);
virtual void visit_edges(JS::Cell::Visitor&) override;
JS::NonnullGCPtr<HeaderList> m_header_list;
GC::Ref<HeaderList> m_header_list;
};
// https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
class OpaqueFilteredResponse final : public FilteredResponse {
JS_CELL(OpaqueFilteredResponse, FilteredResponse);
JS_DECLARE_ALLOCATOR(OpaqueFilteredResponse);
GC_CELL(OpaqueFilteredResponse, FilteredResponse);
GC_DECLARE_ALLOCATOR(OpaqueFilteredResponse);
public:
[[nodiscard]] static JS::NonnullGCPtr<OpaqueFilteredResponse> create(JS::VM&, JS::NonnullGCPtr<Response>);
[[nodiscard]] static GC::Ref<OpaqueFilteredResponse> create(JS::VM&, GC::Ref<Response>);
[[nodiscard]] virtual Type type() const override { return Type::Opaque; }
[[nodiscard]] virtual Vector<URL::URL> const& url_list() const override { return m_url_list; }
[[nodiscard]] virtual Vector<URL::URL>& url_list() override { return m_url_list; }
[[nodiscard]] virtual Status status() const override { return 0; }
[[nodiscard]] virtual ReadonlyBytes status_message() const override { return {}; }
[[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_header_list; }
[[nodiscard]] virtual JS::GCPtr<Body> const& body() const override { return m_body; }
[[nodiscard]] virtual JS::GCPtr<Body>& body() override { return m_body; }
[[nodiscard]] virtual GC::Ref<HeaderList> header_list() const override { return m_header_list; }
[[nodiscard]] virtual GC::Ptr<Body> const& body() const override { return m_body; }
[[nodiscard]] virtual GC::Ptr<Body>& body() override { return m_body; }
private:
OpaqueFilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>);
OpaqueFilteredResponse(GC::Ref<Response>, GC::Ref<HeaderList>);
virtual void visit_edges(JS::Cell::Visitor&) override;
Vector<URL::URL> m_url_list;
JS::NonnullGCPtr<HeaderList> m_header_list;
JS::GCPtr<Body> m_body;
GC::Ref<HeaderList> m_header_list;
GC::Ptr<Body> m_body;
};
// https://fetch.spec.whatwg.org/#concept-filtered-response-opaque-redirect
class OpaqueRedirectFilteredResponse final : public FilteredResponse {
JS_CELL(OpaqueRedirectFilteredResponse, FilteredResponse);
JS_DECLARE_ALLOCATOR(OpaqueRedirectFilteredResponse);
GC_CELL(OpaqueRedirectFilteredResponse, FilteredResponse);
GC_DECLARE_ALLOCATOR(OpaqueRedirectFilteredResponse);
public:
[[nodiscard]] static JS::NonnullGCPtr<OpaqueRedirectFilteredResponse> create(JS::VM&, JS::NonnullGCPtr<Response>);
[[nodiscard]] static GC::Ref<OpaqueRedirectFilteredResponse> create(JS::VM&, GC::Ref<Response>);
[[nodiscard]] virtual Type type() const override { return Type::OpaqueRedirect; }
[[nodiscard]] virtual Status status() const override { return 0; }
[[nodiscard]] virtual ReadonlyBytes status_message() const override { return {}; }
[[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_header_list; }
[[nodiscard]] virtual JS::GCPtr<Body> const& body() const override { return m_body; }
[[nodiscard]] virtual JS::GCPtr<Body>& body() override { return m_body; }
[[nodiscard]] virtual GC::Ref<HeaderList> header_list() const override { return m_header_list; }
[[nodiscard]] virtual GC::Ptr<Body> const& body() const override { return m_body; }
[[nodiscard]] virtual GC::Ptr<Body>& body() override { return m_body; }
private:
OpaqueRedirectFilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>);
OpaqueRedirectFilteredResponse(GC::Ref<Response>, GC::Ref<HeaderList>);
virtual void visit_edges(JS::Cell::Visitor&) override;
JS::NonnullGCPtr<HeaderList> m_header_list;
JS::GCPtr<Body> m_body;
GC::Ref<HeaderList> m_header_list;
GC::Ptr<Body> m_body;
};
}

View file

@ -10,17 +10,17 @@
namespace Web::Fetch::Infrastructure {
JS_DEFINE_ALLOCATOR(IncrementalReadLoopReadRequest);
GC_DEFINE_ALLOCATOR(IncrementalReadLoopReadRequest);
void IncrementalReadLoopReadRequest::on_chunk(JS::Value chunk)
{
auto& realm = m_reader->realm();
// 1. Let continueAlgorithm be null.
JS::GCPtr<JS::HeapFunction<void()>> continue_algorithm;
GC::Ptr<GC::Function<void()>> continue_algorithm;
// 2. If chunk is not a Uint8Array object, then set continueAlgorithm to this step: run processBodyError given a TypeError.
if (!chunk.is_object() || !is<JS::Uint8Array>(chunk.as_object())) {
continue_algorithm = JS::create_heap_function(realm.heap(), [&realm, process_body_error = m_process_body_error] {
continue_algorithm = GC::create_function(realm.heap(), [&realm, process_body_error = m_process_body_error] {
process_body_error->function()(JS::TypeError::create(realm, "Chunk data is not Uint8Array"sv));
});
}
@ -31,7 +31,7 @@ void IncrementalReadLoopReadRequest::on_chunk(JS::Value chunk)
auto& uint8_array = static_cast<JS::Uint8Array&>(chunk.as_object());
auto bytes = MUST(ByteBuffer::copy(uint8_array.data()));
// 2. Set continueAlgorithm to these steps:
continue_algorithm = JS::create_heap_function(realm.heap(), [bytes = move(bytes), body = m_body, reader = m_reader, task_destination = m_task_destination, process_body_chunk = m_process_body_chunk, process_end_of_body = m_process_end_of_body, process_body_error = m_process_body_error] {
continue_algorithm = GC::create_function(realm.heap(), [bytes = move(bytes), body = m_body, reader = m_reader, task_destination = m_task_destination, process_body_chunk = m_process_body_chunk, process_end_of_body = m_process_end_of_body, process_body_error = m_process_body_error] {
HTML::TemporaryExecutionContext execution_context { reader->realm(), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
// 1. Run processBodyChunk given bytes.
process_body_chunk->function()(move(bytes));
@ -48,7 +48,7 @@ void IncrementalReadLoopReadRequest::on_chunk(JS::Value chunk)
void IncrementalReadLoopReadRequest::on_close()
{
// 1. Queue a fetch task given processEndOfBody and taskDestination.
Fetch::Infrastructure::queue_fetch_task(m_task_destination, JS::create_heap_function(m_reader->heap(), [this] {
Fetch::Infrastructure::queue_fetch_task(m_task_destination, GC::create_function(m_reader->heap(), [this] {
m_process_end_of_body->function()();
}));
}
@ -56,12 +56,12 @@ void IncrementalReadLoopReadRequest::on_close()
void IncrementalReadLoopReadRequest::on_error(JS::Value error)
{
// 1. Queue a fetch task to run processBodyError given e, with taskDestination.
Fetch::Infrastructure::queue_fetch_task(m_task_destination, JS::create_heap_function(m_reader->heap(), [this, error = move(error)] {
Fetch::Infrastructure::queue_fetch_task(m_task_destination, GC::create_function(m_reader->heap(), [this, error = move(error)] {
m_process_body_error->function()(error);
}));
}
IncrementalReadLoopReadRequest::IncrementalReadLoopReadRequest(JS::NonnullGCPtr<Body> body, JS::NonnullGCPtr<Streams::ReadableStreamDefaultReader> reader, JS::NonnullGCPtr<JS::Object> task_destination, Body::ProcessBodyChunkCallback process_body_chunk, Body::ProcessEndOfBodyCallback process_end_of_body, Body::ProcessBodyErrorCallback process_body_error)
IncrementalReadLoopReadRequest::IncrementalReadLoopReadRequest(GC::Ref<Body> body, GC::Ref<Streams::ReadableStreamDefaultReader> reader, GC::Ref<JS::Object> task_destination, Body::ProcessBodyChunkCallback process_body_chunk, Body::ProcessEndOfBodyCallback process_end_of_body, Body::ProcessBodyErrorCallback process_body_error)
: m_body(body)
, m_reader(reader)
, m_task_destination(task_destination)

View file

@ -13,11 +13,11 @@ namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#incrementally-read-loop
class IncrementalReadLoopReadRequest : public Streams::ReadRequest {
JS_CELL(IncrementalReadLoopReadRequest, Streams::ReadRequest);
JS_DECLARE_ALLOCATOR(IncrementalReadLoopReadRequest);
GC_CELL(IncrementalReadLoopReadRequest, Streams::ReadRequest);
GC_DECLARE_ALLOCATOR(IncrementalReadLoopReadRequest);
public:
IncrementalReadLoopReadRequest(JS::NonnullGCPtr<Body>, JS::NonnullGCPtr<Streams::ReadableStreamDefaultReader>, JS::NonnullGCPtr<JS::Object> task_destination, Body::ProcessBodyChunkCallback, Body::ProcessEndOfBodyCallback, Body::ProcessBodyErrorCallback);
IncrementalReadLoopReadRequest(GC::Ref<Body>, GC::Ref<Streams::ReadableStreamDefaultReader>, GC::Ref<JS::Object> task_destination, Body::ProcessBodyChunkCallback, Body::ProcessEndOfBodyCallback, Body::ProcessBodyErrorCallback);
virtual void on_chunk(JS::Value chunk) override;
virtual void on_close() override;
@ -26,9 +26,9 @@ public:
private:
virtual void visit_edges(Visitor&) override;
JS::NonnullGCPtr<Body> m_body;
JS::NonnullGCPtr<Streams::ReadableStreamDefaultReader> m_reader;
JS::NonnullGCPtr<JS::Object> m_task_destination;
GC::Ref<Body> m_body;
GC::Ref<Streams::ReadableStreamDefaultReader> m_reader;
GC::Ref<JS::Object> m_task_destination;
Body::ProcessBodyChunkCallback m_process_body_chunk;
Body::ProcessEndOfBodyCallback m_process_end_of_body;
Body::ProcessBodyErrorCallback m_process_body_error;

View file

@ -11,7 +11,7 @@
namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#queue-a-fetch-task
HTML::TaskID queue_fetch_task(JS::Object& task_destination, JS::NonnullGCPtr<JS::HeapFunction<void()>> algorithm)
HTML::TaskID queue_fetch_task(JS::Object& task_destination, GC::Ref<GC::Function<void()>> algorithm)
{
// FIXME: 1. If taskDestination is a parallel queue, then enqueue algorithm to taskDestination.
@ -21,12 +21,12 @@ HTML::TaskID queue_fetch_task(JS::Object& task_destination, JS::NonnullGCPtr<JS:
// AD-HOC: This overload allows tracking the queued task within the fetch controller so that we may cancel queued tasks
// when the spec indicates that we must stop an ongoing fetch.
HTML::TaskID queue_fetch_task(JS::NonnullGCPtr<FetchController> fetch_controller, JS::Object& task_destination, JS::NonnullGCPtr<JS::HeapFunction<void()>> algorithm)
HTML::TaskID queue_fetch_task(GC::Ref<FetchController> fetch_controller, JS::Object& task_destination, GC::Ref<GC::Function<void()>> algorithm)
{
auto fetch_task_id = fetch_controller->next_fetch_task_id();
auto& heap = task_destination.heap();
auto html_task_id = queue_fetch_task(task_destination, JS::create_heap_function(heap, [fetch_controller, fetch_task_id, algorithm]() {
auto html_task_id = queue_fetch_task(task_destination, GC::create_function(heap, [fetch_controller, fetch_task_id, algorithm]() {
fetch_controller->fetch_task_complete(fetch_task_id);
algorithm->function()();
}));

View file

@ -7,17 +7,17 @@
#pragma once
#include <AK/Variant.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Forward.h>
#include <LibWeb/HTML/EventLoop/Task.h>
namespace Web::Fetch::Infrastructure {
// FIXME: 'or a parallel queue'
using TaskDestination = Variant<Empty, JS::NonnullGCPtr<JS::Object>>;
using TaskDestination = Variant<Empty, GC::Ref<JS::Object>>;
HTML::TaskID queue_fetch_task(JS::Object&, JS::NonnullGCPtr<JS::HeapFunction<void()>>);
HTML::TaskID queue_fetch_task(JS::NonnullGCPtr<FetchController>, JS::Object&, JS::NonnullGCPtr<JS::HeapFunction<void()>>);
HTML::TaskID queue_fetch_task(JS::Object&, GC::Ref<GC::Function<void()>>);
HTML::TaskID queue_fetch_task(GC::Ref<FetchController>, JS::Object&, GC::Ref<GC::Function<void()>>);
}

View file

@ -21,9 +21,9 @@
namespace Web::Fetch {
JS_DEFINE_ALLOCATOR(Request);
GC_DEFINE_ALLOCATOR(Request);
Request::Request(JS::Realm& realm, JS::NonnullGCPtr<Infrastructure::Request> request)
Request::Request(JS::Realm& realm, GC::Ref<Infrastructure::Request> request)
: PlatformObject(realm)
, m_request(request)
{
@ -56,32 +56,32 @@ Optional<MimeSniff::MimeType> Request::mime_type_impl() const
// https://fetch.spec.whatwg.org/#concept-body-body
// https://fetch.spec.whatwg.org/#ref-for-concept-body-body%E2%91%A7
JS::GCPtr<Infrastructure::Body const> Request::body_impl() const
GC::Ptr<Infrastructure::Body const> Request::body_impl() const
{
// Objects including the Body interface mixin have an associated body (null or a body).
// A Request objects body is its requests body.
return m_request->body().visit(
[](JS::NonnullGCPtr<Infrastructure::Body> const& b) -> JS::GCPtr<Infrastructure::Body const> { return b; },
[](Empty) -> JS::GCPtr<Infrastructure::Body const> { return nullptr; },
[](GC::Ref<Infrastructure::Body> const& b) -> GC::Ptr<Infrastructure::Body const> { return b; },
[](Empty) -> GC::Ptr<Infrastructure::Body const> { return nullptr; },
// A byte sequence will be safely extracted into a body early on in fetch.
[](ByteBuffer const&) -> JS::GCPtr<Infrastructure::Body const> { VERIFY_NOT_REACHED(); });
[](ByteBuffer const&) -> GC::Ptr<Infrastructure::Body const> { VERIFY_NOT_REACHED(); });
}
// https://fetch.spec.whatwg.org/#concept-body-body
// https://fetch.spec.whatwg.org/#ref-for-concept-body-body%E2%91%A7
JS::GCPtr<Infrastructure::Body> Request::body_impl()
GC::Ptr<Infrastructure::Body> Request::body_impl()
{
// Objects including the Body interface mixin have an associated body (null or a body).
// A Request objects body is its requests body.
return m_request->body().visit(
[](JS::NonnullGCPtr<Infrastructure::Body>& b) -> JS::GCPtr<Infrastructure::Body> { return b; },
[](Empty) -> JS::GCPtr<Infrastructure::Body> { return {}; },
[](GC::Ref<Infrastructure::Body>& b) -> GC::Ptr<Infrastructure::Body> { return b; },
[](Empty) -> GC::Ptr<Infrastructure::Body> { return {}; },
// A byte sequence will be safely extracted into a body early on in fetch.
[](ByteBuffer&) -> JS::GCPtr<Infrastructure::Body> { VERIFY_NOT_REACHED(); });
[](ByteBuffer&) -> GC::Ptr<Infrastructure::Body> { VERIFY_NOT_REACHED(); });
}
// https://fetch.spec.whatwg.org/#request-create
JS::NonnullGCPtr<Request> Request::create(JS::Realm& realm, JS::NonnullGCPtr<Infrastructure::Request> request, Headers::Guard guard, JS::NonnullGCPtr<DOM::AbortSignal> signal)
GC::Ref<Request> Request::create(JS::Realm& realm, GC::Ref<Infrastructure::Request> request, Headers::Guard guard, GC::Ref<DOM::AbortSignal> signal)
{
// 1. Let requestObject be a new Request object with realm.
// 2. Set requestObjects request to request.
@ -99,7 +99,7 @@ JS::NonnullGCPtr<Request> Request::create(JS::Realm& realm, JS::NonnullGCPtr<Inf
}
// https://fetch.spec.whatwg.org/#dom-request
WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm& realm, RequestInfo const& input, RequestInit const& init)
WebIDL::ExceptionOr<GC::Ref<Request>> Request::construct_impl(JS::Realm& realm, RequestInfo const& input, RequestInit const& init)
{
auto& vm = realm.vm();
@ -107,7 +107,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
auto request_object = realm.create<Request>(realm, Infrastructure::Request::create(vm));
// 1. Let request be null.
JS::GCPtr<Infrastructure::Request> input_request;
GC::Ptr<Infrastructure::Request> input_request;
// 2. Let fallbackMode be null.
Optional<Infrastructure::Request::Mode> fallback_mode;
@ -141,13 +141,13 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 6. Otherwise:
else {
// 1. Assert: input is a Request object.
VERIFY(input.has<JS::Handle<Request>>());
VERIFY(input.has<GC::Root<Request>>());
// 2. Set request to inputs request.
input_request = input.get<JS::Handle<Request>>()->request();
input_request = input.get<GC::Root<Request>>()->request();
// 3. Set signal to inputs signal.
input_signal = input.get<JS::Handle<Request>>()->signal();
input_signal = input.get<GC::Root<Request>>()->signal();
}
// 7. Let origin be thiss relevant settings objects origin.
@ -157,8 +157,8 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
auto window = Infrastructure::Request::WindowType { Infrastructure::Request::Window::Client };
// 9. If requests window is an environment settings object and its origin is same origin with origin, then set window to requests window.
if (input_request->window().has<JS::GCPtr<HTML::EnvironmentSettingsObject>>()) {
auto eso = input_request->window().get<JS::GCPtr<HTML::EnvironmentSettingsObject>>();
if (input_request->window().has<GC::Ptr<HTML::EnvironmentSettingsObject>>()) {
auto eso = input_request->window().get<GC::Ptr<HTML::EnvironmentSettingsObject>>();
if (eso->origin().is_same_origin(origin))
window = input_request->window();
}
@ -394,7 +394,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 29. Let signals be « signal » if signal is non-null; otherwise « ».
auto& this_relevant_realm = HTML::relevant_realm(*request_object);
Vector<JS::Handle<DOM::AbortSignal>> signals;
Vector<GC::Root<DOM::AbortSignal>> signals;
if (input_signal != nullptr)
signals.append(*input_signal);
@ -418,7 +418,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 33. If init is not empty, then:
if (!init.is_empty()) {
// 1. Let headers be a copy of thiss headers and its associated header list.
auto headers = Variant<HeadersInit, JS::NonnullGCPtr<Infrastructure::HeaderList>> { request_object->headers()->header_list() };
auto headers = Variant<HeadersInit, GC::Ref<Infrastructure::HeaderList>> { request_object->headers()->header_list() };
// 2. If init["headers"] exists, then set headers to init["headers"].
if (init.headers.has_value())
@ -428,7 +428,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
request_object->headers()->header_list()->clear();
// 4. If headers is a Headers object, then for each header of its header list, append header to thiss headers.
if (auto* header_list = headers.get_pointer<JS::NonnullGCPtr<Infrastructure::HeaderList>>()) {
if (auto* header_list = headers.get_pointer<GC::Ref<Infrastructure::HeaderList>>()) {
for (auto& header : *header_list->ptr())
TRY(request_object->headers()->append(Infrastructure::Header::from_string_pair(header.name, header.value)));
}
@ -440,15 +440,15 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 34. Let inputBody be inputs requests body if input is a Request object; otherwise null.
Optional<Infrastructure::Request::BodyType const&> input_body;
if (input.has<JS::Handle<Request>>())
input_body = input.get<JS::Handle<Request>>()->request()->body();
if (input.has<GC::Root<Request>>())
input_body = input.get<GC::Root<Request>>()->request()->body();
// 35. If either init["body"] exists and is non-null or inputBody is non-null, and requests method is `GET` or `HEAD`, then throw a TypeError.
if (((init.body.has_value() && (*init.body).has_value()) || (input_body.has_value() && !input_body.value().has<Empty>())) && StringView { request->method() }.is_one_of("GET"sv, "HEAD"sv))
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Method must not be GET or HEAD when body is provided"sv };
// 36. Let initBody be null.
JS::GCPtr<Infrastructure::Body> init_body;
GC::Ptr<Infrastructure::Body> init_body;
// 37. If init["body"] exists and is non-null, then:
if (init.body.has_value() && (*init.body).has_value()) {
@ -473,7 +473,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 39. If inputOrInitBody is non-null and inputOrInitBodys source is null, then:
// FIXME: The spec doesn't check if inputOrInitBody is a body before accessing source.
if (input_or_init_body.has_value() && input_or_init_body->has<JS::NonnullGCPtr<Infrastructure::Body>>() && input_or_init_body->get<JS::NonnullGCPtr<Infrastructure::Body>>()->source().has<Empty>()) {
if (input_or_init_body.has_value() && input_or_init_body->has<GC::Ref<Infrastructure::Body>>() && input_or_init_body->get<GC::Ref<Infrastructure::Body>>()->source().has<Empty>()) {
// 1. If initBody is non-null and init["duplex"] does not exist, then throw a TypeError.
if (init_body && !init.duplex.has_value())
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Body without source requires 'duplex' value to be set"sv };
@ -492,7 +492,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 41. If initBody is null and inputBody is non-null, then:
if (!init_body && input_body.has_value()) {
// 2. If input is unusable, then throw a TypeError.
if (input.has<JS::Handle<Request>>() && input.get<JS::Handle<Request>>()->is_unusable())
if (input.has<GC::Root<Request>>() && input.get<GC::Root<Request>>()->is_unusable())
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Request is unusable"sv };
// FIXME: 2. Set finalBody to the result of creating a proxy for inputBody.
@ -502,7 +502,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
if (final_body.has_value())
request_object->request()->set_body(*final_body);
return JS::NonnullGCPtr { *request_object };
return GC::Ref { *request_object };
}
// https://fetch.spec.whatwg.org/#dom-request-method
@ -520,7 +520,7 @@ String Request::url() const
}
// https://fetch.spec.whatwg.org/#dom-request-headers
JS::NonnullGCPtr<Headers> Request::headers() const
GC::Ref<Headers> Request::headers() const
{
// The headers getter steps are to return thiss headers.
return *m_headers;
@ -619,7 +619,7 @@ bool Request::is_history_navigation() const
}
// https://fetch.spec.whatwg.org/#dom-request-signal
JS::NonnullGCPtr<DOM::AbortSignal> Request::signal() const
GC::Ref<DOM::AbortSignal> Request::signal() const
{
// The signal getter steps are to return thiss signal.
return *m_signal;
@ -633,7 +633,7 @@ Bindings::RequestDuplex Request::duplex() const
}
// https://fetch.spec.whatwg.org/#dom-request-clone
WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::clone() const
WebIDL::ExceptionOr<GC::Ref<Request>> Request::clone() const
{
auto& realm = this->realm();

View file

@ -7,8 +7,8 @@
#pragma once
#include <AK/Forward.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/Bindings/RequestPrototype.h>
#include <LibWeb/Fetch/Body.h>
@ -20,7 +20,7 @@
namespace Web::Fetch {
// https://fetch.spec.whatwg.org/#requestinfo
using RequestInfo = Variant<JS::Handle<Request>, String>;
using RequestInfo = Variant<GC::Root<Request>, String>;
// https://fetch.spec.whatwg.org/#requestinit
struct RequestInit {
@ -35,7 +35,7 @@ struct RequestInit {
Optional<Bindings::RequestRedirect> redirect;
Optional<String> integrity;
Optional<bool> keepalive;
Optional<JS::GCPtr<DOM::AbortSignal>> signal;
Optional<GC::Ptr<DOM::AbortSignal>> signal;
Optional<Bindings::RequestDuplex> duplex;
Optional<Bindings::RequestPriority> priority;
Optional<JS::Value> window;
@ -66,27 +66,27 @@ class Request final
: public Bindings::PlatformObject
, public BodyMixin {
WEB_PLATFORM_OBJECT(Request, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(Request);
GC_DECLARE_ALLOCATOR(Request);
public:
[[nodiscard]] static JS::NonnullGCPtr<Request> create(JS::Realm&, JS::NonnullGCPtr<Infrastructure::Request>, Headers::Guard, JS::NonnullGCPtr<DOM::AbortSignal>);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> construct_impl(JS::Realm&, RequestInfo const& input, RequestInit const& init = {});
[[nodiscard]] static GC::Ref<Request> create(JS::Realm&, GC::Ref<Infrastructure::Request>, Headers::Guard, GC::Ref<DOM::AbortSignal>);
static WebIDL::ExceptionOr<GC::Ref<Request>> construct_impl(JS::Realm&, RequestInfo const& input, RequestInit const& init = {});
virtual ~Request() override;
// ^BodyMixin
virtual Optional<MimeSniff::MimeType> mime_type_impl() const override;
virtual JS::GCPtr<Infrastructure::Body> body_impl() override;
virtual JS::GCPtr<Infrastructure::Body const> body_impl() const override;
virtual GC::Ptr<Infrastructure::Body> body_impl() override;
virtual GC::Ptr<Infrastructure::Body const> body_impl() const override;
virtual Bindings::PlatformObject& as_platform_object() override { return *this; }
virtual Bindings::PlatformObject const& as_platform_object() const override { return *this; }
[[nodiscard]] JS::NonnullGCPtr<Infrastructure::Request> request() const { return m_request; }
[[nodiscard]] GC::Ref<Infrastructure::Request> request() const { return m_request; }
// JS API functions
[[nodiscard]] String method() const;
[[nodiscard]] String url() const;
[[nodiscard]] JS::NonnullGCPtr<Headers> headers() const;
[[nodiscard]] GC::Ref<Headers> headers() const;
[[nodiscard]] Bindings::RequestDestination destination() const;
[[nodiscard]] String referrer() const;
[[nodiscard]] Bindings::ReferrerPolicy referrer_policy() const;
@ -98,27 +98,27 @@ public:
[[nodiscard]] bool keepalive() const;
[[nodiscard]] bool is_reload_navigation() const;
[[nodiscard]] bool is_history_navigation() const;
[[nodiscard]] JS::NonnullGCPtr<DOM::AbortSignal> signal() const;
[[nodiscard]] GC::Ref<DOM::AbortSignal> signal() const;
[[nodiscard]] Bindings::RequestDuplex duplex() const;
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> clone() const;
[[nodiscard]] WebIDL::ExceptionOr<GC::Ref<Request>> clone() const;
private:
Request(JS::Realm&, JS::NonnullGCPtr<Infrastructure::Request>);
Request(JS::Realm&, GC::Ref<Infrastructure::Request>);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
// https://fetch.spec.whatwg.org/#concept-request-request
// A Request object has an associated request (a request).
JS::NonnullGCPtr<Infrastructure::Request> m_request;
GC::Ref<Infrastructure::Request> m_request;
// https://fetch.spec.whatwg.org/#request-headers
// A Request object also has an associated headers (null or a Headers object), initially null.
JS::GCPtr<Headers> m_headers;
GC::Ptr<Headers> m_headers;
// https://fetch.spec.whatwg.org/#request-signal
// A Request object has an associated signal (null or an AbortSignal object), initially null.
JS::GCPtr<DOM::AbortSignal> m_signal;
GC::Ptr<DOM::AbortSignal> m_signal;
};
}

View file

@ -19,9 +19,9 @@
namespace Web::Fetch {
JS_DEFINE_ALLOCATOR(Response);
GC_DEFINE_ALLOCATOR(Response);
Response::Response(JS::Realm& realm, JS::NonnullGCPtr<Infrastructure::Response> response)
Response::Response(JS::Realm& realm, GC::Ref<Infrastructure::Response> response)
: PlatformObject(realm)
, m_response(response)
{
@ -53,7 +53,7 @@ Optional<MimeSniff::MimeType> Response::mime_type_impl() const
// https://fetch.spec.whatwg.org/#concept-body-body
// https://fetch.spec.whatwg.org/#ref-for-concept-body-body%E2%91%A8
JS::GCPtr<Infrastructure::Body const> Response::body_impl() const
GC::Ptr<Infrastructure::Body const> Response::body_impl() const
{
// Objects including the Body interface mixin have an associated body (null or a body).
// A Response objects body is its responses body.
@ -62,7 +62,7 @@ JS::GCPtr<Infrastructure::Body const> Response::body_impl() const
// https://fetch.spec.whatwg.org/#concept-body-body
// https://fetch.spec.whatwg.org/#ref-for-concept-body-body%E2%91%A8
JS::GCPtr<Infrastructure::Body> Response::body_impl()
GC::Ptr<Infrastructure::Body> Response::body_impl()
{
// Objects including the Body interface mixin have an associated body (null or a body).
// A Response objects body is its responses body.
@ -70,7 +70,7 @@ JS::GCPtr<Infrastructure::Body> Response::body_impl()
}
// https://fetch.spec.whatwg.org/#response-create
JS::NonnullGCPtr<Response> Response::create(JS::Realm& realm, JS::NonnullGCPtr<Infrastructure::Response> response, Headers::Guard guard)
GC::Ref<Response> Response::create(JS::Realm& realm, GC::Ref<Infrastructure::Response> response, Headers::Guard guard)
{
// 1. Let responseObject be a new Response object with realm.
// 2. Set responseObjects response to response.
@ -126,7 +126,7 @@ WebIDL::ExceptionOr<void> Response::initialize_response(ResponseInit const& init
}
// https://fetch.spec.whatwg.org/#dom-response
WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::construct_impl(JS::Realm& realm, Optional<BodyInit> const& body, ResponseInit const& init)
WebIDL::ExceptionOr<GC::Ref<Response>> Response::construct_impl(JS::Realm& realm, Optional<BodyInit> const& body, ResponseInit const& init)
{
auto& vm = realm.vm();
@ -155,7 +155,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::construct_impl(JS::Rea
}
// https://fetch.spec.whatwg.org/#dom-response-error
JS::NonnullGCPtr<Response> Response::error(JS::VM& vm)
GC::Ref<Response> Response::error(JS::VM& vm)
{
// The static error() method steps are to return the result of creating a Response object, given a new network error, "immutable", and thiss relevant Realm.
// FIXME: How can we reliably get 'this', i.e. the object the function was called on, in IDL-defined functions?
@ -163,7 +163,7 @@ JS::NonnullGCPtr<Response> Response::error(JS::VM& vm)
}
// https://fetch.spec.whatwg.org/#dom-response-redirect
WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::redirect(JS::VM& vm, String const& url, u16 status)
WebIDL::ExceptionOr<GC::Ref<Response>> Response::redirect(JS::VM& vm, String const& url, u16 status)
{
auto& realm = *vm.current_realm();
@ -198,7 +198,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::redirect(JS::VM& vm, S
}
// https://fetch.spec.whatwg.org/#dom-response-json
WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::json(JS::VM& vm, JS::Value data, ResponseInit const& init)
WebIDL::ExceptionOr<GC::Ref<Response>> Response::json(JS::VM& vm, JS::Value data, ResponseInit const& init)
{
auto& realm = *vm.current_realm();
@ -268,14 +268,14 @@ String Response::status_text() const
}
// https://fetch.spec.whatwg.org/#dom-response-headers
JS::NonnullGCPtr<Headers> Response::headers() const
GC::Ref<Headers> Response::headers() const
{
// The headers getter steps are to return thiss headers.
return *m_headers;
}
// https://fetch.spec.whatwg.org/#dom-response-clone
WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::clone() const
WebIDL::ExceptionOr<GC::Ref<Response>> Response::clone() const
{
auto& realm = this->realm();

View file

@ -7,8 +7,8 @@
#pragma once
#include <AK/Forward.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/Bindings/RequestPrototype.h>
#include <LibWeb/Fetch/Body.h>
@ -31,41 +31,41 @@ class Response final
: public Bindings::PlatformObject
, public BodyMixin {
WEB_PLATFORM_OBJECT(Response, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(Response);
GC_DECLARE_ALLOCATOR(Response);
public:
[[nodiscard]] static JS::NonnullGCPtr<Response> create(JS::Realm&, JS::NonnullGCPtr<Infrastructure::Response>, Headers::Guard);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> construct_impl(JS::Realm&, Optional<BodyInit> const& body = {}, ResponseInit const& init = {});
[[nodiscard]] static GC::Ref<Response> create(JS::Realm&, GC::Ref<Infrastructure::Response>, Headers::Guard);
static WebIDL::ExceptionOr<GC::Ref<Response>> construct_impl(JS::Realm&, Optional<BodyInit> const& body = {}, ResponseInit const& init = {});
virtual ~Response() override;
// ^BodyMixin
virtual Optional<MimeSniff::MimeType> mime_type_impl() const override;
virtual JS::GCPtr<Infrastructure::Body> body_impl() override;
virtual JS::GCPtr<Infrastructure::Body const> body_impl() const override;
virtual GC::Ptr<Infrastructure::Body> body_impl() override;
virtual GC::Ptr<Infrastructure::Body const> body_impl() const override;
virtual Bindings::PlatformObject& as_platform_object() override { return *this; }
virtual Bindings::PlatformObject const& as_platform_object() const override { return *this; }
[[nodiscard]] JS::NonnullGCPtr<Infrastructure::Response> response() const { return m_response; }
[[nodiscard]] GC::Ref<Infrastructure::Response> response() const { return m_response; }
// JS API functions
[[nodiscard]] static JS::NonnullGCPtr<Response> error(JS::VM&);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> redirect(JS::VM&, String const& url, u16 status);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> json(JS::VM&, JS::Value data, ResponseInit const& init = {});
[[nodiscard]] static GC::Ref<Response> error(JS::VM&);
static WebIDL::ExceptionOr<GC::Ref<Response>> redirect(JS::VM&, String const& url, u16 status);
static WebIDL::ExceptionOr<GC::Ref<Response>> json(JS::VM&, JS::Value data, ResponseInit const& init = {});
[[nodiscard]] Bindings::ResponseType type() const;
[[nodiscard]] String url() const;
[[nodiscard]] bool redirected() const;
[[nodiscard]] u16 status() const;
[[nodiscard]] bool ok() const;
[[nodiscard]] String status_text() const;
[[nodiscard]] JS::NonnullGCPtr<Headers> headers() const;
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> clone() const;
[[nodiscard]] GC::Ref<Headers> headers() const;
[[nodiscard]] WebIDL::ExceptionOr<GC::Ref<Response>> clone() const;
// Pull in json() from the BodyMixin, which gets lost due to the static json() above
using BodyMixin::json;
private:
Response(JS::Realm&, JS::NonnullGCPtr<Infrastructure::Response>);
Response(JS::Realm&, GC::Ref<Infrastructure::Response>);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
@ -74,11 +74,11 @@ private:
// https://fetch.spec.whatwg.org/#concept-response-response
// A Response object has an associated response (a response).
JS::NonnullGCPtr<Infrastructure::Response> m_response;
GC::Ref<Infrastructure::Response> m_response;
// https://fetch.spec.whatwg.org/#response-headers
// A Response object also has an associated headers (null or a Headers object), initially null.
JS::GCPtr<Headers> m_headers;
GC::Ptr<Headers> m_headers;
};
}