diff --git a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp index 1c06aad97c4..e1f92cd17bf 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp @@ -747,6 +747,7 @@ ErrorOr HTMLFormElement::submit_as_entity_body(URL::URL parsed_action, Vec // 1. Assert: method is POST. POSTResource::RequestContentType mime_type {}; + Vector mime_type_directives; ByteBuffer body; // 2. Switch on enctype: @@ -775,6 +776,7 @@ ErrorOr HTMLFormElement::submit_as_entity_body(URL::URL parsed_action, Vec // 2. Let mimeType be the isomorphic encoding of the concatenation of "multipart/form-data; boundary=" and the multipart/form-data // boundary string generated by the multipart/form-data encoding algorithm. mime_type = POSTResource::RequestContentType::MultipartFormData; + mime_type_directives.empend("boundary"sv, move(body_and_mime_type.boundary)); break; } case EncodingTypeAttributeState::PlainText: { @@ -796,7 +798,7 @@ ErrorOr HTMLFormElement::submit_as_entity_body(URL::URL parsed_action, Vec } // 3. Plan to navigate to parsed action given a POST resource whose request body is body and request content-type is mimeType. - plan_to_navigate_to(parsed_action, POSTResource { .request_body = move(body), .request_content_type = mime_type }, target_navigable, history_handling, user_involvement); + plan_to_navigate_to(parsed_action, POSTResource { .request_body = move(body), .request_content_type = mime_type, .request_content_type_directives = move(mime_type_directives) }, target_navigable, history_handling, user_involvement); return {}; } diff --git a/Userland/Libraries/LibWeb/HTML/Navigable.cpp b/Userland/Libraries/LibWeb/HTML/Navigable.cpp index 18e93ebe44e..a7c8010e7c6 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigable.cpp @@ -702,7 +702,7 @@ static WebIDL::ExceptionOr create_navigation request->set_referrer(entry->document_state()->request_referrer()); // 4. If documentResource is a POST resource, then: - if (document_resource.has()) { + if (auto* post_resource = document_resource.get_pointer()) { // 1. Set request's method to `POST`. request->set_method(TRY_OR_THROW_OOM(vm, ByteBuffer::copy("POST"sv.bytes()))); @@ -710,9 +710,8 @@ static WebIDL::ExceptionOr create_navigation request->set_body(document_resource.get().request_body.value()); // 3. Set `Content-Type` to documentResource's request content-type in request's header list. - auto request_content_type = document_resource.get().request_content_type; - auto request_content_type_string = [request_content_type]() { - switch (request_content_type) { + auto request_content_type = [&]() { + switch (post_resource->request_content_type) { case POSTResource::RequestContentType::ApplicationXWWWFormUrlencoded: return "application/x-www-form-urlencoded"sv; case POSTResource::RequestContentType::MultipartFormData: @@ -723,7 +722,18 @@ static WebIDL::ExceptionOr create_navigation VERIFY_NOT_REACHED(); } }(); - auto header = Fetch::Infrastructure::Header::from_string_pair("Content-Type"sv, request_content_type_string); + + StringBuilder request_content_type_buffer; + if (!post_resource->request_content_type_directives.is_empty()) { + request_content_type_buffer.append(request_content_type); + + for (auto const& directive : post_resource->request_content_type_directives) + request_content_type_buffer.appendff("; {}={}", directive.type, directive.value); + + request_content_type = request_content_type_buffer.string_view(); + } + + auto header = Fetch::Infrastructure::Header::from_string_pair("Content-Type"sv, request_content_type); request->header_list()->append(move(header)); } diff --git a/Userland/Libraries/LibWeb/HTML/POSTResource.h b/Userland/Libraries/LibWeb/HTML/POSTResource.h index c91bad3c4d8..125d942a6e2 100644 --- a/Userland/Libraries/LibWeb/HTML/POSTResource.h +++ b/Userland/Libraries/LibWeb/HTML/POSTResource.h @@ -7,6 +7,9 @@ #pragma once #include +#include +#include +#include namespace Web::HTML { @@ -26,6 +29,12 @@ struct POSTResource { // https://html.spec.whatwg.org/multipage/browsing-the-web.html#post-resource-request-content-type // A request content-type, which is `application/x-www-form-urlencoded`, `multipart/form-data`, or `text/plain`. RequestContentType request_content_type {}; + + struct Directive { + StringView type; + String value; + }; + Vector request_content_type_directives {}; }; }