fix(http2): allow TE "trailers" request headers
The HTTP/2 spec allows TE headers in requests if the value is "trailers". Other TE headers are still stripped. Closes #1642
This commit is contained in:
committed by
Sean McArthur
parent
e3dc6c5511
commit
24f11a421d
@@ -108,7 +108,7 @@ where
|
|||||||
}
|
}
|
||||||
let (head, body) = req.into_parts();
|
let (head, body) = req.into_parts();
|
||||||
let mut req = ::http::Request::from_parts(head, ());
|
let mut req = ::http::Request::from_parts(head, ());
|
||||||
super::strip_connection_headers(req.headers_mut());
|
super::strip_connection_headers(req.headers_mut(), true);
|
||||||
if let Some(len) = body.content_length() {
|
if let Some(len) = body.content_length() {
|
||||||
headers::set_content_length_if_missing(req.headers_mut(), len);
|
headers::set_content_length_if_missing(req.headers_mut(), len);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,15 +15,17 @@ mod server;
|
|||||||
pub(crate) use self::client::Client;
|
pub(crate) use self::client::Client;
|
||||||
pub(crate) use self::server::Server;
|
pub(crate) use self::server::Server;
|
||||||
|
|
||||||
fn strip_connection_headers(headers: &mut HeaderMap) {
|
fn strip_connection_headers(headers: &mut HeaderMap, is_request: bool) {
|
||||||
// List of connection headers from:
|
// List of connection headers from:
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection
|
||||||
|
//
|
||||||
|
// TE headers are allowed in HTTP/2 requests as long as the value is "trailers", so they're
|
||||||
|
// tested separately.
|
||||||
let connection_headers = [
|
let connection_headers = [
|
||||||
HeaderName::from_lowercase(b"keep-alive").unwrap(),
|
HeaderName::from_lowercase(b"keep-alive").unwrap(),
|
||||||
HeaderName::from_lowercase(b"proxy-connection").unwrap(),
|
HeaderName::from_lowercase(b"proxy-connection").unwrap(),
|
||||||
PROXY_AUTHENTICATE,
|
PROXY_AUTHENTICATE,
|
||||||
PROXY_AUTHORIZATION,
|
PROXY_AUTHORIZATION,
|
||||||
TE,
|
|
||||||
TRAILER,
|
TRAILER,
|
||||||
TRANSFER_ENCODING,
|
TRANSFER_ENCODING,
|
||||||
UPGRADE,
|
UPGRADE,
|
||||||
@@ -35,6 +37,17 @@ fn strip_connection_headers(headers: &mut HeaderMap) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if is_request {
|
||||||
|
if headers.get(TE).map(|te_header| te_header != "trailers").unwrap_or(false) {
|
||||||
|
warn!("TE headers not set to \"trailers\" are illegal in HTTP/2 requests");
|
||||||
|
headers.remove(TE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if headers.remove(TE).is_some() {
|
||||||
|
warn!("TE headers illegal in HTTP/2 responses");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(header) = headers.remove(CONNECTION) {
|
if let Some(header) = headers.remove(CONNECTION) {
|
||||||
warn!(
|
warn!(
|
||||||
"Connection header illegal in HTTP/2: {}",
|
"Connection header illegal in HTTP/2: {}",
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ where
|
|||||||
|
|
||||||
let (head, body) = res.into_parts();
|
let (head, body) = res.into_parts();
|
||||||
let mut res = ::http::Response::from_parts(head, ());
|
let mut res = ::http::Response::from_parts(head, ());
|
||||||
super::strip_connection_headers(res.headers_mut());
|
super::strip_connection_headers(res.headers_mut(), false);
|
||||||
if let Some(len) = body.content_length() {
|
if let Some(len) = body.content_length() {
|
||||||
headers::set_content_length_if_missing(res.headers_mut(), len);
|
headers::set_content_length_if_missing(res.headers_mut(), len);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,6 +184,30 @@ t! {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t! {
|
||||||
|
get_allow_te_trailers_header,
|
||||||
|
client:
|
||||||
|
request:
|
||||||
|
uri: "/",
|
||||||
|
headers: {
|
||||||
|
// http2 strips connection headers other than TE "trailers"
|
||||||
|
"te" => "trailers",
|
||||||
|
},
|
||||||
|
;
|
||||||
|
response:
|
||||||
|
status: 200,
|
||||||
|
;
|
||||||
|
server:
|
||||||
|
request:
|
||||||
|
uri: "/",
|
||||||
|
headers: {
|
||||||
|
"te" => "trailers",
|
||||||
|
},
|
||||||
|
;
|
||||||
|
response:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
t! {
|
t! {
|
||||||
get_body_chunked,
|
get_body_chunked,
|
||||||
client:
|
client:
|
||||||
|
|||||||
Reference in New Issue
Block a user