@@ -13,6 +13,7 @@ use http::header::Entry;
13
13
use http:: header:: ValueIter ;
14
14
use http:: header:: { self , HeaderMap , HeaderName , HeaderValue } ;
15
15
use http:: { Method , StatusCode , Version } ;
16
+ use smallvec:: { smallvec, smallvec_inline, SmallVec } ;
16
17
17
18
use crate :: body:: DecodedLength ;
18
19
#[ cfg( feature = "server" ) ]
@@ -29,7 +30,7 @@ use crate::proto::h1::{
29
30
use crate :: proto:: RequestHead ;
30
31
use crate :: proto:: { BodyLength , MessageHead , RequestLine } ;
31
32
32
- const MAX_HEADERS : usize = 100 ;
33
+ const DEFAULT_MAX_HEADERS : usize = 100 ;
33
34
const AVERAGE_HEADER_SIZE : usize = 30 ; // totally scientific
34
35
#[ cfg( feature = "server" ) ]
35
36
const MAX_URI_LEN : usize = ( u16:: MAX - 1 ) as usize ;
@@ -139,9 +140,17 @@ impl Http1Transaction for Server {
139
140
// but we *never* read any of it until after httparse has assigned
140
141
// values into it. By not zeroing out the stack memory, this saves
141
142
// a good ~5% on pipeline benchmarks.
142
- let mut headers_indices = [ MaybeUninit :: < HeaderIndices > :: uninit ( ) ; MAX_HEADERS ] ;
143
+ let mut headers_indices: SmallVec < [ MaybeUninit < HeaderIndices > ; DEFAULT_MAX_HEADERS ] > =
144
+ match ctx. h1_max_headers {
145
+ Some ( cap) => smallvec ! [ MaybeUninit :: uninit( ) ; cap] ,
146
+ None => smallvec_inline ! [ MaybeUninit :: uninit( ) ; DEFAULT_MAX_HEADERS ] ,
147
+ } ;
143
148
{
144
- let mut headers = [ MaybeUninit :: < httparse:: Header < ' _ > > :: uninit ( ) ; MAX_HEADERS ] ;
149
+ let mut headers: SmallVec < [ MaybeUninit < httparse:: Header < ' _ > > ; DEFAULT_MAX_HEADERS ] > =
150
+ match ctx. h1_max_headers {
151
+ Some ( cap) => smallvec ! [ MaybeUninit :: uninit( ) ; cap] ,
152
+ None => smallvec_inline ! [ MaybeUninit :: uninit( ) ; DEFAULT_MAX_HEADERS ] ,
153
+ } ;
145
154
trace ! ( bytes = buf. len( ) , "Request.parse" ) ;
146
155
let mut req = httparse:: Request :: new ( & mut [ ] ) ;
147
156
let bytes = buf. as_ref ( ) ;
@@ -966,9 +975,18 @@ impl Http1Transaction for Client {
966
975
967
976
// Loop to skip information status code headers (100 Continue, etc).
968
977
loop {
969
- let mut headers_indices = [ MaybeUninit :: < HeaderIndices > :: uninit ( ) ; MAX_HEADERS ] ;
978
+ let mut headers_indices: SmallVec < [ MaybeUninit < HeaderIndices > ; DEFAULT_MAX_HEADERS ] > =
979
+ match ctx. h1_max_headers {
980
+ Some ( cap) => smallvec ! [ MaybeUninit :: uninit( ) ; cap] ,
981
+ None => smallvec_inline ! [ MaybeUninit :: uninit( ) ; DEFAULT_MAX_HEADERS ] ,
982
+ } ;
970
983
let ( len, status, reason, version, headers_len) = {
971
- let mut headers = [ MaybeUninit :: < httparse:: Header < ' _ > > :: uninit ( ) ; MAX_HEADERS ] ;
984
+ let mut headers: SmallVec <
985
+ [ MaybeUninit < httparse:: Header < ' _ > > ; DEFAULT_MAX_HEADERS ] ,
986
+ > = match ctx. h1_max_headers {
987
+ Some ( cap) => smallvec ! [ MaybeUninit :: uninit( ) ; cap] ,
988
+ None => smallvec_inline ! [ MaybeUninit :: uninit( ) ; DEFAULT_MAX_HEADERS ] ,
989
+ } ;
972
990
trace ! ( bytes = buf. len( ) , "Response.parse" ) ;
973
991
let mut res = httparse:: Response :: new ( & mut [ ] ) ;
974
992
let bytes = buf. as_ref ( ) ;
@@ -1610,6 +1628,7 @@ mod tests {
1610
1628
cached_headers : & mut None ,
1611
1629
req_method : & mut method,
1612
1630
h1_parser_config : Default :: default ( ) ,
1631
+ h1_max_headers : None ,
1613
1632
h1_header_read_timeout : None ,
1614
1633
h1_header_read_timeout_fut : & mut None ,
1615
1634
h1_header_read_timeout_running : & mut false ,
@@ -1641,6 +1660,7 @@ mod tests {
1641
1660
cached_headers : & mut None ,
1642
1661
req_method : & mut Some ( crate :: Method :: GET ) ,
1643
1662
h1_parser_config : Default :: default ( ) ,
1663
+ h1_max_headers : None ,
1644
1664
h1_header_read_timeout : None ,
1645
1665
h1_header_read_timeout_fut : & mut None ,
1646
1666
h1_header_read_timeout_running : & mut false ,
@@ -1667,6 +1687,7 @@ mod tests {
1667
1687
cached_headers : & mut None ,
1668
1688
req_method : & mut None ,
1669
1689
h1_parser_config : Default :: default ( ) ,
1690
+ h1_max_headers : None ,
1670
1691
h1_header_read_timeout : None ,
1671
1692
h1_header_read_timeout_fut : & mut None ,
1672
1693
h1_header_read_timeout_running : & mut false ,
@@ -1691,6 +1712,7 @@ mod tests {
1691
1712
cached_headers : & mut None ,
1692
1713
req_method : & mut Some ( crate :: Method :: GET ) ,
1693
1714
h1_parser_config : Default :: default ( ) ,
1715
+ h1_max_headers : None ,
1694
1716
h1_header_read_timeout : None ,
1695
1717
h1_header_read_timeout_fut : & mut None ,
1696
1718
h1_header_read_timeout_running : & mut false ,
@@ -1717,6 +1739,7 @@ mod tests {
1717
1739
cached_headers : & mut None ,
1718
1740
req_method : & mut Some ( crate :: Method :: GET ) ,
1719
1741
h1_parser_config : Default :: default ( ) ,
1742
+ h1_max_headers : None ,
1720
1743
h1_header_read_timeout : None ,
1721
1744
h1_header_read_timeout_fut : & mut None ,
1722
1745
h1_header_read_timeout_running : & mut false ,
@@ -1747,6 +1770,7 @@ mod tests {
1747
1770
cached_headers : & mut None ,
1748
1771
req_method : & mut Some ( crate :: Method :: GET ) ,
1749
1772
h1_parser_config,
1773
+ h1_max_headers : None ,
1750
1774
h1_header_read_timeout : None ,
1751
1775
h1_header_read_timeout_fut : & mut None ,
1752
1776
h1_header_read_timeout_running : & mut false ,
@@ -1774,6 +1798,7 @@ mod tests {
1774
1798
cached_headers : & mut None ,
1775
1799
req_method : & mut Some ( crate :: Method :: GET ) ,
1776
1800
h1_parser_config : Default :: default ( ) ,
1801
+ h1_max_headers : None ,
1777
1802
h1_header_read_timeout : None ,
1778
1803
h1_header_read_timeout_fut : & mut None ,
1779
1804
h1_header_read_timeout_running : & mut false ,
@@ -1796,6 +1821,7 @@ mod tests {
1796
1821
cached_headers : & mut None ,
1797
1822
req_method : & mut None ,
1798
1823
h1_parser_config : Default :: default ( ) ,
1824
+ h1_max_headers : None ,
1799
1825
h1_header_read_timeout : None ,
1800
1826
h1_header_read_timeout_fut : & mut None ,
1801
1827
h1_header_read_timeout_running : & mut false ,
@@ -1839,6 +1865,7 @@ mod tests {
1839
1865
cached_headers : & mut None ,
1840
1866
req_method : & mut None ,
1841
1867
h1_parser_config : Default :: default ( ) ,
1868
+ h1_max_headers : None ,
1842
1869
h1_header_read_timeout : None ,
1843
1870
h1_header_read_timeout_fut : & mut None ,
1844
1871
h1_header_read_timeout_running : & mut false ,
@@ -1863,6 +1890,7 @@ mod tests {
1863
1890
cached_headers : & mut None ,
1864
1891
req_method : & mut None ,
1865
1892
h1_parser_config : Default :: default ( ) ,
1893
+ h1_max_headers : None ,
1866
1894
h1_header_read_timeout : None ,
1867
1895
h1_header_read_timeout_fut : & mut None ,
1868
1896
h1_header_read_timeout_running : & mut false ,
@@ -2096,6 +2124,7 @@ mod tests {
2096
2124
cached_headers: & mut None ,
2097
2125
req_method: & mut Some ( Method :: GET ) ,
2098
2126
h1_parser_config: Default :: default ( ) ,
2127
+ h1_max_headers: None ,
2099
2128
h1_header_read_timeout: None ,
2100
2129
h1_header_read_timeout_fut: & mut None ,
2101
2130
h1_header_read_timeout_running: & mut false ,
@@ -2120,6 +2149,7 @@ mod tests {
2120
2149
cached_headers : & mut None ,
2121
2150
req_method : & mut Some ( m) ,
2122
2151
h1_parser_config : Default :: default ( ) ,
2152
+ h1_max_headers : None ,
2123
2153
h1_header_read_timeout : None ,
2124
2154
h1_header_read_timeout_fut : & mut None ,
2125
2155
h1_header_read_timeout_running : & mut false ,
@@ -2144,6 +2174,7 @@ mod tests {
2144
2174
cached_headers : & mut None ,
2145
2175
req_method : & mut Some ( Method :: GET ) ,
2146
2176
h1_parser_config : Default :: default ( ) ,
2177
+ h1_max_headers : None ,
2147
2178
h1_header_read_timeout : None ,
2148
2179
h1_header_read_timeout_fut : & mut None ,
2149
2180
h1_header_read_timeout_running : & mut false ,
@@ -2663,6 +2694,7 @@ mod tests {
2663
2694
cached_headers : & mut None ,
2664
2695
req_method : & mut Some ( Method :: GET ) ,
2665
2696
h1_parser_config : Default :: default ( ) ,
2697
+ h1_max_headers : None ,
2666
2698
h1_header_read_timeout : None ,
2667
2699
h1_header_read_timeout_fut : & mut None ,
2668
2700
h1_header_read_timeout_running : & mut false ,
@@ -2751,6 +2783,7 @@ mod tests {
2751
2783
cached_headers : & mut headers,
2752
2784
req_method : & mut None ,
2753
2785
h1_parser_config : Default :: default ( ) ,
2786
+ h1_max_headers : None ,
2754
2787
h1_header_read_timeout : None ,
2755
2788
h1_header_read_timeout_fut : & mut None ,
2756
2789
h1_header_read_timeout_running : & mut false ,
@@ -2795,6 +2828,7 @@ mod tests {
2795
2828
cached_headers : & mut headers,
2796
2829
req_method : & mut None ,
2797
2830
h1_parser_config : Default :: default ( ) ,
2831
+ h1_max_headers : None ,
2798
2832
h1_header_read_timeout : None ,
2799
2833
h1_header_read_timeout_fut : & mut None ,
2800
2834
h1_header_read_timeout_running : & mut false ,
0 commit comments