diff options
Diffstat (limited to 'src/bun.js/webcore')
-rw-r--r-- | src/bun.js/webcore/blob.zig | 51 | ||||
-rw-r--r-- | src/bun.js/webcore/body.zig | 63 | ||||
-rw-r--r-- | src/bun.js/webcore/request.zig | 10 | ||||
-rw-r--r-- | src/bun.js/webcore/response.classes.ts | 1 | ||||
-rw-r--r-- | src/bun.js/webcore/response.zig | 28 |
5 files changed, 77 insertions, 76 deletions
diff --git a/src/bun.js/webcore/blob.zig b/src/bun.js/webcore/blob.zig index b670a3aaa..284351347 100644 --- a/src/bun.js/webcore/blob.zig +++ b/src/bun.js/webcore/blob.zig @@ -1011,7 +1011,7 @@ pub const Blob = struct { pub const Store = struct { data: Data, - mime_type: MimeType = MimeType.other, + mime_type: MimeType = MimeType.none, ref_count: u32 = 0, is_all_ascii: ?bool = null, allocator: std.mem.Allocator, @@ -2499,47 +2499,18 @@ pub const Blob = struct { this: *Blob, globalThis: *JSC.JSGlobalObject, ) callconv(.C) JSValue { - return ZigString.init(this.content_type).toValue(globalThis); - } - - pub fn setType( - this: *Blob, - globalThis: *JSC.JSGlobalObject, - value: JSC.JSValue, - ) callconv(.C) bool { - var zig_str = if (value.isString()) - value.getZigString(globalThis) - else - ZigString.Empty; - - if (!zig_str.isAllASCII()) { - zig_str = ZigString.Empty; - } - - if (zig_str.eql(ZigString.init(this.content_type))) { - return true; + if (this.content_type.len > 0) { + if (this.content_type_allocated) { + return ZigString.init(this.content_type).toValue(globalThis); + } + return ZigString.init(this.content_type).toValueGC(globalThis); } - const prev_content_type = this.content_type; - { - var slicer = zig_str.toSlice(bun.default_allocator); - defer slicer.deinit(); - const allocated = this.content_type_allocated; - defer if (allocated) bun.default_allocator.free(prev_content_type); - if (globalThis.bunVM().mimeType(slicer.slice())) |mime| { - this.content_type = mime.value; - this.content_type_allocated = false; - return true; - } - var content_type_buf = globalThis.allocator().alloc(u8, slicer.len) catch { - globalThis.throwOutOfMemory(); - return false; - }; - this.content_type = strings.copyLowercase(slicer.slice(), content_type_buf); + if (this.store) |store| { + return ZigString.init(store.mime_type.value).toValue(globalThis); } - this.content_type_allocated = true; - return true; + return ZigString.Empty.toValue(globalThis); } pub fn getSize(this: *Blob, _: *JSC.JSGlobalObject) callconv(.C) JSValue { @@ -2997,13 +2968,11 @@ pub const Blob = struct { var view_ = this.sharedView(); - if (view_.len == 0) - return ZigString.Empty.toValue(global); - return toJSONWithBytes(this, global, view_, lifetime); } pub fn toJSONWithBytes(this: *Blob, global: *JSGlobalObject, buf: []const u8, comptime lifetime: Lifetime) JSValue { + if (buf.len == 0) return global.createSyntaxErrorInstance("Unexpected end of JSON input", .{}); // null == unknown // false == can't be const could_be_all_ascii = this.is_all_ascii orelse this.store.?.is_all_ascii; diff --git a/src/bun.js/webcore/body.zig b/src/bun.js/webcore/body.zig index 509d02989..1a0831333 100644 --- a/src/bun.js/webcore/body.zig +++ b/src/bun.js/webcore/body.zig @@ -138,13 +138,13 @@ pub const Body = struct { return that; } - pub fn init(allocator: std.mem.Allocator, ctx: *JSGlobalObject, response_init: JSC.JSValue, js_type: JSC.JSValue.JSType) !?Init { + pub fn init(allocator: std.mem.Allocator, ctx: *JSGlobalObject, response_init: JSC.JSValue) !?Init { var result = Init{ .status_code = 200 }; if (!response_init.isCell()) return null; - if (js_type == .DOMWrapper) { + if (response_init.jsType() == .DOMWrapper) { // fast path: it's a Request object or a Response object // we can skip calling JS getters if (response_init.as(Request)) |req| { @@ -170,9 +170,24 @@ pub const Body = struct { } if (response_init.fastGet(ctx, .status)) |status_value| { - const number = status_value.to(i32); - if (100 <= number and number < 1000) - result.status_code = @truncate(u16, @intCast(u32, number)); + if (status_value.isHeapBigInt()) { + const less_than = switch (status_value.asBigIntCompare(ctx, JSValue.jsNumber(600))) { + .less_than => true, + else => false, + }; + const greater_than = switch (status_value.asBigIntCompare(ctx, JSValue.jsNumber(99))) { + .greater_than => true, + else => false, + }; + + if (less_than and greater_than) { + result.status_code = @truncate(u16, @intCast(u64, status_value.toInt64())); + } + } else if (status_value.isNumber()) { + const number = status_value.to(i32); + if (100 <= number and number < 600) + result.status_code = @truncate(u16, @intCast(u32, number)); + } } if (response_init.fastGet(ctx, .method)) |method_value| { @@ -233,10 +248,6 @@ pub const Body = struct { // } switch (action) { .getText, .getJSON, .getBlob, .getArrayBuffer => { - switch (readable.ptr) { - .Blob => unreachable, - else => {}, - } value.promise = switch (action) { .getJSON => globalThis.readableStreamToJSON(readable.value), .getArrayBuffer => globalThis.readableStreamToArrayBuffer(readable.value), @@ -726,9 +737,6 @@ pub const Body = struct { bun.default_allocator, JSC.VirtualMachine.get().global, ); - if (this.InternalBlob.was_string) { - new_blob.content_type = MimeType.text.value; - } this.* = .{ .Used = {} }; return new_blob; @@ -903,7 +911,6 @@ pub const Body = struct { value, false, JSValue.zero, - .Cell, ); } @@ -911,14 +918,12 @@ pub const Body = struct { globalThis: *JSGlobalObject, value: JSValue, init: JSValue, - init_type: JSValue.JSType, ) ?Body { return extractBody( globalThis, value, true, init, - init_type, ); } @@ -928,7 +933,6 @@ pub const Body = struct { value: JSValue, comptime has_init: bool, init: JSValue, - init_type: JSC.JSValue.JSType, ) ?Body { var body = Body{ .value = Value{ .Empty = {} }, @@ -937,11 +941,13 @@ pub const Body = struct { var allocator = getAllocator(globalThis); if (comptime has_init) { - if (Init.init(allocator, globalThis, init, init_type)) |maybeInit| { + if (Init.init(allocator, globalThis, init)) |maybeInit| { if (maybeInit) |init_| { body.init = init_; } - } else |_| {} + } else |_| { + return null; + } } body.value = Value.fromJS(globalThis, value) orelse return null; @@ -1065,8 +1071,12 @@ pub fn BodyMixin(comptime Type: type) type { } var encoder = this.getFormDataEncoding() orelse { - globalObject.throw("Invalid MIME type", .{}); - return .zero; + // TODO: catch specific errors from getFormDataEncoding + const err = globalObject.createTypeErrorInstance("Can't decode form data from body because of incorrect MIME type/boundary", .{}); + return JSC.JSPromise.rejectedPromiseValue( + globalObject, + err, + ); }; if (value.* == .Locked) { @@ -1084,7 +1094,7 @@ pub fn BodyMixin(comptime Type: type) type { ) catch |err| { return JSC.JSPromise.rejectedPromiseValue( globalObject, - globalObject.createErrorInstance( + globalObject.createTypeErrorInstance( "FormData parse error {s}", .{ @errorName(err), @@ -1122,6 +1132,17 @@ pub fn BodyMixin(comptime Type: type) type { var ptr = getAllocator(globalObject).create(Blob) catch unreachable; ptr.* = blob; blob.allocator = getAllocator(globalObject); + + 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()); + } + } else { + blob.store.?.mime_type = MimeType.text; + } + } + return JSC.JSPromise.resolvedPromiseValue(globalObject, ptr.toJS(globalObject)); } }; diff --git a/src/bun.js/webcore/request.zig b/src/bun.js/webcore/request.zig index 6581649fc..d6484d2ba 100644 --- a/src/bun.js/webcore/request.zig +++ b/src/bun.js/webcore/request.zig @@ -399,7 +399,7 @@ pub const Request = struct { .Null = {}, }; } else { - if (Body.Init.init(getAllocator(globalThis), globalThis, arguments[0], url_or_object_type) catch null) |req_init| { + if (Body.Init.init(getAllocator(globalThis), globalThis, arguments[0]) catch null) |req_init| { request.headers = req_init.headers; request.method = req_init.method; } @@ -439,7 +439,7 @@ pub const Request = struct { } } - if (Body.Init.init(getAllocator(globalThis), globalThis, arguments[1], arguments[1].jsType()) catch null) |req_init| { + if (Body.Init.init(getAllocator(globalThis), globalThis, arguments[1]) catch null) |req_init| { request.headers = req_init.headers; request.method = req_init.method; } @@ -494,6 +494,12 @@ pub const Request = struct { return &this.body; } + pub fn getFetchHeaders( + this: *Request, + ) ?*FetchHeaders { + return this.headers; + } + pub fn doClone( this: *Request, globalThis: *JSC.JSGlobalObject, diff --git a/src/bun.js/webcore/response.classes.ts b/src/bun.js/webcore/response.classes.ts index 67ac4716b..4fdce1c0c 100644 --- a/src/bun.js/webcore/response.classes.ts +++ b/src/bun.js/webcore/response.classes.ts @@ -135,7 +135,6 @@ export default [ type: { getter: "getType", - setter: "setType", }, size: { diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig index f36af88cf..9dfee821a 100644 --- a/src/bun.js/webcore/response.zig +++ b/src/bun.js/webcore/response.zig @@ -96,6 +96,12 @@ pub const Response = struct { return &this.body.value; } + pub fn getFetchHeaders( + this: *Response, + ) ?*FetchHeaders { + return this.body.init.headers; + } + pub inline fn statusCode(this: *const Response) u16 { return this.body.init.status_code; } @@ -173,7 +179,7 @@ pub const Response = struct { return ZigString.init("error").toValue(globalThis); } - return ZigString.init("basic").toValue(globalThis); + return ZigString.init("default").toValue(globalThis); } pub fn getStatusText( @@ -400,7 +406,7 @@ pub const Response = struct { if (init.isUndefinedOrNull()) {} else if (init.isNumber()) { response.body.init.status_code = @intCast(u16, @min(@max(0, init.toInt32()), std.math.maxInt(u16))); } else { - if (Body.Init.init(getAllocator(globalThis), globalThis, init, init.jsType()) catch null) |_init| { + if (Body.Init.init(getAllocator(globalThis), globalThis, init) catch null) |_init| { response.body.init = _init; } } @@ -446,7 +452,7 @@ pub const Response = struct { if (init.isUndefinedOrNull()) {} else if (init.isNumber()) { response.body.init.status_code = @intCast(u16, @min(@max(0, init.toInt32()), std.math.maxInt(u16))); } else { - if (Body.Init.init(getAllocator(globalThis), globalThis, init, init.jsType()) catch null) |_init| { + if (Body.Init.init(getAllocator(globalThis), globalThis, init) catch null) |_init| { response.body.init = _init; response.body.init.status_code = 302; } @@ -484,7 +490,7 @@ pub const Response = struct { globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame, ) callconv(.C) ?*Response { - const args_list = callframe.arguments(4); + const args_list = callframe.arguments(2); const arguments = args_list.ptr[0..args_list.len]; const body: Body = @as(?Body, brk: { switch (arguments.len) { @@ -495,14 +501,14 @@ pub const Response = struct { break :brk Body.extract(globalThis, arguments[0]); }, else => { - switch (arguments[1].jsType()) { - .Object, .FinalObject, .DOMWrapper => |js_type| { - break :brk Body.extractWithInit(globalThis, arguments[0], arguments[1], js_type); - }, - else => { - break :brk Body.extract(globalThis, arguments[0]); - }, + if (arguments[1].isUndefinedOrNull()) break :brk Body.extract(globalThis, arguments[0]); + if (arguments[1].isObject()) { + break :brk Body.extractWithInit(globalThis, arguments[0], arguments[1]); } + + const err = globalThis.createTypeErrorInstance("Expected options to be one of: null, undefined, or object", .{}); + globalThis.throwValue(err); + break :brk null; }, } unreachable; |