aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/webcore
diff options
context:
space:
mode:
authorGravatar Dylan Conway <35280289+dylan-conway@users.noreply.github.com> 2023-08-07 20:15:53 -0700
committerGravatar GitHub <noreply@github.com> 2023-08-07 20:15:53 -0700
commit2fe6a965af394db7228dce56ce29b629c650764c (patch)
tree9d0df164cd0ffcc2c1000a58aa498476abf0b3c6 /src/bun.js/webcore
parenta32097aa9f53f7c8ea1331c61dc2658bc1b11208 (diff)
downloadbun-2fe6a965af394db7228dce56ce29b629c650764c.tar.gz
bun-2fe6a965af394db7228dce56ce29b629c650764c.tar.zst
bun-2fe6a965af394db7228dce56ce29b629c650764c.zip
implement fetching data urls (#4000)
* fetch data urls * `byteSlice` * deinit slice * allocate `mime_type` string if needed * `content_type_allocated` and uncomment tests * `str_` * createAtom and slice decode result
Diffstat (limited to 'src/bun.js/webcore')
-rw-r--r--src/bun.js/webcore/body.zig2
-rw-r--r--src/bun.js/webcore/response.zig66
2 files changed, 67 insertions, 1 deletions
diff --git a/src/bun.js/webcore/body.zig b/src/bun.js/webcore/body.zig
index 2007063f3..0dea0579d 100644
--- a/src/bun.js/webcore/body.zig
+++ b/src/bun.js/webcore/body.zig
@@ -1222,7 +1222,7 @@ pub fn BodyMixin(comptime Type: type) type {
if (blob.content_type.len == 0 and blob.store != null) {
if (this.getFetchHeaders()) |fetch_headers| {
if (fetch_headers.fastGet(.ContentType)) |content_type| {
- blob.store.?.mime_type = MimeType.init(content_type.slice());
+ blob.store.?.mime_type = MimeType.init(content_type.slice(), null, null);
}
} else {
blob.store.?.mime_type = MimeType.text;
diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig
index 3341c6eaf..0d5691a3f 100644
--- a/src/bun.js/webcore/response.zig
+++ b/src/bun.js/webcore/response.zig
@@ -37,6 +37,7 @@ const JSValue = JSC.JSValue;
const JSError = JSC.JSError;
const JSGlobalObject = JSC.JSGlobalObject;
const NullableAllocator = @import("../../nullable_allocator.zig").NullableAllocator;
+const DataURL = @import("../../resolver/data_url.zig").DataURL;
const VirtualMachine = JSC.VirtualMachine;
const Task = JSC.Task;
@@ -971,6 +972,45 @@ pub const Fetch = struct {
}
};
+ fn dataURLResponse(
+ _data_url: DataURL,
+ globalThis: *JSGlobalObject,
+ allocator: std.mem.Allocator,
+ ) JSValue {
+ var data_url = _data_url;
+
+ const data = data_url.decodeData(allocator) catch {
+ const err = JSC.createError(globalThis, "failed to fetch the data URL", .{});
+ return JSPromise.rejectedPromiseValue(globalThis, err);
+ };
+ var blob = Blob.init(data, allocator, globalThis);
+
+ var allocated = false;
+ const mime_type = bun.HTTP.MimeType.init(data_url.mime_type, allocator, &allocated);
+ blob.content_type = mime_type.value;
+ if (allocated) {
+ blob.content_type_allocated = true;
+ }
+
+ var response = allocator.create(Response) catch @panic("out of memory");
+
+ response.* = Response{
+ .body = Body{
+ .init = Body.Init{
+ .status_code = 200,
+ },
+ .value = .{
+ .Blob = blob,
+ },
+ },
+ .allocator = allocator,
+ .status_text = bun.String.createAtom("OK"),
+ .url = data_url.url.dupeRef(),
+ };
+
+ return JSPromise.resolvedPromiseValue(globalThis, response.toJS(globalThis));
+ }
+
pub export fn Bun__fetch(
ctx: *JSC.JSGlobalObject,
callframe: *JSC.CallFrame,
@@ -1038,6 +1078,19 @@ pub const Fetch = struct {
return JSPromise.rejectedPromiseValue(globalThis, err);
}
+ if (request.url.hasPrefixComptime("data:")) {
+ var url_slice = request.url.toUTF8WithoutRef(bun.default_allocator);
+ defer url_slice.deinit();
+
+ var data_url = DataURL.parseWithoutCheck(url_slice.slice()) catch {
+ const err = JSC.createError(globalThis, "failed to fetch the data URL", .{});
+ return JSPromise.rejectedPromiseValue(globalThis, err);
+ };
+
+ data_url.url = request.url;
+ return dataURLResponse(data_url, globalThis, bun.default_allocator);
+ }
+
url = ZigURL.fromString(bun.default_allocator, request.url) catch {
const err = JSC.toTypeError(.ERR_INVALID_ARG_VALUE, "fetch() URL is invalid", .{}, ctx);
// clean hostname if any
@@ -1187,6 +1240,19 @@ pub const Fetch = struct {
return JSPromise.rejectedPromiseValue(globalThis, err);
}
+ if (str.hasPrefixComptime("data:")) {
+ var url_slice = str.toUTF8WithoutRef(bun.default_allocator);
+ defer url_slice.deinit();
+
+ var data_url = DataURL.parseWithoutCheck(url_slice.slice()) catch {
+ const err = JSC.createError(globalThis, "failed to fetch the data URL", .{});
+ return JSPromise.rejectedPromiseValue(globalThis, err);
+ };
+ data_url.url = str;
+
+ return dataURLResponse(data_url, globalThis, bun.default_allocator);
+ }
+
url = ZigURL.fromString(bun.default_allocator, str) catch {
// clean hostname if any
if (hostname) |host| {