From c5a3f9f543905a13c4644b286fde9616a8d04071 Mon Sep 17 00:00:00 2001 From: wt-l00 Date: Tue, 30 Jun 2020 03:34:03 +0000 Subject: [PATCH] Add more flexibility when parsing the headers Any number of whitespace characters are accepted after ":" when parsing HTTP headers. Create a test function (Add test_parse_header_whitespace). This test addresses parsing header and allow no space and any amount of linear white space after ":". And modified CHANGELOG.md. Signed-off-by: Eisuke Matsushita Signed-off-by: YUAN LYU --- src/common/headers.rs | 48 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/src/common/headers.rs b/src/common/headers.rs index 13dfffe..929aec5 100644 --- a/src/common/headers.rs +++ b/src/common/headers.rs @@ -128,7 +128,7 @@ impl Headers { // Headers must be ASCII, so also UTF-8 valid. match std::str::from_utf8(header_line) { Ok(headers_str) => { - let entry = headers_str.split(": ").collect::>(); + let entry = headers_str.splitn(2, ':').collect::>(); if entry.len() != 2 { return Err(RequestError::InvalidHeader); } @@ -378,9 +378,10 @@ mod tests { assert_eq!(headers.content_length, 55); assert_eq!(headers.accept, MediaType::ApplicationJson); - // Valid headers. + // Valid headers. (${HEADER_NAME} : WHITESPACE ${HEADER_VALUE}) + // Any number of whitespace characters should be accepted including zero. let headers = Headers::try_from( - b"Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT\r\nAccept: text/plain\r\nContent-Length: 49\r\n\r\n" + b"Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT\r\nAccept:text/plain\r\nContent-Length: 49\r\n\r\n" ) .unwrap(); assert_eq!(headers.content_length, 49); @@ -481,6 +482,47 @@ mod tests { .is_err()); } + #[test] + fn test_parse_header_whitespace() { + let mut header = Headers::default(); + // Test that any number of whitespace characters are accepted before the header value. + // For Content-Length + assert!(header.parse_header_line(b"Content-Length:24").is_ok()); + assert!(header.parse_header_line(b"Content-Length: 24").is_ok()); + + // For ContentType + assert!(header + .parse_header_line(b"Content-Type:application/json") + .is_ok()); + assert!(header + .parse_header_line(b"Content-Type: application/json") + .is_ok()); + + // For Accept + assert!(header.parse_header_line(b"Accept:application/json").is_ok()); + assert!(header + .parse_header_line(b"Accept: application/json") + .is_ok()); + + // For Transfer-Encoding + assert!(header + .parse_header_line(b"Transfer-Encoding:chunked") + .is_ok()); + assert!(header.chunked()); + assert!(header + .parse_header_line(b"Transfer-Encoding: chunked") + .is_ok()); + assert!(header.chunked()); + + // For Server + assert!(header.parse_header_line(b"Server:xxx.yyy.zzz").is_ok()); + assert!(header.parse_header_line(b"Server: xxx.yyy.zzz").is_ok()); + + // For Expect + assert!(header.parse_header_line(b"Expect:100-continue").is_ok()); + assert!(header.parse_header_line(b"Expect: 100-continue").is_ok()); + } + #[test] fn test_header_try_from() { // Bad header.