summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Myhra <kennethmyhra@gmail.com>2023-04-02 22:30:56 +0200
committerLinus Groh <mail@linusgroh.de>2023-04-05 09:43:52 +0100
commit1120011de4c3ae731b5c8349c84cd310a56f7e90 (patch)
treef5f55423fc3cd41328101a46797ca36dec4cb16a
parent5df4d66d91149fe66f8660252709a1f6fbdf3124 (diff)
downloadserenity-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.cpp16
-rw-r--r--Userland/Libraries/LibWeb/Fetch/BodyInit.h4
-rw-r--r--Userland/Libraries/LibWeb/Fetch/BodyInit.idl3
-rw-r--r--Userland/Libraries/LibWeb/XHR/FormData.idl6
-rw-r--r--Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h2
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);