diff options
author | Linus Groh <mail@linusgroh.de> | 2022-09-25 19:36:30 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-09-27 14:56:17 +0100 |
commit | 0b52b883af2989cc43b75db4835325a2c31e71d5 (patch) | |
tree | b9a7fb6c90d589dbe4055e9dfb8855da78a0d1b9 /Userland/Libraries | |
parent | 9fb672e9815a240fcefbd948806351c7e943922a (diff) | |
download | serenity-0b52b883af2989cc43b75db4835325a2c31e71d5.zip |
LibWeb: Implement '5.5. Response class' from the Fetch API :^)
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Fetch/Enums.cpp | 21 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Fetch/Enums.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Fetch/Response.cpp | 309 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Fetch/Response.h | 78 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Fetch/Response.idl | 32 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Forward.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/idl_files.cmake | 1 |
9 files changed, 449 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h b/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h index ec05217967..84f60d0932 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h +++ b/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h @@ -307,6 +307,8 @@ #include <LibWeb/Bindings/RequestPrototype.h> #include <LibWeb/Bindings/ResizeObserverConstructor.h> #include <LibWeb/Bindings/ResizeObserverPrototype.h> +#include <LibWeb/Bindings/ResponseConstructor.h> +#include <LibWeb/Bindings/ResponsePrototype.h> #include <LibWeb/Bindings/SVGAnimatedLengthConstructor.h> #include <LibWeb/Bindings/SVGAnimatedLengthPrototype.h> #include <LibWeb/Bindings/SVGCircleElementConstructor.h> @@ -550,6 +552,7 @@ ADD_WINDOW_OBJECT_INTERFACE(ReadableStream) \ ADD_WINDOW_OBJECT_INTERFACE(Request) \ ADD_WINDOW_OBJECT_INTERFACE(ResizeObserver) \ + ADD_WINDOW_OBJECT_INTERFACE(Response) \ ADD_WINDOW_OBJECT_INTERFACE(Screen) \ ADD_WINDOW_OBJECT_INTERFACE(Selection) \ ADD_WINDOW_OBJECT_INTERFACE(ShadowRoot) \ diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index b13e91632c..48d09efd93 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -132,6 +132,7 @@ set(SOURCES Fetch/Infrastructure/HTTP/Statuses.cpp Fetch/Infrastructure/URL.cpp Fetch/Request.cpp + Fetch/Response.cpp FileAPI/Blob.cpp FileAPI/File.cpp FontCache.cpp diff --git a/Userland/Libraries/LibWeb/Fetch/Enums.cpp b/Userland/Libraries/LibWeb/Fetch/Enums.cpp index 25cf434939..fc9779a83c 100644 --- a/Userland/Libraries/LibWeb/Fetch/Enums.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Enums.cpp @@ -5,6 +5,7 @@ */ #include <LibWeb/Bindings/RequestPrototype.h> +#include <LibWeb/Bindings/ResponsePrototype.h> #include <LibWeb/Fetch/Enums.h> #include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h> #include <LibWeb/ReferrerPolicy/ReferrerPolicy.h> @@ -257,4 +258,24 @@ Bindings::RequestRedirect to_bindings_enum(Infrastructure::Request::RedirectMode } } +Bindings::ResponseType to_bindings_enum(Infrastructure::Response::Type type) +{ + switch (type) { + case Infrastructure::Response::Type::Basic: + return Bindings::ResponseType::Basic; + case Infrastructure::Response::Type::CORS: + return Bindings::ResponseType::Cors; + case Infrastructure::Response::Type::Default: + return Bindings::ResponseType::Default; + case Infrastructure::Response::Type::Error: + return Bindings::ResponseType::Error; + case Infrastructure::Response::Type::Opaque: + return Bindings::ResponseType::Opaque; + case Infrastructure::Response::Type::OpaqueRedirect: + return Bindings::ResponseType::Opaqueredirect; + default: + VERIFY_NOT_REACHED(); + } +} + } diff --git a/Userland/Libraries/LibWeb/Fetch/Enums.h b/Userland/Libraries/LibWeb/Fetch/Enums.h index f74921dd1b..2890f97330 100644 --- a/Userland/Libraries/LibWeb/Fetch/Enums.h +++ b/Userland/Libraries/LibWeb/Fetch/Enums.h @@ -8,6 +8,7 @@ #include <AK/Forward.h> #include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h> +#include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h> #include <LibWeb/Forward.h> namespace Web::Fetch { @@ -24,5 +25,6 @@ namespace Web::Fetch { [[nodiscard]] Bindings::RequestCredentials to_bindings_enum(Infrastructure::Request::CredentialsMode); [[nodiscard]] Bindings::RequestCache to_bindings_enum(Infrastructure::Request::CacheMode); [[nodiscard]] Bindings::RequestRedirect to_bindings_enum(Infrastructure::Request::RedirectMode); +[[nodiscard]] Bindings::ResponseType to_bindings_enum(Infrastructure::Response::Type); } diff --git a/Userland/Libraries/LibWeb/Fetch/Response.cpp b/Userland/Libraries/LibWeb/Fetch/Response.cpp new file mode 100644 index 0000000000..8e355f1708 --- /dev/null +++ b/Userland/Libraries/LibWeb/Fetch/Response.cpp @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2022, Linus Groh <linusg@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <AK/URLParser.h> +#include <LibWeb/Bindings/MainThreadVM.h> +#include <LibWeb/Fetch/Enums.h> +#include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h> +#include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h> +#include <LibWeb/Fetch/Infrastructure/HTTP/Statuses.h> +#include <LibWeb/Fetch/Response.h> +#include <LibWeb/HTML/Scripting/Environments.h> +#include <LibWeb/HTML/Window.h> +#include <LibWeb/Infra/JSON.h> + +namespace Web::Fetch { + +Response::Response(JS::Realm& realm, NonnullOwnPtr<Infrastructure::Response> response) + : PlatformObject(realm) + , m_response(move(response)) +{ + auto& window = verify_cast<HTML::Window>(realm.global_object()); + set_prototype(&window.cached_web_prototype("Response")); +} + +Response::~Response() = default; + +void Response::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_headers); +} + +// https://fetch.spec.whatwg.org/#concept-body-mime-type +// https://fetch.spec.whatwg.org/#ref-for-concept-header-extract-mime-type%E2%91%A7 +Optional<MimeSniff::MimeType> Response::mime_type_impl() const +{ + // Objects including the Body interface mixin need to define an associated MIME type algorithm which takes no arguments and returns failure or a MIME type. + // A Response object’s MIME type is to return the result of extracting a MIME type from its response’s header list. + return m_response->header_list()->extract_mime_type(); +} + +// https://fetch.spec.whatwg.org/#concept-body-body +// https://fetch.spec.whatwg.org/#ref-for-concept-body-body%E2%91%A8 +Optional<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. + return m_response->body().has_value() + ? m_response->body().value() + : Optional<Infrastructure::Body const&> {}; +} + +// https://fetch.spec.whatwg.org/#concept-body-body +// https://fetch.spec.whatwg.org/#ref-for-concept-body-body%E2%91%A8 +Optional<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. + return m_response->body().has_value() + ? m_response->body().value() + : Optional<Infrastructure::Body&> {}; +} + +// https://fetch.spec.whatwg.org/#response-create +JS::NonnullGCPtr<Response> Response::create(NonnullOwnPtr<Infrastructure::Response> response, Headers::Guard guard, JS::Realm& realm) +{ + auto& window = verify_cast<HTML::Window>(realm.global_object()); + + // Copy a NonnullRefPtr to the response's header list before response is being move()'d. + auto response_reader_list = response->header_list(); + + // 1. Let responseObject be a new Response object with realm. + // 2. Set responseObject’s response to response. + auto* response_object = realm.heap().allocate<Response>(realm, realm, move(response)); + + // 3. Set responseObject’s headers to a new Headers object with realm, whose headers list is response’s headers list and guard is guard. + response_object->m_headers = realm.heap().allocate<Headers>(realm, window); + response_object->m_headers->set_header_list(move(response_reader_list)); + response_object->m_headers->set_guard(guard); + + // 4. Return responseObject. + return JS::NonnullGCPtr { *response_object }; +} + +// https://fetch.spec.whatwg.org/#initialize-a-response +WebIDL::ExceptionOr<void> Response::initialize_response(ResponseInit const& init, Optional<Infrastructure::BodyWithType> const& body) +{ + auto& vm = Bindings::main_thread_vm(); + auto& realm = *vm.current_realm(); + auto& window = verify_cast<HTML::Window>(realm.global_object()); + + // 1. If init["status"] is not in the range 200 to 599, inclusive, then throw a RangeError. + if (init.status < 200 || init.status > 599) + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Status must be in range 200-599"sv }; + + // FIXME: 2. If init["statusText"] does not match the reason-phrase token production, then throw a TypeError. + + // 3. Set response’s response’s status to init["status"]. + m_response->set_status(init.status); + + // 4. Set response’s response’s status message to init["statusText"]. + m_response->set_status_message(TRY_OR_RETURN_OOM(window, ByteBuffer::copy(init.status_text.bytes()))); + + // 5. If init["headers"] exists, then fill response’s headers with init["headers"]. + if (init.headers.has_value()) + m_headers->fill(*init.headers); + + // 6. If body was given, then: + if (body.has_value()) { + // 1. If response’s status is a null body status, then throw a TypeError. + if (Infrastructure::is_null_body_status(m_response->status())) + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Response with null body status cannot have a body"sv }; + + // 2. Set response’s body to body’s body. + m_response->set_body(body->body); + + // 3. If body’s type is non-null and response’s header list does not contain `Content-Type`, then append (`Content-Type`, body’s type) to response’s header list. + if (body->type.has_value() && m_response->header_list()->contains("Content-Type"sv.bytes())) { + auto header = Infrastructure::Header { + .name = TRY_OR_RETURN_OOM(global_object(), ByteBuffer::copy("Content-Type"sv.bytes())), + .value = TRY_OR_RETURN_OOM(global_object(), ByteBuffer::copy(body->type->span())), + }; + TRY_OR_RETURN_OOM(global_object(), m_response->header_list()->append(move(header))); + } + } + + return {}; +} + +// https://fetch.spec.whatwg.org/#dom-response +WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::create_with_global_object(HTML::Window& window, Optional<BodyInit> const& body, ResponseInit const& init) +{ + auto& realm = window.realm(); + + // Referred to as 'this' in the spec. + auto response_object = [&] { + auto response = adopt_own(*new Infrastructure::Response()); + return JS::NonnullGCPtr { *realm.heap().allocate<Response>(realm, realm, move(response)) }; + }(); + + // 1. Set this’s response to a new response. + // NOTE: This is done at the beginning as the 'this' value Response object + // cannot exist with a null Infrastructure::Response. + + // 2. Set this’s headers to a new Headers object with this’s relevant Realm, whose header list is this’s response’s header list and guard is "response". + response_object->m_headers = realm.heap().allocate<Headers>(realm, window); + 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. + Optional<Infrastructure::BodyWithType> body_with_type; + + // 4. If body is non-null, then set bodyWithType to the result of extracting body. + if (body.has_value()) + body_with_type = TRY(extract_body(realm, *body)); + + // 5. Perform initialize a response given this, init, and bodyWithType. + TRY(response_object->initialize_response(init, body_with_type)); + + return response_object; +} + +// https://fetch.spec.whatwg.org/#dom-response-error +JS::NonnullGCPtr<Response> Response::error() +{ + auto& vm = Bindings::main_thread_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? + return Response::create(Infrastructure::Response::network_error(), Headers::Guard::Immutable, *vm.current_realm()); +} + +// https://fetch.spec.whatwg.org/#dom-response-redirect +WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::redirect(String const& url, u16 status) +{ + auto& vm = Bindings::main_thread_vm(); + auto& realm = *vm.current_realm(); + auto& window = verify_cast<HTML::Window>(realm.global_object()); + + // 1. Let parsedURL be the result of parsing url with current settings object’s API base URL. + auto api_base_url = HTML::current_settings_object().api_base_url(); + auto parsed_url = URLParser::parse(url, &api_base_url); + + // 2. If parsedURL is failure, then throw a TypeError. + if (!parsed_url.is_valid()) + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Redirect URL is not valid"sv }; + + // 3. If status is not a redirect status, then throw a RangeError. + if (!Infrastructure::is_redirect_status(status)) + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Status must be one of 301, 302, 303, 307, or 308"sv }; + + // 4. Let responseObject be the result of creating a Response object, given a new response, "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? + auto response_object = Response::create(make<Infrastructure::Response>(), Headers::Guard::Immutable, *vm.current_realm()); + + // 5. Set responseObject’s response’s status to status. + response_object->response().set_status(status); + + // 6. Let value be parsedURL, serialized and isomorphic encoded. + auto value = parsed_url.serialize(); + + // 7. Append (`Location`, value) to responseObject’s response’s header list. + auto header = Infrastructure::Header { + .name = TRY_OR_RETURN_OOM(window, ByteBuffer::copy("Location"sv.bytes())), + .value = TRY_OR_RETURN_OOM(window, ByteBuffer::copy(value.bytes())), + }; + TRY_OR_RETURN_OOM(window, response_object->response().header_list()->append(move(header))); + + // 8. Return responseObject. + return response_object; +} + +// https://fetch.spec.whatwg.org/#dom-response-json +WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::json(JS::Value data, ResponseInit const& init) +{ + auto& vm = Bindings::main_thread_vm(); + auto& realm = *vm.current_realm(); + auto& window = verify_cast<HTML::Window>(realm.global_object()); + + // 1. Let bytes the result of running serialize a JavaScript value to JSON bytes on data. + auto bytes = TRY(Infra::serialize_javascript_value_to_json_bytes(vm, data)); + + // 2. Let body be the result of extracting bytes. + auto [body, _] = TRY(extract_body(realm, { bytes.bytes() })); + + // 3. Let responseObject be the result of creating a Response object, given a new response, "response", 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? + auto response_object = Response::create(make<Infrastructure::Response>(), Headers::Guard::Response, *vm.current_realm()); + + // 4. Perform initialize a response given responseObject, init, and (body, "application/json"). + auto body_with_type = Infrastructure::BodyWithType { + .body = move(body), + .type = TRY_OR_RETURN_OOM(window, ByteBuffer::copy("application/json"sv.bytes())) + }; + TRY(response_object->initialize_response(init, move(body_with_type))); + + // 5. Return responseObject. + return response_object; +} + +// https://fetch.spec.whatwg.org/#dom-response-type +Bindings::ResponseType Response::type() const +{ + // The type getter steps are to return this’s response’s type. + return to_bindings_enum(m_response->type()); +} + +// https://fetch.spec.whatwg.org/#dom-response-url +String Response::url() const +{ + // The url getter steps are to return the empty string if this’s response’s URL is null; otherwise this’s response’s URL, serialized with exclude fragment set to true. + return !m_response->url().has_value() + ? String::empty() + : m_response->url()->serialize(AK::URL::ExcludeFragment::Yes); +} + +// https://fetch.spec.whatwg.org/#dom-response-redirected +bool Response::redirected() const +{ + // The redirected getter steps are to return true if this’s response’s URL list has more than one item; otherwise false. + return m_response->url_list().size() > 1; +} + +// https://fetch.spec.whatwg.org/#dom-response-status +u16 Response::status() const +{ + // The status getter steps are to return this’s response’s status. + return m_response->status(); +} + +// https://fetch.spec.whatwg.org/#dom-response-ok +bool Response::ok() const +{ + // The ok getter steps are to return true if this’s response’s status is an ok status; otherwise false. + return Infrastructure::is_ok_status(m_response->status()); +} + +// https://fetch.spec.whatwg.org/#dom-response-statustext +String Response::status_text() const +{ + // The statusText getter steps are to return this’s response’s status message. + return String::copy(m_response->status_message()); +} + +// https://fetch.spec.whatwg.org/#dom-response-headers +JS::NonnullGCPtr<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 +{ + // 1. If this is unusable, then throw a TypeError. + if (is_unusable()) + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Response is unusable"sv }; + + // 2. Let clonedResponse be the result of cloning this’s response. + auto cloned_response = TRY(m_response->clone()); + + // 3. Return the result of creating a Response object, given clonedResponse, this’s headers’s guard, and this’s relevant Realm. + return Response::create(move(cloned_response), m_headers->guard(), HTML::relevant_realm(*this)); +} + +} diff --git a/Userland/Libraries/LibWeb/Fetch/Response.h b/Userland/Libraries/LibWeb/Fetch/Response.h new file mode 100644 index 0000000000..e460e87e16 --- /dev/null +++ b/Userland/Libraries/LibWeb/Fetch/Response.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022, Linus Groh <linusg@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Forward.h> +#include <LibJS/Forward.h> +#include <LibWeb/Bindings/PlatformObject.h> +#include <LibWeb/Fetch/Body.h> +#include <LibWeb/Fetch/BodyInit.h> +#include <LibWeb/Fetch/Headers.h> +#include <LibWeb/Forward.h> + +namespace Web::Fetch { + +// https://fetch.spec.whatwg.org/#responseinit +struct ResponseInit { + u16 status; + String status_text; + Optional<HeadersInit> headers; +}; + +// https://fetch.spec.whatwg.org/#response +class Response final + : public Bindings::PlatformObject + , public BodyMixin { + WEB_PLATFORM_OBJECT(Response, Bindings::PlatformObject); + +public: + static JS::NonnullGCPtr<Response> create(NonnullOwnPtr<Infrastructure::Response>, Headers::Guard, JS::Realm&); + static WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> create_with_global_object(HTML::Window&, Optional<BodyInit> const& body = {}, ResponseInit const& init = {}); + + virtual ~Response() override; + + // ^BodyMixin + virtual Optional<MimeSniff::MimeType> mime_type_impl() const override; + 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; } + + // JS API functions + [[nodiscard]] static JS::NonnullGCPtr<Response> error(); + [[nodiscard]] static WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> redirect(String const& url, u16 status); + [[nodiscard]] static WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> json(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; + + // Pull in json() from the BodyMixin, which gets lost due to the static json() above + using BodyMixin::json; + +private: + Response(JS::Realm&, NonnullOwnPtr<Infrastructure::Response>); + + virtual void visit_edges(Cell::Visitor&) override; + + WebIDL::ExceptionOr<void> initialize_response(ResponseInit const&, Optional<Infrastructure::BodyWithType> const&); + + // https://fetch.spec.whatwg.org/#concept-response-response + // A Response object has an associated response (a response). + NonnullOwnPtr<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; +}; + +} diff --git a/Userland/Libraries/LibWeb/Fetch/Response.idl b/Userland/Libraries/LibWeb/Fetch/Response.idl new file mode 100644 index 0000000000..467f7f18bb --- /dev/null +++ b/Userland/Libraries/LibWeb/Fetch/Response.idl @@ -0,0 +1,32 @@ +#import <Fetch/Body.idl> +#import <Fetch/BodyInit.idl> +#import <Fetch/Headers.idl> + +[Exposed=(Window,Worker)] +interface Response { + constructor(optional BodyInit? body = null, optional ResponseInit init = {}); + + [NewObject] static Response error(); + [NewObject] static Response redirect(USVString url, optional unsigned short status = 302); + [NewObject] static Response json(any data, optional ResponseInit init = {}); + + readonly attribute ResponseType type; + + readonly attribute USVString url; + readonly attribute boolean redirected; + readonly attribute unsigned short status; + readonly attribute boolean ok; + readonly attribute ByteString statusText; + [SameObject] readonly attribute Headers headers; + + [NewObject] Response clone(); +}; +Response includes Body; + +dictionary ResponseInit { + unsigned short status = 200; + ByteString statusText = ""; + HeadersInit headers; +}; + +enum ResponseType { "basic", "cors", "default", "error", "opaque", "opaqueredirect" }; diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index fff7f0e60b..d2f0b3c791 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -184,6 +184,7 @@ class BodyMixin; class Headers; class HeadersIterator; class Request; +class Response; } namespace Web::Fetch::Infrastructure { @@ -489,6 +490,7 @@ enum class RequestCredentials; enum class RequestCache; enum class RequestRedirect; enum class RequestDuplex; +enum class ResponseType; enum class ResizeObserverBoxOptions; enum class XMLHttpRequestResponseType; } diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 0f82d23a00..5f293b7a30 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -54,6 +54,7 @@ libweb_js_bindings(Encoding/TextDecoder) libweb_js_bindings(Encoding/TextEncoder) libweb_js_bindings(Fetch/Headers ITERABLE) libweb_js_bindings(Fetch/Request) +libweb_js_bindings(Fetch/Response) libweb_js_bindings(FileAPI/Blob) libweb_js_bindings(FileAPI/File) libweb_js_bindings(Geometry/DOMPoint) |