aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/webcore
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js/webcore')
-rw-r--r--src/bun.js/webcore/blob.zig51
-rw-r--r--src/bun.js/webcore/body.zig63
-rw-r--r--src/bun.js/webcore/request.zig10
-rw-r--r--src/bun.js/webcore/response.classes.ts1
-rw-r--r--src/bun.js/webcore/response.zig28
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;