summaryrefslogtreecommitdiffstats
path: root/third_party/rust/hyper/src/proto/mod.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/hyper/src/proto/mod.rs
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/hyper/src/proto/mod.rs')
-rw-r--r--third_party/rust/hyper/src/proto/mod.rs145
1 files changed, 145 insertions, 0 deletions
diff --git a/third_party/rust/hyper/src/proto/mod.rs b/third_party/rust/hyper/src/proto/mod.rs
new file mode 100644
index 0000000000..7268e21265
--- /dev/null
+++ b/third_party/rust/hyper/src/proto/mod.rs
@@ -0,0 +1,145 @@
+//! 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};
+
+pub(crate) mod h1;
+pub(crate) mod h2;
+
+/// An Incoming Message head. Includes request/status line, and headers.
+#[derive(Clone, Debug, Default, PartialEq)]
+pub struct MessageHead<S> {
+ /// HTTP version of the message.
+ pub version: Version,
+ /// Subject (request line or status line) of Incoming message.
+ pub subject: S,
+ /// Headers of the Incoming message.
+ pub headers: HeaderMap,
+}
+
+/// An incoming request message.
+pub type RequestHead = MessageHead<RequestLine>;
+
+#[derive(Debug, Default, PartialEq)]
+pub struct RequestLine(pub Method, pub Uri);
+
+/// An incoming response message.
+pub type ResponseHead = MessageHead<StatusCode>;
+
+#[derive(Debug)]
+pub enum BodyLength {
+ /// Content-Length
+ Known(u64),
+ /// Transfer-Encoding: chunked (if h1)
+ Unknown,
+}
+
+/// Status of when a Disaptcher future completes.
+pub(crate) enum Dispatched {
+ /// Dispatcher completely shutdown connection.
+ Shutdown,
+ /// Dispatcher has pending upgrade, and so did not shutdown.
+ 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);
+ }
+ }
+}