| ... | @@ -13,8 +13,8 @@ const net = std.net; | ... | @@ -13,8 +13,8 @@ const net = std.net; |
| 13 | const Uri = std.Uri; | 13 | const Uri = std.Uri; |
| 14 | const Allocator = mem.Allocator; | 14 | const Allocator = mem.Allocator; |
| 15 | const assert = std.debug.assert; | 15 | const assert = std.debug.assert; |
| 16 | const Writer = std.io.Writer; | 16 | const Writer = std.Io.Writer; |
| 17 | const Reader = std.io.Reader; | 17 | const Reader = std.Io.Reader; |
| 18 | | 18 | |
| 19 | const Client = @This(); | 19 | const Client = @This(); |
| 20 | | 20 | |
| ... | @@ -704,12 +704,12 @@ pub const Response = struct { | ... | @@ -704,12 +704,12 @@ pub const Response = struct { |
| 704 | /// | 704 | /// |
| 705 | /// See also: | 705 | /// See also: |
| 706 | /// * `readerDecompressing` | 706 | /// * `readerDecompressing` |
| 707 | pub fn reader(response: *Response, buffer: []u8) *Reader { | 707 | pub fn reader(response: *Response, transfer_buffer: []u8) *Reader { |
| 708 | response.head.invalidateStrings(); | 708 | response.head.invalidateStrings(); |
| 709 | const req = response.request; | 709 | const req = response.request; |
| 710 | if (!req.method.responseHasBody()) return .ending; | 710 | if (!req.method.responseHasBody()) return .ending; |
| 711 | const head = &response.head; | 711 | const head = &response.head; |
| 712 | return req.reader.bodyReader(buffer, head.transfer_encoding, head.content_length); | 712 | return req.reader.bodyReader(transfer_buffer, head.transfer_encoding, head.content_length); |
| 713 | } | 713 | } |
| 714 | | 714 | |
| 715 | /// If compressed body has been negotiated this will return decompressed bytes. | 715 | /// If compressed body has been negotiated this will return decompressed bytes. |
| ... | @@ -723,12 +723,14 @@ pub const Response = struct { | ... | @@ -723,12 +723,14 @@ pub const Response = struct { |
| 723 | /// * `reader` | 723 | /// * `reader` |
| 724 | pub fn readerDecompressing( | 724 | pub fn readerDecompressing( |
| 725 | response: *Response, | 725 | response: *Response, |
| | 726 | transfer_buffer: []u8, |
| 726 | decompressor: *http.Decompressor, | 727 | decompressor: *http.Decompressor, |
| 727 | decompression_buffer: []u8, | 728 | decompression_buffer: []u8, |
| 728 | ) *Reader { | 729 | ) *Reader { |
| 729 | response.head.invalidateStrings(); | 730 | response.head.invalidateStrings(); |
| 730 | const head = &response.head; | 731 | const head = &response.head; |
| 731 | return response.request.reader.bodyReaderDecompressing( | 732 | return response.request.reader.bodyReaderDecompressing( |
| | 733 | transfer_buffer, |
| 732 | head.transfer_encoding, | 734 | head.transfer_encoding, |
| 733 | head.content_length, | 735 | head.content_length, |
| 734 | head.content_encoding, | 736 | head.content_encoding, |
| ... | @@ -1322,7 +1324,7 @@ pub const basic_authorization = struct { | ... | @@ -1322,7 +1324,7 @@ pub const basic_authorization = struct { |
| 1322 | const user: Uri.Component = uri.user orelse .empty; | 1324 | const user: Uri.Component = uri.user orelse .empty; |
| 1323 | const password: Uri.Component = uri.password orelse .empty; | 1325 | const password: Uri.Component = uri.password orelse .empty; |
| 1324 | | 1326 | |
| 1325 | var dw: std.io.Writer.Discarding = .init(&.{}); | 1327 | var dw: Writer.Discarding = .init(&.{}); |
| 1326 | user.formatUser(&dw.writer) catch unreachable; // discarding | 1328 | user.formatUser(&dw.writer) catch unreachable; // discarding |
| 1327 | const user_len = dw.count + dw.writer.end; | 1329 | const user_len = dw.count + dw.writer.end; |
| 1328 | | 1330 | |
| ... | @@ -1696,8 +1698,8 @@ pub const FetchOptions = struct { | ... | @@ -1696,8 +1698,8 @@ pub const FetchOptions = struct { |
| 1696 | /// `null` means it will be heap-allocated. | 1698 | /// `null` means it will be heap-allocated. |
| 1697 | decompress_buffer: ?[]u8 = null, | 1699 | decompress_buffer: ?[]u8 = null, |
| 1698 | redirect_behavior: ?Request.RedirectBehavior = null, | 1700 | redirect_behavior: ?Request.RedirectBehavior = null, |
| 1699 | /// If the server sends a body, it will be stored here. | 1701 | /// If the server sends a body, it will be written here. |
| 1700 | response_storage: ?ResponseStorage = null, | 1702 | response_writer: ?*Writer = null, |
| 1701 | | 1703 | |
| 1702 | location: Location, | 1704 | location: Location, |
| 1703 | method: ?http.Method = null, | 1705 | method: ?http.Method = null, |
| ... | @@ -1725,7 +1727,7 @@ pub const FetchOptions = struct { | ... | @@ -1725,7 +1727,7 @@ pub const FetchOptions = struct { |
| 1725 | list: *std.ArrayListUnmanaged(u8), | 1727 | list: *std.ArrayListUnmanaged(u8), |
| 1726 | /// If null then only the existing capacity will be used. | 1728 | /// If null then only the existing capacity will be used. |
| 1727 | allocator: ?Allocator = null, | 1729 | allocator: ?Allocator = null, |
| 1728 | append_limit: std.io.Limit = .unlimited, | 1730 | append_limit: std.Io.Limit = .unlimited, |
| 1729 | }; | 1731 | }; |
| 1730 | }; | 1732 | }; |
| 1731 | | 1733 | |
| ... | @@ -1778,7 +1780,7 @@ pub fn fetch(client: *Client, options: FetchOptions) FetchError!FetchResult { | ... | @@ -1778,7 +1780,7 @@ pub fn fetch(client: *Client, options: FetchOptions) FetchError!FetchResult { |
| 1778 | | 1780 | |
| 1779 | var response = try req.receiveHead(redirect_buffer); | 1781 | var response = try req.receiveHead(redirect_buffer); |
| 1780 | | 1782 | |
| 1781 | const storage = options.response_storage orelse { | 1783 | const response_writer = options.response_writer orelse { |
| 1782 | const reader = response.reader(&.{}); | 1784 | const reader = response.reader(&.{}); |
| 1783 | _ = reader.discardRemaining() catch |err| switch (err) { | 1785 | _ = reader.discardRemaining() catch |err| switch (err) { |
| 1784 | error.ReadFailed => return response.bodyErr().?, | 1786 | error.ReadFailed => return response.bodyErr().?, |
| ... | @@ -1794,21 +1796,14 @@ pub fn fetch(client: *Client, options: FetchOptions) FetchError!FetchResult { | ... | @@ -1794,21 +1796,14 @@ pub fn fetch(client: *Client, options: FetchOptions) FetchError!FetchResult { |
| 1794 | }; | 1796 | }; |
| 1795 | defer if (options.decompress_buffer == null) client.allocator.free(decompress_buffer); | 1797 | defer if (options.decompress_buffer == null) client.allocator.free(decompress_buffer); |
| 1796 | | 1798 | |
| | 1799 | var transfer_buffer: [64]u8 = undefined; |
| 1797 | var decompressor: http.Decompressor = undefined; | 1800 | var decompressor: http.Decompressor = undefined; |
| 1798 | const reader = response.readerDecompressing(&decompressor, decompress_buffer); | 1801 | const reader = response.readerDecompressing(&transfer_buffer, &decompressor, decompress_buffer); |
| 1799 | const list = storage.list; | | |
| 1800 | | 1802 | |
| 1801 | if (storage.allocator) |allocator| { | 1803 | _ = reader.streamRemaining(response_writer) catch |err| switch (err) { |
| 1802 | reader.appendRemaining(allocator, null, list, storage.append_limit) catch |err| switch (err) { | 1804 | error.ReadFailed => return response.bodyErr().?, |
| 1803 | error.ReadFailed => return response.bodyErr().?, | 1805 | else => |e| return e, |
| 1804 | else => |e| return e, | 1806 | }; |
| 1805 | }; | | |
| 1806 | } else { | | |
| 1807 | const buf = storage.append_limit.slice(list.unusedCapacitySlice()); | | |
| 1808 | list.items.len += reader.readSliceShort(buf) catch |err| switch (err) { | | |
| 1809 | error.ReadFailed => return response.bodyErr().?, | | |
| 1810 | }; | | |
| 1811 | } | | |
| 1812 | | 1807 | |
| 1813 | return .{ .status = response.head.status }; | 1808 | return .{ .status = response.head.status }; |
| 1814 | } | 1809 | } |