diff options
author | 2023-08-07 20:15:53 -0700 | |
---|---|---|
committer | 2023-08-07 20:15:53 -0700 | |
commit | 2fe6a965af394db7228dce56ce29b629c650764c (patch) | |
tree | 9d0df164cd0ffcc2c1000a58aa498476abf0b3c6 /src/resolver/data_url.zig | |
parent | a32097aa9f53f7c8ea1331c61dc2658bc1b11208 (diff) | |
download | bun-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 '')
-rw-r--r-- | src/resolver/data_url.zig | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/src/resolver/data_url.zig b/src/resolver/data_url.zig index dd31605d9..f2a042c4f 100644 --- a/src/resolver/data_url.zig +++ b/src/resolver/data_url.zig @@ -34,7 +34,7 @@ pub const PercentEncoding = struct { if (comptime Environment.allow_assert) std.debug.assert(str.len > 0); return switch (str[0]) { 'a'...'z', 'A'...'Z', '0'...'9', '-', '.', '_', '~', '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=', ':', '@' => true, - '%' => str.len > 3 and isHex(str[1]) and isHex(str[2]), + '%' => str.len >= 3 and isHex(str[1]) and isHex(str[2]), else => false, }; } @@ -53,7 +53,7 @@ pub const PercentEncoding = struct { } if (ret == null) { ret = try allocator.alloc(u8, path.len); - bun.copy(u8, ret, path[0..i]); + bun.copy(u8, ret.?, path[0..i]); ret_index = i; } @@ -71,22 +71,28 @@ pub const PercentEncoding = struct { } } - if (ret) |some| return allocator.shrink(some, ret_index); + if (ret) |some| return some[0..ret_index]; return null; } }; pub const DataURL = struct { + url: bun.String = bun.String.empty, mime_type: string, data: string, is_base64: bool = false, - pub fn parse(url: string) ?DataURL { + pub fn parse(url: string) !?DataURL { if (!strings.startsWith(url, "data:")) { return null; } - const comma = strings.indexOfChar(url, ',') orelse return null; + var result = try parseWithoutCheck(url); + return result; + } + + pub fn parseWithoutCheck(url: string) !DataURL { + const comma = strings.indexOfChar(url, ',') orelse return error.InvalidDataURL; var parsed = DataURL{ .mime_type = url["data:".len..comma], @@ -102,6 +108,21 @@ pub const DataURL = struct { } pub fn decodeMimeType(d: DataURL) bun.HTTP.MimeType { - return bun.HTTP.MimeType.init(d.mime_type); + return bun.HTTP.MimeType.init(d.mime_type, null, null); + } + + pub fn decodeData(url: DataURL, allocator: std.mem.Allocator) ![]u8 { + const percent_decoded = PercentEncoding.decode(allocator, url.data) catch url.data orelse url.data; + if (url.is_base64) { + const len = bun.base64.decodeLen(percent_decoded); + var buf = try allocator.alloc(u8, len); + const result = bun.base64.decode(buf, percent_decoded); + if (result.fail or result.written != len) { + return error.Base64DecodeError; + } + return buf; + } + + return allocator.dupe(u8, percent_decoded); } }; |