@@ -921,17 +921,44 @@ fn parse_headers_iter_uninit<'a, 'b>(
921
921
922
922
let mut iter = autoshrink. headers . iter_mut ( ) ;
923
923
924
+ macro_rules! maybe_continue_after_obsolete_line_folding {
925
+ ( $bytes: ident, $label: lifetime) => {
926
+ if config. allow_obsolete_multiline_headers_in_responses {
927
+ match $bytes. peek( ) {
928
+ None => {
929
+ // Next byte may be a space, in which case that header
930
+ // is using obsolete line folding, so we may have more
931
+ // whitespace to skip after colon.
932
+ return Ok ( Status :: Partial ) ;
933
+ }
934
+ Some ( b' ' ) | Some ( b'\t' ) => {
935
+ // The space will be consumed next iteration.
936
+ continue $label;
937
+ }
938
+ _ => {
939
+ // There is another byte after the end of the line,
940
+ // but it's not whitespace, so it's probably another
941
+ // header or the final line return. This header is thus
942
+ // empty.
943
+ } ,
944
+ }
945
+ }
946
+ }
947
+ }
948
+
924
949
' headers: loop {
925
950
// a newline here means the head is over!
926
- let b = next ! ( bytes) ;
951
+ let mut b = next ! ( bytes) ;
927
952
if b == b'\r' {
928
953
expect ! ( bytes. next( ) == b'\n' => Err ( Error :: NewLine ) ) ;
929
954
result = Ok ( Status :: Complete ( count + bytes. pos ( ) ) ) ;
930
955
break ;
931
- } else if b == b'\n' {
956
+ }
957
+ if b == b'\n' {
932
958
result = Ok ( Status :: Complete ( count + bytes. pos ( ) ) ) ;
933
959
break ;
934
- } else if !is_header_name_token ( b) {
960
+ }
961
+ if !is_header_name_token ( b) {
935
962
return Err ( Error :: HeaderName ) ;
936
963
}
937
964
@@ -982,44 +1009,25 @@ fn parse_headers_iter_uninit<'a, 'b>(
982
1009
count += bytes. pos ( ) ;
983
1010
bytes. slice ( ) ;
984
1011
continue ' whitespace_after_colon;
985
- } else {
986
- if !is_header_value_token ( b) {
987
- if b == b'\r' {
988
- expect ! ( bytes. next( ) == b'\n' => Err ( Error :: HeaderValue ) ) ;
989
- } else if b != b'\n' {
990
- return Err ( Error :: HeaderValue ) ;
991
- }
1012
+ }
1013
+ if is_header_value_token ( b) {
1014
+ break ' whitespace_after_colon;
1015
+ }
992
1016
993
- if config. allow_obsolete_multiline_headers_in_responses {
994
- match bytes. peek ( ) {
995
- None => {
996
- // Next byte may be a space, in which case that header
997
- // is using obsolete line folding, so we may have more
998
- // whitespace to skip after colon.
999
- return Ok ( Status :: Partial ) ;
1000
- }
1001
- Some ( b' ' ) | Some ( b'\t' ) => {
1002
- // The space will be consumed next iteration.
1003
- continue ' whitespace_after_colon;
1004
- }
1005
- _ => {
1006
- // There is another byte after the end of the line,
1007
- // but it's not whitespace, so it's probably another
1008
- // header or the final line return. This header is thus
1009
- // empty.
1010
- } ,
1011
- }
1012
- }
1017
+ if b == b'\r' {
1018
+ expect ! ( bytes. next( ) == b'\n' => Err ( Error :: HeaderValue ) ) ;
1019
+ } else if b != b'\n' {
1020
+ return Err ( Error :: HeaderValue ) ;
1021
+ }
1013
1022
1014
- count += bytes. pos ( ) ;
1015
- let whitespace_slice = bytes. slice ( ) ;
1023
+ maybe_continue_after_obsolete_line_folding ! ( bytes, ' whitespace_after_colon) ;
1016
1024
1017
- // This produces an empty slice that points to the beginning
1018
- // of the whitespace.
1019
- break ' value & whitespace_slice [ 0 .. 0 ] ;
1020
- }
1021
- break ' whitespace_after_colon ;
1022
- }
1025
+ count += bytes . pos ( ) ;
1026
+ let whitespace_slice = bytes . slice ( ) ;
1027
+
1028
+ // This produces an empty slice that points to the beginning
1029
+ // of the whitespace.
1030
+ break ' value & whitespace_slice [ 0 .. 0 ] ;
1023
1031
}
1024
1032
1025
1033
' value_lines: loop {
@@ -1036,19 +1044,16 @@ fn parse_headers_iter_uninit<'a, 'b>(
1036
1044
break ' value_line;
1037
1045
}
1038
1046
} ) ;
1039
- ( $bytes: ident) => ( {
1040
- check!( $bytes, _0) ;
1041
- check!( $bytes, _1) ;
1042
- check!( $bytes, _2) ;
1043
- check!( $bytes, _3) ;
1044
- check!( $bytes, _4) ;
1045
- check!( $bytes, _5) ;
1046
- check!( $bytes, _6) ;
1047
- check!( $bytes, _7) ;
1048
- } )
1049
1047
}
1050
1048
1051
- check ! ( bytes8) ;
1049
+ check ! ( bytes8, _0) ;
1050
+ check ! ( bytes8, _1) ;
1051
+ check ! ( bytes8, _2) ;
1052
+ check ! ( bytes8, _3) ;
1053
+ check ! ( bytes8, _4) ;
1054
+ check ! ( bytes8, _5) ;
1055
+ check ! ( bytes8, _6) ;
1056
+ check ! ( bytes8, _7) ;
1052
1057
1053
1058
continue ' value_line;
1054
1059
}
@@ -1069,25 +1074,7 @@ fn parse_headers_iter_uninit<'a, 'b>(
1069
1074
return Err ( Error :: HeaderValue ) ;
1070
1075
} ;
1071
1076
1072
- if config. allow_obsolete_multiline_headers_in_responses {
1073
- match bytes. peek ( ) {
1074
- None => {
1075
- // Next byte may be a space, in which case that header
1076
- // may be using line folding, so we need more data.
1077
- return Ok ( Status :: Partial ) ;
1078
- }
1079
- Some ( b' ' ) | Some ( b'\t' ) => {
1080
- // The space will be consumed next iteration.
1081
- continue ' value_lines;
1082
- }
1083
- _ => {
1084
- // There is another byte after the end of the line,
1085
- // but it's not a space, so it's probably another
1086
- // header or the final line return. We are thus done
1087
- // with this current header.
1088
- } ,
1089
- }
1090
- }
1077
+ maybe_continue_after_obsolete_line_folding ! ( bytes, ' value_lines) ;
1091
1078
1092
1079
count += bytes. pos ( ) ;
1093
1080
// having just checked that a newline exists, it's safe to skip it.
0 commit comments