Skip to content

Commit

Permalink
Implement Request#blob and Response#blob methods
Browse files Browse the repository at this point in the history
  • Loading branch information
andreiltd committed Nov 25, 2024
1 parent 996d85d commit d140a41
Show file tree
Hide file tree
Showing 15 changed files with 46 additions and 29 deletions.
5 changes: 3 additions & 2 deletions builtins/web/blob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
#include "builtin.h"
#include "encode.h"
#include "extension-api.h"
#include "js/HashTable.h"
#include "mozilla/UniquePtr.h"
#include "rust-encoding.h"
#include "streams/native-stream-source.h"

#include "mozilla/UniquePtr.h"
#include "js/ArrayBuffer.h"
#include "js/Conversions.h"
#include "js/experimental/TypedData.h"
#include "js/HashTable.h"
#include "js/Stream.h"
#include "js/TypeDecls.h"
#include "js/Value.h"
#include "js/Vector.h"

#include <regex>

Expand Down
15 changes: 15 additions & 0 deletions builtins/web/fetch/request-response.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "request-response.h"

#include "../blob.h"
#include "../streams/native-stream-source.h"
#include "../streams/transform-stream.h"
#include "../url.h"
Expand All @@ -8,6 +9,7 @@
#include "extension-api.h"
#include "fetch_event.h"
#include "host_api.h"
#include "js/String.h"
#include "picosha2.h"

#include "js/Array.h"
Expand Down Expand Up @@ -546,6 +548,17 @@ bool RequestOrResponse::parse_body(JSContext *cx, JS::HandleObject self, JS::Uni
}
static_cast<void>(buf.release());
result.setObject(*array_buffer);
} else if constexpr (result_type == RequestOrResponse::BodyReadResult::Blob) {
auto bytes = reinterpret_cast<uint8_t *>(buf.get());
auto data = std::make_unique<std::vector<uint8_t>>(bytes, bytes + len);
JS::RootedObject blob(cx, blob::Blob::create(cx, std::move(data), JS_GetEmptyString(cx)));

if (!blob) {
return RejectPromiseWithPendingError(cx, result_promise);
}

// We can drop `buf` as the data has been now copied over to blob
result.setObject(*blob);
} else {
JS::RootedString text(cx, JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(buf.get(), len)));
if (!text) {
Expand Down Expand Up @@ -1313,6 +1326,7 @@ const JSPropertySpec Request::static_properties[] = {
const JSFunctionSpec Request::methods[] = {
JS_FN("arrayBuffer", Request::bodyAll<RequestOrResponse::BodyReadResult::ArrayBuffer>, 0,
JSPROP_ENUMERATE),
JS_FN("blob", Request::bodyAll<RequestOrResponse::BodyReadResult::Blob>, 0, JSPROP_ENUMERATE),
JS_FN("json", Request::bodyAll<RequestOrResponse::BodyReadResult::JSON>, 0, JSPROP_ENUMERATE),
JS_FN("text", Request::bodyAll<RequestOrResponse::BodyReadResult::Text>, 0, JSPROP_ENUMERATE),
JS_FN("clone", Request::clone, 0, JSPROP_ENUMERATE),
Expand Down Expand Up @@ -2304,6 +2318,7 @@ const JSPropertySpec Response::static_properties[] = {
const JSFunctionSpec Response::methods[] = {
JS_FN("arrayBuffer", bodyAll<RequestOrResponse::BodyReadResult::ArrayBuffer>, 0,
JSPROP_ENUMERATE),
JS_FN("blob", bodyAll<RequestOrResponse::BodyReadResult::Blob>, 0, JSPROP_ENUMERATE),
JS_FN("json", bodyAll<RequestOrResponse::BodyReadResult::JSON>, 0, JSPROP_ENUMERATE),
JS_FN("text", bodyAll<RequestOrResponse::BodyReadResult::Text>, 0, JSPROP_ENUMERATE),
JS_FS_END,
Expand Down
1 change: 1 addition & 0 deletions builtins/web/fetch/request-response.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class RequestOrResponse final {

enum class BodyReadResult {
ArrayBuffer,
Blob,
JSON,
Text,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
"status": "PASS"
},
"Blob is cloned": {
"status": "FAIL"
"status": "PASS"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"status": "PASS"
},
"Consume request's body as blob": {
"status": "FAIL"
"status": "PASS"
},
"Consume request's body as arrayBuffer": {
"status": "PASS"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"status": "PASS"
},
"Consume String request's body as blob": {
"status": "FAIL"
"status": "PASS"
},
"Consume String request's body as arrayBuffer": {
"status": "PASS"
Expand All @@ -18,7 +18,7 @@
"status": "PASS"
},
"Consume ArrayBuffer request's body as blob": {
"status": "FAIL"
"status": "PASS"
},
"Consume ArrayBuffer request's body as arrayBuffer": {
"status": "PASS"
Expand All @@ -33,7 +33,7 @@
"status": "PASS"
},
"Consume Uint8Array request's body as blob": {
"status": "FAIL"
"status": "PASS"
},
"Consume Uint8Array request's body as arrayBuffer": {
"status": "PASS"
Expand All @@ -48,7 +48,7 @@
"status": "PASS"
},
"Consume Int8Array request's body as blob": {
"status": "FAIL"
"status": "PASS"
},
"Consume Int8Array request's body as arrayBuffer": {
"status": "PASS"
Expand All @@ -63,7 +63,7 @@
"status": "PASS"
},
"Consume Float32Array request's body as blob": {
"status": "FAIL"
"status": "PASS"
},
"Consume Float32Array request's body as arrayBuffer": {
"status": "PASS"
Expand All @@ -78,7 +78,7 @@
"status": "PASS"
},
"Consume DataView request's body as blob": {
"status": "FAIL"
"status": "PASS"
},
"Consume DataView request's body as arrayBuffer": {
"status": "PASS"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@
"status": "PASS"
},
"Testing empty Request Content-Type header": {
"status": "FAIL"
"status": "PASS"
},
"Test that Request.headers has the [SameObject] extended attribute": {
"status": "PASS"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"status": "PASS"
},
"Request has blob method": {
"status": "FAIL"
"status": "PASS"
},
"Request has formData method": {
"status": "FAIL"
Expand Down Expand Up @@ -71,4 +71,4 @@
"Request does not expose blocking attribute": {
"status": "PASS"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"status": "PASS"
},
"Consume response's body as blob": {
"status": "FAIL"
"status": "PASS"
},
"Consume response's body as arrayBuffer": {
"status": "PASS"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"status": "PASS"
},
"ReadableStream start() Error propagates to Response.blob() Promise": {
"status": "FAIL"
"status": "PASS"
},
"ReadableStream start() Error propagates to Response.bytes() Promise": {
"status": "FAIL"
Expand All @@ -27,7 +27,7 @@
"status": "PASS"
},
"ReadableStream pull() Error propagates to Response.blob() Promise": {
"status": "FAIL"
"status": "PASS"
},
"ReadableStream pull() Error propagates to Response.bytes() Promise": {
"status": "FAIL"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"status": "PASS"
},
"ReadableStream with non-Uint8Array chunk passed to Response.blob() causes TypeError": {
"status": "FAIL"
"status": "PASS"
},
"ReadableStream with non-Uint8Array chunk passed to Response.bytes() causes TypeError": {
"status": "FAIL"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Getting blob after getting the Response body - not disturbed, not locked (body source: fetch)": {
"status": "FAIL"
"status": "PASS"
},
"Getting text after getting the Response body - not disturbed, not locked (body source: fetch)": {
"status": "PASS"
Expand All @@ -12,7 +12,7 @@
"status": "PASS"
},
"Getting blob after getting the Response body - not disturbed, not locked (body source: stream)": {
"status": "FAIL"
"status": "PASS"
},
"Getting text after getting the Response body - not disturbed, not locked (body source: stream)": {
"status": "PASS"
Expand All @@ -24,7 +24,7 @@
"status": "PASS"
},
"Getting blob after getting the Response body - not disturbed, not locked (body source: string)": {
"status": "FAIL"
"status": "PASS"
},
"Getting text after getting the Response body - not disturbed, not locked (body source: string)": {
"status": "PASS"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Getting blob after getting a locked Response body (body source: fetch)": {
"status": "FAIL"
"status": "PASS"
},
"Getting text after getting a locked Response body (body source: fetch)": {
"status": "PASS"
Expand All @@ -12,7 +12,7 @@
"status": "PASS"
},
"Getting blob after getting a locked Response body (body source: stream)": {
"status": "FAIL"
"status": "PASS"
},
"Getting text after getting a locked Response body (body source: stream)": {
"status": "PASS"
Expand All @@ -24,7 +24,7 @@
"status": "PASS"
},
"Getting blob after getting a locked Response body (body source: string)": {
"status": "FAIL"
"status": "PASS"
},
"Getting text after getting a locked Response body (body source: string)": {
"status": "PASS"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Getting blob after reading the Response body (body source: fetch)": {
"status": "FAIL"
"status": "PASS"
},
"Getting text after reading the Response body (body source: fetch)": {
"status": "PASS"
Expand All @@ -12,7 +12,7 @@
"status": "PASS"
},
"Getting blob after reading the Response body (body source: stream)": {
"status": "FAIL"
"status": "PASS"
},
"Getting text after reading the Response body (body source: stream)": {
"status": "PASS"
Expand All @@ -24,7 +24,7 @@
"status": "PASS"
},
"Getting blob after reading the Response body (body source: string)": {
"status": "FAIL"
"status": "PASS"
},
"Getting text after reading the Response body (body source: string)": {
"status": "PASS"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Getting blob after cancelling the Response body (body source: fetch)": {
"status": "FAIL"
"status": "PASS"
},
"Getting text after cancelling the Response body (body source: fetch)": {
"status": "PASS"
Expand All @@ -12,7 +12,7 @@
"status": "PASS"
},
"Getting blob after cancelling the Response body (body source: stream)": {
"status": "FAIL"
"status": "PASS"
},
"Getting text after cancelling the Response body (body source: stream)": {
"status": "PASS"
Expand All @@ -24,7 +24,7 @@
"status": "PASS"
},
"Getting blob after cancelling the Response body (body source: string)": {
"status": "FAIL"
"status": "PASS"
},
"Getting text after cancelling the Response body (body source: string)": {
"status": "PASS"
Expand Down

0 comments on commit d140a41

Please sign in to comment.