| ... | @@ -218,17 +218,7 @@ pub const Connection = struct { | ... | @@ -218,17 +218,7 @@ pub const Connection = struct { |
| 218 | pub const buffer_size = std.crypto.tls.max_ciphertext_record_len; | 218 | pub const buffer_size = std.crypto.tls.max_ciphertext_record_len; |
| 219 | const BufferSize = std.math.IntFittingRange(0, buffer_size); | 219 | const BufferSize = std.math.IntFittingRange(0, buffer_size); |
| 220 | | 220 | |
| 221 | pub const Protocol = enum { | 221 | pub const Protocol = enum { plain, tls }; |
| 222 | plain, | | |
| 223 | tls, | | |
| 224 | | | |
| 225 | pub fn port(p: Protocol) u16 { | | |
| 226 | return switch (p) { | | |
| 227 | .plain => 80, | | |
| 228 | .tls => 443, | | |
| 229 | }; | | |
| 230 | } | | |
| 231 | }; | | |
| 232 | | 222 | |
| 233 | pub fn readvDirectTls(conn: *Connection, buffers: []std.posix.iovec) ReadError!usize { | 223 | pub fn readvDirectTls(conn: *Connection, buffers: []std.posix.iovec) ReadError!usize { |
| 234 | return conn.tls_client.readv(conn.stream, buffers) catch |err| { | 224 | return conn.tls_client.readv(conn.stream, buffers) catch |err| { |
| ... | @@ -815,7 +805,7 @@ pub const Request = struct { | ... | @@ -815,7 +805,7 @@ pub const Request = struct { |
| 815 | } | 805 | } |
| 816 | | 806 | |
| 817 | req.uri = valid_uri; | 807 | req.uri = valid_uri; |
| 818 | req.connection = try req.client.connect(new_host, valid_uri.port.?, protocol); | 808 | req.connection = try req.client.connect(new_host, uriPort(valid_uri, protocol), protocol); |
| 819 | req.redirect_behavior.subtractOne(); | 809 | req.redirect_behavior.subtractOne(); |
| 820 | req.response.parser.reset(); | 810 | req.response.parser.reset(); |
| 821 | | 811 | |
| ... | @@ -857,13 +847,8 @@ pub const Request = struct { | ... | @@ -857,13 +847,8 @@ pub const Request = struct { |
| 857 | try w.writeAll("\r\n"); | 847 | try w.writeAll("\r\n"); |
| 858 | | 848 | |
| 859 | if (try emitOverridableHeader("host: ", req.headers.host, w)) { | 849 | if (try emitOverridableHeader("host: ", req.headers.host, w)) { |
| 860 | // URI has already been validated so this cannot fail. | | |
| 861 | const default_port = (uriProtocol(req.uri) catch unreachable).port(); | | |
| 862 | try w.writeAll("host: "); | 850 | try w.writeAll("host: "); |
| 863 | try req.uri.writeToStream(.{ | 851 | try req.uri.writeToStream(.{ .authority = true }, w); |
| 864 | .authority = true, | | |
| 865 | .port = req.uri.port.? != default_port, | | |
| 866 | }, w); | | |
| 867 | try w.writeAll("\r\n"); | 852 | try w.writeAll("\r\n"); |
| 868 | } | 853 | } |
| 869 | | 854 | |
| ... | @@ -1279,7 +1264,7 @@ fn createProxyFromEnvVar(arena: Allocator, env_var_names: []const []const u8) !? | ... | @@ -1279,7 +1264,7 @@ fn createProxyFromEnvVar(arena: Allocator, env_var_names: []const []const u8) !? |
| 1279 | .protocol = protocol, | 1264 | .protocol = protocol, |
| 1280 | .host = valid_uri.host.?.raw, | 1265 | .host = valid_uri.host.?.raw, |
| 1281 | .authorization = authorization, | 1266 | .authorization = authorization, |
| 1282 | .port = valid_uri.port.?, | 1267 | .port = uriPort(valid_uri, protocol), |
| 1283 | .supports_connect = true, | 1268 | .supports_connect = true, |
| 1284 | }; | 1269 | }; |
| 1285 | return proxy; | 1270 | return proxy; |
| ... | @@ -1584,27 +1569,29 @@ pub const RequestOptions = struct { | ... | @@ -1584,27 +1569,29 @@ pub const RequestOptions = struct { |
| 1584 | privileged_headers: []const http.Header = &.{}, | 1569 | privileged_headers: []const http.Header = &.{}, |
| 1585 | }; | 1570 | }; |
| 1586 | | 1571 | |
| 1587 | fn uriProtocol(uri: Uri) !Connection.Protocol { | 1572 | fn validateUri(uri: Uri, arena: Allocator) !struct { Connection.Protocol, Uri } { |
| 1588 | const protocol_map = std.ComptimeStringMap(Connection.Protocol, .{ | 1573 | const protocol_map = std.ComptimeStringMap(Connection.Protocol, .{ |
| 1589 | .{ "http", .plain }, | 1574 | .{ "http", .plain }, |
| 1590 | .{ "ws", .plain }, | 1575 | .{ "ws", .plain }, |
| 1591 | .{ "https", .tls }, | 1576 | .{ "https", .tls }, |
| 1592 | .{ "wss", .tls }, | 1577 | .{ "wss", .tls }, |
| 1593 | }); | 1578 | }); |
| 1594 | return protocol_map.get(uri.scheme) orelse return error.UnsupportedUriScheme; | 1579 | const protocol = protocol_map.get(uri.scheme) orelse return error.UnsupportedUriScheme; |
| 1595 | } | | |
| 1596 | | | |
| 1597 | fn validateUri(uri: Uri, arena: Allocator) !struct { Connection.Protocol, Uri } { | | |
| 1598 | const protocol = try uriProtocol(uri); | | |
| 1599 | var valid_uri = uri; | 1580 | var valid_uri = uri; |
| 1600 | // The host is always going to be needed as a raw string for hostname resolution anyway. | 1581 | // The host is always going to be needed as a raw string for hostname resolution anyway. |
| 1601 | valid_uri.host = .{ | 1582 | valid_uri.host = .{ |
| 1602 | .raw = try (uri.host orelse return error.UriMissingHost).toRawMaybeAlloc(arena), | 1583 | .raw = try (uri.host orelse return error.UriMissingHost).toRawMaybeAlloc(arena), |
| 1603 | }; | 1584 | }; |
| 1604 | valid_uri.port = uri.port orelse protocol.port(); | | |
| 1605 | return .{ protocol, valid_uri }; | 1585 | return .{ protocol, valid_uri }; |
| 1606 | } | 1586 | } |
| 1607 | | 1587 | |
| | 1588 | fn uriPort(uri: Uri, protocol: Connection.Protocol) u16 { |
| | 1589 | return uri.port orelse switch (protocol) { |
| | 1590 | .plain => 80, |
| | 1591 | .tls => 443, |
| | 1592 | }; |
| | 1593 | } |
| | 1594 | |
| 1608 | /// Open a connection to the host specified by `uri` and prepare to send a HTTP request. | 1595 | /// Open a connection to the host specified by `uri` and prepare to send a HTTP request. |
| 1609 | /// | 1596 | /// |
| 1610 | /// `uri` must remain alive during the entire request. | 1597 | /// `uri` must remain alive during the entire request. |
| ... | @@ -1650,7 +1637,7 @@ pub fn open( | ... | @@ -1650,7 +1637,7 @@ pub fn open( |
| 1650 | } | 1637 | } |
| 1651 | | 1638 | |
| 1652 | const conn = options.connection orelse | 1639 | const conn = options.connection orelse |
| 1653 | try client.connect(valid_uri.host.?.raw, valid_uri.port.?, protocol); | 1640 | try client.connect(valid_uri.host.?.raw, uriPort(valid_uri, protocol), protocol); |
| 1654 | | 1641 | |
| 1655 | var req: Request = .{ | 1642 | var req: Request = .{ |
| 1656 | .uri = valid_uri, | 1643 | .uri = valid_uri, |