feat(http1): Make HTTP/1 support an optional feature
cc #2251 BREAKING CHANGE: This puts all HTTP/1 methods and support behind an `http1` cargo feature, which will not be enabled by default. To use HTTP/1, add `features = ["http1"]` to the hyper dependency in your `Cargo.toml`.
This commit is contained in:
		
							
								
								
									
										123
									
								
								src/proto/mod.rs
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								src/proto/mod.rs
									
									
									
									
									
								
							| @@ -1,10 +1,11 @@ | ||||
| //! Pieces pertaining to the HTTP message protocol. | ||||
| use http::{HeaderMap, Method, StatusCode, Uri, Version}; | ||||
|  | ||||
| pub(crate) use self::body_length::DecodedLength; | ||||
| pub(crate) use self::h1::{dispatch, Conn, ServerTransaction}; | ||||
| cfg_http1! { | ||||
|     pub(crate) mod h1; | ||||
|  | ||||
|     pub(crate) use self::h1::{dispatch, Conn, ServerTransaction}; | ||||
| } | ||||
|  | ||||
| pub(crate) mod h1; | ||||
| cfg_http2! { | ||||
|     pub(crate) mod h2; | ||||
| } | ||||
| @@ -13,23 +14,27 @@ cfg_http2! { | ||||
| #[derive(Clone, Debug, Default, PartialEq)] | ||||
| pub struct MessageHead<S> { | ||||
|     /// HTTP version of the message. | ||||
|     pub version: Version, | ||||
|     pub version: http::Version, | ||||
|     /// Subject (request line or status line) of Incoming message. | ||||
|     pub subject: S, | ||||
|     /// Headers of the Incoming message. | ||||
|     pub headers: HeaderMap, | ||||
|     pub headers: http::HeaderMap, | ||||
| } | ||||
|  | ||||
| /// An incoming request message. | ||||
| #[cfg(feature = "http1")] | ||||
| pub type RequestHead = MessageHead<RequestLine>; | ||||
|  | ||||
| #[derive(Debug, Default, PartialEq)] | ||||
| pub struct RequestLine(pub Method, pub Uri); | ||||
| #[cfg(feature = "http1")] | ||||
| pub struct RequestLine(pub http::Method, pub http::Uri); | ||||
|  | ||||
| /// An incoming response message. | ||||
| pub type ResponseHead = MessageHead<StatusCode>; | ||||
| #[cfg(feature = "http1")] | ||||
| pub type ResponseHead = MessageHead<http::StatusCode>; | ||||
|  | ||||
| #[derive(Debug)] | ||||
| #[cfg(feature = "http1")] | ||||
| pub enum BodyLength { | ||||
|     /// Content-Length | ||||
|     Known(u64), | ||||
| @@ -42,106 +47,6 @@ pub(crate) enum Dispatched { | ||||
|     /// Dispatcher completely shutdown connection. | ||||
|     Shutdown, | ||||
|     /// Dispatcher has pending upgrade, and so did not shutdown. | ||||
|     #[cfg(feature = "http1")] | ||||
|     Upgrade(crate::upgrade::Pending), | ||||
| } | ||||
|  | ||||
| /// A separate module to encapsulate the invariants of the DecodedLength type. | ||||
| mod body_length { | ||||
|     use std::fmt; | ||||
|  | ||||
|     #[derive(Clone, Copy, PartialEq, Eq)] | ||||
|     pub(crate) struct DecodedLength(u64); | ||||
|  | ||||
|     const MAX_LEN: u64 = std::u64::MAX - 2; | ||||
|  | ||||
|     impl DecodedLength { | ||||
|         pub(crate) const CLOSE_DELIMITED: DecodedLength = DecodedLength(::std::u64::MAX); | ||||
|         pub(crate) const CHUNKED: DecodedLength = DecodedLength(::std::u64::MAX - 1); | ||||
|         pub(crate) const ZERO: DecodedLength = DecodedLength(0); | ||||
|  | ||||
|         #[cfg(test)] | ||||
|         pub(crate) fn new(len: u64) -> Self { | ||||
|             debug_assert!(len <= MAX_LEN); | ||||
|             DecodedLength(len) | ||||
|         } | ||||
|  | ||||
|         /// Takes the length as a content-length without other checks. | ||||
|         /// | ||||
|         /// Should only be called if previously confirmed this isn't | ||||
|         /// CLOSE_DELIMITED or CHUNKED. | ||||
|         #[inline] | ||||
|         pub(crate) fn danger_len(self) -> u64 { | ||||
|             debug_assert!(self.0 < Self::CHUNKED.0); | ||||
|             self.0 | ||||
|         } | ||||
|  | ||||
|         /// Converts to an Option<u64> representing a Known or Unknown length. | ||||
|         pub(crate) fn into_opt(self) -> Option<u64> { | ||||
|             match self { | ||||
|                 DecodedLength::CHUNKED | DecodedLength::CLOSE_DELIMITED => None, | ||||
|                 DecodedLength(known) => Some(known), | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// Checks the `u64` is within the maximum allowed for content-length. | ||||
|         pub(crate) fn checked_new(len: u64) -> Result<Self, crate::error::Parse> { | ||||
|             if len <= MAX_LEN { | ||||
|                 Ok(DecodedLength(len)) | ||||
|             } else { | ||||
|                 warn!("content-length bigger than maximum: {} > {}", len, MAX_LEN); | ||||
|                 Err(crate::error::Parse::TooLarge) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         pub(crate) fn sub_if(&mut self, amt: u64) { | ||||
|             match *self { | ||||
|                 DecodedLength::CHUNKED | DecodedLength::CLOSE_DELIMITED => (), | ||||
|                 DecodedLength(ref mut known) => { | ||||
|                     *known -= amt; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     impl fmt::Debug for DecodedLength { | ||||
|         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
|             match *self { | ||||
|                 DecodedLength::CLOSE_DELIMITED => f.write_str("CLOSE_DELIMITED"), | ||||
|                 DecodedLength::CHUNKED => f.write_str("CHUNKED"), | ||||
|                 DecodedLength(n) => f.debug_tuple("DecodedLength").field(&n).finish(), | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     impl fmt::Display for DecodedLength { | ||||
|         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
|             match *self { | ||||
|                 DecodedLength::CLOSE_DELIMITED => f.write_str("close-delimited"), | ||||
|                 DecodedLength::CHUNKED => f.write_str("chunked encoding"), | ||||
|                 DecodedLength::ZERO => f.write_str("empty"), | ||||
|                 DecodedLength(n) => write!(f, "content-length ({} bytes)", n), | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #[cfg(test)] | ||||
|     mod tests { | ||||
|         use super::*; | ||||
|  | ||||
|         #[test] | ||||
|         fn sub_if_known() { | ||||
|             let mut len = DecodedLength::new(30); | ||||
|             len.sub_if(20); | ||||
|  | ||||
|             assert_eq!(len.0, 10); | ||||
|         } | ||||
|  | ||||
|         #[test] | ||||
|         fn sub_if_chunked() { | ||||
|             let mut len = DecodedLength::CHUNKED; | ||||
|             len.sub_if(20); | ||||
|  | ||||
|             assert_eq!(len, DecodedLength::CHUNKED); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user