@@ -160,9 +160,7 @@ pub const Connection = struct {
160
160
proxied : bool = false ,
161
161
closing : bool = false ,
162
162
163
- read_start : u16 = 0 ,
164
- read_end : u16 = 0 ,
165
- read_buf : [buffer_size ]u8 = undefined ,
163
+ buffered : std .io .BufferedReaderWriter (std.crypto.tls.max_ciphertext_record_len , 4096 , * Connection ),
166
164
167
165
pub fn rawReadAtLeast (conn : * Connection , buffer : []u8 , len : usize ) ReadError ! usize {
168
166
return switch (conn .protocol ) {
@@ -181,61 +179,8 @@ pub const Connection = struct {
181
179
};
182
180
}
183
181
184
- pub fn fill (conn : * Connection ) ReadError ! void {
185
- if (conn .read_end != conn .read_start ) return ;
186
-
187
- const nread = try conn .rawReadAtLeast (conn .read_buf [0.. ], 1 );
188
- if (nread == 0 ) return error .EndOfStream ;
189
- conn .read_start = 0 ;
190
- conn .read_end = @as (u16 , @intCast (nread ));
191
- }
192
-
193
- pub fn peek (conn : * Connection ) []const u8 {
194
- return conn .read_buf [conn .read_start .. conn .read_end ];
195
- }
196
-
197
- pub fn drop (conn : * Connection , num : u16 ) void {
198
- conn .read_start += num ;
199
- }
200
-
201
- pub fn readAtLeast (conn : * Connection , buffer : []u8 , len : usize ) ReadError ! usize {
202
- assert (len <= buffer .len );
203
-
204
- var out_index : u16 = 0 ;
205
- while (out_index < len ) {
206
- const available_read = conn .read_end - conn .read_start ;
207
- const available_buffer = buffer .len - out_index ;
208
-
209
- if (available_read > available_buffer ) { // partially read buffered data
210
- @memcpy (buffer [out_index .. ], conn .read_buf [conn .read_start .. conn .read_end ][0.. available_buffer ]);
211
- out_index += @as (u16 , @intCast (available_buffer ));
212
- conn .read_start += @as (u16 , @intCast (available_buffer ));
213
-
214
- break ;
215
- } else if (available_read > 0 ) { // fully read buffered data
216
- @memcpy (buffer [out_index .. ][0.. available_read ], conn .read_buf [conn .read_start .. conn .read_end ]);
217
- out_index += available_read ;
218
- conn .read_start += available_read ;
219
-
220
- if (out_index >= len ) break ;
221
- }
222
-
223
- const leftover_buffer = available_buffer - available_read ;
224
- const leftover_len = len - out_index ;
225
-
226
- if (leftover_buffer > conn .read_buf .len ) {
227
- // skip the buffer if the output is large enough
228
- return conn .rawReadAtLeast (buffer [out_index .. ], leftover_len );
229
- }
230
-
231
- try conn .fill ();
232
- }
233
-
234
- return out_index ;
235
- }
236
-
237
182
pub fn read (conn : * Connection , buffer : []u8 ) ReadError ! usize {
238
- return conn .readAtLeast (buffer , 1 );
183
+ return conn .rawReadAtLeast (buffer , 1 );
239
184
}
240
185
241
186
pub const ReadError = error {
@@ -250,7 +195,7 @@ pub const Connection = struct {
250
195
pub const Reader = std .io .Reader (* Connection , ReadError , read );
251
196
252
197
pub fn reader (conn : * Connection ) Reader {
253
- return Reader { .context = conn };
198
+ return . { .context = conn };
254
199
}
255
200
256
201
pub fn writeAll (conn : * Connection , buffer : []const u8 ) ! void {
@@ -537,8 +482,7 @@ pub const Request = struct {
537
482
538
483
/// Send the request to the server.
539
484
pub fn start (req : * Request ) StartError ! void {
540
- var buffered = std .io .bufferedWriter (req .connection .? .data .writer ());
541
- const w = buffered .writer ();
485
+ const w = req .connection .? .data .buffered .writer ();
542
486
543
487
try w .writeAll (@tagName (req .method ));
544
488
try w .writeByte (' ' );
@@ -612,7 +556,7 @@ pub const Request = struct {
612
556
613
557
try w .writeAll ("\r \n " );
614
558
615
- try buffered .flush ();
559
+ try req . connection .? . data . buffered .flush ();
616
560
}
617
561
618
562
pub const TransferReadError = Connection .ReadError || proto .HeadersParser .ReadError ;
@@ -628,7 +572,7 @@ pub const Request = struct {
628
572
629
573
var index : usize = 0 ;
630
574
while (index == 0 ) {
631
- const amt = try req .response .parser .read (& req .connection .? .data , buf [index .. ], req .response .skip );
575
+ const amt = try req .response .parser .read (& req .connection .? .data . buffered , buf [index .. ], req .response .skip );
632
576
if (amt == 0 and req .response .parser .done ) break ;
633
577
index += amt ;
634
578
}
@@ -646,10 +590,11 @@ pub const Request = struct {
646
590
pub fn wait (req : * Request ) WaitError ! void {
647
591
while (true ) { // handle redirects
648
592
while (true ) { // read headers
649
- try req .connection .? .data .fill ();
593
+ const rest = req .connection .? .data .buffered .peek (0 );
594
+ if (rest .len == 0 ) return error .EndOfStream ;
650
595
651
- const nchecked = try req .response .parser .checkCompleteHead (req .client .allocator , req . connection .? . data . peek () );
652
- req .connection .? .data .drop ( @as ( u16 , @ intCast (nchecked ) ));
596
+ const nchecked = try req .response .parser .checkCompleteHead (req .client .allocator , rest );
597
+ try req .connection .? .data .buffered . discard ( @ intCast (nchecked ));
653
598
654
599
if (req .response .parser .state .isContent ()) break ;
655
600
}
@@ -765,10 +710,12 @@ pub const Request = struct {
765
710
const has_trail = ! req .response .parser .state .isContent ();
766
711
767
712
while (! req .response .parser .state .isContent ()) { // read trailing headers
768
- try req .connection .? .data .fill ();
713
+ const rest = req .connection .? .data .buffered .peek (0 );
714
+ if (rest .len == 0 ) return error .EndOfStream ;
715
+
716
+ const nchecked = try req .response .parser .checkCompleteHead (req .client .allocator , rest );
769
717
770
- const nchecked = try req .response .parser .checkCompleteHead (req .client .allocator , req .connection .? .data .peek ());
771
- req .connection .? .data .drop (@as (u16 , @intCast (nchecked )));
718
+ try req .connection .? .data .buffered .discard (@intCast (nchecked ));
772
719
}
773
720
774
721
if (has_trail ) {
@@ -898,6 +845,7 @@ pub fn connectUnproxied(client: *Client, host: []const u8, port: u16, protocol:
898
845
.stream = stream ,
899
846
.tls_client = undefined ,
900
847
.protocol = protocol ,
848
+ .buffered = undefined ,
901
849
902
850
.host = try client .allocator .dupe (u8 , host ),
903
851
.port = port ,
@@ -916,6 +864,11 @@ pub fn connectUnproxied(client: *Client, host: []const u8, port: u16, protocol:
916
864
conn .data .tls_client .allow_truncation_attacks = true ;
917
865
},
918
866
}
867
+ conn .data .buffered = .{ .buffered_reader = .{
868
+ .unbuffered_reader = & conn .data ,
869
+ }, .buffered_writer = .{
870
+ .unbuffered_writer = & conn .data ,
871
+ } };
919
872
920
873
client .connection_pool .addUsed (conn );
921
874
0 commit comments