@@ -181,9 +181,18 @@ impl Request {
181181 /// ```
182182 /// use micro_http::Request;
183183 ///
184- /// let http_request = Request::try_from(b"GET http://localhost/home HTTP/1.0\r\n\r\n").unwrap();
184+ /// let max_request_len = 2000;
185+ /// let request_bytes = b"GET http://localhost/home HTTP/1.0\r\n\r\n";
186+ /// let http_request = Request::try_from(request_bytes, Some(max_request_len)).unwrap();
185187 /// ```
186- pub fn try_from ( byte_stream : & [ u8 ] ) -> Result < Self , RequestError > {
188+ pub fn try_from ( byte_stream : & [ u8 ] , max_len : Option < usize > ) -> Result < Self , RequestError > {
189+ // If a size limit is provided, verify the request length does not exceed it.
190+ if let Some ( limit) = max_len {
191+ if byte_stream. len ( ) >= limit {
192+ return Err ( RequestError :: InvalidRequest ) ;
193+ }
194+ }
195+
187196 // The first line of the request is the Request Line. The line ending is CR LF.
188197 let request_line_end = match find ( byte_stream, & [ CR , LF ] ) {
189198 Some ( len) => len,
@@ -439,7 +448,7 @@ mod tests {
439448 } ;
440449 let request_bytes = b"GET http://localhost/home HTTP/1.0\r \n \
441450 Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT\r \n \r \n ";
442- let request = Request :: try_from ( request_bytes) . unwrap ( ) ;
451+ let request = Request :: try_from ( request_bytes, None ) . unwrap ( ) ;
443452 assert_eq ! ( request, expected_request) ;
444453 assert_eq ! ( request. uri( ) , & Uri :: new( "http://localhost/home" ) ) ;
445454 assert_eq ! ( request. http_version( ) , Version :: Http10 ) ;
@@ -448,14 +457,14 @@ mod tests {
448457 // Test for invalid Request (missing CR LF).
449458 let request_bytes = b"GET / HTTP/1.1" ;
450459 assert_eq ! (
451- Request :: try_from( request_bytes) . unwrap_err( ) ,
460+ Request :: try_from( request_bytes, None ) . unwrap_err( ) ,
452461 RequestError :: InvalidRequest
453462 ) ;
454463
455464 // Test for invalid Request (length is less than minimum).
456465 let request_bytes = b"GET" ;
457466 assert_eq ! (
458- Request :: try_from( request_bytes) . unwrap_err( ) ,
467+ Request :: try_from( request_bytes, None ) . unwrap_err( ) ,
459468 RequestError :: InvalidRequest
460469 ) ;
461470
@@ -464,18 +473,29 @@ mod tests {
464473 Content-Length: 13\r \n \
465474 Content-Type: application/json\r \n \r \n whatever body";
466475 assert_eq ! (
467- Request :: try_from( request_bytes) . unwrap_err( ) ,
476+ Request :: try_from( request_bytes, None ) . unwrap_err( ) ,
468477 RequestError :: InvalidRequest
469478 ) ;
470479
480+ // Test for request larger than maximum len provided.
481+ let request_bytes = b"GET http://localhost/home HTTP/1.0\r \n \
482+ Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT\r \n \r \n ";
483+ assert_eq ! (
484+ Request :: try_from( request_bytes, Some ( 20 ) ) . unwrap_err( ) ,
485+ RequestError :: InvalidRequest
486+ ) ;
487+
488+ // Test request smaller than maximum len provided is ok.
489+ let request_bytes = b"GET http://localhost/home HTTP/1.0\r \n \
490+ Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT\r \n \r \n ";
491+ assert ! ( Request :: try_from( request_bytes, Some ( 500 ) ) . is_ok( ) ) ;
492+
471493 // Test for a request with the headers we are looking for.
472- let request = Request :: try_from (
473- b"PATCH http://localhost/home HTTP/1.1\r \n \
474- Expect: 100-continue\r \n \
475- Transfer-Encoding: chunked\r \n \
476- Content-Length: 26\r \n \r \n this is not\n \r \n a json \n body",
477- )
478- . unwrap ( ) ;
494+ let request_bytes = b"PATCH http://localhost/home HTTP/1.1\r \n \
495+ Expect: 100-continue\r \n \
496+ Transfer-Encoding: chunked\r \n \
497+ Content-Length: 26\r \n \r \n this is not\n \r \n a json \n body";
498+ let request = Request :: try_from ( request_bytes, None ) . unwrap ( ) ;
479499 assert_eq ! ( request. uri( ) , & Uri :: new( "http://localhost/home" ) ) ;
480500 assert_eq ! ( request. http_version( ) , Version :: Http11 ) ;
481501 assert_eq ! ( request. method( ) , Method :: Patch ) ;
@@ -490,31 +510,26 @@ mod tests {
490510 ) ;
491511
492512 // Test for an invalid request format.
493- Request :: try_from ( b"PATCH http://localhost/home HTTP/1.1\r \n " ) . unwrap_err ( ) ;
513+ Request :: try_from ( b"PATCH http://localhost/home HTTP/1.1\r \n " , None ) . unwrap_err ( ) ;
494514
495515 // Test for an invalid encoding.
496- assert ! ( Request :: try_from(
497- b"PATCH http://localhost/home HTTP/1.1\r \n \
498- Expect: 100-continue\r \n \
499- Transfer-Encoding: identity; q=0\r \n \
500- Content-Length: 26\r \n \r \n this is not\n \r \n a json \n body",
501- )
502- . is_ok( ) ) ;
516+ let request_bytes = b"PATCH http://localhost/home HTTP/1.1\r \n \
517+ Expect: 100-continue\r \n \
518+ Transfer-Encoding: identity; q=0\r \n \
519+ Content-Length: 26\r \n \r \n this is not\n \r \n a json \n body";
520+
521+ assert ! ( Request :: try_from( request_bytes, None ) . is_ok( ) ) ;
503522
504523 // Test for an invalid content length.
505- let request = Request :: try_from (
506- b"PATCH http://localhost/home HTTP/1.1\r \n \
507- Content-Length: 5000\r \n \r \n this is a short body",
508- )
509- . unwrap_err ( ) ;
524+ let request_bytes = b"PATCH http://localhost/home HTTP/1.1\r \n \
525+ Content-Length: 5000\r \n \r \n this is a short body";
526+ let request = Request :: try_from ( request_bytes, None ) . unwrap_err ( ) ;
510527 assert_eq ! ( request, RequestError :: InvalidRequest ) ;
511528
512529 // Test for a request without a body and an optional header.
513- let request = Request :: try_from (
514- b"GET http://localhost/ HTTP/1.0\r \n \
515- Accept-Encoding: gzip\r \n \r \n ",
516- )
517- . unwrap ( ) ;
530+ let request_bytes = b"GET http://localhost/ HTTP/1.0\r \n \
531+ Accept-Encoding: gzip\r \n \r \n ";
532+ let request = Request :: try_from ( request_bytes, None ) . unwrap ( ) ;
518533 assert_eq ! ( request. uri( ) , & Uri :: new( "http://localhost/" ) ) ;
519534 assert_eq ! ( request. http_version( ) , Version :: Http10 ) ;
520535 assert_eq ! ( request. method( ) , Method :: Get ) ;
@@ -523,8 +538,9 @@ mod tests {
523538 assert_eq ! ( request. headers. content_length( ) , 0 ) ;
524539 assert ! ( request. body. is_none( ) ) ;
525540
526- let request = Request :: try_from ( b"GET http://localhost/ HTTP/1.0\r \n \
527- Accept-Encoding: identity;q=0\r \n \r \n ") ;
541+ let request_bytes = b"GET http://localhost/ HTTP/1.0\r \n \
542+ Accept-Encoding: identity;q=0\r \n \r \n ";
543+ let request = Request :: try_from ( request_bytes, None ) ;
528544 assert_eq ! (
529545 request. unwrap_err( ) ,
530546 RequestError :: HeaderError ( HttpHeaderError :: InvalidValue (
0 commit comments