fix(http1): apply header title case for consecutive dashes (#2613)
Fix the header title-casing to work with consecutive dashes. Previously with two dashes in a row the first dash would uppercase the second dash which would then not count, so `weird--header` would be cased as `Weird--header` instead of `Weird--Header`.
This commit is contained in:
		| @@ -1308,36 +1308,18 @@ fn record_header_indices( | |||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Write header names as title case. The header name is assumed to be ASCII, | // Write header names as title case. The header name is assumed to be ASCII. | ||||||
| // therefore it is trivial to convert an ASCII character from lowercase to |  | ||||||
| // uppercase. It is as simple as XORing the lowercase character byte with |  | ||||||
| // space. |  | ||||||
| fn title_case(dst: &mut Vec<u8>, name: &[u8]) { | fn title_case(dst: &mut Vec<u8>, name: &[u8]) { | ||||||
|     dst.reserve(name.len()); |     dst.reserve(name.len()); | ||||||
|  |  | ||||||
|     let mut iter = name.iter(); |     // Ensure first character is uppercased | ||||||
|  |     let mut prev = b'-'; | ||||||
|     // Uppercase the first character |     for &(mut c) in name { | ||||||
|     if let Some(c) = iter.next() { |         if prev == b'-' { | ||||||
|         if *c >= b'a' && *c <= b'z' { |             c.make_ascii_uppercase(); | ||||||
|             dst.push(*c ^ b' '); |  | ||||||
|         } else { |  | ||||||
|             dst.push(*c); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     while let Some(c) = iter.next() { |  | ||||||
|         dst.push(*c); |  | ||||||
|  |  | ||||||
|         if *c == b'-' { |  | ||||||
|             if let Some(c) = iter.next() { |  | ||||||
|                 if *c >= b'a' && *c <= b'z' { |  | ||||||
|                     dst.push(*c ^ b' '); |  | ||||||
|                 } else { |  | ||||||
|                     dst.push(*c); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |         dst.push(c); | ||||||
|  |         prev = c; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -2316,6 +2298,8 @@ mod tests { | |||||||
|             .insert("content-length", HeaderValue::from_static("10")); |             .insert("content-length", HeaderValue::from_static("10")); | ||||||
|         head.headers |         head.headers | ||||||
|             .insert("content-type", HeaderValue::from_static("application/json")); |             .insert("content-type", HeaderValue::from_static("application/json")); | ||||||
|  |         head.headers | ||||||
|  |             .insert("weird--header", HeaderValue::from_static("")); | ||||||
|  |  | ||||||
|         let mut vec = Vec::new(); |         let mut vec = Vec::new(); | ||||||
|         Server::encode( |         Server::encode( | ||||||
| @@ -2331,7 +2315,7 @@ mod tests { | |||||||
|         .unwrap(); |         .unwrap(); | ||||||
|  |  | ||||||
|         let expected_response = |         let expected_response = | ||||||
|             b"HTTP/1.1 200 OK\r\nContent-Length: 10\r\nContent-Type: application/json\r\n"; |             b"HTTP/1.1 200 OK\r\nContent-Length: 10\r\nContent-Type: application/json\r\nWeird--Header: \r\n"; | ||||||
|  |  | ||||||
|         assert_eq!(&vec[..expected_response.len()], &expected_response[..]); |         assert_eq!(&vec[..expected_response.len()], &expected_response[..]); | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user