aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/api/server.zig
diff options
context:
space:
mode:
authorGravatar Ciro Spaciari <ciro.spaciari@gmail.com> 2023-03-15 18:30:31 -0300
committerGravatar GitHub <noreply@github.com> 2023-03-15 14:30:31 -0700
commitac970146b43db29d0f87024f70d21f332be00feb (patch)
tree65e4ebc99f16c7ec62ac86e3ed18aacd05ab3c18 /src/bun.js/api/server.zig
parentacd361855ab67be451a92b80c38ce8bfc899d275 (diff)
downloadbun-ac970146b43db29d0f87024f70d21f332be00feb.tar.gz
bun-ac970146b43db29d0f87024f70d21f332be00feb.tar.zst
bun-ac970146b43db29d0f87024f70d21f332be00feb.zip
allows Bun.serve to listen on IPV6 (#2400)
Diffstat (limited to 'src/bun.js/api/server.zig')
-rw-r--r--src/bun.js/api/server.zig89
1 files changed, 63 insertions, 26 deletions
diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig
index aae3be914..113432942 100644
--- a/src/bun.js/api/server.zig
+++ b/src/bun.js/api/server.zig
@@ -428,35 +428,64 @@ pub const ServerConfig = struct {
if (args.base_url.protocol.len == 0) {
const protocol: string = if (args.ssl_config != null) "https" else "http";
-
- args.base_uri = (if ((args.port == 80 and args.ssl_config == null) or (args.port == 443 and args.ssl_config != null))
- std.fmt.allocPrint(bun.default_allocator, "{s}://{s}/{s}", .{
- protocol,
- args.base_url.hostname,
- strings.trimLeadingChar(args.base_url.pathname, '/'),
- })
- else
- std.fmt.allocPrint(bun.default_allocator, "{s}://{s}:{d}/{s}", .{
- protocol,
- args.base_url.hostname,
- args.port,
- strings.trimLeadingChar(args.base_url.pathname, '/'),
- })) catch unreachable;
+ const hostname = args.base_url.hostname;
+ const needsBrackets: bool = strings.isIPV6Address(hostname) and hostname[0] != '[';
+ if (needsBrackets) {
+ args.base_uri = (if ((args.port == 80 and args.ssl_config == null) or (args.port == 443 and args.ssl_config != null))
+ std.fmt.allocPrint(bun.default_allocator, "{s}://[{s}]/{s}", .{
+ protocol,
+ hostname,
+ strings.trimLeadingChar(args.base_url.pathname, '/'),
+ })
+ else
+ std.fmt.allocPrint(bun.default_allocator, "{s}://[{s}]:{d}/{s}", .{
+ protocol,
+ hostname,
+ args.port,
+ strings.trimLeadingChar(args.base_url.pathname, '/'),
+ })) catch unreachable;
+ } else {
+ args.base_uri = (if ((args.port == 80 and args.ssl_config == null) or (args.port == 443 and args.ssl_config != null))
+ std.fmt.allocPrint(bun.default_allocator, "{s}://{s}/{s}", .{
+ protocol,
+ hostname,
+ strings.trimLeadingChar(args.base_url.pathname, '/'),
+ })
+ else
+ std.fmt.allocPrint(bun.default_allocator, "{s}://{s}:{d}/{s}", .{
+ protocol,
+ hostname,
+ args.port,
+ strings.trimLeadingChar(args.base_url.pathname, '/'),
+ })) catch unreachable;
+ }
args.base_url = URL.parse(args.base_uri);
}
} else {
const hostname: string =
if (has_hostname and std.mem.span(args.hostname).len > 0) std.mem.span(args.hostname) else "0.0.0.0";
- const protocol: string = if (args.ssl_config != null) "https" else "http";
- args.base_uri = (if ((args.port == 80 and args.ssl_config == null) or (args.port == 443 and args.ssl_config != null))
- std.fmt.allocPrint(bun.default_allocator, "{s}://{s}/", .{
- protocol,
- hostname,
- })
- else
- std.fmt.allocPrint(bun.default_allocator, "{s}://{s}:{d}/", .{ protocol, hostname, args.port })) catch unreachable;
+ const needsBrackets: bool = strings.isIPV6Address(hostname) and hostname[0] != '[';
+
+ const protocol: string = if (args.ssl_config != null) "https" else "http";
+ if (needsBrackets) {
+ args.base_uri = (if ((args.port == 80 and args.ssl_config == null) or (args.port == 443 and args.ssl_config != null))
+ std.fmt.allocPrint(bun.default_allocator, "{s}://[{s}]/", .{
+ protocol,
+ hostname,
+ })
+ else
+ std.fmt.allocPrint(bun.default_allocator, "{s}://[{s}]:{d}/", .{ protocol, hostname, args.port })) catch unreachable;
+ } else {
+ args.base_uri = (if ((args.port == 80 and args.ssl_config == null) or (args.port == 443 and args.ssl_config != null))
+ std.fmt.allocPrint(bun.default_allocator, "{s}://{s}/", .{
+ protocol,
+ hostname,
+ })
+ else
+ std.fmt.allocPrint(bun.default_allocator, "{s}://{s}:{d}/", .{ protocol, hostname, args.port })) catch unreachable;
+ }
if (!strings.isAllASCII(hostname)) {
JSC.throwInvalidArguments("Unicode hostnames must already be encoded for now.\nnew URL(input).hostname should do the trick.", .{}, global, exception);
@@ -4856,13 +4885,21 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type {
}
const hostname = bun.span(this.config.hostname);
+
// When "localhost" is specified, we omit the hostname entirely
// Otherwise, "curl http://localhost:3000" doesn't actually work due to IPV6 vs IPV4 issues
// This prints a spurious log si_destination_compare on macOS but only when debugger is connected
- const host: [*:0]const u8 = if (hostname.len == 0 or (!ssl_enabled and strings.eqlComptime(hostname, "localhost")))
- ""
- else
- this.config.hostname;
+ var host: [*:0]const u8 = undefined;
+ var host_buff: [1024:0]u8 = undefined;
+
+ if (hostname.len == 0 or (!ssl_enabled and strings.eqlComptime(hostname, "localhost"))) {
+ host = "";
+ } else if (hostname.len > 2 and hostname[0] == '[') {
+ // remove "[" and "]" from hostname
+ host = std.fmt.bufPrintZ(&host_buff, "{s}", .{hostname[1 .. hostname.len - 1]}) catch unreachable;
+ } else {
+ host = this.config.hostname;
+ }
this.ref();