@@ -181,9 +181,18 @@ impl Request {
181
181
/// ```
182
182
/// use micro_http::Request;
183
183
///
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();
185
187
/// ```
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
+
187
196
// The first line of the request is the Request Line. The line ending is CR LF.
188
197
let request_line_end = match find ( byte_stream, & [ CR , LF ] ) {
189
198
Some ( len) => len,
@@ -439,7 +448,7 @@ mod tests {
439
448
} ;
440
449
let request_bytes = b"GET http://localhost/home HTTP/1.0\r \n \
441
450
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 ( ) ;
443
452
assert_eq ! ( request, expected_request) ;
444
453
assert_eq ! ( request. uri( ) , & Uri :: new( "http://localhost/home" ) ) ;
445
454
assert_eq ! ( request. http_version( ) , Version :: Http10 ) ;
@@ -448,14 +457,14 @@ mod tests {
448
457
// Test for invalid Request (missing CR LF).
449
458
let request_bytes = b"GET / HTTP/1.1" ;
450
459
assert_eq ! (
451
- Request :: try_from( request_bytes) . unwrap_err( ) ,
460
+ Request :: try_from( request_bytes, None ) . unwrap_err( ) ,
452
461
RequestError :: InvalidRequest
453
462
) ;
454
463
455
464
// Test for invalid Request (length is less than minimum).
456
465
let request_bytes = b"GET" ;
457
466
assert_eq ! (
458
- Request :: try_from( request_bytes) . unwrap_err( ) ,
467
+ Request :: try_from( request_bytes, None ) . unwrap_err( ) ,
459
468
RequestError :: InvalidRequest
460
469
) ;
461
470
@@ -464,18 +473,29 @@ mod tests {
464
473
Content-Length: 13\r \n \
465
474
Content-Type: application/json\r \n \r \n whatever body";
466
475
assert_eq ! (
467
- Request :: try_from( request_bytes) . unwrap_err( ) ,
476
+ Request :: try_from( request_bytes, None ) . unwrap_err( ) ,
468
477
RequestError :: InvalidRequest
469
478
) ;
470
479
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
+
471
493
// 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 ( ) ;
479
499
assert_eq ! ( request. uri( ) , & Uri :: new( "http://localhost/home" ) ) ;
480
500
assert_eq ! ( request. http_version( ) , Version :: Http11 ) ;
481
501
assert_eq ! ( request. method( ) , Method :: Patch ) ;
@@ -490,31 +510,26 @@ mod tests {
490
510
) ;
491
511
492
512
// 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 ( ) ;
494
514
495
515
// 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( ) ) ;
503
522
504
523
// 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 ( ) ;
510
527
assert_eq ! ( request, RequestError :: InvalidRequest ) ;
511
528
512
529
// 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 ( ) ;
518
533
assert_eq ! ( request. uri( ) , & Uri :: new( "http://localhost/" ) ) ;
519
534
assert_eq ! ( request. http_version( ) , Version :: Http10 ) ;
520
535
assert_eq ! ( request. method( ) , Method :: Get ) ;
@@ -523,8 +538,9 @@ mod tests {
523
538
assert_eq ! ( request. headers. content_length( ) , 0 ) ;
524
539
assert ! ( request. body. is_none( ) ) ;
525
540
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 ) ;
528
544
assert_eq ! (
529
545
request. unwrap_err( ) ,
530
546
RequestError :: HeaderError ( HttpHeaderError :: InvalidValue (
0 commit comments