| ... | @@ -25,9 +25,6 @@ next_https_rescan_certs: bool = true, | ... | @@ -25,9 +25,6 @@ next_https_rescan_certs: bool = true, |
| 25 | /// The pool of connections that can be reused (and currently in use). | 25 | /// The pool of connections that can be reused (and currently in use). |
| 26 | connection_pool: ConnectionPool = .{}, | 26 | connection_pool: ConnectionPool = .{}, |
| 27 | | 27 | |
| 28 | /// The last error that occurred on this client. This is not threadsafe, do not expect it to be completely accurate. | | |
| 29 | last_error: ?ExtraError = null, | | |
| 30 | | | |
| 31 | pub const ExtraError = union(enum) { | 28 | pub const ExtraError = union(enum) { |
| 32 | pub const TcpConnectError = std.net.TcpConnectToHostError; | 29 | pub const TcpConnectError = std.net.TcpConnectToHostError; |
| 33 | pub const TlsError = std.crypto.tls.Client.InitError(net.Stream); | 30 | pub const TlsError = std.crypto.tls.Client.InitError(net.Stream); |
| ... | @@ -184,31 +181,33 @@ pub const Connection = struct { | ... | @@ -184,31 +181,33 @@ pub const Connection = struct { |
| 184 | | 181 | |
| 185 | pub const Protocol = enum { plain, tls }; | 182 | pub const Protocol = enum { plain, tls }; |
| 186 | | 183 | |
| 187 | pub fn read(conn: *Connection, buffer: []u8) !usize { | 184 | pub fn read(conn: *Connection, buffer: []u8) ReadError!usize { |
| 188 | switch (conn.protocol) { | 185 | return switch (conn.protocol) { |
| 189 | .plain => return conn.stream.read(buffer), | 186 | .plain => conn.stream.read(buffer), |
| 190 | .tls => return conn.tls_client.read(conn.stream, buffer), | 187 | .tls => conn.tls_client.read(conn.stream, buffer), |
| 191 | } | 188 | } catch |err| switch (err) { |
| | 189 | error.TlsConnectionTruncated, error.TlsRecordOverflow, error.TlsDecodeError, error.TlsBadRecordMac, error.TlsBadLength, error.TlsIllegalParameter, error.TlsUnexpectedMessage => return error.TlsFailure, |
| | 190 | error.TlsAlert => return error.TlsAlert, |
| | 191 | error.ConnectionTimedOut => return error.ConnectionTimedOut, |
| | 192 | error.ConnectionResetByPeer, error.BrokenPipe => return error.ConnectionResetByPeer, |
| | 193 | else => return error.UnexpectedReadFailure, |
| | 194 | }; |
| 192 | } | 195 | } |
| 193 | | 196 | |
| 194 | pub fn readAtLeast(conn: *Connection, buffer: []u8, len: usize) !usize { | 197 | pub fn readAtLeast(conn: *Connection, buffer: []u8, len: usize) ReadError!usize { |
| 195 | switch (conn.protocol) { | 198 | return switch (conn.protocol) { |
| 196 | .plain => return conn.stream.readAtLeast(buffer, len), | 199 | .plain => conn.stream.readAtLeast(buffer, len), |
| 197 | .tls => return conn.tls_client.readAtLeast(conn.stream, buffer, len), | 200 | .tls => conn.tls_client.readAtLeast(conn.stream, buffer, len), |
| 198 | } | 201 | } catch |err| switch (err) { |
| | 202 | error.TlsConnectionTruncated, error.TlsRecordOverflow, error.TlsDecodeError, error.TlsBadRecordMac, error.TlsBadLength, error.TlsIllegalParameter, error.TlsUnexpectedMessage => return error.TlsFailure, |
| | 203 | error.TlsAlert => return error.TlsAlert, |
| | 204 | error.ConnectionTimedOut => return error.ConnectionTimedOut, |
| | 205 | error.ConnectionResetByPeer, error.BrokenPipe => return error.ConnectionResetByPeer, |
| | 206 | else => return error.UnexpectedReadFailure, |
| | 207 | }; |
| 199 | } | 208 | } |
| 200 | | 209 | |
| 201 | pub const ReadError = net.Stream.ReadError || error{ | 210 | pub const ReadError = error{ TlsFailure, TlsAlert, ConnectionTimedOut, ConnectionResetByPeer, UnexpectedReadFailure }; |
| 202 | TlsConnectionTruncated, | | |
| 203 | TlsRecordOverflow, | | |
| 204 | TlsDecodeError, | | |
| 205 | TlsAlert, | | |
| 206 | TlsBadRecordMac, | | |
| 207 | Overflow, | | |
| 208 | TlsBadLength, | | |
| 209 | TlsIllegalParameter, | | |
| 210 | TlsUnexpectedMessage, | | |
| 211 | }; | | |
| 212 | | 211 | |
| 213 | pub const Reader = std.io.Reader(*Connection, ReadError, read); | 212 | pub const Reader = std.io.Reader(*Connection, ReadError, read); |
| 214 | | 213 | |
| ... | @@ -217,20 +216,30 @@ pub const Connection = struct { | ... | @@ -217,20 +216,30 @@ pub const Connection = struct { |
| 217 | } | 216 | } |
| 218 | | 217 | |
| 219 | pub fn writeAll(conn: *Connection, buffer: []const u8) !void { | 218 | pub fn writeAll(conn: *Connection, buffer: []const u8) !void { |
| 220 | switch (conn.protocol) { | 219 | return switch (conn.protocol) { |
| 221 | .plain => return conn.stream.writeAll(buffer), | 220 | .plain => conn.stream.writeAll(buffer), |
| 222 | .tls => return conn.tls_client.writeAll(conn.stream, buffer), | 221 | .tls => conn.tls_client.writeAll(conn.stream, buffer), |
| 223 | } | 222 | } catch |err| switch (err) { |
| | 223 | error.BrokenPipe, error.ConnectionResetByPeer => return error.ConnectionResetByPeer, |
| | 224 | else => return error.UnexpectedWriteFailure, |
| | 225 | }; |
| 224 | } | 226 | } |
| 225 | | 227 | |
| 226 | pub fn write(conn: *Connection, buffer: []const u8) !usize { | 228 | pub fn write(conn: *Connection, buffer: []const u8) !usize { |
| 227 | switch (conn.protocol) { | 229 | return switch (conn.protocol) { |
| 228 | .plain => return conn.stream.write(buffer), | 230 | .plain => conn.stream.write(buffer), |
| 229 | .tls => return conn.tls_client.write(conn.stream, buffer), | 231 | .tls => conn.tls_client.write(conn.stream, buffer), |
| 230 | } | 232 | } catch |err| switch (err) { |
| | 233 | error.BrokenPipe, error.ConnectionResetByPeer => return error.ConnectionResetByPeer, |
| | 234 | else => return error.UnexpectedWriteFailure, |
| | 235 | }; |
| 231 | } | 236 | } |
| 232 | | 237 | |
| 233 | pub const WriteError = net.Stream.WriteError || error{}; | 238 | pub const WriteError = error{ |
| | 239 | ConnectionResetByPeer, |
| | 240 | UnexpectedWriteFailure, |
| | 241 | }; |
| | 242 | |
| 234 | pub const Writer = std.io.Writer(*Connection, WriteError, write); | 243 | pub const Writer = std.io.Writer(*Connection, WriteError, write); |
| 235 | | 244 | |
| 236 | pub fn writer(conn: *Connection) Writer { | 245 | pub fn writer(conn: *Connection) Writer { |
| ... | @@ -604,7 +613,7 @@ pub const Request = struct { | ... | @@ -604,7 +613,7 @@ pub const Request = struct { |
| 604 | try buffered.flush(); | 613 | try buffered.flush(); |
| 605 | } | 614 | } |
| 606 | | 615 | |
| 607 | pub const TransferReadError = proto.HeadersParser.ReadError || error{ReadFailed}; | 616 | pub const TransferReadError = BufferedConnection.ReadError || proto.HeadersParser.ReadError; |
| 608 | | 617 | |
| 609 | pub const TransferReader = std.io.Reader(*Request, TransferReadError, transferRead); | 618 | pub const TransferReader = std.io.Reader(*Request, TransferReadError, transferRead); |
| 610 | | 619 | |
| ... | @@ -617,10 +626,7 @@ pub const Request = struct { | ... | @@ -617,10 +626,7 @@ pub const Request = struct { |
| 617 | | 626 | |
| 618 | var index: usize = 0; | 627 | var index: usize = 0; |
| 619 | while (index == 0) { | 628 | while (index == 0) { |
| 620 | const amt = req.response.parser.read(&req.connection.data.buffered, buf[index..], req.response.skip) catch |err| { | 629 | const amt = try req.response.parser.read(&req.connection.data.buffered, buf[index..], req.response.skip); |
| 621 | req.client.last_error = .{ .read = err }; | | |
| 622 | return error.ReadFailed; | | |
| 623 | }; | | |
| 624 | if (amt == 0 and req.response.parser.done) break; | 630 | if (amt == 0 and req.response.parser.done) break; |
| 625 | index += amt; | 631 | index += amt; |
| 626 | } | 632 | } |
| ... | @@ -638,10 +644,7 @@ pub const Request = struct { | ... | @@ -638,10 +644,7 @@ pub const Request = struct { |
| 638 | pub fn do(req: *Request) DoError!void { | 644 | pub fn do(req: *Request) DoError!void { |
| 639 | while (true) { // handle redirects | 645 | while (true) { // handle redirects |
| 640 | while (true) { // read headers | 646 | while (true) { // read headers |
| 641 | req.connection.data.buffered.fill() catch |err| { | 647 | try req.connection.data.buffered.fill(); |
| 642 | req.client.last_error = .{ .read = err }; | | |
| 643 | return error.ReadFailed; | | |
| 644 | }; | | |
| 645 | | 648 | |
| 646 | const nchecked = try req.response.parser.checkCompleteHead(req.client.allocator, req.connection.data.buffered.peek()); | 649 | const nchecked = try req.response.parser.checkCompleteHead(req.client.allocator, req.connection.data.buffered.peek()); |
| 647 | req.connection.data.buffered.clear(@intCast(u16, nchecked)); | 650 | req.connection.data.buffered.clear(@intCast(u16, nchecked)); |
| ... | @@ -712,16 +715,10 @@ pub const Request = struct { | ... | @@ -712,16 +715,10 @@ pub const Request = struct { |
| 712 | if (req.response.headers.transfer_compression) |tc| switch (tc) { | 715 | if (req.response.headers.transfer_compression) |tc| switch (tc) { |
| 713 | .compress => return error.CompressionNotSupported, | 716 | .compress => return error.CompressionNotSupported, |
| 714 | .deflate => req.response.compression = .{ | 717 | .deflate => req.response.compression = .{ |
| 715 | .deflate = std.compress.zlib.zlibStream(req.client.allocator, req.transferReader()) catch |err| { | 718 | .deflate = std.compress.zlib.zlibStream(req.client.allocator, req.transferReader()) catch return error.CompressionInitializationFailed, |
| 716 | req.client.last_error = .{ .zlib_init = err }; | | |
| 717 | return error.CompressionInitializationFailed; | | |
| 718 | }, | | |
| 719 | }, | 719 | }, |
| 720 | .gzip => req.response.compression = .{ | 720 | .gzip => req.response.compression = .{ |
| 721 | .gzip = std.compress.gzip.decompress(req.client.allocator, req.transferReader()) catch |err| { | 721 | .gzip = std.compress.gzip.decompress(req.client.allocator, req.transferReader()) catch return error.CompressionInitializationFailed, |
| 722 | req.client.last_error = .{ .gzip_init = err }; | | |
| 723 | return error.CompressionInitializationFailed; | | |
| 724 | }, | | |
| 725 | }, | 722 | }, |
| 726 | .zstd => req.response.compression = .{ | 723 | .zstd => req.response.compression = .{ |
| 727 | .zstd = std.compress.zstd.decompressStream(req.client.allocator, req.transferReader()), | 724 | .zstd = std.compress.zstd.decompressStream(req.client.allocator, req.transferReader()), |
| ... | @@ -734,7 +731,7 @@ pub const Request = struct { | ... | @@ -734,7 +731,7 @@ pub const Request = struct { |
| 734 | } | 731 | } |
| 735 | } | 732 | } |
| 736 | | 733 | |
| 737 | pub const ReadError = TransferReadError || proto.HeadersParser.CheckCompleteHeadError; | 734 | pub const ReadError = TransferReadError || proto.HeadersParser.CheckCompleteHeadError || error{DecompressionFailure}; |
| 738 | | 735 | |
| 739 | pub const Reader = std.io.Reader(*Request, ReadError, read); | 736 | pub const Reader = std.io.Reader(*Request, ReadError, read); |
| 740 | | 737 | |
| ... | @@ -746,30 +743,15 @@ pub const Request = struct { | ... | @@ -746,30 +743,15 @@ pub const Request = struct { |
| 746 | pub fn read(req: *Request, buffer: []u8) ReadError!usize { | 743 | pub fn read(req: *Request, buffer: []u8) ReadError!usize { |
| 747 | while (true) { | 744 | while (true) { |
| 748 | const out_index = switch (req.response.compression) { | 745 | const out_index = switch (req.response.compression) { |
| 749 | .deflate => |*deflate| deflate.read(buffer) catch |err| { | 746 | .deflate => |*deflate| deflate.read(buffer) catch return error.DecompressionFailure, |
| 750 | req.client.last_error = .{ .decompress = err }; | 747 | .gzip => |*gzip| gzip.read(buffer) catch return error.DecompressionFailure, |
| 751 | err catch {}; | 748 | .zstd => |*zstd| zstd.read(buffer) catch return error.DecompressionFailure, |
| 752 | return error.ReadFailed; | | |
| 753 | }, | | |
| 754 | .gzip => |*gzip| gzip.read(buffer) catch |err| { | | |
| 755 | req.client.last_error = .{ .decompress = err }; | | |
| 756 | err catch {}; | | |
| 757 | return error.ReadFailed; | | |
| 758 | }, | | |
| 759 | .zstd => |*zstd| zstd.read(buffer) catch |err| { | | |
| 760 | req.client.last_error = .{ .decompress = err }; | | |
| 761 | err catch {}; | | |
| 762 | return error.ReadFailed; | | |
| 763 | }, | | |
| 764 | else => try req.transferRead(buffer), | 749 | else => try req.transferRead(buffer), |
| 765 | }; | 750 | }; |
| 766 | | 751 | |
| 767 | if (out_index == 0) { | 752 | if (out_index == 0) { |
| 768 | while (!req.response.parser.state.isContent()) { // read trailing headers | 753 | while (!req.response.parser.state.isContent()) { // read trailing headers |
| 769 | req.connection.data.buffered.fill() catch |err| { | 754 | try req.connection.data.buffered.fill(); |
| 770 | req.client.last_error = .{ .read = err }; | | |
| 771 | return error.ReadFailed; | | |
| 772 | }; | | |
| 773 | | 755 | |
| 774 | const nchecked = try req.response.parser.checkCompleteHead(req.client.allocator, req.connection.data.buffered.peek()); | 756 | const nchecked = try req.response.parser.checkCompleteHead(req.client.allocator, req.connection.data.buffered.peek()); |
| 775 | req.connection.data.buffered.clear(@intCast(u16, nchecked)); | 757 | req.connection.data.buffered.clear(@intCast(u16, nchecked)); |
| ... | @@ -784,17 +766,14 @@ pub const Request = struct { | ... | @@ -784,17 +766,14 @@ pub const Request = struct { |
| 784 | pub fn readAll(req: *Request, buffer: []u8) !usize { | 766 | pub fn readAll(req: *Request, buffer: []u8) !usize { |
| 785 | var index: usize = 0; | 767 | var index: usize = 0; |
| 786 | while (index < buffer.len) { | 768 | while (index < buffer.len) { |
| 787 | const amt = read(req, buffer[index..]) catch |err| { | 769 | const amt = try read(req, buffer[index..]); |
| 788 | req.client.last_error = .{ .read = err }; | | |
| 789 | return error.ReadFailed; | | |
| 790 | }; | | |
| 791 | if (amt == 0) break; | 770 | if (amt == 0) break; |
| 792 | index += amt; | 771 | index += amt; |
| 793 | } | 772 | } |
| 794 | return index; | 773 | return index; |
| 795 | } | 774 | } |
| 796 | | 775 | |
| 797 | pub const WriteError = error{ WriteFailed, NotWriteable, MessageTooLong }; | 776 | pub const WriteError = BufferedConnection.WriteError || error{ NotWriteable, MessageTooLong }; |
| 798 | | 777 | |
| 799 | pub const Writer = std.io.Writer(*Request, WriteError, write); | 778 | pub const Writer = std.io.Writer(*Request, WriteError, write); |
| 800 | | 779 | |
| ... | @@ -806,28 +785,16 @@ pub const Request = struct { | ... | @@ -806,28 +785,16 @@ pub const Request = struct { |
| 806 | pub fn write(req: *Request, bytes: []const u8) WriteError!usize { | 785 | pub fn write(req: *Request, bytes: []const u8) WriteError!usize { |
| 807 | switch (req.headers.transfer_encoding) { | 786 | switch (req.headers.transfer_encoding) { |
| 808 | .chunked => { | 787 | .chunked => { |
| 809 | req.connection.data.conn.writer().print("{x}\r\n", .{bytes.len}) catch |err| { | 788 | try req.connection.data.conn.writer().print("{x}\r\n", .{bytes.len}); |
| 810 | req.client.last_error = .{ .write = err }; | 789 | try req.connection.data.conn.writeAll(bytes); |
| 811 | return error.WriteFailed; | 790 | try req.connection.data.conn.writeAll("\r\n"); |
| 812 | }; | | |
| 813 | req.connection.data.conn.writeAll(bytes) catch |err| { | | |
| 814 | req.client.last_error = .{ .write = err }; | | |
| 815 | return error.WriteFailed; | | |
| 816 | }; | | |
| 817 | req.connection.data.conn.writeAll("\r\n") catch |err| { | | |
| 818 | req.client.last_error = .{ .write = err }; | | |
| 819 | return error.WriteFailed; | | |
| 820 | }; | | |
| 821 | | 791 | |
| 822 | return bytes.len; | 792 | return bytes.len; |
| 823 | }, | 793 | }, |
| 824 | .content_length => |*len| { | 794 | .content_length => |*len| { |
| 825 | if (len.* < bytes.len) return error.MessageTooLong; | 795 | if (len.* < bytes.len) return error.MessageTooLong; |
| 826 | | 796 | |
| 827 | const amt = req.connection.data.conn.write(bytes) catch |err| { | 797 | const amt = try req.connection.data.conn.write(bytes); |
| 828 | req.client.last_error = .{ .write = err }; | | |
| 829 | return error.WriteFailed; | | |
| 830 | }; | | |
| 831 | len.* -= amt; | 798 | len.* -= amt; |
| 832 | return amt; | 799 | return amt; |
| 833 | }, | 800 | }, |
| ... | @@ -835,8 +802,10 @@ pub const Request = struct { | ... | @@ -835,8 +802,10 @@ pub const Request = struct { |
| 835 | } | 802 | } |
| 836 | } | 803 | } |
| 837 | | 804 | |
| | 805 | pub const FinishError = WriteError || error{ MessageNotCompleted }; |
| | 806 | |
| 838 | /// Finish the body of a request. This notifies the server that you have no more data to send. | 807 | /// Finish the body of a request. This notifies the server that you have no more data to send. |
| 839 | pub fn finish(req: *Request) !void { | 808 | pub fn finish(req: *Request) FinishError!void { |
| 840 | switch (req.headers.transfer_encoding) { | 809 | switch (req.headers.transfer_encoding) { |
| 841 | .chunked => req.connection.data.conn.writeAll("0\r\n\r\n") catch |err| { | 810 | .chunked => req.connection.data.conn.writeAll("0\r\n\r\n") catch |err| { |
| 842 | req.client.last_error = .{ .write = err }; | 811 | req.client.last_error = .{ .write = err }; |
| ... | @@ -857,7 +826,7 @@ pub fn deinit(client: *Client) void { | ... | @@ -857,7 +826,7 @@ pub fn deinit(client: *Client) void { |
| 857 | client.* = undefined; | 826 | client.* = undefined; |
| 858 | } | 827 | } |
| 859 | | 828 | |
| 860 | pub const ConnectError = Allocator.Error || error{ ConnectionFailed, TlsInitializationFailed }; | 829 | pub const ConnectError = Allocator.Error || error{ ConnectionRefused, NetworkUnreachable, ConnectionTimedOut, ConnectionResetByPeer, TemporaryNameServerFailure, NameServerFailure, UnknownHostName, HostLacksNetworkAddresses, UnexpectedConnectFailure, TlsInitializationFailed }; |
| 861 | | 830 | |
| 862 | /// Connect to `host:port` using the specified protocol. This will reuse a connection if one is already open. | 831 | /// Connect to `host:port` using the specified protocol. This will reuse a connection if one is already open. |
| 863 | /// This function is threadsafe. | 832 | /// This function is threadsafe. |
| ... | @@ -873,9 +842,16 @@ pub fn connect(client: *Client, host: []const u8, port: u16, protocol: Connectio | ... | @@ -873,9 +842,16 @@ pub fn connect(client: *Client, host: []const u8, port: u16, protocol: Connectio |
| 873 | errdefer client.allocator.destroy(conn); | 842 | errdefer client.allocator.destroy(conn); |
| 874 | conn.* = .{ .data = undefined }; | 843 | conn.* = .{ .data = undefined }; |
| 875 | | 844 | |
| 876 | const stream = net.tcpConnectToHost(client.allocator, host, port) catch |err| { | 845 | const stream = net.tcpConnectToHost(client.allocator, host, port) catch |err| switch (err) { |
| 877 | client.last_error = .{ .connect = err }; | 846 | error.ConnectionRefused => return error.ConnectionRefused, |
| 878 | return error.ConnectionFailed; | 847 | error.NetworkUnreachable => return error.NetworkUnreachable, |
| | 848 | error.ConnectionTimedOut => return error.ConnectionTimedOut, |
| | 849 | error.ConnectionResetByPeer => return error.ConnectionResetByPeer, |
| | 850 | error.TemporaryNameServerFailure => return error.TemporaryNameServerFailure, |
| | 851 | error.NameServerFailure => return error.NameServerFailure, |
| | 852 | error.UnknownHostName => return error.UnknownHostName, |
| | 853 | error.HostLacksNetworkAddresses => return error.HostLacksNetworkAddresses, |
| | 854 | else => return error.UnexpectedConnectFailure, |
| 879 | }; | 855 | }; |
| 880 | errdefer stream.close(); | 856 | errdefer stream.close(); |
| 881 | | 857 | |
| ... | @@ -896,10 +872,7 @@ pub fn connect(client: *Client, host: []const u8, port: u16, protocol: Connectio | ... | @@ -896,10 +872,7 @@ pub fn connect(client: *Client, host: []const u8, port: u16, protocol: Connectio |
| 896 | conn.data.buffered.conn.tls_client = try client.allocator.create(std.crypto.tls.Client); | 872 | conn.data.buffered.conn.tls_client = try client.allocator.create(std.crypto.tls.Client); |
| 897 | errdefer client.allocator.destroy(conn.data.buffered.conn.tls_client); | 873 | errdefer client.allocator.destroy(conn.data.buffered.conn.tls_client); |
| 898 | | 874 | |
| 899 | conn.data.buffered.conn.tls_client.* = std.crypto.tls.Client.init(stream, client.ca_bundle, host) catch |err| { | 875 | conn.data.buffered.conn.tls_client.* = std.crypto.tls.Client.init(stream, client.ca_bundle, host) catch return error.TlsInitializationFailed; |
| 900 | client.last_error = .{ .tls = err }; | | |
| 901 | return error.TlsInitializationFailed; | | |
| 902 | }; | | |
| 903 | // This is appropriate for HTTPS because the HTTP headers contain | 876 | // This is appropriate for HTTPS because the HTTP headers contain |
| 904 | // the content length which is used to detect truncation attacks. | 877 | // the content length which is used to detect truncation attacks. |
| 905 | conn.data.buffered.conn.tls_client.allow_truncation_attacks = true; | 878 | conn.data.buffered.conn.tls_client.allow_truncation_attacks = true; |
| ... | @@ -911,12 +884,11 @@ pub fn connect(client: *Client, host: []const u8, port: u16, protocol: Connectio | ... | @@ -911,12 +884,11 @@ pub fn connect(client: *Client, host: []const u8, port: u16, protocol: Connectio |
| 911 | return conn; | 884 | return conn; |
| 912 | } | 885 | } |
| 913 | | 886 | |
| 914 | pub const RequestError = ConnectError || error{ | 887 | pub const RequestError = ConnectError || BufferedConnection.WriteError || error{ |
| 915 | UnsupportedUrlScheme, | 888 | UnsupportedUrlScheme, |
| 916 | UriMissingHost, | 889 | UriMissingHost, |
| 917 | | 890 | |
| 918 | CertificateAuthorityBundleFailed, | 891 | CertificateBundleLoadFailure, |
| 919 | WriteFailed, | | |
| 920 | }; | 892 | }; |
| 921 | | 893 | |
| 922 | pub const Options = struct { | 894 | pub const Options = struct { |
| ... | @@ -962,10 +934,7 @@ pub fn request(client: *Client, uri: Uri, headers: Request.Headers, options: Opt | ... | @@ -962,10 +934,7 @@ pub fn request(client: *Client, uri: Uri, headers: Request.Headers, options: Opt |
| 962 | defer client.ca_bundle_mutex.unlock(); | 934 | defer client.ca_bundle_mutex.unlock(); |
| 963 | | 935 | |
| 964 | if (client.next_https_rescan_certs) { | 936 | if (client.next_https_rescan_certs) { |
| 965 | client.ca_bundle.rescan(client.allocator) catch |err| { | 937 | client.ca_bundle.rescan(client.allocator) catch return error.CertificateBundleLoadFailure; |
| 966 | client.last_error = .{ .ca_bundle = err }; | | |
| 967 | return error.CertificateAuthorityBundleFailed; | | |
| 968 | }; | | |
| 969 | @atomicStore(bool, &client.next_https_rescan_certs, false, .Release); | 938 | @atomicStore(bool, &client.next_https_rescan_certs, false, .Release); |
| 970 | } | 939 | } |
| 971 | } | 940 | } |
| ... | @@ -989,13 +958,7 @@ pub fn request(client: *Client, uri: Uri, headers: Request.Headers, options: Opt | ... | @@ -989,13 +958,7 @@ pub fn request(client: *Client, uri: Uri, headers: Request.Headers, options: Opt |
| 989 | | 958 | |
| 990 | req.arena = std.heap.ArenaAllocator.init(client.allocator); | 959 | req.arena = std.heap.ArenaAllocator.init(client.allocator); |
| 991 | | 960 | |
| 992 | req.start(uri, headers) catch |err| { | 961 | try req.start(uri, headers); |
| 993 | if (err == error.OutOfMemory) return error.OutOfMemory; | | |
| 994 | const err_casted = @errSetCast(BufferedConnection.WriteError, err); | | |
| 995 | | | |
| 996 | client.last_error = .{ .write = err_casted }; | | |
| 997 | return error.WriteFailed; | | |
| 998 | }; | | |
| 999 | | 962 | |
| 1000 | return req; | 963 | return req; |
| 1001 | } | 964 | } |