@@ -451,7 +451,8 @@ pub const Response = struct {
451
451
pub const Request = struct {
452
452
uri : Uri ,
453
453
client : * Client ,
454
- connection : * ConnectionPool.Node ,
454
+ /// is null when this connection is released
455
+ connection : ? * ConnectionPool.Node ,
455
456
456
457
method : http.Method ,
457
458
version : http.Version = .@"HTTP/1.1" ,
@@ -481,13 +482,14 @@ pub const Request = struct {
481
482
req .response .parser .header_bytes .deinit (req .client .allocator );
482
483
}
483
484
484
- if (! req .response .parser .done ) {
485
- // If the response wasn't fully read, then we need to close the connection.
486
- req .connection .data .closing = true ;
485
+ if (req .connection ) | connection | {
486
+ if (! req .response .parser .done ) {
487
+ // If the response wasn't fully read, then we need to close the connection.
488
+ connection .data .closing = true ;
489
+ }
490
+ req .client .connection_pool .release (req .client , connection );
487
491
}
488
492
489
- req .client .connection_pool .release (req .client , req .connection );
490
-
491
493
req .arena .deinit ();
492
494
req .* = undefined ;
493
495
}
@@ -504,7 +506,8 @@ pub const Request = struct {
504
506
.zstd = > | * zstd | zstd .deinit (),
505
507
}
506
508
507
- req .client .connection_pool .release (req .client , req .connection );
509
+ req .client .connection_pool .release (req .client , req .connection .? );
510
+ req .connection = null ;
508
511
509
512
const protocol = protocol_map .get (uri .scheme ) orelse return error .UnsupportedUrlScheme ;
510
513
@@ -534,7 +537,7 @@ pub const Request = struct {
534
537
535
538
/// Send the request to the server.
536
539
pub fn start (req : * Request ) StartError ! void {
537
- var buffered = std .io .bufferedWriter (req .connection .data .writer ());
540
+ var buffered = std .io .bufferedWriter (req .connection .? . data .writer ());
538
541
const w = buffered .writer ();
539
542
540
543
try w .writeAll (@tagName (req .method ));
@@ -544,7 +547,7 @@ pub const Request = struct {
544
547
try w .writeAll (req .uri .host .? );
545
548
try w .writeByte (':' );
546
549
try w .print ("{}" , .{req .uri .port .? });
547
- } else if (req .connection .data .proxied ) {
550
+ } else if (req .connection .? . data .proxied ) {
548
551
// proxied connections require the full uri
549
552
try w .print ("{+/}" , .{req .uri });
550
553
} else {
@@ -625,7 +628,7 @@ pub const Request = struct {
625
628
626
629
var index : usize = 0 ;
627
630
while (index == 0 ) {
628
- const amt = try req .response .parser .read (& req .connection .data , buf [index .. ], req .response .skip );
631
+ const amt = try req .response .parser .read (& req .connection .? . data , buf [index .. ], req .response .skip );
629
632
if (amt == 0 and req .response .parser .done ) break ;
630
633
index += amt ;
631
634
}
@@ -643,23 +646,23 @@ pub const Request = struct {
643
646
pub fn wait (req : * Request ) WaitError ! void {
644
647
while (true ) { // handle redirects
645
648
while (true ) { // read headers
646
- try req .connection .data .fill ();
649
+ try req .connection .? . data .fill ();
647
650
648
- const nchecked = try req .response .parser .checkCompleteHead (req .client .allocator , req .connection .data .peek ());
649
- req .connection .data .drop (@intCast (u16 , nchecked ));
651
+ const nchecked = try req .response .parser .checkCompleteHead (req .client .allocator , req .connection .? . data .peek ());
652
+ req .connection .? . data .drop (@intCast (u16 , nchecked ));
650
653
651
654
if (req .response .parser .state .isContent ()) break ;
652
655
}
653
656
654
657
try req .response .parse (req .response .parser .header_bytes .items , false );
655
658
656
659
if (req .response .status == .switching_protocols ) {
657
- req .connection .data .closing = false ;
660
+ req .connection .? . data .closing = false ;
658
661
req .response .parser .done = true ;
659
662
}
660
663
661
664
if (req .method == .CONNECT and req .response .status == .ok ) {
662
- req .connection .data .closing = false ;
665
+ req .connection .? . data .closing = false ;
663
666
req .response .parser .done = true ;
664
667
}
665
668
@@ -670,9 +673,9 @@ pub const Request = struct {
670
673
const res_connection = req .response .headers .getFirstValue ("connection" );
671
674
const res_keepalive = res_connection != null and ! std .ascii .eqlIgnoreCase ("close" , res_connection .? );
672
675
if (res_keepalive and (req_keepalive or req_connection == null )) {
673
- req .connection .data .closing = false ;
676
+ req .connection .? . data .closing = false ;
674
677
} else {
675
- req .connection .data .closing = true ;
678
+ req .connection .? . data .closing = true ;
676
679
}
677
680
678
681
if (req .response .transfer_encoding ) | te | {
@@ -762,10 +765,10 @@ pub const Request = struct {
762
765
const has_trail = ! req .response .parser .state .isContent ();
763
766
764
767
while (! req .response .parser .state .isContent ()) { // read trailing headers
765
- try req .connection .data .fill ();
768
+ try req .connection .? . data .fill ();
766
769
767
- const nchecked = try req .response .parser .checkCompleteHead (req .client .allocator , req .connection .data .peek ());
768
- req .connection .data .drop (@intCast (u16 , nchecked ));
770
+ const nchecked = try req .response .parser .checkCompleteHead (req .client .allocator , req .connection .? . data .peek ());
771
+ req .connection .? . data .drop (@intCast (u16 , nchecked ));
769
772
}
770
773
771
774
if (has_trail ) {
@@ -803,16 +806,16 @@ pub const Request = struct {
803
806
pub fn write (req : * Request , bytes : []const u8 ) WriteError ! usize {
804
807
switch (req .transfer_encoding ) {
805
808
.chunked = > {
806
- try req .connection .data .writer ().print ("{x}\r \n " , .{bytes .len });
807
- try req .connection .data .writeAll (bytes );
808
- try req .connection .data .writeAll ("\r \n " );
809
+ try req .connection .? . data .writer ().print ("{x}\r \n " , .{bytes .len });
810
+ try req .connection .? . data .writeAll (bytes );
811
+ try req .connection .? . data .writeAll ("\r \n " );
809
812
810
813
return bytes .len ;
811
814
},
812
815
.content_length = > | * len | {
813
816
if (len .* < bytes .len ) return error .MessageTooLong ;
814
817
815
- const amt = try req .connection .data .write (bytes );
818
+ const amt = try req .connection .? . data .write (bytes );
816
819
len .* -= amt ;
817
820
return amt ;
818
821
},
@@ -832,7 +835,7 @@ pub const Request = struct {
832
835
/// Finish the body of a request. This notifies the server that you have no more data to send.
833
836
pub fn finish (req : * Request ) FinishError ! void {
834
837
switch (req .transfer_encoding ) {
835
- .chunked = > try req .connection .data .writeAll ("0\r \n \r \n " ),
838
+ .chunked = > try req .connection .? . data .writeAll ("0\r \n \r \n " ),
836
839
.content_length = > | len | if (len != 0 ) return error .MessageNotCompleted ,
837
840
.none = > {},
838
841
}
0 commit comments