mirror of
https://github.com/ziglang/zig.git
synced 2024-11-26 15:12:31 +00:00
std.http.Client: always omit port when it matches default
This makes the host http header have the port if and only if it differs from the defaults based on the protocol. This is an alternate implementation that closes #19624.
This commit is contained in:
parent
419753f45e
commit
6deb3e3986
@ -242,6 +242,9 @@ pub const WriteToStreamOptions = struct {
|
||||
|
||||
/// When true, include the fragment part of the URI. Ignored when `path` is false.
|
||||
fragment: bool = false,
|
||||
|
||||
/// When true, include the port part of the URI. Ignored when `port` is null.
|
||||
port: bool = true,
|
||||
};
|
||||
|
||||
pub fn writeToStream(
|
||||
@ -267,7 +270,9 @@ pub fn writeToStream(
|
||||
}
|
||||
if (uri.host) |host| {
|
||||
try writer.print("{host}", .{host});
|
||||
if (uri.port) |port| try writer.print(":{d}", .{port});
|
||||
if (options.port) {
|
||||
if (uri.port) |port| try writer.print(":{d}", .{port});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.path) {
|
||||
|
@ -218,7 +218,17 @@ pub const Connection = struct {
|
||||
pub const buffer_size = std.crypto.tls.max_ciphertext_record_len;
|
||||
const BufferSize = std.math.IntFittingRange(0, buffer_size);
|
||||
|
||||
pub const Protocol = enum { plain, tls };
|
||||
pub const Protocol = enum {
|
||||
plain,
|
||||
tls,
|
||||
|
||||
pub fn port(p: Protocol) u16 {
|
||||
return switch (p) {
|
||||
.plain => 80,
|
||||
.tls => 443,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub fn readvDirectTls(conn: *Connection, buffers: []std.posix.iovec) ReadError!usize {
|
||||
return conn.tls_client.readv(conn.stream, buffers) catch |err| {
|
||||
@ -805,7 +815,7 @@ pub const Request = struct {
|
||||
}
|
||||
|
||||
req.uri = valid_uri;
|
||||
req.connection = try req.client.connect(new_host, uriPort(valid_uri, protocol), protocol);
|
||||
req.connection = try req.client.connect(new_host, valid_uri.port.?, protocol);
|
||||
req.redirect_behavior.subtractOne();
|
||||
req.response.parser.reset();
|
||||
|
||||
@ -847,8 +857,13 @@ pub const Request = struct {
|
||||
try w.writeAll("\r\n");
|
||||
|
||||
if (try emitOverridableHeader("host: ", req.headers.host, w)) {
|
||||
// URI has already been validated so this cannot fail.
|
||||
const default_port = (uriProtocol(req.uri) catch unreachable).port();
|
||||
try w.writeAll("host: ");
|
||||
try req.uri.writeToStream(.{ .authority = true }, w);
|
||||
try req.uri.writeToStream(.{
|
||||
.authority = true,
|
||||
.port = req.uri.port.? != default_port,
|
||||
}, w);
|
||||
try w.writeAll("\r\n");
|
||||
}
|
||||
|
||||
@ -1264,7 +1279,7 @@ fn createProxyFromEnvVar(arena: Allocator, env_var_names: []const []const u8) !?
|
||||
.protocol = protocol,
|
||||
.host = valid_uri.host.?.raw,
|
||||
.authorization = authorization,
|
||||
.port = uriPort(valid_uri, protocol),
|
||||
.port = valid_uri.port.?,
|
||||
.supports_connect = true,
|
||||
};
|
||||
return proxy;
|
||||
@ -1569,29 +1584,27 @@ pub const RequestOptions = struct {
|
||||
privileged_headers: []const http.Header = &.{},
|
||||
};
|
||||
|
||||
fn validateUri(uri: Uri, arena: Allocator) !struct { Connection.Protocol, Uri } {
|
||||
fn uriProtocol(uri: Uri) !Connection.Protocol {
|
||||
const protocol_map = std.ComptimeStringMap(Connection.Protocol, .{
|
||||
.{ "http", .plain },
|
||||
.{ "ws", .plain },
|
||||
.{ "https", .tls },
|
||||
.{ "wss", .tls },
|
||||
});
|
||||
const protocol = protocol_map.get(uri.scheme) orelse return error.UnsupportedUriScheme;
|
||||
return protocol_map.get(uri.scheme) orelse return error.UnsupportedUriScheme;
|
||||
}
|
||||
|
||||
fn validateUri(uri: Uri, arena: Allocator) !struct { Connection.Protocol, Uri } {
|
||||
const protocol = try uriProtocol(uri);
|
||||
var valid_uri = uri;
|
||||
// The host is always going to be needed as a raw string for hostname resolution anyway.
|
||||
valid_uri.host = .{
|
||||
.raw = try (uri.host orelse return error.UriMissingHost).toRawMaybeAlloc(arena),
|
||||
};
|
||||
valid_uri.port = uri.port orelse protocol.port();
|
||||
return .{ protocol, valid_uri };
|
||||
}
|
||||
|
||||
fn uriPort(uri: Uri, protocol: Connection.Protocol) u16 {
|
||||
return uri.port orelse switch (protocol) {
|
||||
.plain => 80,
|
||||
.tls => 443,
|
||||
};
|
||||
}
|
||||
|
||||
/// Open a connection to the host specified by `uri` and prepare to send a HTTP request.
|
||||
///
|
||||
/// `uri` must remain alive during the entire request.
|
||||
@ -1637,7 +1650,7 @@ pub fn open(
|
||||
}
|
||||
|
||||
const conn = options.connection orelse
|
||||
try client.connect(valid_uri.host.?.raw, uriPort(valid_uri, protocol), protocol);
|
||||
try client.connect(valid_uri.host.?.raw, valid_uri.port.?, protocol);
|
||||
|
||||
var req: Request = .{
|
||||
.uri = valid_uri,
|
||||
|
Loading…
Reference in New Issue
Block a user