diff options
author | Kenneth Myhra <kennethmyhra@gmail.com> | 2023-04-02 22:30:56 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2023-04-05 09:43:52 +0100 |
commit | 1120011de4c3ae731b5c8349c84cd310a56f7e90 (patch) | |
tree | f5f55423fc3cd41328101a46797ca36dec4cb16a | |
parent | 5df4d66d91149fe66f8660252709a1f6fbdf3124 (diff) | |
download | serenity-1120011de4c3ae731b5c8349c84cd310a56f7e90.zip |
LibWeb: Add FormData support to XHR
This adds FormData support to XHR so that it can post
multipart/form-data encoded data.
-rw-r--r-- | Userland/Libraries/LibWeb/Fetch/BodyInit.cpp | 16 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Fetch/BodyInit.h | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Fetch/BodyInit.idl | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/XHR/FormData.idl | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h | 2 |
5 files changed, 24 insertions, 7 deletions
diff --git a/Userland/Libraries/LibWeb/Fetch/BodyInit.cpp b/Userland/Libraries/LibWeb/Fetch/BodyInit.cpp index 076711867f..b116de67f3 100644 --- a/Userland/Libraries/LibWeb/Fetch/BodyInit.cpp +++ b/Userland/Libraries/LibWeb/Fetch/BodyInit.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org> - * Copyright (c) 2022, Kenneth Myhra <kennethmyhra@serenityos.org> + * Copyright (c) 2022-2023, Kenneth Myhra <kennethmyhra@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,9 +8,11 @@ #include <LibJS/Runtime/Completion.h> #include <LibWeb/Fetch/BodyInit.h> #include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h> +#include <LibWeb/HTML/FormControlInfrastructure.h> #include <LibWeb/URL/URLSearchParams.h> #include <LibWeb/WebIDL/AbstractOperations.h> #include <LibWeb/WebIDL/ExceptionOr.h> +#include <LibWeb/XHR/FormData.h> namespace Web::Fetch { @@ -66,7 +68,7 @@ WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm& realm, Optional<ByteBuffer> type {}; // 10. Switch on object. - // FIXME: Still need to support BufferSource and FormData + // FIXME: Still need to support BufferSource TRY(object.visit( [&](JS::Handle<FileAPI::Blob> const& blob) -> WebIDL::ExceptionOr<void> { // Set source to object. @@ -88,6 +90,16 @@ WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm& realm, source = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(*buffer_source.cell())); return {}; }, + [&](JS::Handle<XHR::FormData> const& form_data) -> WebIDL::ExceptionOr<void> { + // Set action to this step: run the multipart/form-data encoding algorithm, with object’s entry list and UTF-8. + auto serialized_form_data = TRY_OR_THROW_OOM(vm, HTML::serialize_to_multipart_form_data(form_data->entry_list())); + // Set source to object. + source = serialized_form_data.serialized_data; + // FIXME: Set length to unclear, see html/6424 for improving this. + // Set type to `multipart/form-data; boundary=`, followed by the multipart/form-data boundary string generated by the multipart/form-data encoding algorithm. + type = TRY_OR_THROW_OOM(vm, ByteBuffer::copy(TRY_OR_THROW_OOM(vm, String::formatted("multipart/form-data; boundary={}"sv, serialized_form_data.boundary)).bytes())); + return {}; + }, [&](JS::Handle<URL::URLSearchParams> const& url_search_params) -> WebIDL::ExceptionOr<void> { // Set source to the result of running the application/x-www-form-urlencoded serializer with object’s list. auto search_params_bytes = TRY(url_search_params->to_string()).bytes(); diff --git a/Userland/Libraries/LibWeb/Fetch/BodyInit.h b/Userland/Libraries/LibWeb/Fetch/BodyInit.h index f22deb9c7b..787c19ffcb 100644 --- a/Userland/Libraries/LibWeb/Fetch/BodyInit.h +++ b/Userland/Libraries/LibWeb/Fetch/BodyInit.h @@ -14,9 +14,9 @@ namespace Web::Fetch { // https://fetch.spec.whatwg.org/#bodyinit -using BodyInit = Variant<JS::Handle<Streams::ReadableStream>, JS::Handle<FileAPI::Blob>, JS::Handle<JS::Object>, JS::Handle<URL::URLSearchParams>, String>; +using BodyInit = Variant<JS::Handle<Streams::ReadableStream>, JS::Handle<FileAPI::Blob>, JS::Handle<JS::Object>, JS::Handle<XHR::FormData>, JS::Handle<URL::URLSearchParams>, String>; -using BodyInitOrReadableBytes = Variant<JS::Handle<Streams::ReadableStream>, JS::Handle<FileAPI::Blob>, JS::Handle<JS::Object>, JS::Handle<URL::URLSearchParams>, String, ReadonlyBytes>; +using BodyInitOrReadableBytes = Variant<JS::Handle<Streams::ReadableStream>, JS::Handle<FileAPI::Blob>, JS::Handle<JS::Object>, JS::Handle<XHR::FormData>, JS::Handle<URL::URLSearchParams>, String, ReadonlyBytes>; WebIDL::ExceptionOr<Infrastructure::BodyWithType> safely_extract_body(JS::Realm&, BodyInitOrReadableBytes const&); WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm&, BodyInitOrReadableBytes const&, bool keepalive = false); diff --git a/Userland/Libraries/LibWeb/Fetch/BodyInit.idl b/Userland/Libraries/LibWeb/Fetch/BodyInit.idl index a1040b46ee..4eb8c7cb25 100644 --- a/Userland/Libraries/LibWeb/Fetch/BodyInit.idl +++ b/Userland/Libraries/LibWeb/Fetch/BodyInit.idl @@ -1,9 +1,10 @@ #import <FileAPI/Blob.idl> #import <Streams/ReadableStream.idl> #import <URL/URLSearchParams.idl> +#import <XHR/FormData.idl> // https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit -typedef (Blob or BufferSource or URLSearchParams or USVString) XMLHttpRequestBodyInit; +typedef (Blob or BufferSource or FormData or URLSearchParams or USVString) XMLHttpRequestBodyInit; // https://fetch.spec.whatwg.org/#bodyinit typedef (ReadableStream or XMLHttpRequestBodyInit) BodyInit; diff --git a/Userland/Libraries/LibWeb/XHR/FormData.idl b/Userland/Libraries/LibWeb/XHR/FormData.idl index 269f15801e..caffdc16b9 100644 --- a/Userland/Libraries/LibWeb/XHR/FormData.idl +++ b/Userland/Libraries/LibWeb/XHR/FormData.idl @@ -1,6 +1,10 @@ #import <FileAPI/Blob.idl> #import <FileAPI/File.idl> -#import <HTML/HTMLFormElement.idl> +// FIXME: This #import currently gives the following error after XHR/FormData.idl was #imported in Fetch/BodyInit.idl: +// "LibWeb/HTML/Window.idl:114: error: Mixin 'WindowOrWorkerGlobalScope' was never defined." +// XHR/FormData.idl needs to be #imported in Fetch/BodyInit.idl while removing #import HTML/HTMLFormElement.idl +// currently makes no difference. +// #import <HTML/HTMLFormElement.idl> typedef (File or USVString) FormDataEntryValue; diff --git a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h index bcb8a48865..d37701e6ec 100644 --- a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h +++ b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h @@ -26,7 +26,7 @@ namespace Web::XHR { // https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit -using DocumentOrXMLHttpRequestBodyInit = Variant<JS::Handle<Web::DOM::Document>, JS::Handle<Web::FileAPI::Blob>, JS::Handle<JS::Object>, JS::Handle<Web::URL::URLSearchParams>, AK::String>; +using DocumentOrXMLHttpRequestBodyInit = Variant<JS::Handle<Web::DOM::Document>, JS::Handle<Web::FileAPI::Blob>, JS::Handle<JS::Object>, JS::Handle<XHR::FormData>, JS::Handle<Web::URL::URLSearchParams>, AK::String>; class XMLHttpRequest final : public XMLHttpRequestEventTarget { WEB_PLATFORM_OBJECT(XMLHttpRequest, XMLHttpRequestEventTarget); |