@@ -781,31 +781,44 @@ impl Client {
781
781
782
782
impl Client {
783
783
fn set_length ( head : & mut RequestHead , body : Option < BodyLength > ) -> Encoder {
784
- if let Some ( body) = body {
785
- let can_chunked = head. version == Version :: HTTP_11
786
- && ( head. subject . 0 != Method :: HEAD )
787
- && ( head. subject . 0 != Method :: GET )
788
- && ( head. subject . 0 != Method :: CONNECT ) ;
789
- set_length ( & mut head. headers , body, can_chunked)
784
+ let body = if let Some ( body) = body {
785
+ body
790
786
} else {
791
787
head. headers . remove ( header:: TRANSFER_ENCODING ) ;
792
- Encoder :: length ( 0 )
793
- }
794
- }
795
- }
788
+ return Encoder :: length ( 0 )
789
+ } ;
790
+
791
+ // HTTP/1.0 doesn't know about chunked
792
+ let can_chunked = head. version == Version :: HTTP_11 ;
793
+ let headers = & mut head. headers ;
794
+
795
+ // If the user already set specific headers, we should respect them, regardless
796
+ // of what the Payload knows about itself. They set them for a reason.
796
797
797
- fn set_length ( headers : & mut HeaderMap , body : BodyLength , can_chunked : bool ) -> Encoder {
798
- // If the user already set specific headers, we should respect them, regardless
799
- // of what the Payload knows about itself. They set them for a reason .
798
+ // Because of the borrow checker, we can't check the for an existing
799
+ // Content-Length header while holding an `Entry` for the Transfer-Encoding
800
+ // header, so unfortunately, we must do the check here, first .
800
801
801
- // Because of the borrow checker, we can't check the for an existing
802
- // Content-Length header while holding an `Entry` for the Transfer-Encoding
803
- // header, so unfortunately, we must do the check here, first.
802
+ let existing_con_len = headers:: content_length_parse_all ( headers) ;
803
+ let mut should_remove_con_len = false ;
804
804
805
- let existing_con_len = headers:: content_length_parse_all ( headers) ;
806
- let mut should_remove_con_len = false ;
805
+ if !can_chunked {
806
+ // Chunked isn't legal, so if it is set, we need to remove it.
807
+ if headers. remove ( header:: TRANSFER_ENCODING ) . is_some ( ) {
808
+ trace ! ( "removing illegal transfer-encoding header" ) ;
809
+ }
810
+
811
+ return if let Some ( len) = existing_con_len {
812
+ Encoder :: length ( len)
813
+ } else if let BodyLength :: Known ( len) = body {
814
+ set_content_length ( headers, len)
815
+ } else {
816
+ // HTTP/1.0 client requests without a content-length
817
+ // cannot have any body at all.
818
+ Encoder :: length ( 0 )
819
+ } ;
820
+ }
807
821
808
- if can_chunked {
809
822
// If the user set a transfer-encoding, respect that. Let's just
810
823
// make sure `chunked` is the final encoding.
811
824
let encoder = match headers. entry ( header:: TRANSFER_ENCODING )
@@ -841,9 +854,22 @@ fn set_length(headers: &mut HeaderMap, body: BodyLength, can_chunked: bool) -> E
841
854
if let Some ( len) = existing_con_len {
842
855
Some ( Encoder :: length ( len) )
843
856
} else if let BodyLength :: Unknown = body {
844
- should_remove_con_len = true ;
845
- te. insert ( HeaderValue :: from_static ( "chunked" ) ) ;
846
- Some ( Encoder :: chunked ( ) )
857
+ // GET, HEAD, and CONNECT almost never have bodies.
858
+ //
859
+ // So instead of sending a "chunked" body with a 0-chunk,
860
+ // assume no body here. If you *must* send a body,
861
+ // set the headers explicitly.
862
+ match head. subject . 0 {
863
+ Method :: GET |
864
+ Method :: HEAD |
865
+ Method :: CONNECT => {
866
+ Some ( Encoder :: length ( 0 ) )
867
+ } ,
868
+ _ => {
869
+ te. insert ( HeaderValue :: from_static ( "chunked" ) ) ;
870
+ Some ( Encoder :: chunked ( ) )
871
+ } ,
872
+ }
847
873
} else {
848
874
None
849
875
}
@@ -869,27 +895,6 @@ fn set_length(headers: &mut HeaderMap, body: BodyLength, can_chunked: bool) -> E
869
895
} ;
870
896
871
897
set_content_length ( headers, len)
872
- } else {
873
- // Chunked isn't legal, so if it is set, we need to remove it.
874
- // Also, if it *is* set, then we shouldn't replace with a length,
875
- // since the user tried to imply there isn't a length.
876
- let encoder = if headers. remove ( header:: TRANSFER_ENCODING ) . is_some ( ) {
877
- trace ! ( "removing illegal transfer-encoding header" ) ;
878
- should_remove_con_len = true ;
879
- Encoder :: close_delimited ( )
880
- } else if let Some ( len) = existing_con_len {
881
- Encoder :: length ( len)
882
- } else if let BodyLength :: Known ( len) = body {
883
- set_content_length ( headers, len)
884
- } else {
885
- Encoder :: close_delimited ( )
886
- } ;
887
-
888
- if should_remove_con_len && existing_con_len. is_some ( ) {
889
- headers. remove ( header:: CONTENT_LENGTH ) ;
890
- }
891
-
892
- encoder
893
898
}
894
899
}
895
900
0 commit comments