1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:28:12 +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

@ -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 {