aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/api/server.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js/api/server.zig')
-rw-r--r--src/bun.js/api/server.zig285
1 files changed, 215 insertions, 70 deletions
diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig
index 762d35bb6..823456777 100644
--- a/src/bun.js/api/server.zig
+++ b/src/bun.js/api/server.zig
@@ -91,6 +91,34 @@ const SendfileContext = struct {
const DateTime = bun.DateTime;
const linux = std.os.linux;
+const BlobFileContentResult = struct {
+ data: [:0]const u8,
+ fn init(comptime fieldname: []const u8, js_obj: JSC.JSValue, global: *JSC.JSGlobalObject, exception: JSC.C.ExceptionRef) ?BlobFileContentResult {
+ if (JSC.WebCore.Body.Value.fromJS(global, js_obj)) |body| {
+ if (body == .Blob and body.Blob.store != null and body.Blob.store.?.data == .file) {
+ var fs: JSC.Node.NodeFS = .{};
+ const read = fs.readFileWithOptions(.{ .path = body.Blob.store.?.data.file.pathlike }, .sync, .null_terminated);
+ switch (read) {
+ .err => {
+ global.throwValue(read.err.toJSC(global));
+ return .{ .data = "" };
+ },
+ else => {
+ const str = read.result.null_terminated;
+ if (str.len > 0) {
+ return .{ .data = str };
+ }
+ JSC.throwInvalidArguments(std.fmt.comptimePrint("Invalid {s} file", .{fieldname}), .{}, global, exception);
+ return .{ .data = str };
+ },
+ }
+ }
+ }
+
+ return null;
+ }
+};
+
pub const ServerConfig = struct {
port: u16 = 0,
hostname: [*:0]const u8 = "localhost",
@@ -276,8 +304,20 @@ pub const ServerConfig = struct {
valid_count += 1;
any = true;
}
+ } else if (BlobFileContentResult.init("key", item, global, exception)) |content| {
+ if (content.data.len > 0) {
+ native_array[valid_count] = content.data.ptr;
+ valid_count += 1;
+ any = true;
+ } else {
+ arena.deinit();
+ // mark and free all CA's
+ result.cert = native_array;
+ result.deinit();
+ return null;
+ }
} else {
- global.throwInvalidArguments("key argument must be an array containing string, Buffer or TypedArray", .{});
+ global.throwInvalidArguments("key argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile", .{});
arena.deinit();
// mark and free all keys
result.key = native_array;
@@ -296,10 +336,40 @@ pub const ServerConfig = struct {
result.key_count = valid_count;
}
+ } else if (BlobFileContentResult.init("key", js_obj, global, exception)) |content| {
+ if (content.data.len > 0) {
+ const native_array = bun.default_allocator.alloc([*c]const u8, 1) catch unreachable;
+ native_array[0] = content.data.ptr;
+ result.key = native_array;
+ result.key_count = 1;
+ any = true;
+ } else {
+ result.deinit();
+ return null;
+ }
} else {
- global.throwInvalidArguments("key argument must be an array containing string, Buffer or TypedArray", .{});
- result.deinit();
- return null;
+ const native_array = bun.default_allocator.alloc([*c]const u8, 1) catch unreachable;
+ var arena: std.heap.ArenaAllocator = std.heap.ArenaAllocator.init(bun.default_allocator);
+ if (JSC.Node.StringOrBuffer.fromJS(global, arena.allocator(), js_obj, exception)) |sb| {
+ const sliced = sb.slice();
+ if (sliced.len > 0) {
+ native_array[0] = bun.default_allocator.dupeZ(u8, sliced) catch unreachable;
+ any = true;
+ result.key = native_array;
+ result.key_count = 1;
+ } else {
+ bun.default_allocator.free(native_array);
+ }
+ } else {
+ global.throwInvalidArguments("key argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile", .{});
+ arena.deinit();
+ // mark and free all certs
+ result.key = native_array;
+ result.deinit();
+ return null;
+ }
+
+ arena.deinit();
}
}
@@ -336,8 +406,20 @@ pub const ServerConfig = struct {
valid_count += 1;
any = true;
}
+ } else if (BlobFileContentResult.init("cert", item, global, exception)) |content| {
+ if (content.data.len > 0) {
+ native_array[valid_count] = content.data.ptr;
+ valid_count += 1;
+ any = true;
+ } else {
+ arena.deinit();
+ // mark and free all CA's
+ result.cert = native_array;
+ result.deinit();
+ return null;
+ }
} else {
- global.throwInvalidArguments("cert argument must be an array containing string, Buffer or TypedArray", .{});
+ global.throwInvalidArguments("cert argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile", .{});
arena.deinit();
// mark and free all certs
result.cert = native_array;
@@ -356,19 +438,51 @@ pub const ServerConfig = struct {
result.cert_count = valid_count;
}
+ } else if (BlobFileContentResult.init("cert", js_obj, global, exception)) |content| {
+ if (content.data.len > 0) {
+ const native_array = bun.default_allocator.alloc([*c]const u8, 1) catch unreachable;
+ native_array[0] = content.data.ptr;
+ result.cert = native_array;
+ result.cert_count = 1;
+ any = true;
+ } else {
+ result.deinit();
+ return null;
+ }
} else {
- global.throwInvalidArguments("cert argument must be an array containing string, Buffer or TypedArray", .{});
- result.deinit();
- return null;
+ const native_array = bun.default_allocator.alloc([*c]const u8, 1) catch unreachable;
+ var arena: std.heap.ArenaAllocator = std.heap.ArenaAllocator.init(bun.default_allocator);
+ if (JSC.Node.StringOrBuffer.fromJS(global, arena.allocator(), js_obj, exception)) |sb| {
+ const sliced = sb.slice();
+ if (sliced.len > 0) {
+ native_array[0] = bun.default_allocator.dupeZ(u8, sliced) catch unreachable;
+ any = true;
+ result.cert = native_array;
+ result.cert_count = 1;
+ } else {
+ bun.default_allocator.free(native_array);
+ }
+ } else {
+ global.throwInvalidArguments("cert argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile", .{});
+ arena.deinit();
+ // mark and free all certs
+ result.cert = native_array;
+ result.deinit();
+ return null;
+ }
+
+ arena.deinit();
}
}
if (obj.getTruthy(global, "requestCert")) |request_cert| {
result.request_cert = if (request_cert.asBoolean()) 1 else 0;
+ any = true;
}
if (obj.getTruthy(global, "rejectUnauthorized")) |reject_unauthorized| {
result.reject_unauthorized = if (reject_unauthorized.asBoolean()) 1 else 0;
+ any = true;
}
if (obj.getTruthy(global, "ciphers")) |ssl_ciphers| {
@@ -379,79 +493,119 @@ pub const ServerConfig = struct {
any = true;
}
}
-
- // Optional
- if (any) {
- if (obj.getTruthy(global, "secureOptions")) |secure_options| {
- if (secure_options.isNumber()) {
- result.secure_options = secure_options.toU32();
- }
+ if (obj.getTruthy(global, "serverName")) |server_name| {
+ var sliced = server_name.toSlice(global, bun.default_allocator);
+ defer sliced.deinit();
+ if (sliced.len > 0) {
+ result.server_name = bun.default_allocator.dupeZ(u8, sliced.slice()) catch unreachable;
+ any = true;
}
+ }
- if (obj.getTruthy(global, "serverName")) |key_file_name| {
- var sliced = key_file_name.toSlice(global, bun.default_allocator);
- defer sliced.deinit();
- if (sliced.len > 0) {
- result.server_name = bun.default_allocator.dupeZ(u8, sliced.slice()) catch unreachable;
- }
- }
+ if (obj.getTruthy(global, "ca")) |js_obj| {
+ if (js_obj.jsType().isArray()) {
+ const count = js_obj.getLengthOfArray(global);
+ if (count > 0) {
+ const native_array = bun.default_allocator.alloc([*c]const u8, count) catch unreachable;
+
+ var i: u32 = 0;
+ var valid_count: u32 = 0;
- if (obj.getTruthy(global, "ca")) |js_obj| {
- if (js_obj.jsType().isArray()) {
- const count = js_obj.getLengthOfArray(global);
- if (count > 0) {
- const native_array = bun.default_allocator.alloc([*c]const u8, count) catch unreachable;
-
- var i: u32 = 0;
- var valid_count: u32 = 0;
-
- var arena: std.heap.ArenaAllocator = std.heap.ArenaAllocator.init(bun.default_allocator);
- while (i < count) : (i += 1) {
- const item = js_obj.getIndex(global, i);
- if (JSC.Node.StringOrBuffer.fromJS(global, arena.allocator(), item, exception)) |sb| {
- const sliced = sb.slice();
- if (sliced.len > 0) {
- native_array[valid_count] = bun.default_allocator.dupeZ(u8, sliced) catch unreachable;
- valid_count += 1;
- any = true;
- }
+ var arena: std.heap.ArenaAllocator = std.heap.ArenaAllocator.init(bun.default_allocator);
+ while (i < count) : (i += 1) {
+ const item = js_obj.getIndex(global, i);
+ if (JSC.Node.StringOrBuffer.fromJS(global, arena.allocator(), item, exception)) |sb| {
+ const sliced = sb.slice();
+ if (sliced.len > 0) {
+ native_array[valid_count] = bun.default_allocator.dupeZ(u8, sliced) catch unreachable;
+ valid_count += 1;
+ any = true;
+ }
+ } else if (BlobFileContentResult.init("ca", item, global, exception)) |content| {
+ if (content.data.len > 0) {
+ native_array[valid_count] = content.data.ptr;
+ valid_count += 1;
+ any = true;
} else {
- global.throwInvalidArguments("ca argument must be an array containing string, Buffer or TypedArray", .{});
arena.deinit();
// mark and free all CA's
result.cert = native_array;
result.deinit();
return null;
}
+ } else {
+ global.throwInvalidArguments("ca argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile", .{});
+ arena.deinit();
+ // mark and free all CA's
+ result.cert = native_array;
+ result.deinit();
+ return null;
}
+ }
- arena.deinit();
+ arena.deinit();
- if (valid_count == 0) {
- bun.default_allocator.free(native_array);
- } else {
- result.ca = native_array;
- }
+ if (valid_count == 0) {
+ bun.default_allocator.free(native_array);
+ } else {
+ result.ca = native_array;
+ }
- result.ca_count = valid_count;
+ result.ca_count = valid_count;
+ }
+ } else if (BlobFileContentResult.init("ca", js_obj, global, exception)) |content| {
+ if (content.data.len > 0) {
+ const native_array = bun.default_allocator.alloc([*c]const u8, 1) catch unreachable;
+ native_array[0] = content.data.ptr;
+ result.ca = native_array;
+ result.ca_count = 1;
+ any = true;
+ } else {
+ result.deinit();
+ return null;
+ }
+ } else {
+ const native_array = bun.default_allocator.alloc([*c]const u8, 1) catch unreachable;
+ var arena: std.heap.ArenaAllocator = std.heap.ArenaAllocator.init(bun.default_allocator);
+ if (JSC.Node.StringOrBuffer.fromJS(global, arena.allocator(), js_obj, exception)) |sb| {
+ const sliced = sb.slice();
+ if (sliced.len > 0) {
+ native_array[0] = bun.default_allocator.dupeZ(u8, sliced) catch unreachable;
+ any = true;
+ result.ca = native_array;
+ result.ca_count = 1;
+ } else {
+ bun.default_allocator.free(native_array);
}
} else {
- global.throwInvalidArguments("cert argument must be an array containing string, Buffer or TypedArray", .{});
+ JSC.throwInvalidArguments("ca argument must be an string, Buffer, TypedArray, BunFile or an array containing string, Buffer, TypedArray or BunFile", .{}, global, exception);
+ arena.deinit();
+ // mark and free all certs
+ result.ca = native_array;
result.deinit();
return null;
}
+ arena.deinit();
}
+ }
- if (obj.getTruthy(global, "caFile")) |ca_file_name| {
- var sliced = ca_file_name.toSlice(global, bun.default_allocator);
- defer sliced.deinit();
- if (sliced.len > 0) {
- result.ca_file_name = bun.default_allocator.dupeZ(u8, sliced.slice()) catch unreachable;
- if (std.os.system.access(result.ca_file_name, std.os.F_OK) != 0) {
- JSC.throwInvalidArguments("Invalid caFile path", .{}, global, exception);
- result.deinit();
- return null;
- }
+ if (obj.getTruthy(global, "caFile")) |ca_file_name| {
+ var sliced = ca_file_name.toSlice(global, bun.default_allocator);
+ defer sliced.deinit();
+ if (sliced.len > 0) {
+ result.ca_file_name = bun.default_allocator.dupeZ(u8, sliced.slice()) catch unreachable;
+ if (std.os.system.access(result.ca_file_name, std.os.F_OK) != 0) {
+ JSC.throwInvalidArguments("Invalid caFile path", .{}, global, exception);
+ result.deinit();
+ return null;
+ }
+ }
+ }
+ // Optional
+ if (any) {
+ if (obj.getTruthy(global, "secureOptions")) |secure_options| {
+ if (secure_options.isNumber()) {
+ result.secure_options = secure_options.toU32();
}
}
@@ -5142,16 +5296,7 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type {
if (ssl_enabled) {
BoringSSL.load();
const ssl_config = this.config.ssl_config orelse @panic("Assertion failure: ssl_config");
- this.app = App.create(
- .{
- .key_file_name = ssl_config.key_file_name,
- .cert_file_name = ssl_config.cert_file_name,
- .passphrase = ssl_config.passphrase,
- .dh_params_file_name = ssl_config.dh_params_file_name,
- .ca_file_name = ssl_config.ca_file_name,
- .ssl_prefer_low_memory_usage = @as(c_int, @boolToInt(ssl_config.low_memory_mode)),
- },
- );
+ this.app = App.create(ssl_config.asUSockets());
if (ssl_config.server_name != null and std.mem.span(ssl_config.server_name).len > 0) {
this.app.addServerName(ssl_config.server_name);