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
						Sean McArthur
					
				
			
			
				
	
			
			
			
						parent
						
							e3dc6c5511
						
					
				
				
					commit
					24f11a421d
				
			| @@ -108,7 +108,7 @@ where | ||||
|                             } | ||||
|                             let (head, body) = req.into_parts(); | ||||
|                             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() { | ||||
|                                 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::server::Server; | ||||
|  | ||||
| fn strip_connection_headers(headers: &mut HeaderMap) { | ||||
| fn strip_connection_headers(headers: &mut HeaderMap, is_request: bool) { | ||||
|     // List of connection headers from: | ||||
|     // 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 = [ | ||||
|         HeaderName::from_lowercase(b"keep-alive").unwrap(), | ||||
|         HeaderName::from_lowercase(b"proxy-connection").unwrap(), | ||||
|         PROXY_AUTHENTICATE, | ||||
|         PROXY_AUTHORIZATION, | ||||
|         TE, | ||||
|         TRAILER, | ||||
|         TRANSFER_ENCODING, | ||||
|         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) { | ||||
|         warn!( | ||||
|             "Connection header illegal in HTTP/2: {}", | ||||
|   | ||||
| @@ -192,7 +192,7 @@ where | ||||
|  | ||||
|                     let (head, body) = res.into_parts(); | ||||
|                     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() { | ||||
|                         headers::set_content_length_if_missing(res.headers_mut(), len); | ||||
|                     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user