2
2
// SPDX-License-Identifier: Apache-2.0
3
3
4
4
use std:: fmt:: { Display , Error , Formatter } ;
5
+ use std:: str:: Utf8Error ;
5
6
6
7
pub mod headers;
7
8
@@ -13,6 +14,55 @@ pub mod ascii {
13
14
pub const CRLF_LEN : usize = 2 ;
14
15
}
15
16
17
+ ///Errors associated with a header that is invalid.
18
+ #[ derive( Debug , PartialEq ) ]
19
+ pub enum HttpHeaderError {
20
+ /// The content length specified is longer than the limit imposed by Micro Http.
21
+ SizeLimitExceeded ( String ) ,
22
+ /// The header specified is not supported.
23
+ UnsupportedName ( String ) ,
24
+ /// The value for the specified header is not supported.
25
+ UnsupportedValue ( String , String ) ,
26
+ /// The specified header contains illegal characters.
27
+ InvalidUtf8String ( Utf8Error ) ,
28
+ /// The requested feature is not currently supported.
29
+ UnsupportedFeature ( String , String ) ,
30
+ /// The header is misformatted.
31
+ InvalidFormat ( String ) ,
32
+ ///The value specified is not valid.
33
+ InvalidValue ( String , String ) ,
34
+ }
35
+
36
+ impl Display for HttpHeaderError {
37
+ fn fmt ( & self , f : & mut Formatter ) -> Result < ( ) , Error > {
38
+ match self {
39
+ Self :: SizeLimitExceeded ( inner) => {
40
+ write ! ( f, "Invalid content length. Header: {}" , inner)
41
+ }
42
+ Self :: UnsupportedName ( inner) => write ! ( f, "Unsupported header name. Key: {}" , inner) ,
43
+ Self :: UnsupportedValue ( header_key, header_value) => write ! (
44
+ f,
45
+ "Unsupported value. Key:{}; Value:{}" ,
46
+ header_key, header_value
47
+ ) ,
48
+ Self :: InvalidUtf8String ( header_key) => {
49
+ write ! ( f, "Header contains invalid characters. Key: {}" , header_key)
50
+ }
51
+ Self :: UnsupportedFeature ( header_key, header_value) => write ! (
52
+ f,
53
+ "Unsupported feature. Key: {}; Value: {}" ,
54
+ header_key, header_value
55
+ ) ,
56
+ Self :: InvalidFormat ( header_key) => {
57
+ write ! ( f, "Header is incorrectly formatted. Key: {}" , header_key)
58
+ }
59
+ Self :: InvalidValue ( header_name, value) => {
60
+ write ! ( f, "Invalid value. Key:{}; Value:{}" , header_name, value)
61
+ }
62
+ }
63
+ }
64
+ }
65
+
16
66
/// Errors associated with parsing the HTTP Request from a u8 slice.
17
67
#[ derive( Debug , PartialEq ) ]
18
68
pub enum RequestError {
@@ -26,10 +76,8 @@ pub enum RequestError {
26
76
InvalidUri ( & ' static str ) ,
27
77
/// The HTTP Version in the Request is not supported or it is invalid.
28
78
InvalidHttpVersion ( & ' static str ) ,
29
- /// The header specified may be valid, but is not supported by this HTTP implementation.
30
- UnsupportedHeader ,
31
- /// Header specified is invalid.
32
- InvalidHeader ,
79
+ /// Header specified is either invalid or not supported by this HTTP implementation.
80
+ HeaderError ( HttpHeaderError ) ,
33
81
/// The Request is invalid and cannot be served.
34
82
InvalidRequest ,
35
83
/// Overflow occurred when parsing a request.
@@ -52,8 +100,7 @@ impl Display for RequestError {
52
100
Self :: InvalidHttpMethod ( inner) => write ! ( f, "Invalid HTTP Method: {}" , inner) ,
53
101
Self :: InvalidUri ( inner) => write ! ( f, "Invalid URI: {}" , inner) ,
54
102
Self :: InvalidHttpVersion ( inner) => write ! ( f, "Invalid HTTP Version: {}" , inner) ,
55
- Self :: UnsupportedHeader => write ! ( f, "Unsupported header." ) ,
56
- Self :: InvalidHeader => write ! ( f, "Invalid header." ) ,
103
+ Self :: HeaderError ( inner) => write ! ( f, "Invalid header. Reason: {}" , inner) ,
57
104
Self :: InvalidRequest => write ! ( f, "Invalid request." ) ,
58
105
Self :: Overflow => write ! ( f, "Overflow occurred when parsing a request." ) ,
59
106
Self :: Underflow => write ! ( f, "Underflow occurred when parsing a request." ) ,
@@ -340,10 +387,6 @@ mod tests {
340
387
format!( "{}" , RequestError :: HeadersWithoutPendingRequest ) ,
341
388
"No request was pending while the request headers were being parsed."
342
389
) ;
343
- assert_eq ! (
344
- format!( "{}" , RequestError :: InvalidHeader ) ,
345
- "Invalid header."
346
- ) ;
347
390
assert_eq ! (
348
391
format!( "{}" , RequestError :: InvalidHttpMethod ( "test" ) ) ,
349
392
"Invalid HTTP Method: test"
@@ -368,9 +411,60 @@ mod tests {
368
411
format!( "{}" , RequestError :: Underflow ) ,
369
412
"Underflow occurred when parsing a request."
370
413
) ;
414
+ }
415
+
416
+ #[ test]
417
+ fn test_display_header_error ( ) {
418
+ assert_eq ! (
419
+ format!(
420
+ "{}" ,
421
+ RequestError :: HeaderError ( HttpHeaderError :: SizeLimitExceeded ( "test" . to_string( ) ) )
422
+ ) ,
423
+ "Invalid header. Reason: Invalid content length. Header: test"
424
+ ) ;
425
+ assert_eq ! (
426
+ format!(
427
+ "{}" ,
428
+ RequestError :: HeaderError ( HttpHeaderError :: UnsupportedName ( "test" . to_string( ) ) )
429
+ ) ,
430
+ "Invalid header. Reason: Unsupported header name. Key: test"
431
+ ) ;
371
432
assert_eq ! (
372
- format!( "{}" , RequestError :: UnsupportedHeader ) ,
373
- "Unsupported header."
433
+ format!(
434
+ "{}" ,
435
+ RequestError :: HeaderError ( HttpHeaderError :: UnsupportedValue (
436
+ "test" . to_string( ) ,
437
+ "test" . to_string( )
438
+ ) )
439
+ ) ,
440
+ "Invalid header. Reason: Unsupported value. Key:test; Value:test"
441
+ ) ;
442
+ let value = String :: from_utf8 ( vec ! [ 0 , 159 ] ) ;
443
+ assert_eq ! (
444
+ format!(
445
+ "{}" ,
446
+ RequestError :: HeaderError ( HttpHeaderError :: InvalidUtf8String (
447
+ value. unwrap_err( ) . utf8_error( )
448
+ ) )
449
+ ) ,
450
+ "Invalid header. Reason: Header contains invalid characters. Key: invalid utf-8 sequence of 1 bytes from index 1"
451
+ ) ;
452
+ assert_eq ! (
453
+ format!(
454
+ "{}" ,
455
+ RequestError :: HeaderError ( HttpHeaderError :: UnsupportedFeature (
456
+ "test" . to_string( ) ,
457
+ "test" . to_string( )
458
+ ) )
459
+ ) ,
460
+ "Invalid header. Reason: Unsupported feature. Key: test; Value: test"
461
+ ) ;
462
+ assert_eq ! (
463
+ format!(
464
+ "{}" ,
465
+ RequestError :: HeaderError ( HttpHeaderError :: InvalidFormat ( "test" . to_string( ) ) )
466
+ ) ,
467
+ "Invalid header. Reason: Header is incorrectly formatted. Key: test"
374
468
) ;
375
469
}
376
470
0 commit comments