-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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`.
- Loading branch information
1 parent
2f2ceb2
commit 2a19ab7
Showing
31 changed files
with
459 additions
and
239 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
use std::fmt; | ||
|
||
#[derive(Clone, Copy, PartialEq, Eq)] | ||
pub(crate) struct DecodedLength(u64); | ||
|
||
#[cfg(any(feature = "http1", feature = "http2", test))] | ||
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] | ||
#[cfg(feature = "http1")] | ||
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. | ||
#[cfg(any(feature = "http1", feature = "http2"))] | ||
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,37 @@ | ||
macro_rules! cfg_http2 { | ||
macro_rules! cfg_any_http { | ||
($($item:item)*) => { | ||
$( | ||
#[cfg(feature = "http2")] | ||
//#[cfg_attr(docsrs, doc(cfg(feature = "http2")))] | ||
#[cfg(any( | ||
feature = "http1", | ||
feature = "http2", | ||
))] | ||
#[cfg_attr(docsrs, doc(cfg(any( | ||
feature = "http1", | ||
feature = "http2", | ||
))))] | ||
$item | ||
)* | ||
} | ||
} | ||
|
||
cfg_any_http! { | ||
macro_rules! cfg_http1 { | ||
($($item:item)*) => { | ||
$( | ||
#[cfg(feature = "http1")] | ||
#[cfg_attr(docsrs, doc(cfg(feature = "http1")))] | ||
$item | ||
)* | ||
} | ||
} | ||
|
||
macro_rules! cfg_http2 { | ||
($($item:item)*) => { | ||
$( | ||
#[cfg(feature = "http2")] | ||
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))] | ||
$item | ||
)* | ||
} | ||
} | ||
} |
Oops, something went wrong.