make it build again

This commit is contained in:
Ciro Spaciari
2024-11-26 17:41:51 -08:00
parent b4ee149905
commit d36ed1c306
6 changed files with 157 additions and 161 deletions

View File

@@ -9,6 +9,7 @@
pub const DevServer = @This();
pub const debug = bun.Output.Scoped(.Bake, false);
pub const igLog = bun.Output.scoped(.IncrementalGraph, false);
const DebugHTTPServer = @import("../bun.js/api/server.zig").DebugHTTPServer;
pub const Options = struct {
/// Arena must live until DevServer.deinit()
@@ -617,7 +618,7 @@ fn ensureRouteIsBundled(
.data = switch (kind) {
.js_payload => .{ .js_payload = resp },
.server_handler => .{
.server_handler = (dev.server.?.DebugHTTPServer.prepareJsRequestContext(req, resp) orelse return)
.server_handler = (dev.server.?.ptr.as(DebugHTTPServer).prepareJsRequestContext(req, resp) orelse return)
.save(dev.vm.global, req, resp),
},
},
@@ -670,7 +671,7 @@ fn ensureRouteIsBundled(
.data = switch (kind) {
.js_payload => .{ .js_payload = resp },
.server_handler => .{
.server_handler = (dev.server.?.DebugHTTPServer.prepareJsRequestContext(req, resp) orelse return)
.server_handler = (dev.server.?.ptr.as(DebugHTTPServer).prepareJsRequestContext(req, resp) orelse return)
.save(dev.vm.global, req, resp),
},
},
@@ -1679,21 +1680,14 @@ pub fn routeBundlePtr(dev: *DevServer, idx: RouteBundle.Index) *RouteBundle {
return &dev.route_bundles.items[idx.get()];
}
fn onRequest(dev: *DevServer, req: *Request, resp: *Response) void {
fn onRequest(dev: *DevServer, req: *uws.Request, resp: *Response) void {
var params: FrameworkRouter.MatchedParams = undefined;
if (dev.router.matchSlow(req.url(), &params)) |route_index| {
dev.ensureRouteIsBundled(route_index, .server_handler, req, resp) catch bun.outOfMemory();
return;
}
switch (dev.server.?) {
inline .DebugHTTPServer, .HTTPServer => |s| if (s.config.onRequest != .zero) {
s.onRequest(req, resp);
return;
},
else => @panic("TODO: HTTPS"),
}
dev.server.?.onRequest(req, resp);
sendBuiltInNotFound(resp);
}

View File

@@ -1404,8 +1404,7 @@ pub const ServerConfig = struct {
if (try arg.getTruthy(global, "onNodeHTTPRequest")) |onRequest_| {
if (!onRequest_.isCallable(global.vm())) {
global.throwInvalidArguments("Expected onNodeHTTPRequest to be a function", .{});
return;
return global.throwInvalidArguments("Expected onNodeHTTPRequest to be a function", .{});
}
const onRequest = onRequest_.withAsyncContextIfNeeded(global);
JSC.C.JSValueProtect(global, onRequest.asObjectRef());
@@ -4776,8 +4775,7 @@ pub const ServerWebSocket = struct {
const args = callframe.arguments_old(4);
if (args.len < 1) {
log("publish()", .{});
globalThis.throw("publish requires at least 1 argument", .{});
return .zero;
return globalThis.throw2("publish requires at least 1 argument", .{});
}
const app = this.handler.app orelse {
@@ -4794,27 +4792,23 @@ pub const ServerWebSocket = struct {
if (topic_value.isEmptyOrUndefinedOrNull() or !topic_value.isString()) {
log("publish() topic invalid", .{});
globalThis.throw("publish requires a topic string", .{});
return .zero;
return globalThis.throw2("publish requires a topic string", .{});
}
var topic_slice = topic_value.toSlice(globalThis, bun.default_allocator);
defer topic_slice.deinit();
if (topic_slice.len == 0) {
globalThis.throw("publish requires a non-empty topic", .{});
return .zero;
return globalThis.throw2("publish requires a non-empty topic", .{});
}
if (!compress_value.isBoolean() and !compress_value.isUndefined() and compress_value != .zero) {
globalThis.throw("publish expects compress to be a boolean", .{});
return .zero;
return globalThis.throw2("publish expects compress to be a boolean", .{});
}
const compress = args.len > 1 and compress_value.toBoolean();
if (message_value.isEmptyOrUndefinedOrNull()) {
globalThis.throw("publish requires a non-empty message", .{});
return .zero;
return globalThis.throw2("publish requires a non-empty message", .{});
}
if (message_value.asArrayBuffer(globalThis)) |array_buffer| {
@@ -4849,8 +4843,6 @@ pub const ServerWebSocket = struct {
if (result) @as(i32, @intCast(@as(u31, @truncate(buffer.len)))) else @as(i32, 0),
);
}
return .zero;
}
pub fn publishText(
@@ -4862,8 +4854,7 @@ pub const ServerWebSocket = struct {
if (args.len < 1) {
log("publish()", .{});
globalThis.throw("publish requires at least 1 argument", .{});
return .zero;
return globalThis.throw2("publish requires at least 1 argument", .{});
}
const app = this.handler.app orelse {
@@ -4880,23 +4871,20 @@ pub const ServerWebSocket = struct {
if (topic_value.isEmptyOrUndefinedOrNull() or !topic_value.isString()) {
log("publish() topic invalid", .{});
globalThis.throw("publishText requires a topic string", .{});
return .zero;
return globalThis.throw2("publishText requires a topic string", .{});
}
var topic_slice = topic_value.toSlice(globalThis, bun.default_allocator);
defer topic_slice.deinit();
if (!compress_value.isBoolean() and !compress_value.isUndefined() and compress_value != .zero) {
globalThis.throw("publishText expects compress to be a boolean", .{});
return .zero;
return globalThis.throw2("publishText expects compress to be a boolean", .{});
}
const compress = args.len > 1 and compress_value.toBoolean();
if (message_value.isEmptyOrUndefinedOrNull() or !message_value.isString()) {
globalThis.throw("publishText requires a non-empty message", .{});
return .zero;
return globalThis.throw2("publishText requires a non-empty message", .{});
}
var string_slice = message_value.toSlice(globalThis, bun.default_allocator);
@@ -4925,8 +4913,7 @@ pub const ServerWebSocket = struct {
if (args.len < 1) {
log("publishBinary()", .{});
globalThis.throw("publishBinary requires at least 1 argument", .{});
return .zero;
return globalThis.throw2("publishBinary requires at least 1 argument", .{});
}
const app = this.handler.app orelse {
@@ -4942,32 +4929,27 @@ pub const ServerWebSocket = struct {
if (topic_value.isEmptyOrUndefinedOrNull() or !topic_value.isString()) {
log("publishBinary() topic invalid", .{});
globalThis.throw("publishBinary requires a topic string", .{});
return .zero;
return globalThis.throw2("publishBinary requires a topic string", .{});
}
var topic_slice = topic_value.toSlice(globalThis, bun.default_allocator);
defer topic_slice.deinit();
if (topic_slice.len == 0) {
globalThis.throw("publishBinary requires a non-empty topic", .{});
return .zero;
return globalThis.throw2("publishBinary requires a non-empty topic", .{});
}
if (!compress_value.isBoolean() and !compress_value.isUndefined() and compress_value != .zero) {
globalThis.throw("publishBinary expects compress to be a boolean", .{});
return .zero;
return globalThis.throw2("publishBinary expects compress to be a boolean", .{});
}
const compress = args.len > 1 and compress_value.toBoolean();
if (message_value.isEmptyOrUndefinedOrNull()) {
globalThis.throw("publishBinary requires a non-empty message", .{});
return .zero;
return globalThis.throw2("publishBinary requires a non-empty message", .{});
}
const array_buffer = message_value.asArrayBuffer(globalThis) orelse {
globalThis.throw("publishBinary expects an ArrayBufferView", .{});
return .zero;
return globalThis.throw2("publishBinary expects an ArrayBufferView", .{});
};
const buffer = array_buffer.slice();
@@ -4988,7 +4970,7 @@ pub const ServerWebSocket = struct {
globalThis: *JSC.JSGlobalObject,
topic_str: *JSC.JSString,
array: *JSC.JSUint8Array,
) JSC.JSValue {
) bun.JSError!JSC.JSValue {
const app = this.handler.app orelse {
log("publish() closed", .{});
return JSValue.jsNumber(0);
@@ -5000,8 +4982,7 @@ pub const ServerWebSocket = struct {
var topic_slice = topic_str.toSlice(globalThis, bun.default_allocator);
defer topic_slice.deinit();
if (topic_slice.len == 0) {
globalThis.throw("publishBinary requires a non-empty topic", .{});
return .zero;
return globalThis.throw2("publishBinary requires a non-empty topic", .{});
}
const compress = true;
@@ -5028,7 +5009,7 @@ pub const ServerWebSocket = struct {
globalThis: *JSC.JSGlobalObject,
topic_str: *JSC.JSString,
str: *JSC.JSString,
) JSC.JSValue {
) bun.JSError!JSC.JSValue {
const app = this.handler.app orelse {
log("publish() closed", .{});
return JSValue.jsNumber(0);
@@ -5040,8 +5021,7 @@ pub const ServerWebSocket = struct {
var topic_slice = topic_str.toSlice(globalThis, bun.default_allocator);
defer topic_slice.deinit();
if (topic_slice.len == 0) {
globalThis.throw("publishBinary requires a non-empty topic", .{});
return .zero;
return globalThis.throw2("publishBinary requires a non-empty topic", .{});
}
const compress = true;
@@ -5100,8 +5080,7 @@ pub const ServerWebSocket = struct {
const result = corker.result;
if (result.isAnyError()) {
globalThis.throwValue(result);
return .zero;
return globalThis.throwValue2(result);
}
return result;
@@ -5116,8 +5095,7 @@ pub const ServerWebSocket = struct {
if (args.len < 1) {
log("send()", .{});
globalThis.throw("send requires at least 1 argument", .{});
return .zero;
return globalThis.throw2("send requires at least 1 argument", .{});
}
if (this.isClosed()) {
@@ -5129,15 +5107,13 @@ pub const ServerWebSocket = struct {
const compress_value = args.ptr[1];
if (!compress_value.isBoolean() and !compress_value.isUndefined() and compress_value != .zero) {
globalThis.throw("send expects compress to be a boolean", .{});
return .zero;
return globalThis.throw2("send expects compress to be a boolean", .{});
}
const compress = args.len > 1 and compress_value.toBoolean();
if (message_value.isEmptyOrUndefinedOrNull()) {
globalThis.throw("send requires a non-empty message", .{});
return .zero;
return globalThis.throw2("send requires a non-empty message", .{});
}
if (message_value.asArrayBuffer(globalThis)) |buffer| {
@@ -5177,8 +5153,6 @@ pub const ServerWebSocket = struct {
},
}
}
return .zero;
}
pub fn sendText(
@@ -5190,8 +5164,7 @@ pub const ServerWebSocket = struct {
if (args.len < 1) {
log("sendText()", .{});
globalThis.throw("sendText requires at least 1 argument", .{});
return .zero;
return globalThis.throw2("sendText requires at least 1 argument", .{});
}
if (this.isClosed()) {
@@ -5203,15 +5176,13 @@ pub const ServerWebSocket = struct {
const compress_value = args.ptr[1];
if (!compress_value.isBoolean() and !compress_value.isUndefined() and compress_value != .zero) {
globalThis.throw("sendText expects compress to be a boolean", .{});
return .zero;
return globalThis.throw2("sendText expects compress to be a boolean", .{});
}
const compress = args.len > 1 and compress_value.toBoolean();
if (message_value.isEmptyOrUndefinedOrNull() or !message_value.isString()) {
globalThis.throw("sendText expects a string", .{});
return .zero;
return globalThis.throw2("sendText expects a string", .{});
}
var string_slice = message_value.toSlice(globalThis, bun.default_allocator);
@@ -5274,8 +5245,7 @@ pub const ServerWebSocket = struct {
if (args.len < 1) {
log("sendBinary()", .{});
globalThis.throw("sendBinary requires at least 1 argument", .{});
return .zero;
return globalThis.throw2("sendBinary requires at least 1 argument", .{});
}
if (this.isClosed()) {
@@ -5287,15 +5257,13 @@ pub const ServerWebSocket = struct {
const compress_value = args.ptr[1];
if (!compress_value.isBoolean() and !compress_value.isUndefined() and compress_value != .zero) {
globalThis.throw("sendBinary expects compress to be a boolean", .{});
return .zero;
return globalThis.throw2("sendBinary expects compress to be a boolean", .{});
}
const compress = args.len > 1 and compress_value.toBoolean();
const buffer = message_value.asArrayBuffer(globalThis) orelse {
globalThis.throw("sendBinary requires an ArrayBufferView", .{});
return .zero;
return globalThis.throw2("sendBinary requires an ArrayBufferView", .{});
};
switch (this.websocket().send(buffer.slice(), .binary, compress, true)) {
@@ -5585,8 +5553,7 @@ pub const ServerWebSocket = struct {
) bun.JSError!JSValue {
const args = callframe.arguments_old(1);
if (args.len < 1) {
globalThis.throw("subscribe requires at least 1 argument", .{});
return .zero;
return globalThis.throw2("subscribe requires at least 1 argument", .{});
}
if (this.isClosed()) {
@@ -5604,13 +5571,12 @@ pub const ServerWebSocket = struct {
if (comptime !bun.FeatureFlags.breaking_changes_1_2) {
if (globalThis.hasException()) {
return .zero;
return error.JSError;
}
}
if (topic.len == 0) {
globalThis.throw("subscribe requires a non-empty topic name", .{});
return .zero;
return globalThis.throw2("subscribe requires a non-empty topic name", .{});
}
return JSValue.jsBoolean(this.websocket().subscribe(topic.slice()));
@@ -5622,8 +5588,7 @@ pub const ServerWebSocket = struct {
) bun.JSError!JSValue {
const args = callframe.arguments_old(1);
if (args.len < 1) {
globalThis.throw("unsubscribe requires at least 1 argument", .{});
return .zero;
return globalThis.throw2("unsubscribe requires at least 1 argument", .{});
}
if (this.isClosed()) {
@@ -5641,13 +5606,12 @@ pub const ServerWebSocket = struct {
if (comptime !bun.FeatureFlags.breaking_changes_1_2) {
if (globalThis.hasException()) {
return .zero;
return error.JSError;
}
}
if (topic.len == 0) {
globalThis.throw("unsubscribe requires a non-empty topic name", .{});
return .zero;
return globalThis.throw2("unsubscribe requires a non-empty topic name", .{});
}
return JSValue.jsBoolean(this.websocket().unsubscribe(topic.slice()));
@@ -5659,8 +5623,7 @@ pub const ServerWebSocket = struct {
) bun.JSError!JSValue {
const args = callframe.arguments_old(1);
if (args.len < 1) {
globalThis.throw("isSubscribed requires at least 1 argument", .{});
return .zero;
return globalThis.throw2("isSubscribed requires at least 1 argument", .{});
}
if (this.isClosed()) {
@@ -5678,13 +5641,12 @@ pub const ServerWebSocket = struct {
if (comptime !bun.FeatureFlags.breaking_changes_1_2) {
if (globalThis.hasException()) {
return .zero;
return error.JSError;
}
}
if (topic.len == 0) {
globalThis.throw("isSubscribed requires a non-empty topic name", .{});
return .zero;
return globalThis.throw2("isSubscribed requires a non-empty topic name", .{});
}
return JSValue.jsBoolean(this.websocket().isSubscribed(topic.slice()));
@@ -6086,12 +6048,12 @@ pub const NodeHTTPResponse = struct {
if (this.isDone()) {
globalObject.ERR_STREAM_ALREADY_FINISHED("Stream is already ended", .{}).throw();
return .undefined;
return error.JSError;
}
const state = this.response.state();
if (handleEndedIfNecessary(state, globalObject)) {
return .zero;
return error.JSError;
}
const status_code_value = if (arguments.len > 0) arguments[0] else .undefined;
@@ -6103,7 +6065,7 @@ pub const NodeHTTPResponse = struct {
break :brk globalObject.validateIntegerRange(status_code_value, i32, 200, .{
.min = 100,
.max = 599,
}) orelse return .zero;
}) orelse return error.JSError;
}
break :brk 200;
@@ -6118,12 +6080,12 @@ pub const NodeHTTPResponse = struct {
defer status_message_slice.deinit();
if (globalObject.hasException()) {
return .zero;
return error.JSError;
}
if (state.isHttpStatusCalled()) {
globalObject.ERR_HTTP_HEADERS_SENT("Stream already started", .{}).throw();
return .zero;
return error.JSError;
}
do_it: {
@@ -6153,7 +6115,7 @@ pub const NodeHTTPResponse = struct {
}
pub fn writeContinue(this: *NodeHTTPResponse, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) JSC.JSValue {
const arguments = callframe.arguments(1).slice();
const arguments = callframe.arguments_old(1).slice();
_ = arguments; // autofix
if (this.isDone()) {
return .undefined;
@@ -6161,7 +6123,7 @@ pub const NodeHTTPResponse = struct {
const state = this.response.state();
if (handleEndedIfNecessary(state, globalObject)) {
return .zero;
return error.JSError;
}
this.response.writeContinue();
@@ -6283,7 +6245,7 @@ pub const NodeHTTPResponse = struct {
pub export fn Bun__NodeHTTPRequest__onResolve(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(JSC.conv) JSC.JSValue {
log("onResolve", .{});
const arguments = callframe.arguments(2).slice();
const arguments = callframe.arguments_old(2).slice();
const this: *NodeHTTPResponse = arguments[1].as(NodeHTTPResponse).?;
this.promise.deinit();
defer this.deref();
@@ -6305,7 +6267,7 @@ pub const NodeHTTPResponse = struct {
}
pub export fn Bun__NodeHTTPRequest__onReject(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(JSC.conv) JSC.JSValue {
const arguments = callframe.arguments(2).slice();
const arguments = callframe.arguments_old(2).slice();
const err = arguments[0];
const this: *NodeHTTPResponse = arguments[1].as(NodeHTTPResponse).?;
this.promise.deinit();
@@ -6453,16 +6415,16 @@ pub const NodeHTTPResponse = struct {
globalObject: *JSC.JSGlobalObject,
arguments: []const JSC.JSValue,
comptime is_end: bool,
) JSC.JSValue {
) bun.JSError!JSC.JSValue {
if (this.isDone()) {
globalObject.ERR_STREAM_WRITE_AFTER_END("Stream already ended", .{}).throw();
return .zero;
return error.JSError;
}
const state = this.response.state();
if (!state.isResponsePending()) {
globalObject.ERR_STREAM_WRITE_AFTER_END("Stream already ended", .{}).throw();
return .zero;
return error.JSError;
}
const input_value = if (arguments.len > 0) arguments[0] else .undefined;
@@ -6496,22 +6458,19 @@ pub const NodeHTTPResponse = struct {
}
encoding = JSC.Node.Encoding.fromJS(encoding_value, globalObject) orelse {
globalObject.throwInvalidArguments("Invalid encoding", .{});
return .zero;
return globalObject.throwInvalidArguments("Invalid encoding", .{});
};
}
break :brk JSC.Node.StringOrBuffer.fromJSWithEncoding(globalObject, bun.default_allocator, input_value, encoding) orelse {
if (!globalObject.hasException()) {
return globalObject.throwInvalidArgumentTypeValue("input", "string or buffer", input_value);
}
return .zero;
const result = JSC.Node.StringOrBuffer.fromJSWithEncoding(globalObject, bun.default_allocator, input_value, encoding) catch |err| return err;
break :brk result orelse {
return globalObject.throwInvalidArgumentTypeValue("input", "string or buffer", input_value);
};
};
defer string_or_buffer.deinit();
if (globalObject.hasException()) {
return .zero;
return error.JSError;
}
const bytes = string_or_buffer.slice();
@@ -6641,13 +6600,13 @@ pub const NodeHTTPResponse = struct {
}
pub fn write(this: *NodeHTTPResponse, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue {
const arguments = callframe.arguments(3).slice();
const arguments = callframe.arguments_old(3).slice();
return writeOrEnd(this, globalObject, arguments, false);
}
pub fn end(this: *NodeHTTPResponse, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue {
const arguments = callframe.arguments(3).slice();
const arguments = callframe.arguments_old(3).slice();
return writeOrEnd(this, globalObject, arguments, true);
}
@@ -6673,14 +6632,14 @@ pub const NodeHTTPResponse = struct {
}
pub fn cork(this: *NodeHTTPResponse, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue {
const arguments = callframe.arguments(1).slice();
const arguments = callframe.arguments_old(1).slice();
if (arguments.len == 0 or !arguments[0].isCallable(globalObject.vm())) {
return globalObject.throwInvalidArgumentTypeValue("cork", "function", arguments[0]);
}
if (this.finished or this.aborted) {
globalObject.ERR_STREAM_ALREADY_FINISHED("Stream is already ended", .{}).throw();
return .zero;
return error.JSError;
}
var result: JSC.JSValue = .zero;
@@ -6692,11 +6651,10 @@ pub const NodeHTTPResponse = struct {
if (is_exception) {
if (result != .zero) {
globalObject.throwValue(result);
return globalObject.throwValue2(result);
} else {
globalObject.throw("unknown error", .{});
return globalObject.throw2("unknown error", .{});
}
return .zero;
}
if (result == .zero) {
@@ -6778,21 +6736,19 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
pub const doTimeout = timeout;
pub fn doSubscriberCount(this: *ThisServer, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue {
const arguments = callframe.arguments(1);
const arguments = callframe.arguments_old(1);
if (arguments.len < 1) {
globalThis.throwNotEnoughArguments("subscriberCount", 1, 0);
return .zero;
return globalThis.throwNotEnoughArguments("subscriberCount", 1, 0);
}
if (arguments.ptr[0].isEmptyOrUndefinedOrNull()) {
globalThis.throwInvalidArguments("subscriberCount requires a topic name as a string", .{});
return .zero;
return globalThis.throwInvalidArguments("subscriberCount requires a topic name as a string", .{});
}
var topic = arguments.ptr[0].toSlice(globalThis, bun.default_allocator);
defer topic.deinit();
if (globalThis.hasException()) {
return .zero;
return error.JSError;
}
if (topic.len == 0) {
@@ -6806,16 +6762,15 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
pub usingnamespace bun.New(@This());
pub fn constructor(globalThis: *JSC.JSGlobalObject, _: *JSC.CallFrame) bun.JSError!*ThisServer {
return globalThis.throw("Server() is not a constructor", .{});
return globalThis.throw2("Server() is not a constructor", .{});
}
extern fn JSSocketAddress__create(global: *JSC.JSGlobalObject, ip: JSValue, port: i32, is_ipv6: bool) JSValue;
pub fn requestIP(this: *ThisServer, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue {
const arguments = callframe.arguments(1).slice();
const arguments = callframe.arguments_old(1).slice();
if (arguments.len < 1 or arguments[0].isEmptyOrUndefinedOrNull()) {
globalObject.throwNotEnoughArguments("requestIP", 1, 0);
return .zero;
return globalObject.throwNotEnoughArguments("requestIP", 1, 0);
}
if (this.config.address == .unix) {
@@ -6846,10 +6801,9 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
}
pub fn timeout(this: *ThisServer, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue {
const arguments = callframe.arguments(2).slice();
const arguments = callframe.arguments_old(2).slice();
if (arguments.len < 2 or arguments[0].isEmptyOrUndefinedOrNull()) {
globalObject.throwNotEnoughArguments("timeout", 2, arguments.len);
return .zero;
return globalObject.throwNotEnoughArguments("timeout", 2, arguments.len);
}
const seconds = arguments[1];
@@ -6859,8 +6813,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
}
if (!seconds.isNumber()) {
this.globalThis.throw("timeout() requires a number", .{});
return .zero;
return this.globalThis.throw2("timeout() requires a number", .{});
}
const value = seconds.to(c_uint);
@@ -6871,8 +6824,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
_ = response.response.timeout(@intCast(@min(value, 255)));
}
} else {
this.globalThis.throwInvalidArguments("timeout() requires a Request object", .{});
return .zero;
return this.globalThis.throwInvalidArguments("timeout() requires a Request object", .{});
}
return JSValue.jsUndefined();
@@ -6890,15 +6842,13 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
if (topic.len == 0) {
httplog("publish() topic invalid", .{});
globalThis.throw("publish requires a topic string", .{});
return .zero;
return globalThis.throw2("publish requires a topic string", .{});
}
var topic_slice = topic.toSlice(bun.default_allocator);
defer topic_slice.deinit();
if (topic_slice.len == 0) {
globalThis.throw("publish requires a non-empty topic", .{});
return .zero;
return globalThis.throw2("publish requires a non-empty topic", .{});
}
const compress = (compress_value orelse JSValue.jsBoolean(true)).toBoolean();
@@ -6922,8 +6872,6 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
@as(i32, @intFromBool(uws.AnyWebSocket.publishWithOptions(ssl_enabled, app, topic_slice.slice(), buffer, .text, compress))) * @as(i32, @intCast(@as(u31, @truncate(buffer.len)))),
);
}
return .zero;
}
pub fn onUpgrade(
@@ -6933,8 +6881,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
optional: ?JSValue,
) bun.JSError!JSValue {
if (this.config.websocket == null) {
globalThis.throwInvalidArguments("To enable websocket support, set the \"websocket\" object in Bun.serve({})", .{});
return error.JSError;
return globalThis.throwInvalidArguments("To enable websocket support, set the \"websocket\" object in Bun.serve({})", .{});
}
if (this.flags.terminated) {
@@ -6967,8 +6914,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
}
if (!opts.isObject()) {
globalThis.throwInvalidArguments("upgrade options must be an object", .{});
return error.JSError;
return globalThis.throwInvalidArguments("upgrade options must be an object", .{});
}
if (opts.fastGet(globalThis, .data)) |headers_value| {
@@ -6994,7 +6940,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
break :brk null;
} orelse {
if (!globalThis.hasException()) {
globalThis.throwInvalidArguments("upgrade options.headers must be a Headers or an object", .{});
return globalThis.throwInvalidArguments("upgrade options.headers must be a Headers or an object", .{});
}
return error.JSError;
};
@@ -7025,8 +6971,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp
}
var request = object.as(Request) orelse {
globalThis.throwInvalidArguments("upgrade requires a Request object", .{});
return error.JSError;
return globalThis.throwInvalidArguments("upgrade requires a Request object", .{});
};
var upgrader = request.request_context.get(RequestContext) orelse return JSC.jsBoolean(false);
@@ -8652,6 +8597,20 @@ pub const AnyServer = packed struct {
return &server_config.websocket.?.handler;
}
pub fn onRequest(
this: AnyServer,
req: *uws.Request,
resp: *uws.NewApp(false).Response,
) void {
return switch (this.ptr.tag()) {
Ptr.case(HTTPServer) => this.ptr.as(HTTPServer).onRequest(req, resp),
Ptr.case(HTTPSServer) => @panic("TODO: https"),
Ptr.case(DebugHTTPServer) => this.ptr.as(DebugHTTPServer).onRequest(req, resp),
Ptr.case(DebugHTTPSServer) => @panic("TODO: https"),
else => bun.unreachablePanic("Invalid pointer tag", .{}),
};
}
pub fn from(server: anytype) AnyServer {
return .{ .ptr = Ptr.init(server) };
}

View File

@@ -411,7 +411,7 @@ pub const Task = TaggedPointerUnion(.{
AppendFile,
AsyncGlobWalkTask,
AsyncTransformTask,
bun.bake.DevServer.HotReloadTask,
bun.bake.DevServer.HotReloadEvent,
bun.shell.Interpreter.Builtin.Yes.YesTask,
Chmod,
Chown,
@@ -484,10 +484,6 @@ pub const Task = TaggedPointerUnion(.{
WriteFile,
WriteFileTask,
Writev,
ProcessWaiterThreadTask,
RuntimeTranspilerStore,
ServerAllConnectionsClosedTask,
bun.bake.DevServer.HotReloadEvent,
bun.bundle_v2.DeferredBatchTask,
});
const UnboundedQueue = @import("./unbounded_queue.zig").UnboundedQueue;

View File

@@ -63,14 +63,12 @@ pub const TextEncoder = struct {
return uint8array;
} else {
const bytes = strings.allocateLatin1IntoUTF8(globalThis.bunVM().allocator, []const u8, slice) catch {
globalThis.throwOutOfMemory();
return .zero;
return globalThis.throwOutOfMemoryValue();
};
bun.assert(bytes.len >= slice.len);
return ArrayBuffer.fromBytes(bytes, .Uint8Array).toJSUnchecked(globalThis, null);
}
}
pub export fn TextEncoder__encode16(
globalThis: *JSGlobalObject,
ptr: [*]const u16,
@@ -111,8 +109,53 @@ pub const TextEncoder = struct {
@TypeOf(slice),
slice,
) catch {
globalThis.throwOutOfMemory();
return .zero;
return JSC.toInvalidArguments("Out of memory", .{}, globalThis);
};
return ArrayBuffer.fromBytes(bytes, .Uint8Array).toJSUnchecked(globalThis, null);
}
}
pub export fn c(
globalThis: *JSGlobalObject,
ptr: [*]const u16,
len: usize,
) JSValue {
// as much as possible, rely on JSC to own the memory
// their code is more battle-tested than bun's code
// so we do a stack allocation here
// and then copy into JSC memory
// unless it's huge
// JSC will GC Uint8Array that occupy less than 512 bytes
// so it's extra good for that case
// this also means there won't be reallocations for small strings
var buf: [2048]u8 = undefined;
const slice = ptr[0..len];
// max utf16 -> utf8 length
if (slice.len <= buf.len / 4) {
const result = strings.copyUTF16IntoUTF8(&buf, @TypeOf(slice), slice, true);
if (result.read == 0 or result.written == 0) {
const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, 3);
const array_buffer = uint8array.asArrayBuffer(globalThis).?;
const replacement_char = [_]u8{ 239, 191, 189 };
@memcpy(array_buffer.slice()[0..replacement_char.len], &replacement_char);
return uint8array;
}
const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, result.written);
bun.assert(result.written <= buf.len);
bun.assert(result.read == slice.len);
const array_buffer = uint8array.asArrayBuffer(globalThis).?;
bun.assert(result.written == array_buffer.len);
@memcpy(array_buffer.slice()[0..result.written], buf[0..result.written]);
return uint8array;
} else {
const bytes = strings.toUTF8AllocWithType(
bun.default_allocator,
@TypeOf(slice),
slice,
) catch {
return globalThis.throwOutOfMemoryValue();
};
return ArrayBuffer.fromBytes(bytes, .Uint8Array).toJSUnchecked(globalThis, null);
}

View File

@@ -112,7 +112,7 @@ pub const Response = struct {
pub export fn jsFunctionRequestOrResponseHasBodyValue(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(JSC.conv) JSC.JSValue {
_ = globalObject; // autofix
const arguments = callframe.arguments(1);
const arguments = callframe.arguments_old(1);
const this_value = arguments.ptr[0];
if (this_value.isEmptyOrUndefinedOrNull()) {
return .false;
@@ -128,7 +128,7 @@ pub const Response = struct {
}
pub export fn jsFunctionGetCompleteRequestOrResponseBodyValueAsArrayBuffer(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(JSC.conv) JSC.JSValue {
const arguments = callframe.arguments(1);
const arguments = callframe.arguments_old(1);
const this_value = arguments.ptr[0];
if (this_value.isEmptyOrUndefinedOrNull()) {
return .undefined;
@@ -152,11 +152,11 @@ pub const Response = struct {
return .undefined;
}
defer body.* = .{ .Used = {} };
return blob.toArrayBuffer(globalObject, .transfer);
return blob.toArrayBuffer(globalObject, .transfer) catch return .zero;
},
.WTFStringImpl, .InternalBlob => {
var any_blob = body.useAsAnyBlob();
return any_blob.toArrayBufferTransfer(globalObject);
return any_blob.toArrayBufferTransfer(globalObject) catch return .zero;
},
.Error, .Locked => return .undefined,
}

View File

@@ -946,8 +946,12 @@ const ServerPrototype = {
resolveFunction && resolveFunction();
}
http_res.once("close", onClose);
server.emit("request", http_req, http_res);
const upgrade = http_req.headers.upgrade;
if (upgrade) {
server.emit("upgrade", http_req, http_req.socket, kEmptyBuffer);
} else {
server.emit("request", http_req, http_res);
}
socket.cork(drainMicrotasks);