Browse Source

LibWeb/Fetch: Implement Body::bytes()

See:
- https://github.com/whatwg/fetch/commit/1085f4f
Jamie Mansfield 1 year ago
parent
commit
08e4cf1f3b

+ 18 - 0
Userland/Libraries/LibWeb/Fetch/Body.cpp

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2024, Jamie Mansfield <jmansfield@cadixdev.org>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -9,6 +10,7 @@
 #include <LibJS/Runtime/Completion.h>
 #include <LibJS/Runtime/Completion.h>
 #include <LibJS/Runtime/Error.h>
 #include <LibJS/Runtime/Error.h>
 #include <LibJS/Runtime/PromiseCapability.h>
 #include <LibJS/Runtime/PromiseCapability.h>
+#include <LibJS/Runtime/TypedArray.h>
 #include <LibTextCodec/Decoder.h>
 #include <LibTextCodec/Decoder.h>
 #include <LibWeb/Bindings/ExceptionOrUtils.h>
 #include <LibWeb/Bindings/ExceptionOrUtils.h>
 #include <LibWeb/Bindings/HostDefined.h>
 #include <LibWeb/Bindings/HostDefined.h>
@@ -70,6 +72,16 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> BodyMixin::blob() const
     return consume_body(realm, *this, PackageDataType::Blob);
     return consume_body(realm, *this, PackageDataType::Blob);
 }
 }
 
 
+// https://fetch.spec.whatwg.org/#dom-body-bytes
+WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> BodyMixin::bytes() const
+{
+    auto& vm = Bindings::main_thread_vm();
+    auto& realm = *vm.current_realm();
+
+    // The bytes() method steps are to return the result of running consume body with this and Uint8Array.
+    return consume_body(realm, *this, PackageDataType::Uint8Array);
+}
+
 // https://fetch.spec.whatwg.org/#dom-body-formdata
 // https://fetch.spec.whatwg.org/#dom-body-formdata
 WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> BodyMixin::form_data() const
 WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> BodyMixin::form_data() const
 {
 {
@@ -115,6 +127,12 @@ WebIDL::ExceptionOr<JS::Value> package_data(JS::Realm& realm, ByteBuffer bytes,
         auto mime_type_string = mime_type.has_value() ? MUST(mime_type->serialized()) : String {};
         auto mime_type_string = mime_type.has_value() ? MUST(mime_type->serialized()) : String {};
         return FileAPI::Blob::create(realm, move(bytes), move(mime_type_string));
         return FileAPI::Blob::create(realm, move(bytes), move(mime_type_string));
     }
     }
+    case PackageDataType::Uint8Array: {
+        // Return the result of creating a Uint8Array from bytes in this’s relevant realm.
+        auto bytes_length = bytes.size();
+        auto array_buffer = JS::ArrayBuffer::create(realm, move(bytes));
+        return JS::Uint8Array::create(realm, bytes_length, *array_buffer);
+    }
     case PackageDataType::FormData:
     case PackageDataType::FormData:
         // If mimeType’s essence is "multipart/form-data", then:
         // If mimeType’s essence is "multipart/form-data", then:
         if (mime_type.has_value() && mime_type->essence() == "multipart/form-data"sv) {
         if (mime_type.has_value() && mime_type->essence() == "multipart/form-data"sv) {

+ 3 - 0
Userland/Libraries/LibWeb/Fetch/Body.h

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2024, Jamie Mansfield <jmansfield@cadixdev.org>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -16,6 +17,7 @@ namespace Web::Fetch {
 enum class PackageDataType {
 enum class PackageDataType {
     ArrayBuffer,
     ArrayBuffer,
     Blob,
     Blob,
+    Uint8Array,
     FormData,
     FormData,
     JSON,
     JSON,
     Text,
     Text,
@@ -39,6 +41,7 @@ public:
     // JS API functions
     // JS API functions
     [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> array_buffer() const;
     [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> array_buffer() const;
     [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> blob() const;
     [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> blob() const;
+    [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> bytes() const;
     [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> form_data() const;
     [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> form_data() const;
     [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> json() const;
     [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> json() const;
     [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> text() const;
     [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> text() const;

+ 1 - 0
Userland/Libraries/LibWeb/Fetch/Body.idl

@@ -8,6 +8,7 @@ interface mixin Body {
     readonly attribute boolean bodyUsed;
     readonly attribute boolean bodyUsed;
     [NewObject] Promise<ArrayBuffer> arrayBuffer();
     [NewObject] Promise<ArrayBuffer> arrayBuffer();
     [NewObject] Promise<Blob> blob();
     [NewObject] Promise<Blob> blob();
+    [NewObject] Promise<Uint8Array> bytes();
     [NewObject] Promise<FormData> formData();
     [NewObject] Promise<FormData> formData();
     [NewObject] Promise<any> json();
     [NewObject] Promise<any> json();
     [NewObject] Promise<USVString> text();
     [NewObject] Promise<USVString> text();