@@ -161,6 +161,8 @@ pub enum Error {
161161 TooManyHeaders ,
162162 /// Invalid byte in HTTP version.
163163 Version ,
164+ /// Unparsed headers are larger than the configured max size.
165+ HeadersTooLarge ,
164166}
165167
166168impl Error {
@@ -174,6 +176,7 @@ impl Error {
174176 Error :: Token => "invalid token" ,
175177 Error :: TooManyHeaders => "too many headers" ,
176178 Error :: Version => "invalid HTTP version" ,
179+ Error :: HeadersTooLarge => "headers too large" ,
177180 }
178181 }
179182}
@@ -261,6 +264,7 @@ pub struct ParserConfig {
261264 allow_multiple_spaces_in_response_status_delimiters : bool ,
262265 ignore_invalid_headers_in_responses : bool ,
263266 ignore_invalid_headers_in_requests : bool ,
267+ max_header_list_size : Option < usize > ,
264268}
265269
266270impl ParserConfig {
@@ -440,6 +444,18 @@ impl ParserConfig {
440444 ) -> Result < usize > {
441445 response. parse_with_config_and_uninit_headers ( buf, self , headers)
442446 }
447+
448+ /// Set the maximum size of all headers.
449+ ///
450+ /// The value is based on the size of unparsed header fields, including the
451+ /// length of the name and value in octets, an overhead of 24 octets for
452+ /// each header field and 8 octets for each additional whitespace.
453+ ///
454+ /// Default is unlimited.
455+ pub fn max_header_list_size ( & mut self , val : usize ) -> & mut Self {
456+ self . max_header_list_size = Some ( val) ;
457+ self
458+ }
443459}
444460
445461/// A parsed Request.
@@ -513,6 +529,11 @@ impl<'h, 'b> Request<'h, 'b> {
513529 newline ! ( bytes) ;
514530
515531 let len = orig_len - bytes. len ( ) ;
532+ if let Some ( max) = config. max_header_list_size {
533+ if len > max {
534+ return Err ( Error :: HeadersTooLarge ) ;
535+ }
536+ }
516537 let headers_len = complete ! ( parse_headers_iter_uninit(
517538 & mut headers,
518539 & mut bytes,
@@ -710,6 +731,11 @@ impl<'h, 'b> Response<'h, 'b> {
710731
711732
712733 let len = orig_len - bytes. len ( ) ;
734+ if let Some ( max) = config. max_header_list_size {
735+ if len > max {
736+ return Err ( Error :: HeadersTooLarge ) ;
737+ }
738+ }
713739 let headers_len = complete ! ( parse_headers_iter_uninit(
714740 & mut headers,
715741 & mut bytes,
@@ -2498,4 +2524,40 @@ mod tests {
24982524 assert ! ( REQUEST . as_ptr( ) <= method. as_ptr( ) ) ;
24992525 assert ! ( method. as_ptr( ) <= buf_end) ;
25002526 }
2527+
2528+ #[ test]
2529+ fn test_request_max_header_list_size ( ) {
2530+ const REQUEST : & [ u8 ] = b"GET / HTTP/1.1\r \n Header: value\r \n \r \n " ;
2531+
2532+ let mut headers = [ EMPTY_HEADER ; 1 ] ;
2533+ let mut request = Request :: new ( & mut headers[ ..] ) ;
2534+
2535+ let result = crate :: ParserConfig :: default ( )
2536+ . max_header_list_size ( 10 )
2537+ . parse_request ( & mut request, REQUEST ) ;
2538+ assert_eq ! ( result, Err ( crate :: Error :: HeadersTooLarge ) ) ;
2539+
2540+ let result = crate :: ParserConfig :: default ( )
2541+ . max_header_list_size ( 17 )
2542+ . parse_request ( & mut request, REQUEST ) ;
2543+ assert_eq ! ( result, Ok ( Status :: Complete ( REQUEST . len( ) ) ) ) ;
2544+ }
2545+
2546+ #[ test]
2547+ fn test_response_max_header_list_size ( ) {
2548+ const RESPONSE : & [ u8 ] = b"HTTP/1.1 200 OK\r \n Header: value\r \n \r \n " ;
2549+
2550+ let mut headers = [ EMPTY_HEADER ; 1 ] ;
2551+ let mut response = Response :: new ( & mut headers[ ..] ) ;
2552+
2553+ let result = crate :: ParserConfig :: default ( )
2554+ . max_header_list_size ( 10 )
2555+ . parse_response ( & mut response, RESPONSE ) ;
2556+ assert_eq ! ( result, Err ( crate :: Error :: HeadersTooLarge ) ) ;
2557+
2558+ let result = crate :: ParserConfig :: default ( )
2559+ . max_header_list_size ( 17 )
2560+ . parse_response ( & mut response, RESPONSE ) ;
2561+ assert_eq ! ( result, Ok ( Status :: Complete ( RESPONSE . len( ) ) ) ) ;
2562+ }
25012563}
0 commit comments