aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js')
-rw-r--r--src/bun.js/ResolveMessage.zig3
-rw-r--r--src/bun.js/webcore/body.zig2
-rw-r--r--src/bun.js/webcore/response.zig66
3 files changed, 70 insertions, 1 deletions
diff --git a/src/bun.js/ResolveMessage.zig b/src/bun.js/ResolveMessage.zig
index b9b2d7b06..457a8ec4f 100644
--- a/src/bun.js/ResolveMessage.zig
+++ b/src/bun.js/ResolveMessage.zig
@@ -35,6 +35,9 @@ pub const ResolveMessage = struct {
return try std.fmt.allocPrint(allocator, "Cannot find module \"{s}\" from \"{s}\"", .{ specifier, referrer });
}
},
+ error.InvalidDataURL => {
+ return try std.fmt.allocPrint(allocator, "Cannot resolve invalid data URL \"{s}\" from \"{s}\"", .{ specifier, referrer });
+ },
else => {
if (Resolver.isPackagePath(specifier)) {
return try std.fmt.allocPrint(allocator, "{s} while resolving package \"{s}\" from \"{s}\"", .{ @errorName(err), specifier, referrer });
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| {