diff options
Diffstat (limited to 'src/bun.js')
-rw-r--r-- | src/bun.js/ResolveMessage.zig | 3 | ||||
-rw-r--r-- | src/bun.js/webcore/body.zig | 2 | ||||
-rw-r--r-- | src/bun.js/webcore/response.zig | 66 |
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| { |