authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-01-30 14:06:53+01:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-01-31 12:05:12+01:00
log82b37ea0240c0e77857149d80beb4dda2b095dbb
treec4e2f561f9d80480f08fce2328f501e2f222b8e0
parentd7a27bf803fd29c499090c7bd0460fae9f0cf0f7

http: support basic access authentication


1 files changed, 34 insertions(+), 24 deletions(-)

lib/std/http/Client.zig+34-24
......@@ -657,7 +657,7 @@ pub const Request = struct {
657657 };
658658 }
659659
660 pub const SendError = Connection.WriteError || error{ InvalidContentLength, UnsupportedTransferEncoding };
660 pub const SendError = Allocator.Error || Connection.WriteError || error{ InvalidContentLength, UnsupportedTransferEncoding };
661661
662662 pub const SendOptions = struct {
663663 /// Specifies that the uri should be used as is. You guarantee that the uri is already escaped.
......@@ -695,6 +695,14 @@ pub const Request = struct {
695695 try w.writeAll("\r\n");
696696 }
697697
698 if ((req.uri.user != null or req.uri.password != null) and
699 !req.headers.contains("authorization"))
700 {
701 try w.writeAll("Authorization: ");
702 try w.writeAll(try basicAuthorizationValue(req.arena.allocator(), req.uri));
703 try w.writeAll("\r\n");
704 }
705
698706 if (!req.headers.contains("user-agent")) {
699707 try w.writeAll("User-Agent: zig/");
700708 try w.writeAll(builtin.zig_version_string);
......@@ -1122,19 +1130,11 @@ pub fn loadDefaultProxies(client: *Client) !void {
11221130 },
11231131 };
11241132
1125 if (uri.user != null and uri.password != null) {
1126 const prefix = "Basic ";
1127
1128 const unencoded = try std.fmt.allocPrint(client.allocator, "{s}:{s}", .{ uri.user.?, uri.password.? });
1129 defer client.allocator.free(unencoded);
1133 if (uri.user != null or uri.password != null) {
1134 const authorization = try basicAuthorizationValue(client.allocator, uri);
1135 defer client.allocator.free(authorization);
11301136
1131 const buffer = try client.allocator.alloc(u8, std.base64.standard.Encoder.calcSize(unencoded.len) + prefix.len);
1132 defer client.allocator.free(buffer);
1133
1134 const result = std.base64.standard.Encoder.encode(buffer[prefix.len..], unencoded);
1135 @memcpy(buffer[0..prefix.len], prefix);
1136
1137 try client.http_proxy.?.headers.append("proxy-authorization", result);
1137 try client.http_proxy.?.headers.append("proxy-authorization", authorization);
11381138 }
11391139 }
11401140
......@@ -1173,21 +1173,31 @@ pub fn loadDefaultProxies(client: *Client) !void {
11731173 },
11741174 };
11751175
1176 if (uri.user != null and uri.password != null) {
1177 const prefix = "Basic ";
1176 if (uri.user != null or uri.password != null) {
1177 const authorization = try basicAuthorizationValue(client.allocator, uri);
1178 defer client.allocator.free(authorization);
11781179
1179 const unencoded = try std.fmt.allocPrint(client.allocator, "{s}:{s}", .{ uri.user.?, uri.password.? });
1180 defer client.allocator.free(unencoded);
1180 try client.https_proxy.?.headers.append("proxy-authorization", authorization);
1181 }
1182 }
1183}
11811184
1182 const buffer = try client.allocator.alloc(u8, std.base64.standard.Encoder.calcSize(unencoded.len) + prefix.len);
1183 defer client.allocator.free(buffer);
1185pub fn basicAuthorizationValue(
1186 allocator: Allocator,
1187 uri: Uri,
1188) Allocator.Error![]const u8 {
1189 const prefix = "Basic ";
11841190
1185 const result = std.base64.standard.Encoder.encode(buffer[prefix.len..], unencoded);
1186 @memcpy(buffer[0..prefix.len], prefix);
1191 const unencoded = try std.fmt.allocPrint(allocator, "{s}:{s}", .{ uri.user orelse "", uri.password orelse "" });
1192 defer allocator.free(unencoded);
11871193
1188 try client.https_proxy.?.headers.append("proxy-authorization", result);
1189 }
1190 }
1194 const buffer = try allocator.alloc(u8, prefix.len + std.base64.standard.Encoder.calcSize(unencoded.len));
1195 errdefer allocator.free(buffer);
1196
1197 @memcpy(buffer[0..prefix.len], prefix);
1198 _ = std.base64.standard.Encoder.encode(buffer[prefix.len..], unencoded);
1199
1200 return buffer;
11911201}
11921202
11931203pub const ConnectTcpError = Allocator.Error || error{ ConnectionRefused, NetworkUnreachable, ConnectionTimedOut, ConnectionResetByPeer, TemporaryNameServerFailure, NameServerFailure, UnknownHostName, HostLacksNetworkAddresses, UnexpectedConnectFailure, TlsInitializationFailed };