1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 06:47:40 +00:00

LibWeb: Make Fetch::Infrastructure::{Request,Response} ref-counted

With the addition of the 'fetch params' struct, the single ownership
model we had so far falls apart completely.

Additionally, this works nicely for FilteredResponse's internal response
instead of risking a dangling reference.

Replacing the public constructor with a create() function also found a
few instances of a Request being stack-allocated!
This commit is contained in:
Linus Groh 2022-10-04 23:45:47 +01:00
parent 886ca9c7b6
commit 1c12f5c31d
14 changed files with 228 additions and 175 deletions

View file

@ -14,6 +14,11 @@ Request::Request()
{
}
NonnullRefPtr<Request> Request::create()
{
return adopt_ref(*new Request());
}
// https://fetch.spec.whatwg.org/#concept-request-url
AK::URL const& Request::url() const
{
@ -164,15 +169,50 @@ ErrorOr<ByteBuffer> Request::byte_serialize_origin() const
}
// https://fetch.spec.whatwg.org/#concept-request-clone
WebIDL::ExceptionOr<NonnullOwnPtr<Request>> Request::clone() const
WebIDL::ExceptionOr<NonnullRefPtr<Request>> Request::clone() const
{
// To clone a request request, run these steps:
// 1. Let newRequest be a copy of request, except for its body.
BodyType tmp_body;
swap(tmp_body, const_cast<BodyType&>(m_body));
auto new_request = make<Infrastructure::Request>(*this);
swap(tmp_body, const_cast<BodyType&>(m_body));
auto new_request = Infrastructure::Request::create();
new_request->set_method(m_method);
new_request->set_local_urls_only(m_local_urls_only);
for (auto const& header : *m_header_list)
MUST(new_request->header_list()->append(header));
new_request->set_unsafe_request(m_unsafe_request);
new_request->set_client(m_client);
new_request->set_reserved_client(m_reserved_client);
new_request->set_replaces_client_id(m_replaces_client_id);
new_request->set_window(m_window);
new_request->set_keepalive(m_keepalive);
new_request->set_initiator_type(m_initiator_type);
new_request->set_service_workers_mode(m_service_workers_mode);
new_request->set_initiator(m_initiator);
new_request->set_destination(m_destination);
new_request->set_priority(m_priority);
new_request->set_origin(m_origin);
new_request->set_policy_container(m_policy_container);
new_request->set_referrer(m_referrer);
new_request->set_referrer_policy(m_referrer_policy);
new_request->set_mode(m_mode);
new_request->set_use_cors_preflight(m_use_cors_preflight);
new_request->set_credentials_mode(m_credentials_mode);
new_request->set_use_url_credentials(m_use_url_credentials);
new_request->set_cache_mode(m_cache_mode);
new_request->set_redirect_mode(m_redirect_mode);
new_request->set_integrity_metadata(m_integrity_metadata);
new_request->set_cryptographic_nonce_metadata(m_cryptographic_nonce_metadata);
new_request->set_parser_metadata(m_parser_metadata);
new_request->set_reload_navigation(m_reload_navigation);
new_request->set_history_navigation(m_history_navigation);
new_request->set_user_activation(m_user_activation);
new_request->set_render_blocking(m_render_blocking);
new_request->set_url_list(m_url_list);
new_request->set_redirect_count(m_redirect_count);
new_request->set_response_tainting(m_response_tainting);
new_request->set_prevent_no_cache_cache_control_header_modification(m_prevent_no_cache_cache_control_header_modification);
new_request->set_done(m_done);
new_request->set_timing_allow_failed(m_timing_allow_failed);
// 2. If requests body is non-null, set newRequests body to the result of cloning requests body.
if (auto const* body = m_body.get_pointer<Body>())

View file

@ -10,6 +10,7 @@
#include <AK/Error.h>
#include <AK/Forward.h>
#include <AK/Optional.h>
#include <AK/RefCounted.h>
#include <AK/String.h>
#include <AK/URL.h>
#include <AK/Variant.h>
@ -23,7 +24,7 @@
namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#concept-request
class Request final {
class Request final : public RefCounted<Request> {
public:
enum class CacheMode {
Default,
@ -154,7 +155,7 @@ public:
using ReservedClientType = Variant<Empty, HTML::Environment*, HTML::EnvironmentSettingsObject*>;
using WindowType = Variant<Window, HTML::EnvironmentSettingsObject*>;
Request();
static NonnullRefPtr<Request> create();
[[nodiscard]] ReadonlyBytes method() const { return m_method; }
void set_method(ByteBuffer method) { m_method = move(method); }
@ -290,13 +291,15 @@ public:
[[nodiscard]] String serialize_origin() const;
[[nodiscard]] ErrorOr<ByteBuffer> byte_serialize_origin() const;
[[nodiscard]] WebIDL::ExceptionOr<NonnullOwnPtr<Request>> clone() const;
[[nodiscard]] WebIDL::ExceptionOr<NonnullRefPtr<Request>> clone() const;
[[nodiscard]] ErrorOr<void> add_range_reader(u64 first, Optional<u64> const& last);
[[nodiscard]] bool cross_origin_embedder_policy_allows_credentials() const;
private:
Request();
// https://fetch.spec.whatwg.org/#concept-request-method
// A request has an associated method (a method). Unless stated otherwise it is `GET`.
ByteBuffer m_method { ByteBuffer::copy("GET"sv.bytes()).release_value() };

View file

@ -14,20 +14,25 @@ Response::Response()
{
}
NonnullRefPtr<Response> Response::create()
{
return adopt_ref(*new Response());
}
// https://fetch.spec.whatwg.org/#ref-for-concept-network-error%E2%91%A3
// 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.
NonnullOwnPtr<Response> Response::aborted_network_error()
NonnullRefPtr<Response> Response::aborted_network_error()
{
auto response = network_error();
response->set_aborted(true);
return response;
}
NonnullOwnPtr<Response> Response::network_error()
NonnullRefPtr<Response> Response::network_error()
{
auto response = make<Response>();
auto response = Response::create();
response->set_status(0);
response->set_type(Type::Error);
VERIFY(!response->body().has_value());
@ -83,17 +88,28 @@ ErrorOr<Optional<AK::URL>> Response::location_url(Optional<String> const& reques
}
// https://fetch.spec.whatwg.org/#concept-response-clone
WebIDL::ExceptionOr<NonnullOwnPtr<Response>> Response::clone() const
WebIDL::ExceptionOr<NonnullRefPtr<Response>> Response::clone() const
{
// To clone a response response, run these steps:
// FIXME: 1. If response is a filtered response, then return a new identical filtered response whose internal response is a clone of responses internal response.
// 2. Let newResponse be a copy of response, except for its body.
Optional<Body> tmp_body;
swap(tmp_body, const_cast<Optional<Body>&>(m_body));
auto new_response = make<Infrastructure::Response>(*this);
swap(tmp_body, const_cast<Optional<Body>&>(m_body));
auto new_response = Infrastructure::Response::create();
new_response->set_type(m_type);
new_response->set_aborted(m_aborted);
new_response->set_url_list(m_url_list);
new_response->set_status(m_status);
new_response->set_status_message(m_status_message);
for (auto const& header : *m_header_list)
MUST(new_response->header_list()->append(header));
new_response->set_cache_state(m_cache_state);
new_response->set_cors_exposed_header_name_list(m_cors_exposed_header_name_list);
new_response->set_range_requested(m_range_requested);
new_response->set_request_includes_credentials(m_request_includes_credentials);
new_response->set_timing_allow_passed(m_timing_allow_passed);
new_response->set_body_info(m_body_info);
// FIXME: service worker timing info
// 3. If responses body is non-null, then set newResponses body to the result of cloning responses body.
if (m_body.has_value())
@ -103,8 +119,8 @@ WebIDL::ExceptionOr<NonnullOwnPtr<Response>> Response::clone() const
return new_response;
}
FilteredResponse::FilteredResponse(Response& internal_response)
: m_internal_response(internal_response)
FilteredResponse::FilteredResponse(NonnullRefPtr<Response> internal_response)
: m_internal_response(move(internal_response))
{
}
@ -112,69 +128,69 @@ FilteredResponse::~FilteredResponse()
{
}
ErrorOr<NonnullOwnPtr<BasicFilteredResponse>> BasicFilteredResponse::create(Response& internal_response)
ErrorOr<NonnullRefPtr<BasicFilteredResponse>> BasicFilteredResponse::create(NonnullRefPtr<Response> internal_response)
{
// A basic filtered response is a filtered response whose type is "basic" and header list excludes
// any headers in internal responses header list whose name is a forbidden response-header name.
auto header_list = make_ref_counted<HeaderList>();
for (auto const& header : *internal_response.header_list()) {
for (auto const& header : *internal_response->header_list()) {
if (!is_forbidden_response_header_name(header.name))
TRY(header_list->append(header));
}
return adopt_own(*new BasicFilteredResponse(internal_response, move(header_list)));
return adopt_ref(*new BasicFilteredResponse(internal_response, move(header_list)));
}
BasicFilteredResponse::BasicFilteredResponse(Response& internal_response, NonnullRefPtr<HeaderList> header_list)
: FilteredResponse(internal_response)
BasicFilteredResponse::BasicFilteredResponse(NonnullRefPtr<Response> internal_response, NonnullRefPtr<HeaderList> header_list)
: FilteredResponse(move(internal_response))
, m_header_list(move(header_list))
{
}
ErrorOr<NonnullOwnPtr<CORSFilteredResponse>> CORSFilteredResponse::create(Response& internal_response)
ErrorOr<NonnullRefPtr<CORSFilteredResponse>> CORSFilteredResponse::create(NonnullRefPtr<Response> internal_response)
{
// A CORS filtered response is a filtered response whose type is "cors" and header list excludes
// any headers in internal responses header list whose name is not a CORS-safelisted response-header
// name, given internal responses CORS-exposed header-name list.
Vector<ReadonlyBytes> cors_exposed_header_name_list;
for (auto const& header_name : internal_response.cors_exposed_header_name_list())
for (auto const& header_name : internal_response->cors_exposed_header_name_list())
cors_exposed_header_name_list.append(header_name.span());
auto header_list = make_ref_counted<HeaderList>();
for (auto const& header : *internal_response.header_list()) {
for (auto const& header : *internal_response->header_list()) {
if (is_cors_safelisted_response_header_name(header.name, cors_exposed_header_name_list))
TRY(header_list->append(header));
}
return adopt_own(*new CORSFilteredResponse(internal_response, move(header_list)));
return adopt_ref(*new CORSFilteredResponse(internal_response, move(header_list)));
}
CORSFilteredResponse::CORSFilteredResponse(Response& internal_response, NonnullRefPtr<HeaderList> header_list)
: FilteredResponse(internal_response)
CORSFilteredResponse::CORSFilteredResponse(NonnullRefPtr<Response> internal_response, NonnullRefPtr<HeaderList> header_list)
: FilteredResponse(move(internal_response))
, m_header_list(move(header_list))
{
}
NonnullOwnPtr<OpaqueFilteredResponse> OpaqueFilteredResponse::create(Response& internal_response)
NonnullRefPtr<OpaqueFilteredResponse> OpaqueFilteredResponse::create(NonnullRefPtr<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 adopt_own(*new OpaqueFilteredResponse(internal_response));
return adopt_ref(*new OpaqueFilteredResponse(move(internal_response)));
}
OpaqueFilteredResponse::OpaqueFilteredResponse(Response& internal_response)
: FilteredResponse(internal_response)
OpaqueFilteredResponse::OpaqueFilteredResponse(NonnullRefPtr<Response> internal_response)
: FilteredResponse(move(internal_response))
, m_header_list(make_ref_counted<HeaderList>())
{
}
NonnullOwnPtr<OpaqueRedirectFilteredResponse> OpaqueRedirectFilteredResponse::create(Response& internal_response)
NonnullRefPtr<OpaqueRedirectFilteredResponse> OpaqueRedirectFilteredResponse::create(NonnullRefPtr<Response> internal_response)
{
return adopt_own(*new OpaqueRedirectFilteredResponse(internal_response));
return adopt_ref(*new OpaqueRedirectFilteredResponse(move(internal_response)));
}
OpaqueRedirectFilteredResponse::OpaqueRedirectFilteredResponse(Response& internal_response)
: FilteredResponse(internal_response)
OpaqueRedirectFilteredResponse::OpaqueRedirectFilteredResponse(NonnullRefPtr<Response> internal_response)
: FilteredResponse(move(internal_response))
, m_header_list(make_ref_counted<HeaderList>())
{
}

View file

@ -10,6 +10,7 @@
#include <AK/Error.h>
#include <AK/Forward.h>
#include <AK/Optional.h>
#include <AK/RefCounted.h>
#include <AK/URL.h>
#include <AK/Vector.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h>
@ -19,7 +20,7 @@
namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#concept-response
class Response {
class Response : public RefCounted<Response> {
public:
enum class CacheState {
Local,
@ -44,10 +45,10 @@ public:
u64 decoded_size { 0 };
};
[[nodiscard]] static NonnullOwnPtr<Response> aborted_network_error();
[[nodiscard]] static NonnullOwnPtr<Response> network_error();
[[nodiscard]] static NonnullRefPtr<Response> create();
[[nodiscard]] static NonnullRefPtr<Response> aborted_network_error();
[[nodiscard]] static NonnullRefPtr<Response> network_error();
Response();
virtual ~Response() = default;
[[nodiscard]] virtual Type type() const { return m_type; }
@ -100,7 +101,10 @@ public:
[[nodiscard]] Optional<AK::URL const&> url() const;
[[nodiscard]] ErrorOr<Optional<AK::URL>> location_url(Optional<String> const& request_fragment) const;
[[nodiscard]] WebIDL::ExceptionOr<NonnullOwnPtr<Response>> clone() const;
[[nodiscard]] WebIDL::ExceptionOr<NonnullRefPtr<Response>> clone() const;
protected:
Response();
private:
// https://fetch.spec.whatwg.org/#concept-response-type
@ -162,41 +166,40 @@ private:
// https://fetch.spec.whatwg.org/#concept-filtered-response
class FilteredResponse : public Response {
public:
explicit FilteredResponse(Response&);
explicit FilteredResponse(NonnullRefPtr<Response>);
virtual ~FilteredResponse() = 0;
[[nodiscard]] virtual Type type() const override { return m_internal_response.type(); }
[[nodiscard]] virtual bool aborted() const override { return m_internal_response.aborted(); }
[[nodiscard]] virtual Vector<AK::URL> const& url_list() const 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 NonnullRefPtr<HeaderList> const& header_list() const override { return m_internal_response.header_list(); }
[[nodiscard]] virtual Optional<Body> const& body() const 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(); }
[[nodiscard]] virtual bool request_includes_credentials() const override { return m_internal_response.request_includes_credentials(); }
[[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]] virtual Type type() const override { return m_internal_response->type(); }
[[nodiscard]] virtual bool aborted() const override { return m_internal_response->aborted(); }
[[nodiscard]] virtual Vector<AK::URL> const& url_list() const 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 NonnullRefPtr<HeaderList> const& header_list() const override { return m_internal_response->header_list(); }
[[nodiscard]] virtual Optional<Body> const& body() const 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(); }
[[nodiscard]] virtual bool request_includes_credentials() const override { return m_internal_response->request_includes_credentials(); }
[[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]] Response const& internal_response() const { return m_internal_response; }
[[nodiscard]] Response& internal_response() { return m_internal_response; }
[[nodiscard]] NonnullRefPtr<Response> internal_response() const { return m_internal_response; }
protected:
// https://fetch.spec.whatwg.org/#concept-internal-response
Response& m_internal_response;
NonnullRefPtr<Response> m_internal_response;
};
// https://fetch.spec.whatwg.org/#concept-filtered-response-basic
class BasicFilteredResponse final : public FilteredResponse {
public:
static ErrorOr<NonnullOwnPtr<BasicFilteredResponse>> create(Response&);
static ErrorOr<NonnullRefPtr<BasicFilteredResponse>> create(NonnullRefPtr<Response>);
[[nodiscard]] virtual Type type() const override { return Type::Basic; }
[[nodiscard]] virtual NonnullRefPtr<HeaderList> const& header_list() const override { return m_header_list; }
private:
BasicFilteredResponse(Response&, NonnullRefPtr<HeaderList>);
BasicFilteredResponse(NonnullRefPtr<Response>, NonnullRefPtr<HeaderList>);
NonnullRefPtr<HeaderList> m_header_list;
};
@ -204,13 +207,13 @@ private:
// https://fetch.spec.whatwg.org/#concept-filtered-response-cors
class CORSFilteredResponse final : public FilteredResponse {
public:
static ErrorOr<NonnullOwnPtr<CORSFilteredResponse>> create(Response&);
static ErrorOr<NonnullRefPtr<CORSFilteredResponse>> create(NonnullRefPtr<Response>);
[[nodiscard]] virtual Type type() const override { return Type::CORS; }
[[nodiscard]] virtual NonnullRefPtr<HeaderList> const& header_list() const override { return m_header_list; }
private:
CORSFilteredResponse(Response&, NonnullRefPtr<HeaderList>);
CORSFilteredResponse(NonnullRefPtr<Response>, NonnullRefPtr<HeaderList>);
NonnullRefPtr<HeaderList> m_header_list;
};
@ -218,7 +221,7 @@ private:
// https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
class OpaqueFilteredResponse final : public FilteredResponse {
public:
static NonnullOwnPtr<OpaqueFilteredResponse> create(Response&);
static NonnullRefPtr<OpaqueFilteredResponse> create(NonnullRefPtr<Response>);
[[nodiscard]] virtual Type type() const override { return Type::Opaque; }
[[nodiscard]] virtual Vector<AK::URL> const& url_list() const override { return m_url_list; }
@ -228,7 +231,7 @@ public:
[[nodiscard]] virtual Optional<Body> const& body() const override { return m_body; }
private:
explicit OpaqueFilteredResponse(Response&);
explicit OpaqueFilteredResponse(NonnullRefPtr<Response>);
Vector<AK::URL> m_url_list;
NonnullRefPtr<HeaderList> m_header_list;
@ -238,7 +241,7 @@ private:
// https://fetch.spec.whatwg.org/#concept-filtered-response-opaque-redirect
class OpaqueRedirectFilteredResponse final : public FilteredResponse {
public:
static NonnullOwnPtr<OpaqueRedirectFilteredResponse> create(Response&);
static NonnullRefPtr<OpaqueRedirectFilteredResponse> create(NonnullRefPtr<Response>);
[[nodiscard]] virtual Type type() const override { return Type::OpaqueRedirect; }
[[nodiscard]] virtual Status status() const override { return 0; }
@ -247,7 +250,7 @@ public:
[[nodiscard]] virtual Optional<Body> const& body() const override { return m_body; }
private:
explicit OpaqueRedirectFilteredResponse(Response&);
explicit OpaqueRedirectFilteredResponse(NonnullRefPtr<Response>);
NonnullRefPtr<HeaderList> m_header_list;
Optional<Body> m_body;

View file

@ -4,7 +4,6 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/ScopeGuard.h>
#include <AK/URLParser.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/DOM/AbortSignal.h>
@ -20,7 +19,7 @@
namespace Web::Fetch {
Request::Request(JS::Realm& realm, NonnullOwnPtr<Infrastructure::Request> request)
Request::Request(JS::Realm& realm, NonnullRefPtr<Infrastructure::Request> request)
: PlatformObject(realm)
, m_request(move(request))
{
@ -72,7 +71,7 @@ Optional<Infrastructure::Body&> Request::body_impl()
}
// https://fetch.spec.whatwg.org/#request-create
JS::NonnullGCPtr<Request> Request::create(NonnullOwnPtr<Infrastructure::Request> request, Headers::Guard guard, JS::Realm& realm)
JS::NonnullGCPtr<Request> Request::create(NonnullRefPtr<Infrastructure::Request> request, Headers::Guard guard, JS::Realm& realm)
{
// Copy a NonnullRefPtr to the request's header list before request is being move()'d.
auto request_reader_list = request->header_list();
@ -97,16 +96,10 @@ JS::NonnullGCPtr<Request> Request::create(NonnullOwnPtr<Infrastructure::Request>
WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm& realm, RequestInfo const& input, RequestInit const& init)
{
// Referred to as 'this' in the spec.
auto request_object = JS::NonnullGCPtr { *realm.heap().allocate<Request>(realm, realm, make<Infrastructure::Request>()) };
auto request_object = JS::NonnullGCPtr { *realm.heap().allocate<Request>(realm, realm, Infrastructure::Request::create()) };
// 1. Let request be null.
Infrastructure::Request const* input_request = nullptr;
// Cleanup for the special case where we create a temporary Request ourselves
// instead of just taking a pointer from something else.
ArmedScopeGuard delete_input_request { [&] {
delete input_request;
} };
RefPtr<Infrastructure::Request> input_request;
// 2. Let fallbackMode be null.
Optional<Infrastructure::Request::Mode> fallback_mode;
@ -131,9 +124,8 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Input URL must not include credentials"sv };
// 4. Set request to a new request whose URL is parsedURL.
auto* new_request = new Infrastructure::Request();
new_request->set_url(move(parsed_url));
input_request = new_request;
input_request = Infrastructure::Request::create();
input_request->set_url(move(parsed_url));
// 5. Set fallbackMode to "cors".
fallback_mode = Infrastructure::Request::Mode::CORS;
@ -144,8 +136,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
VERIFY(input.has<JS::Handle<Request>>());
// 2. Set request to inputs request.
input_request = &input.get<JS::Handle<Request>>()->request();
delete_input_request.disarm();
input_request = input.get<JS::Handle<Request>>()->request();
// 3. Set signal to inputs signal.
input_signal = input.get<JS::Handle<Request>>()->signal();
@ -175,114 +166,114 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 12. Set request to a new request with the following properties:
// NOTE: This is done at the beginning as the 'this' value Request object
// cannot exist with a null Infrastructure::Request.
auto& request = request_object->request();
auto request = request_object->request();
// URL
// requests URL.
request.set_url(input_request->url());
request->set_url(input_request->url());
// method
// requests method.
request.set_method(TRY_OR_RETURN_OOM(realm, ByteBuffer::copy(request.method())));
request->set_method(TRY_OR_RETURN_OOM(realm, ByteBuffer::copy(request->method())));
// header list
// A copy of requests header list.
auto header_list_copy = make_ref_counted<Infrastructure::HeaderList>();
for (auto& header : *request.header_list())
for (auto& header : *request->header_list())
TRY_OR_RETURN_OOM(realm, header_list_copy->append(header));
request.set_header_list(move(header_list_copy));
request->set_header_list(move(header_list_copy));
// unsafe-request flag
// Set.
request.set_unsafe_request(true);
request->set_unsafe_request(true);
// client
// Thiss relevant settings object.
request.set_client(&HTML::relevant_settings_object(*request_object));
request->set_client(&HTML::relevant_settings_object(*request_object));
// window
// window.
request.set_window(window);
request->set_window(window);
// priority
// requests priority.
request.set_priority(input_request->priority());
request->set_priority(input_request->priority());
// origin
// requests origin. The propagation of the origin is only significant for navigation requests being handled by a service worker. In this scenario a request can have an origin that is different from the current client.
request.set_origin(input_request->origin());
request->set_origin(input_request->origin());
// referrer
// requests referrer.
request.set_referrer(input_request->referrer());
request->set_referrer(input_request->referrer());
// referrer policy
// requests referrer policy.
request.set_referrer_policy(input_request->referrer_policy());
request->set_referrer_policy(input_request->referrer_policy());
// mode
// requests mode.
request.set_mode(input_request->mode());
request->set_mode(input_request->mode());
// credentials mode
// requests credentials mode.
request.set_credentials_mode(input_request->credentials_mode());
request->set_credentials_mode(input_request->credentials_mode());
// cache mode
// requests cache mode.
request.set_cache_mode(input_request->cache_mode());
request->set_cache_mode(input_request->cache_mode());
// redirect mode
// requests redirect mode.
request.set_redirect_mode(input_request->redirect_mode());
request->set_redirect_mode(input_request->redirect_mode());
// integrity metadata
// requests integrity metadata.
request.set_integrity_metadata(input_request->integrity_metadata());
request->set_integrity_metadata(input_request->integrity_metadata());
// keepalive
// requests keepalive.
request.set_keepalive(input_request->keepalive());
request->set_keepalive(input_request->keepalive());
// reload-navigation flag
// requests reload-navigation flag.
request.set_reload_navigation(input_request->reload_navigation());
request->set_reload_navigation(input_request->reload_navigation());
// history-navigation flag
// requests history-navigation flag.
request.set_history_navigation(input_request->history_navigation());
request->set_history_navigation(input_request->history_navigation());
// URL list
// A clone of requests URL list.
request.set_url_list(input_request->url_list());
request->set_url_list(input_request->url_list());
// initiator type
// "fetch".
request.set_initiator_type(Infrastructure::Request::InitiatorType::Fetch);
request->set_initiator_type(Infrastructure::Request::InitiatorType::Fetch);
// 13. If init is not empty, then:
if (!init.is_empty()) {
// 1. If requests mode is "navigate", then set it to "same-origin".
if (request.mode() == Infrastructure::Request::Mode::Navigate)
request.set_mode(Infrastructure::Request::Mode::SameOrigin);
if (request->mode() == Infrastructure::Request::Mode::Navigate)
request->set_mode(Infrastructure::Request::Mode::SameOrigin);
// 2. Unset requests reload-navigation flag.
request.set_reload_navigation(false);
request->set_reload_navigation(false);
// 3. Unset requests history-navigation flag.
request.set_history_navigation(false);
request->set_history_navigation(false);
// 4. Set requests origin to "client".
request.set_origin(Infrastructure::Request::Origin::Client);
request->set_origin(Infrastructure::Request::Origin::Client);
// 5. Set requests referrer to "client".
request.set_referrer(Infrastructure::Request::Referrer::Client);
request->set_referrer(Infrastructure::Request::Referrer::Client);
// 6. Set requests referrer policy to the empty string.
request.set_referrer_policy({});
request->set_referrer_policy({});
// 7. Set requests URL to requests current URL.
request.set_url(request.current_url());
request->set_url(request->current_url());
// 8. Set requests URL list to « requests URL ».
// NOTE: This is done implicitly by assigning the initial URL above.
@ -295,7 +286,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 2. If referrer is the empty string, then set requests referrer to "no-referrer".
if (referrer.is_empty()) {
request.set_referrer(Infrastructure::Request::Referrer::NoReferrer);
request->set_referrer(Infrastructure::Request::Referrer::NoReferrer);
}
// 3. Otherwise:
else {
@ -312,18 +303,18 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// then set requests referrer to "client".
// FIXME: Actually use the given origin once we have https://url.spec.whatwg.org/#concept-url-origin.
if ((parsed_referrer.scheme() == "about"sv && parsed_referrer.path() == "client"sv) || !HTML::Origin().is_same_origin(origin)) {
request.set_referrer(Infrastructure::Request::Referrer::Client);
request->set_referrer(Infrastructure::Request::Referrer::Client);
}
// 4. Otherwise, set requests referrer to parsedReferrer.
else {
request.set_referrer(move(parsed_referrer));
request->set_referrer(move(parsed_referrer));
}
}
}
// 15. If init["referrerPolicy"] exists, then set requests referrer policy to it.
if (init.referrer_policy.has_value())
request.set_referrer_policy(from_bindings_enum(*init.referrer_policy));
request->set_referrer_policy(from_bindings_enum(*init.referrer_policy));
// 16. Let mode be init["mode"] if it exists, and fallbackMode otherwise.
auto mode = init.mode.has_value()
@ -336,31 +327,31 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 18. If mode is non-null, set requests mode to mode.
if (mode.has_value())
request.set_mode(*mode);
request->set_mode(*mode);
// 19. If init["credentials"] exists, then set requests credentials mode to it.
if (init.credentials.has_value())
request.set_credentials_mode(from_bindings_enum(*init.credentials));
request->set_credentials_mode(from_bindings_enum(*init.credentials));
// 20. If init["cache"] exists, then set requests cache mode to it.
if (init.cache.has_value())
request.set_cache_mode(from_bindings_enum(*init.cache));
request->set_cache_mode(from_bindings_enum(*init.cache));
// 21. If requests cache mode is "only-if-cached" and requests mode is not "same-origin", then throw a TypeError.
if (request.cache_mode() == Infrastructure::Request::CacheMode::OnlyIfCached && request.mode() != Infrastructure::Request::Mode::SameOrigin)
if (request->cache_mode() == Infrastructure::Request::CacheMode::OnlyIfCached && request->mode() != Infrastructure::Request::Mode::SameOrigin)
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Mode must be 'same-origin' when cache mode is 'only-if-cached'"sv };
// 22. If init["redirect"] exists, then set requests redirect mode to it.
if (init.redirect.has_value())
request.set_redirect_mode(from_bindings_enum(*init.redirect));
request->set_redirect_mode(from_bindings_enum(*init.redirect));
// 23. If init["integrity"] exists, then set requests integrity metadata to it.
if (init.integrity.has_value())
request.set_integrity_metadata(*init.integrity);
request->set_integrity_metadata(*init.integrity);
// 24. If init["keepalive"] exists, then set requests keepalive to it.
if (init.keepalive.has_value())
request.set_keepalive(*init.keepalive);
request->set_keepalive(*init.keepalive);
// 25. If init["method"] exists, then:
if (init.method.has_value()) {
@ -377,7 +368,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
method = TRY_OR_RETURN_OOM(realm, Infrastructure::normalize_method(method.bytes()));
// 4. Set requests method to method.
request.set_method(MUST(ByteBuffer::copy(method.bytes())));
request->set_method(MUST(ByteBuffer::copy(method.bytes())));
}
// 26. If init["signal"] exists, then set signal to it.
@ -399,13 +390,13 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 30. Set thiss headers to a new Headers object with thiss relevant Realm, whose header list is requests header list and guard is "request".
request_object->m_headers = realm.heap().allocate<Headers>(realm, realm);
request_object->m_headers->set_header_list(request.header_list());
request_object->m_headers->set_header_list(request->header_list());
request_object->m_headers->set_guard(Headers::Guard::Request);
// 31. If thiss requests mode is "no-cors", then:
if (request_object->request().mode() == Infrastructure::Request::Mode::NoCORS) {
if (request_object->request()->mode() == Infrastructure::Request::Mode::NoCORS) {
// 1. If thiss requests method is not a CORS-safelisted method, then throw a TypeError.
if (!Infrastructure::is_cors_safelisted_method(request_object->request().method()))
if (!Infrastructure::is_cors_safelisted_method(request_object->request()->method()))
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Method must be one of GET, HEAD, or POST"sv };
// 2. Set thiss headerss guard to "request-no-cors".
@ -438,11 +429,11 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 33. Let inputBody be inputs requests body if input is a Request object; otherwise null.
auto const& input_body = input.has<JS::Handle<Request>>()
? input.get<JS::Handle<Request>>()->request().body().get<Infrastructure::Body>()
? input.get<JS::Handle<Request>>()->request()->body().get<Infrastructure::Body>()
: Optional<Infrastructure::Body> {};
// 34. If either init["body"] exists and is non-null or inputBody is non-null, and requests method is `GET` or `HEAD`, then throw a TypeError.
if (((init.body.has_value() && (*init.body).has_value()) || input_body.has_value()) && StringView { request.method() }.is_one_of("GET"sv, "HEAD"sv))
if (((init.body.has_value() && (*init.body).has_value()) || input_body.has_value()) && 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 };
// 35. Let initBody be null.
@ -451,7 +442,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 36. If init["body"] exists and is non-null, then:
if (init.body.has_value() && (*init.body).has_value()) {
// 1. Let bodyWithType be the result of extracting init["body"], with keepalive set to requests keepalive.
auto body_with_type = TRY(extract_body(realm, (*init.body).value(), request.keepalive()));
auto body_with_type = TRY(extract_body(realm, (*init.body).value(), request->keepalive()));
// 2. Set initBody to bodyWithTypes body.
init_body = move(body_with_type.body);
@ -474,11 +465,11 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Body without source requires 'duplex' value to be set"sv };
// 2. If thiss requests mode is neither "same-origin" nor "cors", then throw a TypeError.
if (request_object->request().mode() != Infrastructure::Request::Mode::SameOrigin && request_object->request().mode() != Infrastructure::Request::Mode::CORS)
if (request_object->request()->mode() != Infrastructure::Request::Mode::SameOrigin && request_object->request()->mode() != Infrastructure::Request::Mode::CORS)
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Request mode must be 'same-origin' or 'cors'"sv };
// 3. Set thiss requests use-CORS-preflight flag.
request_object->request().set_use_cors_preflight(true);
request_object->request()->set_use_cors_preflight(true);
}
// 39. Let finalBody be inputOrInitBody.
@ -495,7 +486,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// 41. Set thiss requests body to finalBody.
if (final_body.has_value())
request_object->request().set_body(*final_body);
request_object->request()->set_body(*final_body);
return JS::NonnullGCPtr { *request_object };
}

View file

@ -12,6 +12,7 @@
#include <LibWeb/Fetch/Body.h>
#include <LibWeb/Fetch/BodyInit.h>
#include <LibWeb/Fetch/Headers.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h>
#include <LibWeb/Forward.h>
namespace Web::Fetch {
@ -63,7 +64,7 @@ class Request final
WEB_PLATFORM_OBJECT(Request, Bindings::PlatformObject);
public:
static JS::NonnullGCPtr<Request> create(NonnullOwnPtr<Infrastructure::Request>, Headers::Guard, JS::Realm&);
static JS::NonnullGCPtr<Request> create(NonnullRefPtr<Infrastructure::Request>, Headers::Guard, JS::Realm&);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> construct_impl(JS::Realm&, RequestInfo const& input, RequestInit const& init = {});
virtual ~Request() override;
@ -73,8 +74,7 @@ public:
virtual Optional<Infrastructure::Body&> body_impl() override;
virtual Optional<Infrastructure::Body const&> body_impl() const override;
[[nodiscard]] Infrastructure::Request& request() { return *m_request; }
[[nodiscard]] Infrastructure::Request const& request() const { return *m_request; }
[[nodiscard]] NonnullRefPtr<Infrastructure::Request> request() const { return m_request; }
// JS API functions
[[nodiscard]] String method() const;
@ -95,13 +95,13 @@ public:
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> clone() const;
private:
Request(JS::Realm&, NonnullOwnPtr<Infrastructure::Request>);
Request(JS::Realm&, NonnullRefPtr<Infrastructure::Request>);
virtual void visit_edges(Cell::Visitor&) override;
// https://fetch.spec.whatwg.org/#concept-request-request
// A Request object has an associated request (a request).
NonnullOwnPtr<Infrastructure::Request> m_request;
NonnullRefPtr<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.

View file

@ -17,7 +17,7 @@
namespace Web::Fetch {
Response::Response(JS::Realm& realm, NonnullOwnPtr<Infrastructure::Response> response)
Response::Response(JS::Realm& realm, NonnullRefPtr<Infrastructure::Response> response)
: PlatformObject(realm)
, m_response(move(response))
{
@ -64,7 +64,7 @@ Optional<Infrastructure::Body&> Response::body_impl()
}
// https://fetch.spec.whatwg.org/#response-create
JS::NonnullGCPtr<Response> Response::create(NonnullOwnPtr<Infrastructure::Response> response, Headers::Guard guard, JS::Realm& realm)
JS::NonnullGCPtr<Response> Response::create(NonnullRefPtr<Infrastructure::Response> response, Headers::Guard guard, JS::Realm& realm)
{
// Copy a NonnullRefPtr to the response's header list before response is being move()'d.
auto response_reader_list = response->header_list();
@ -127,7 +127,7 @@ WebIDL::ExceptionOr<void> Response::initialize_response(ResponseInit const& init
WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::construct_impl(JS::Realm& realm, Optional<BodyInit> const& body, ResponseInit const& init)
{
// Referred to as 'this' in the spec.
auto response_object = JS::NonnullGCPtr { *realm.heap().allocate<Response>(realm, realm, make<Infrastructure::Response>()) };
auto response_object = JS::NonnullGCPtr { *realm.heap().allocate<Response>(realm, realm, Infrastructure::Response::create()) };
// 1. Set thiss response to a new response.
// NOTE: This is done at the beginning as the 'this' value Response object
@ -135,7 +135,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::construct_impl(JS::Rea
// 2. Set thiss headers to a new Headers object with thiss relevant Realm, whose header list is thiss responses header list and guard is "response".
response_object->m_headers = realm.heap().allocate<Headers>(realm, realm);
response_object->m_headers->set_header_list(response_object->response().header_list());
response_object->m_headers->set_header_list(response_object->response()->header_list());
response_object->m_headers->set_guard(Headers::Guard::Response);
// 3. Let bodyWithType be null.
@ -180,10 +180,10 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::redirect(String const&
// 4. Let responseObject be the result of creating a Response object, given a new response, "immutable", and thiss relevant Realm.
// FIXME: How can we reliably get 'this', i.e. the object the function was called on, in IDL-defined functions?
auto response_object = Response::create(make<Infrastructure::Response>(), Headers::Guard::Immutable, realm);
auto response_object = Response::create(Infrastructure::Response::create(), Headers::Guard::Immutable, realm);
// 5. Set responseObjects responses status to status.
response_object->response().set_status(status);
response_object->response()->set_status(status);
// 6. Let value be parsedURL, serialized and isomorphic encoded.
auto value = parsed_url.serialize();
@ -193,7 +193,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::redirect(String const&
.name = TRY_OR_RETURN_OOM(realm, ByteBuffer::copy("Location"sv.bytes())),
.value = TRY_OR_RETURN_OOM(realm, ByteBuffer::copy(value.bytes())),
};
TRY_OR_RETURN_OOM(realm, response_object->response().header_list()->append(move(header)));
TRY_OR_RETURN_OOM(realm, response_object->response()->header_list()->append(move(header)));
// 8. Return responseObject.
return response_object;
@ -213,7 +213,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::json(JS::Value data, R
// 3. Let responseObject be the result of creating a Response object, given a new response, "response", and thiss relevant Realm.
// FIXME: How can we reliably get 'this', i.e. the object the function was called on, in IDL-defined functions?
auto response_object = Response::create(make<Infrastructure::Response>(), Headers::Guard::Response, realm);
auto response_object = Response::create(Infrastructure::Response::create(), Headers::Guard::Response, realm);
// 4. Perform initialize a response given responseObject, init, and (body, "application/json").
auto body_with_type = Infrastructure::BodyWithType {

View file

@ -12,6 +12,7 @@
#include <LibWeb/Fetch/Body.h>
#include <LibWeb/Fetch/BodyInit.h>
#include <LibWeb/Fetch/Headers.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h>
#include <LibWeb/Forward.h>
namespace Web::Fetch {
@ -30,7 +31,7 @@ class Response final
WEB_PLATFORM_OBJECT(Response, Bindings::PlatformObject);
public:
static JS::NonnullGCPtr<Response> create(NonnullOwnPtr<Infrastructure::Response>, Headers::Guard, JS::Realm&);
static JS::NonnullGCPtr<Response> create(NonnullRefPtr<Infrastructure::Response>, Headers::Guard, JS::Realm&);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> construct_impl(JS::Realm&, Optional<BodyInit> const& body = {}, ResponseInit const& init = {});
virtual ~Response() override;
@ -40,8 +41,7 @@ public:
virtual Optional<Infrastructure::Body&> body_impl() override;
virtual Optional<Infrastructure::Body const&> body_impl() const override;
[[nodiscard]] Infrastructure::Response& response() { return *m_response; }
[[nodiscard]] Infrastructure::Response const& response() const { return *m_response; }
[[nodiscard]] NonnullRefPtr<Infrastructure::Response> response() const { return m_response; }
// JS API functions
[[nodiscard]] static JS::NonnullGCPtr<Response> error();
@ -60,7 +60,7 @@ public:
using BodyMixin::json;
private:
Response(JS::Realm&, NonnullOwnPtr<Infrastructure::Response>);
Response(JS::Realm&, NonnullRefPtr<Infrastructure::Response>);
virtual void visit_edges(Cell::Visitor&) override;
@ -68,7 +68,7 @@ private:
// https://fetch.spec.whatwg.org/#concept-response-response
// A Response object has an associated response (a response).
NonnullOwnPtr<Infrastructure::Response> m_response;
NonnullRefPtr<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.

View file

@ -864,21 +864,21 @@ void BrowsingContext::remove()
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate
WebIDL::ExceptionOr<void> BrowsingContext::navigate(
Fetch::Infrastructure::Request resource,
NonnullRefPtr<Fetch::Infrastructure::Request> resource,
BrowsingContext& source_browsing_context,
bool exceptions_enabled,
HistoryHandlingBehavior history_handling,
Optional<PolicyContainer> history_policy_container,
String navigation_type,
Optional<String> navigation_id,
Function<void(NonnullOwnPtr<Fetch::Infrastructure::Response>)> process_response_end_of_body)
Function<void(NonnullRefPtr<Fetch::Infrastructure::Response>)> process_response_end_of_body)
{
// 1. If resource is a URL, then set resource to a new request whose URL is resource.
// NOTE: This function only accepts resources that are already a request, so this is irrelevant.
// 2. If resource is a request and historyHandling is "reload", then set resource's reload-navigation flag.
if (history_handling == HistoryHandlingBehavior::Reload)
resource.set_reload_navigation(true);
resource->set_reload_navigation(true);
// 3. If the source browsing context is not allowed to navigate browsingContext, then:
if (!source_browsing_context.is_allowed_to_navigate(*this)) {
@ -918,8 +918,8 @@ WebIDL::ExceptionOr<void> BrowsingContext::navigate(
// - resource is a request whose URL's scheme is "javascript"
if (history_handling == HistoryHandlingBehavior::Default
&& (still_on_its_initial_about_blank_document()
|| resource.url().equals(active_document()->url())
|| resource.url().scheme() == "javascript"sv)) {
|| resource->url().equals(active_document()->url())
|| resource->url().scheme() == "javascript"sv)) {
// then set historyHandling to "replace".
history_handling = HistoryHandlingBehavior::Replace;
}
@ -928,10 +928,10 @@ WebIDL::ExceptionOr<void> BrowsingContext::navigate(
// resource's URL equals browsingContext's active document's URL with exclude fragments set to true,
// and resource's URL's fragment is non-null, then:
if (history_handling != HistoryHandlingBehavior::Reload
&& resource.url().equals(active_document()->url(), AK::URL::ExcludeFragment::Yes)
&& !resource.url().fragment().is_null()) {
&& resource->url().equals(active_document()->url(), AK::URL::ExcludeFragment::Yes)
&& !resource->url().fragment().is_null()) {
// 1. Navigate to a fragment given browsingContext, resource's URL, historyHandling, and navigationId.
navigate_to_a_fragment(resource.url(), history_handling, *navigation_id);
navigate_to_a_fragment(resource->url(), history_handling, *navigation_id);
// 2. Return.
return {};
@ -982,7 +982,7 @@ WebIDL::ExceptionOr<void> BrowsingContext::navigate(
(void)process_response_end_of_body;
// AD-HOC:
loader().load(resource.url(), FrameLoader::Type::IFrame);
loader().load(resource->url(), FrameLoader::Type::IFrame);
return {};
}
@ -1039,18 +1039,18 @@ WebIDL::ExceptionOr<void> BrowsingContext::traverse_the_history(size_t entry_ind
VERIFY(history_handling == HistoryHandlingBehavior::Default);
// 2. Let request be a new request whose URL is entry's URL.
auto request = Fetch::Infrastructure::Request();
request.set_url(entry->url);
auto request = Fetch::Infrastructure::Request::create();
request->set_url(entry->url);
// 3. If explicitHistoryNavigation is true, then set request's history-navigation flag.
if (explicit_history_navigation)
request.set_history_navigation(true);
request->set_history_navigation(true);
// 4. Navigate the browsing context to request with historyHandling set to "entry update"
// and with historyPolicyContainer set to entry's policy container.
// The navigation must be done using the same source browsing context as was used the first time entry was created.
VERIFY(entry->original_source_browsing_context);
TRY(navigate(request, *entry->original_source_browsing_context, false, HistoryHandlingBehavior::EntryUpdate, entry->policy_container));
TRY(navigate(move(request), *entry->original_source_browsing_context, false, HistoryHandlingBehavior::EntryUpdate, entry->policy_container));
// 5. Return.
return {};

View file

@ -141,14 +141,14 @@ public:
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate
WebIDL::ExceptionOr<void> navigate(
Fetch::Infrastructure::Request resource,
NonnullRefPtr<Fetch::Infrastructure::Request> resource,
BrowsingContext& source_browsing_context,
bool exceptions_enabled = false,
HistoryHandlingBehavior history_handling = HistoryHandlingBehavior::Default,
Optional<PolicyContainer> history_policy_container = {},
String navigation_type = "other",
Optional<String> navigation_id = {},
Function<void(NonnullOwnPtr<Fetch::Infrastructure::Response>)> process_response_end_of_body = {});
Function<void(NonnullRefPtr<Fetch::Infrastructure::Response>)> process_response_end_of_body = {});
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate-fragid
WebIDL::ExceptionOr<void> navigate_to_a_fragment(AK::URL const&, HistoryHandlingBehavior, String navigation_id);

View file

@ -163,8 +163,8 @@ void BrowsingContextContainer::shared_attribute_processing_steps_for_iframe_and_
}
// 5. Let resource be a new request whose URL is url and whose referrer policy is the current state of element's referrerpolicy content attribute.
auto resource = Fetch::Infrastructure::Request();
resource.set_url(url);
auto resource = Fetch::Infrastructure::Request::create();
resource->set_url(url);
// FIXME: Set the referrer policy.
// AD-HOC:
@ -191,7 +191,7 @@ void BrowsingContextContainer::shared_attribute_processing_steps_for_iframe_and_
}
// https://html.spec.whatwg.org/multipage/iframe-embed-object.html#navigate-an-iframe-or-frame
void BrowsingContextContainer::navigate_an_iframe_or_frame(Fetch::Infrastructure::Request resource)
void BrowsingContextContainer::navigate_an_iframe_or_frame(NonnullRefPtr<Fetch::Infrastructure::Request> resource)
{
// 1. Let historyHandling be "default".
auto history_handling = HistoryHandlingBehavior::Default;

View file

@ -35,7 +35,7 @@ protected:
void shared_attribute_processing_steps_for_iframe_and_frame(bool initial_insertion);
// https://html.spec.whatwg.org/multipage/iframe-embed-object.html#navigate-an-iframe-or-frame
void navigate_an_iframe_or_frame(Fetch::Infrastructure::Request);
void navigate_an_iframe_or_frame(NonnullRefPtr<Fetch::Infrastructure::Request>);
void create_new_nested_browsing_context();

View file

@ -23,10 +23,10 @@ struct NavigationParams {
String id;
// null or a request that started the navigation
OwnPtr<Fetch::Infrastructure::Request> request;
RefPtr<Fetch::Infrastructure::Request> request;
// a response that ultimately was navigated to (potentially a network error)
NonnullOwnPtr<Fetch::Infrastructure::Response> response;
NonnullRefPtr<Fetch::Infrastructure::Response> response;
// an origin to use for the new Document
Origin origin;

View file

@ -299,7 +299,7 @@ bool FrameLoader::load(const AK::URL& url, Type type)
void FrameLoader::load_html(StringView html, const AK::URL& url)
{
auto response = make<Fetch::Infrastructure::Response>();
auto response = Fetch::Infrastructure::Response::create();
response->url_list().append(url);
HTML::NavigationParams navigation_params {
.id = {},
@ -419,7 +419,7 @@ void FrameLoader::resource_did_load()
// FIXME: Pass incumbentNavigationOrigin
auto response_origin = HTML::determine_the_origin(browsing_context(), url, final_sandboxing_flag_set, {});
auto response = make<Fetch::Infrastructure::Response>();
auto response = Fetch::Infrastructure::Response::create();
response->url_list().append(url);
HTML::NavigationParams navigation_params {
.id = {},