From b8fa572c6742c0f1f63da0f63c8b86835a86988d Mon Sep 17 00:00:00 2001 From: Kenneth Myhra Date: Mon, 22 Jul 2024 13:49:07 +0200 Subject: [PATCH] LibWeb: Implement formData() method steps for x-www-form-urlencoded The Response interface of the Fetch API can now parse form urlencoded bodies when Content-Type is set to 'application/x-www-form-urlencoded'. --- .../Fetch/fetch-response-url-encoded.txt | 3 +++ .../input/Fetch/fetch-response-url-encoded.html | 17 +++++++++++++++++ Userland/Libraries/LibWeb/Fetch/Body.cpp | 15 +++++++++++---- Userland/Libraries/LibWeb/XHR/FormData.cpp | 12 +++++++++++- Userland/Libraries/LibWeb/XHR/FormData.h | 5 ++++- 5 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/Fetch/fetch-response-url-encoded.txt create mode 100644 Tests/LibWeb/Text/input/Fetch/fetch-response-url-encoded.html diff --git a/Tests/LibWeb/Text/expected/Fetch/fetch-response-url-encoded.txt b/Tests/LibWeb/Text/expected/Fetch/fetch-response-url-encoded.txt new file mode 100644 index 00000000000..f10581337e3 --- /dev/null +++ b/Tests/LibWeb/Text/expected/Fetch/fetch-response-url-encoded.txt @@ -0,0 +1,3 @@ +value-a +value-b +value-c1,value-c2 diff --git a/Tests/LibWeb/Text/input/Fetch/fetch-response-url-encoded.html b/Tests/LibWeb/Text/input/Fetch/fetch-response-url-encoded.html new file mode 100644 index 00000000000..37f2fc88b86 --- /dev/null +++ b/Tests/LibWeb/Text/input/Fetch/fetch-response-url-encoded.html @@ -0,0 +1,17 @@ + + diff --git a/Userland/Libraries/LibWeb/Fetch/Body.cpp b/Userland/Libraries/LibWeb/Fetch/Body.cpp index faf8636ddb9..09619416c33 100644 --- a/Userland/Libraries/LibWeb/Fetch/Body.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Body.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include namespace Web::Fetch { @@ -143,10 +145,15 @@ WebIDL::ExceptionOr package_data(JS::Realm& realm, ByteBuffer bytes, } // Otherwise, if mimeType’s essence is "application/x-www-form-urlencoded", then: else if (mime_type.has_value() && mime_type->essence() == "application/x-www-form-urlencoded"sv) { - // FIXME: 1. Let entries be the result of parsing bytes. - // FIXME: 2. If entries is failure, then throw a TypeError. - // FIXME: 3. Return a new FormData object whose entry list is entries. - return JS::js_null(); + // 1. Let entries be the result of parsing bytes. + auto entries = DOMURL::url_decode(StringView { bytes }); + + // 2. If entries is failure, then throw a TypeError. + if (entries.is_error()) + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, entries.error().string_literal() }; + + // 3. Return a new FormData object whose entry list is entries. + return TRY(XHR::FormData::create(realm, entries.release_value())); } // Otherwise, throw a TypeError. else { diff --git a/Userland/Libraries/LibWeb/XHR/FormData.cpp b/Userland/Libraries/LibWeb/XHR/FormData.cpp index 7165449fbb5..f1ae609f215 100644 --- a/Userland/Libraries/LibWeb/XHR/FormData.cpp +++ b/Userland/Libraries/LibWeb/XHR/FormData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Kenneth Myhra + * Copyright (c) 2023-2024, Kenneth Myhra * * SPDX-License-Identifier: BSD-2-Clause */ @@ -40,6 +40,16 @@ WebIDL::ExceptionOr> FormData::construct_impl(JS::Rea return realm.heap().allocate(realm, realm, move(entry_list)); } +WebIDL::ExceptionOr> FormData::create(JS::Realm& realm, Vector entry_list) +{ + Vector list; + list.ensure_capacity(entry_list.size()); + for (auto& entry : entry_list) + list.unchecked_append({ .name = move(entry.name), .value = move(entry.value) }); + + return construct_impl(realm, move(list)); +} + FormData::FormData(JS::Realm& realm, Vector entry_list) : PlatformObject(realm) , m_entry_list(move(entry_list)) diff --git a/Userland/Libraries/LibWeb/XHR/FormData.h b/Userland/Libraries/LibWeb/XHR/FormData.h index f607ba27cbc..7ed5fe3517b 100644 --- a/Userland/Libraries/LibWeb/XHR/FormData.h +++ b/Userland/Libraries/LibWeb/XHR/FormData.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Kenneth Myhra + * Copyright (c) 2023-2024, Kenneth Myhra * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -26,6 +27,8 @@ public: static WebIDL::ExceptionOr> construct_impl(JS::Realm&, JS::GCPtr form = {}); static WebIDL::ExceptionOr> construct_impl(JS::Realm&, Vector entry_list); + static WebIDL::ExceptionOr> create(JS::Realm&, Vector entry_list); + WebIDL::ExceptionOr append(String const& name, String const& value); WebIDL::ExceptionOr append(String const& name, JS::NonnullGCPtr const& blob_value, Optional const& filename = {}); void delete_(String const& name);