mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-05 01:42:54 +00:00
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:
parent
ce23efc5f6
commit
f87041bf3a
Notes:
github-actions[bot]
2024-11-15 13:50:17 +00:00
Author: https://github.com/shannonbooth
Commit: f87041bf3a
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2345
1722 changed files with 9939 additions and 9906 deletions
|
@ -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 this’s body is null; otherwise this’s body’s 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 object’s body given successSteps, errorSteps, and object’s 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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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 object’s 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 object’s 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 object’s 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 object’s 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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 this’s 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 request’s body is non-null and is readable, then cancel request’s 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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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 fetchParams’s 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.
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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:
|
|||
// - request’s 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)
|
||||
// - request’s window is an environment settings object
|
||||
&& request.window().has<JS::GCPtr<HTML::EnvironmentSettingsObject>>()
|
||||
&& request.window().has<GC::Ptr<HTML::EnvironmentSettingsObject>>()
|
||||
// - request’s method is `GET`
|
||||
&& StringView { request.method() }.equals_ignoring_ascii_case("GET"sv)
|
||||
// - request’s unsafe-request flag is not set or request’s 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 fetchParams’s 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 request’s local-URLs-only flag is set and request’s 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");
|
||||
|
||||
// -> fetchParams’s preloaded response candidate is not null
|
||||
if (!fetch_params.preloaded_response_candidate().has<Empty>()) {
|
||||
// 1. Wait until fetchParams’s 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: fetchParams’s 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 fetchParams’s 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>>());
|
||||
}
|
||||
// -> request’s current URL’s origin is same origin with request’s origin, and request’s 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 request’s 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 response’s 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 internalResponse’s URL list is empty, then set it to a clone of request’s 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 request’s 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 fetchParams’s request’s done flag.
|
||||
fetch_params.request()->set_done(true);
|
||||
|
||||
|
@ -690,7 +690,7 @@ void fetch_response_handover(JS::Realm& realm, Infrastructure::FetchParams const
|
|||
// object is fetchParams’s task destination, then run fetchParams’s controller’s report timing steps
|
||||
// given fetchParams’s request’s client’s 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 fetchParams’s 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 fetchParams’s process response is non-null, then queue a fetch task to run fetchParams’s process response
|
||||
// given response, with fetchParams’s 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 response’s 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 internalResponse’s 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 fetchParams’s 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 fetchParams’s 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
|
||||
// fetchParams’s 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 request’s 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 response’s
|
||||
// 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 request’s method using request, and either request’s
|
||||
// method is not a CORS-safelisted method or request’s 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 request’s redirect mode is "follow", then set request’s 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 internalResponse’s 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 response’s 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 internalResponse’s location URL given request’s current URL’s 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
|
|||
// request’s body’s source.
|
||||
// NOTE: request’s body’s source’s 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 httpRequest’s body’s length, if httpRequest’s 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 request’s 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 request’s body is non-null, then:
|
||||
if (!request->body().has<Empty>()) {
|
||||
// 1. If request’s body’s 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 request’s body to the body of the result of safely extracting request’s body’s 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 response’s 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
|
||||
// - request’s body is null, or request’s body is non-null and request’s body’s 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 fetchParams’s 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 response’s 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 response’s 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 response’s status is an ok status, then:
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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".
|
||||
|
|
|
@ -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 this’s header list.
|
||||
auto value_pairs_to_iterate_over = [&]() {
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
|
|
@ -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>();
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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: this’s full timing info is not null.
|
||||
VERIFY(m_full_timing_info);
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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 timingInfo’s start time.
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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>();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 request’s body is non-null, set newRequest’s body to the result of cloning request’s 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.
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
|
|
@ -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 response’s 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 response’s 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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()();
|
||||
}));
|
||||
|
|
|
@ -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()>>);
|
||||
|
||||
}
|
||||
|
|
|
@ -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 object’s body is its request’s 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 object’s body is its request’s 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 requestObject’s 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 input’s request.
|
||||
input_request = input.get<JS::Handle<Request>>()->request();
|
||||
input_request = input.get<GC::Root<Request>>()->request();
|
||||
|
||||
// 3. Set signal to input’s signal.
|
||||
input_signal = input.get<JS::Handle<Request>>()->signal();
|
||||
input_signal = input.get<GC::Root<Request>>()->signal();
|
||||
}
|
||||
|
||||
// 7. Let origin be this’s relevant settings object’s 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 request’s window is an environment settings object and its origin is same origin with origin, then set window to request’s 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 this’s 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 this’s 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 input’s request’s 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 request’s 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 inputOrInitBody’s 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 this’s 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 this’s 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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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 object’s body is its response’s 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 object’s body is its response’s 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 responseObject’s 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 this’s 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 this’s 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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue