summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/Fetch/Infrastructure
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2022-10-30 01:52:07 +0000
committerLinus Groh <mail@linusgroh.de>2022-10-30 11:30:23 +0000
commitb1968b8bedbe4266c3a488589e64492955023799 (patch)
tree5e04e2ac323fa1ebeca28ffb36d3e3499618ec93 /Userland/Libraries/LibWeb/Fetch/Infrastructure
parent63122d0276c3e44c005d0c5eaf57f297ecd567f0 (diff)
downloadserenity-b1968b8bedbe4266c3a488589e64492955023799.zip
LibWeb: Make Fetch::Infrastructure::{Request,Response,HeaderList} GC'd
This is the way. On a more serious note, there's no reason to keep adding ref-counted classes to LibWeb now that the majority of classes is GC'd - it only adds the risk of discovering some cycle down the line, and forces us to use handles as we can't visit().
Diffstat (limited to 'Userland/Libraries/LibWeb/Fetch/Infrastructure')
-rw-r--r--Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.cpp7
-rw-r--r--Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.h8
-rw-r--r--Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.cpp20
-rw-r--r--Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.h22
-rw-r--r--Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.cpp122
-rw-r--r--Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.h92
6 files changed, 178 insertions, 93 deletions
diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.cpp b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.cpp
index 0147f03883..838ce31906 100644
--- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.cpp
+++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.cpp
@@ -11,6 +11,8 @@
#include <AK/GenericLexer.h>
#include <AK/QuickSort.h>
#include <AK/ScopeGuard.h>
+#include <LibJS/Heap/Heap.h>
+#include <LibJS/Runtime/VM.h>
#include <LibRegex/Regex.h>
#include <LibWeb/Fetch/Infrastructure/HTTP.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h>
@@ -42,6 +44,11 @@ ErrorOr<Header> Header::from_string_pair(StringView name, StringView value)
};
}
+JS::NonnullGCPtr<HeaderList> HeaderList::create(JS::VM& vm)
+{
+ return { *vm.heap().allocate_without_realm<HeaderList>() };
+}
+
// https://fetch.spec.whatwg.org/#header-list-contains
bool HeaderList::contains(ReadonlyBytes name) const
{
diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.h b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.h
index 71a8932644..15ad9355e2 100644
--- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.h
+++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.h
@@ -13,6 +13,8 @@
#include <AK/Optional.h>
#include <AK/String.h>
#include <AK/Vector.h>
+#include <LibJS/Forward.h>
+#include <LibJS/Heap/Cell.h>
#include <LibWeb/MimeSniff/MimeType.h>
namespace Web::Fetch::Infrastructure {
@@ -29,13 +31,17 @@ struct Header {
// https://fetch.spec.whatwg.org/#concept-header-list
// A header list is a list of zero or more headers. It is initially the empty list.
class HeaderList final
- : public RefCounted<HeaderList>
+ : public JS::Cell
, Vector<Header> {
+ JS_CELL(HeaderList, JS::Cell);
+
public:
using Vector::begin;
using Vector::clear;
using Vector::end;
+ [[nodiscard]] static JS::NonnullGCPtr<HeaderList> create(JS::VM&);
+
[[nodiscard]] bool contains(ReadonlyBytes) const;
[[nodiscard]] ErrorOr<Optional<ByteBuffer>> get(ReadonlyBytes) const;
[[nodiscard]] ErrorOr<Optional<Vector<String>>> get_decode_and_split(ReadonlyBytes) const;
diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.cpp b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.cpp
index fa9c8d978f..2e2db5be8c 100644
--- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.cpp
+++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.cpp
@@ -5,18 +5,26 @@
*/
#include <AK/Array.h>
+#include <LibJS/Heap/Heap.h>
+#include <LibJS/Runtime/Realm.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h>
namespace Web::Fetch::Infrastructure {
-Request::Request()
- : m_header_list(make_ref_counted<HeaderList>())
+Request::Request(JS::NonnullGCPtr<HeaderList> header_list)
+ : m_header_list(header_list)
{
}
-NonnullRefPtr<Request> Request::create()
+void Request::visit_edges(JS::Cell::Visitor& visitor)
{
- return adopt_ref(*new Request());
+ Base::visit_edges(visitor);
+ visitor.visit(m_header_list);
+}
+
+JS::NonnullGCPtr<Request> Request::create(JS::VM& vm)
+{
+ return { *vm.heap().allocate_without_realm<Request>(HeaderList::create(vm)) };
}
// https://fetch.spec.whatwg.org/#concept-request-url
@@ -181,12 +189,12 @@ ErrorOr<ByteBuffer> Request::byte_serialize_origin() const
}
// https://fetch.spec.whatwg.org/#concept-request-clone
-WebIDL::ExceptionOr<NonnullRefPtr<Request>> Request::clone() const
+WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::clone(JS::VM& vm) const
{
// To clone a request request, run these steps:
// 1. Let newRequest be a copy of request, except for its body.
- auto new_request = Infrastructure::Request::create();
+ auto new_request = Infrastructure::Request::create(vm);
new_request->set_method(m_method);
new_request->set_local_urls_only(m_local_urls_only);
for (auto const& header : *m_header_list)
diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.h b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.h
index ff78135a5b..2bca0f6bda 100644
--- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.h
+++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.h
@@ -10,11 +10,12 @@
#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>
#include <AK/Vector.h>
+#include <LibJS/Forward.h>
+#include <LibJS/Heap/Cell.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h>
#include <LibWeb/HTML/Origin.h>
@@ -24,7 +25,9 @@
namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#concept-request
-class Request final : public RefCounted<Request> {
+class Request final : public JS::Cell {
+ JS_CELL(Request, JS::Cell);
+
public:
enum class CacheMode {
Default,
@@ -156,7 +159,7 @@ public:
using ReservedClientType = Variant<Empty, HTML::Environment*, HTML::EnvironmentSettingsObject*>;
using WindowType = Variant<Window, HTML::EnvironmentSettingsObject*>;
- static NonnullRefPtr<Request> create();
+ [[nodiscard]] static JS::NonnullGCPtr<Request> create(JS::VM&);
[[nodiscard]] ReadonlyBytes method() const { return m_method; }
void set_method(ByteBuffer method) { m_method = move(method); }
@@ -164,9 +167,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]] NonnullRefPtr<HeaderList> const& header_list() const { return m_header_list; }
- [[nodiscard]] NonnullRefPtr<HeaderList>& header_list() { return m_header_list; }
- void set_header_list(NonnullRefPtr<HeaderList> header_list) { m_header_list = move(header_list); }
+ [[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]] bool unsafe_request() const { return m_unsafe_request; }
void set_unsafe_request(bool unsafe_request) { m_unsafe_request = unsafe_request; }
@@ -294,14 +296,16 @@ public:
[[nodiscard]] String serialize_origin() const;
[[nodiscard]] ErrorOr<ByteBuffer> byte_serialize_origin() const;
- [[nodiscard]] WebIDL::ExceptionOr<NonnullRefPtr<Request>> clone() const;
+ [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> clone(JS::VM&) const;
[[nodiscard]] ErrorOr<void> add_range_header(u64 first, Optional<u64> const& last);
[[nodiscard]] bool cross_origin_embedder_policy_allows_credentials() const;
private:
- Request();
+ explicit Request(JS::NonnullGCPtr<HeaderList>);
+
+ virtual void visit_edges(JS::Cell::Visitor&) override;
// https://fetch.spec.whatwg.org/#concept-request-method
// A request has an associated method (a method). Unless stated otherwise it is `GET`.
@@ -313,7 +317,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.
- NonnullRefPtr<HeaderList> m_header_list;
+ JS::NonnullGCPtr<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.
diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.cpp b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.cpp
index 398f7fed19..bc53c3cd21 100644
--- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.cpp
+++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.cpp
@@ -4,36 +4,44 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
+#include <LibJS/Heap/Heap.h>
+#include <LibJS/Runtime/VM.h>
#include <LibWeb/Bindings/MainThreadVM.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h>
namespace Web::Fetch::Infrastructure {
-Response::Response()
- : m_header_list(make_ref_counted<HeaderList>())
+Response::Response(JS::NonnullGCPtr<HeaderList> header_list)
+ : m_header_list(header_list)
{
}
-NonnullRefPtr<Response> Response::create()
+void Response::visit_edges(JS::Cell::Visitor& visitor)
{
- return adopt_ref(*new Response());
+ Base::visit_edges(visitor);
+ visitor.visit(m_header_list);
+}
+
+JS::NonnullGCPtr<Response> Response::create(JS::VM& vm)
+{
+ return { *vm.heap().allocate_without_realm<Response>(HeaderList::create(vm)) };
}
// 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.
-NonnullRefPtr<Response> Response::aborted_network_error()
+JS::NonnullGCPtr<Response> Response::aborted_network_error(JS::VM& vm)
{
- auto response = network_error();
+ auto response = network_error(vm);
response->set_aborted(true);
return response;
}
-NonnullRefPtr<Response> Response::network_error()
+JS::NonnullGCPtr<Response> Response::network_error(JS::VM& vm)
{
- auto response = Response::create();
+ auto response = Response::create(vm);
response->set_status(0);
response->set_type(Type::Error);
VERIFY(!response->body().has_value());
@@ -93,29 +101,28 @@ ErrorOr<Optional<AK::URL>> Response::location_url(Optional<String> const& reques
}
// https://fetch.spec.whatwg.org/#concept-response-clone
-WebIDL::ExceptionOr<NonnullRefPtr<Response>> Response::clone() const
+WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::clone(JS::VM& vm) const
{
// To clone a response response, run these steps:
- auto& vm = Bindings::main_thread_vm();
auto& realm = *vm.current_realm();
// 1. If response is a filtered response, then return a new identical filtered response whose internal response is a clone of response’s internal response.
if (is<FilteredResponse>(*this)) {
- auto internal_response = TRY(static_cast<FilteredResponse const&>(*this).internal_response()->clone());
+ auto internal_response = TRY(static_cast<FilteredResponse const&>(*this).internal_response()->clone(vm));
if (is<BasicFilteredResponse>(*this))
- return TRY_OR_RETURN_OOM(realm, BasicFilteredResponse::create(move(internal_response)));
+ return TRY_OR_RETURN_OOM(realm, BasicFilteredResponse::create(vm, internal_response));
if (is<CORSFilteredResponse>(*this))
- return TRY_OR_RETURN_OOM(realm, CORSFilteredResponse::create(move(internal_response)));
+ return TRY_OR_RETURN_OOM(realm, CORSFilteredResponse::create(vm, internal_response));
if (is<OpaqueFilteredResponse>(*this))
- return OpaqueFilteredResponse::create(move(internal_response));
+ return OpaqueFilteredResponse::create(vm, internal_response);
if (is<OpaqueRedirectFilteredResponse>(*this))
- return OpaqueRedirectFilteredResponse::create(move(internal_response));
+ return OpaqueRedirectFilteredResponse::create(vm, internal_response);
VERIFY_NOT_REACHED();
}
// 2. Let newResponse be a copy of response, except for its body.
- auto new_response = Infrastructure::Response::create();
+ auto new_response = Infrastructure::Response::create(vm);
new_response->set_type(m_type);
new_response->set_aborted(m_aborted);
new_response->set_url_list(m_url_list);
@@ -139,8 +146,9 @@ WebIDL::ExceptionOr<NonnullRefPtr<Response>> Response::clone() const
return new_response;
}
-FilteredResponse::FilteredResponse(NonnullRefPtr<Response> internal_response)
- : m_internal_response(move(internal_response))
+FilteredResponse::FilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list)
+ : Response(header_list)
+ , m_internal_response(internal_response)
{
}
@@ -148,26 +156,38 @@ FilteredResponse::~FilteredResponse()
{
}
-ErrorOr<NonnullRefPtr<BasicFilteredResponse>> BasicFilteredResponse::create(NonnullRefPtr<Response> internal_response)
+void FilteredResponse::visit_edges(JS::Cell::Visitor& visitor)
+{
+ Base::visit_edges(visitor);
+ visitor.visit(m_internal_response);
+}
+
+ErrorOr<JS::NonnullGCPtr<BasicFilteredResponse>> BasicFilteredResponse::create(JS::VM& vm, JS::NonnullGCPtr<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.
- auto header_list = make_ref_counted<HeaderList>();
+ auto header_list = HeaderList::create(vm);
for (auto const& header : *internal_response->header_list()) {
if (!is_forbidden_response_header_name(header.name))
TRY(header_list->append(header));
}
- return adopt_ref(*new BasicFilteredResponse(move(internal_response), move(header_list)));
+ return { *vm.heap().allocate_without_realm<BasicFilteredResponse>(internal_response, header_list) };
}
-BasicFilteredResponse::BasicFilteredResponse(NonnullRefPtr<Response> internal_response, NonnullRefPtr<HeaderList> header_list)
- : FilteredResponse(move(internal_response))
- , m_header_list(move(header_list))
+BasicFilteredResponse::BasicFilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list)
+ : FilteredResponse(internal_response, header_list)
+ , m_header_list(header_list)
{
}
-ErrorOr<NonnullRefPtr<CORSFilteredResponse>> CORSFilteredResponse::create(NonnullRefPtr<Response> internal_response)
+void BasicFilteredResponse::visit_edges(JS::Cell::Visitor& visitor)
+{
+ Base::visit_edges(visitor);
+ visitor.visit(m_header_list);
+}
+
+ErrorOr<JS::NonnullGCPtr<CORSFilteredResponse>> CORSFilteredResponse::create(JS::VM& vm, JS::NonnullGCPtr<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
@@ -176,43 +196,63 @@ ErrorOr<NonnullRefPtr<CORSFilteredResponse>> CORSFilteredResponse::create(Nonnul
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>();
+ auto header_list = HeaderList::create(vm);
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_ref(*new CORSFilteredResponse(move(internal_response), move(header_list)));
+ return { *vm.heap().allocate_without_realm<CORSFilteredResponse>(internal_response, header_list) };
}
-CORSFilteredResponse::CORSFilteredResponse(NonnullRefPtr<Response> internal_response, NonnullRefPtr<HeaderList> header_list)
- : FilteredResponse(move(internal_response))
- , m_header_list(move(header_list))
+CORSFilteredResponse::CORSFilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list)
+ : FilteredResponse(internal_response, header_list)
+ , m_header_list(header_list)
{
}
-NonnullRefPtr<OpaqueFilteredResponse> OpaqueFilteredResponse::create(NonnullRefPtr<Response> internal_response)
+void CORSFilteredResponse::visit_edges(JS::Cell::Visitor& visitor)
{
- // An opaque-redirect filtered response is a filtered response whose type is "opaqueredirect",
+ Base::visit_edges(visitor);
+ visitor.visit(m_header_list);
+}
+
+JS::NonnullGCPtr<OpaqueFilteredResponse> OpaqueFilteredResponse::create(JS::VM& vm, JS::NonnullGCPtr<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 adopt_ref(*new OpaqueFilteredResponse(move(internal_response)));
+ return { *vm.heap().allocate_without_realm<OpaqueFilteredResponse>(internal_response, HeaderList::create(vm)) };
+}
+
+OpaqueFilteredResponse::OpaqueFilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list)
+ : FilteredResponse(internal_response, header_list)
+ , m_header_list(header_list)
+{
}
-OpaqueFilteredResponse::OpaqueFilteredResponse(NonnullRefPtr<Response> internal_response)
- : FilteredResponse(move(internal_response))
- , m_header_list(make_ref_counted<HeaderList>())
+void OpaqueFilteredResponse::visit_edges(JS::Cell::Visitor& visitor)
{
+ Base::visit_edges(visitor);
+ visitor.visit(m_header_list);
+}
+
+JS::NonnullGCPtr<OpaqueRedirectFilteredResponse> OpaqueRedirectFilteredResponse::create(JS::VM& vm, JS::NonnullGCPtr<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_without_realm<OpaqueRedirectFilteredResponse>(internal_response, HeaderList::create(vm)) };
}
-NonnullRefPtr<OpaqueRedirectFilteredResponse> OpaqueRedirectFilteredResponse::create(NonnullRefPtr<Response> internal_response)
+OpaqueRedirectFilteredResponse::OpaqueRedirectFilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list)
+ : FilteredResponse(internal_response, header_list)
+ , m_header_list(header_list)
{
- return adopt_ref(*new OpaqueRedirectFilteredResponse(move(internal_response)));
}
-OpaqueRedirectFilteredResponse::OpaqueRedirectFilteredResponse(NonnullRefPtr<Response> internal_response)
- : FilteredResponse(move(internal_response))
- , m_header_list(make_ref_counted<HeaderList>())
+void OpaqueRedirectFilteredResponse::visit_edges(JS::Cell::Visitor& visitor)
{
+ Base::visit_edges(visitor);
+ visitor.visit(m_header_list);
}
}
diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.h b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.h
index 4df9eb9b50..589bcbbc0f 100644
--- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.h
+++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.h
@@ -10,9 +10,10 @@
#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 <LibJS/Forward.h>
+#include <LibJS/Heap/Cell.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h>
#include <LibWeb/Fetch/Infrastructure/HTTP/Statuses.h>
@@ -20,7 +21,9 @@
namespace Web::Fetch::Infrastructure {
// https://fetch.spec.whatwg.org/#concept-response
-class Response : public RefCounted<Response> {
+class Response : public JS::Cell {
+ JS_CELL(Response, JS::Cell);
+
public:
enum class CacheState {
Local,
@@ -45,9 +48,9 @@ public:
u64 decoded_size { 0 };
};
- [[nodiscard]] static NonnullRefPtr<Response> create();
- [[nodiscard]] static NonnullRefPtr<Response> aborted_network_error();
- [[nodiscard]] static NonnullRefPtr<Response> network_error();
+ [[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&);
virtual ~Response() = default;
@@ -67,9 +70,8 @@ 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 NonnullRefPtr<HeaderList> const& header_list() const { return m_header_list; }
- [[nodiscard]] virtual NonnullRefPtr<HeaderList>& header_list() { return m_header_list; }
- void set_header_list(NonnullRefPtr<HeaderList> header_list) { m_header_list = move(header_list); }
+ [[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 Optional<Body> const& body() const { return m_body; }
[[nodiscard]] virtual Optional<Body>& body() { return m_body; }
@@ -99,10 +101,12 @@ public:
[[nodiscard]] Optional<AK::URL const&> url() const;
[[nodiscard]] ErrorOr<Optional<AK::URL>> location_url(Optional<String> const& request_fragment) const;
- [[nodiscard]] WebIDL::ExceptionOr<NonnullRefPtr<Response>> clone() const;
+ [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> clone(JS::VM&) const;
protected:
- Response();
+ explicit Response(JS::NonnullGCPtr<HeaderList>);
+
+ virtual void visit_edges(JS::Cell::Visitor&) override;
private:
// https://fetch.spec.whatwg.org/#concept-response-type
@@ -127,7 +131,7 @@ 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.
- NonnullRefPtr<HeaderList> m_header_list;
+ JS::NonnullGCPtr<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.
@@ -163,8 +167,10 @@ private:
// https://fetch.spec.whatwg.org/#concept-filtered-response
class FilteredResponse : public Response {
+ JS_CELL(FilteredResponse, Response);
+
public:
- explicit FilteredResponse(NonnullRefPtr<Response>);
+ FilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>);
virtual ~FilteredResponse() = 0;
[[nodiscard]] virtual Type type() const override { return m_internal_response->type(); }
@@ -173,8 +179,7 @@ public:
[[nodiscard]] virtual Vector<AK::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 NonnullRefPtr<HeaderList> const& header_list() const override { return m_internal_response->header_list(); }
- [[nodiscard]] virtual NonnullRefPtr<HeaderList>& header_list() override { return m_internal_response->header_list(); }
+ [[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> 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<Body>& body() override { return m_internal_response->body(); }
[[nodiscard]] virtual Optional<CacheState> const& cache_state() const override { return m_internal_response->cache_state(); }
@@ -184,83 +189,98 @@ 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]] NonnullRefPtr<Response> internal_response() const { return m_internal_response; }
+ [[nodiscard]] JS::NonnullGCPtr<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
- NonnullRefPtr<Response> m_internal_response;
+ JS::NonnullGCPtr<Response> m_internal_response;
};
// https://fetch.spec.whatwg.org/#concept-filtered-response-basic
class BasicFilteredResponse final : public FilteredResponse {
+ JS_CELL(OpaqueRedirectFilteredResponse, FilteredResponse);
+
public:
- static ErrorOr<NonnullRefPtr<BasicFilteredResponse>> create(NonnullRefPtr<Response>);
+ [[nodiscard]] static ErrorOr<JS::NonnullGCPtr<BasicFilteredResponse>> create(JS::VM&, JS::NonnullGCPtr<Response>);
[[nodiscard]] virtual Type type() const override { return Type::Basic; }
- [[nodiscard]] virtual NonnullRefPtr<HeaderList> const& header_list() const override { return m_header_list; }
- [[nodiscard]] virtual NonnullRefPtr<HeaderList>& header_list() override { return m_header_list; }
+ [[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_header_list; }
private:
- BasicFilteredResponse(NonnullRefPtr<Response>, NonnullRefPtr<HeaderList>);
+ BasicFilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>);
+
+ virtual void visit_edges(JS::Cell::Visitor&) override;
- NonnullRefPtr<HeaderList> m_header_list;
+ JS::NonnullGCPtr<HeaderList> m_header_list;
};
// https://fetch.spec.whatwg.org/#concept-filtered-response-cors
class CORSFilteredResponse final : public FilteredResponse {
+ JS_CELL(CORSFilteredResponse, FilteredResponse);
+
public:
- static ErrorOr<NonnullRefPtr<CORSFilteredResponse>> create(NonnullRefPtr<Response>);
+ [[nodiscard]] static ErrorOr<JS::NonnullGCPtr<CORSFilteredResponse>> create(JS::VM&, JS::NonnullGCPtr<Response>);
[[nodiscard]] virtual Type type() const override { return Type::CORS; }
- [[nodiscard]] virtual NonnullRefPtr<HeaderList> const& header_list() const override { return m_header_list; }
- [[nodiscard]] virtual NonnullRefPtr<HeaderList>& header_list() override { return m_header_list; }
+ [[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_header_list; }
private:
- CORSFilteredResponse(NonnullRefPtr<Response>, NonnullRefPtr<HeaderList>);
+ CORSFilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>);
+
+ virtual void visit_edges(JS::Cell::Visitor&) override;
- NonnullRefPtr<HeaderList> m_header_list;
+ JS::NonnullGCPtr<HeaderList> m_header_list;
};
// https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
class OpaqueFilteredResponse final : public FilteredResponse {
+ JS_CELL(OpaqueFilteredResponse, FilteredResponse);
+
public:
- static NonnullRefPtr<OpaqueFilteredResponse> create(NonnullRefPtr<Response>);
+ [[nodiscard]] static JS::NonnullGCPtr<OpaqueFilteredResponse> create(JS::VM&, JS::NonnullGCPtr<Response>);
[[nodiscard]] virtual Type type() const override { return Type::Opaque; }
[[nodiscard]] virtual Vector<AK::URL> const& url_list() const override { return m_url_list; }
[[nodiscard]] virtual Vector<AK::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 NonnullRefPtr<HeaderList> const& header_list() const override { return m_header_list; }
- [[nodiscard]] virtual NonnullRefPtr<HeaderList>& header_list() override { return m_header_list; }
+ [[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_header_list; }
[[nodiscard]] virtual Optional<Body> const& body() const override { return m_body; }
[[nodiscard]] virtual Optional<Body>& body() override { return m_body; }
private:
- explicit OpaqueFilteredResponse(NonnullRefPtr<Response>);
+ OpaqueFilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>);
+
+ virtual void visit_edges(JS::Cell::Visitor&) override;
Vector<AK::URL> m_url_list;
- NonnullRefPtr<HeaderList> m_header_list;
+ JS::NonnullGCPtr<HeaderList> m_header_list;
Optional<Body> m_body;
};
// https://fetch.spec.whatwg.org/#concept-filtered-response-opaque-redirect
class OpaqueRedirectFilteredResponse final : public FilteredResponse {
+ JS_CELL(OpaqueRedirectFilteredResponse, FilteredResponse);
+
public:
- static NonnullRefPtr<OpaqueRedirectFilteredResponse> create(NonnullRefPtr<Response>);
+ [[nodiscard]] static JS::NonnullGCPtr<OpaqueRedirectFilteredResponse> create(JS::VM&, JS::NonnullGCPtr<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 NonnullRefPtr<HeaderList> const& header_list() const override { return m_header_list; }
- [[nodiscard]] virtual NonnullRefPtr<HeaderList>& header_list() override { return m_header_list; }
+ [[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_header_list; }
[[nodiscard]] virtual Optional<Body> const& body() const override { return m_body; }
[[nodiscard]] virtual Optional<Body>& body() override { return m_body; }
private:
- explicit OpaqueRedirectFilteredResponse(NonnullRefPtr<Response>);
+ OpaqueRedirectFilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>);
+
+ virtual void visit_edges(JS::Cell::Visitor&) override;
- NonnullRefPtr<HeaderList> m_header_list;
+ JS::NonnullGCPtr<HeaderList> m_header_list;
Optional<Body> m_body;
};