@@ -20,7 +20,7 @@ use mucell::MuCell;
2020use uany:: { UnsafeAnyExt } ;
2121use unicase:: UniCase ;
2222
23- use { http, HttpResult } ;
23+ use { http, HttpResult , HttpError } ;
2424
2525pub use self :: shared:: { Encoding , QualityItem , qitem} ;
2626pub use self :: common:: * ;
@@ -118,6 +118,10 @@ pub struct Headers {
118118 data : HashMap < HeaderName , MuCell < Item > >
119119}
120120
121+ // To prevent DOS from a server sending a never ending header.
122+ // The value was copied from curl.
123+ const MAX_HEADERS_COUNT : u32 = 100 * 1024 ;
124+
121125impl Headers {
122126
123127 /// Creates a new, empty headers map.
@@ -130,10 +134,16 @@ impl Headers {
130134 #[ doc( hidden) ]
131135 pub fn from_raw < R : Reader > ( rdr : & mut R ) -> HttpResult < Headers > {
132136 let mut headers = Headers :: new ( ) ;
137+ let mut count = 0u32 ;
133138 loop {
134139 match try!( http:: read_header ( rdr) ) {
135140 Some ( ( name, value) ) => {
136141 debug ! ( "raw header: {:?}={:?}" , name, & value[ ] ) ;
142+ count += ( name. len ( ) + value. len ( ) ) as u32 ;
143+ if count > MAX_HEADERS_COUNT {
144+ debug ! ( "Max header size reached, aborting" ) ;
145+ return Err ( HttpError :: HttpHeaderError )
146+ }
137147 let name = UniCase ( Owned ( name) ) ;
138148 let mut item = match headers. data . entry ( name) {
139149 Entry :: Vacant ( entry) => entry. insert ( MuCell :: new ( Item :: raw ( vec ! [ ] ) ) ) ,
0 commit comments