diff options
Diffstat (limited to 'src/bun.js/webcore/response.zig')
-rw-r--r-- | src/bun.js/webcore/response.zig | 66 |
1 files changed, 66 insertions, 0 deletions
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| { |