[bun dev] Automatically set origin - improve support for proxying Bun

Previously, when running Bun behind a reverse proxy, you had to pass an explicit `--origin` arg and it could only run behind one proxy at a time.

Now, Bun automatically determines the origin from the request if possible. It reads `Forwarded`, `X-Forwarded-Proto`, `X-Forwarded-Host`, `Origin`, and lastly `Host`. If none are available, it falls back to the `--origin` CLI arg.

This change is important for usecases like Replit which shows multiple iframes in different origins.
This commit is contained in:
Jarred Sumner
2022-01-01 18:12:57 -08:00
parent e4693b8aaf
commit 6a28cfd2ba
8 changed files with 247 additions and 64 deletions

View File

@@ -15,7 +15,11 @@ const C = _global.C;
// This is close to WHATWG URL, but we don't want the validation errors
pub const URL = struct {
hash: string = "",
/// hostname, but with a port
/// `localhost:3000`
host: string = "",
/// hostname does not have a port
/// `localhost`
hostname: string = "",
href: string = "",
origin: string = "",
@@ -86,6 +90,36 @@ pub const URL = struct {
return "localhost";
}
pub const HostFormatter = struct {
host: string,
port: string,
is_https: bool = false,
pub fn format(formatter: HostFormatter, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
if (strings.indexOfChar(formatter.host, ':') != null) {
try writer.writeAll(formatter.host);
return;
}
try writer.writeAll(formatter.host);
const is_port_optional = (formatter.is_https and (formatter.port.len == 0 or strings.eqlComptime(formatter.port, "443"))) or
(!formatter.is_https and (formatter.port.len == 0 or strings.eqlComptime(formatter.port, "80")));
if (!is_port_optional) {
try writer.writeAll(":");
try writer.writeAll(formatter.port);
return;
}
}
};
pub fn displayHost(this: *const URL) HostFormatter {
return HostFormatter{
.host = if (this.host.len > 0) this.host else this.displayHostname(),
.port = this.port,
.is_https = this.isHTTPS(),
};
}
pub fn hasHTTPLikeProtocol(this: *const URL) bool {
return strings.eqlComptime(this.protocol, "http") or strings.eqlComptime(this.protocol, "https");
}