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