Skip to content

Commit

Permalink
feat(upgrade): add upgrade feature
Browse files Browse the repository at this point in the history
  • Loading branch information
tottoto committed Oct 15, 2023
1 parent 8ebe25c commit ef1054a
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 4 deletions.
9 changes: 6 additions & 3 deletions Cargo.toml
Expand Up @@ -26,7 +26,6 @@ futures-util = { version = "0.3", default-features = false }
http = "0.2"
http-body = "=1.0.0-rc.2"
pin-project-lite = "0.2.4"
tokio = { version = "1.13", features = ["sync"] }

# Optional

Expand All @@ -36,6 +35,7 @@ httparse = { version = "1.8", optional = true }
httpdate = { version = "1.0", optional = true }
itoa = { version = "1", optional = true }
libc = { version = "0.2", optional = true }
tokio = { version = "1", features = ["sync"], optional = true }
tracing = { version = "0.1", default-features = false, features = ["std"], optional = true }
want = { version = "0.3", optional = true }

Expand Down Expand Up @@ -74,13 +74,16 @@ full = [
]

# HTTP versions
http1 = ["dep:httparse", "dep:itoa"]
http2 = ["dep:h2"]
http1 = ["upgrade", "dep:httparse", "dep:itoa"]
http2 = ["upgrade", "dep:h2"]

# Client/Server
client = ["dep:want"]
server = ["dep:httpdate"]

# HTTP Upgrades
upgrade = ["dep:tokio"]

# C-API support (currently unstable (no semver))
ffi = ["dep:libc", "dep:http-body-util"]

Expand Down
2 changes: 2 additions & 0 deletions src/common/io/mod.rs
@@ -1,7 +1,9 @@
#[cfg(all(any(feature = "client", feature = "server"), feature = "http2"))]
mod compat;
#[cfg(feature = "upgrade")]
mod rewind;

#[cfg(all(any(feature = "client", feature = "server"), feature = "http2"))]
pub(crate) use self::compat::{compat, Compat};
#[cfg(feature = "upgrade")]
pub(crate) use self::rewind::Rewind;
9 changes: 9 additions & 0 deletions src/error.rs
Expand Up @@ -48,6 +48,7 @@ pub(super) enum Kind {
#[cfg(all(any(feature = "client", feature = "server"), feature = "http1"))]
UnexpectedMessage,
/// A pending item was dropped before ever being processed.
#[cfg(feature = "upgrade")]
Canceled,
/// Indicates a channel (client or body sender) is closed.
ChannelClosed,
Expand Down Expand Up @@ -140,6 +141,7 @@ pub(super) enum User {
UnsupportedStatusCode,

/// User tried polling for an upgrade that doesn't exist.
#[cfg(feature = "upgrade")]
NoUpgrade,

/// User polled for an upgrade, but low-level API is not using upgrades.
Expand Down Expand Up @@ -186,6 +188,7 @@ impl Error {
}

/// Returns true if this was about a `Request` that was canceled.
#[cfg(feature = "upgrade")]
pub fn is_canceled(&self) -> bool {
matches!(self.inner.kind, Kind::Canceled)
}
Expand Down Expand Up @@ -216,6 +219,7 @@ impl Error {
}
}

#[cfg(feature = "upgrade")]
pub(super) fn with<C: Into<Cause>>(mut self, cause: C) -> Error {
self.inner.cause = Some(cause.into());
self
Expand Down Expand Up @@ -248,6 +252,7 @@ impl Error {
.unwrap_or(h2::Reason::INTERNAL_ERROR)
}

#[cfg(feature = "upgrade")]
pub(super) fn new_canceled() -> Error {
Error::new(Kind::Canceled)
}
Expand Down Expand Up @@ -304,6 +309,7 @@ impl Error {
Error::new(Kind::User(User::BodyWriteAborted))
}

#[cfg(feature = "upgrade")]
fn new_user(user: User) -> Error {
Error::new(Kind::User(user))
}
Expand All @@ -325,6 +331,7 @@ impl Error {
Error::new_user(User::UnsupportedStatusCode)
}

#[cfg(feature = "upgrade")]
pub(super) fn new_user_no_upgrade() -> Error {
Error::new_user(User::NoUpgrade)
}
Expand Down Expand Up @@ -408,6 +415,7 @@ impl Error {
#[cfg(all(any(feature = "client", feature = "server"), feature = "http1"))]
Kind::UnexpectedMessage => "received unexpected message from connection",
Kind::ChannelClosed => "channel closed",
#[cfg(feature = "upgrade")]
Kind::Canceled => "operation was canceled",
#[cfg(all(feature = "http1", feature = "server"))]
Kind::HeaderTimeout => "read header from client timeout",
Expand Down Expand Up @@ -450,6 +458,7 @@ impl Error {
Kind::User(User::UnsupportedStatusCode) => {
"response has 1xx status code, not supported by server"
}
#[cfg(feature = "upgrade")]
Kind::User(User::NoUpgrade) => "no upgrade available",
#[cfg(all(any(feature = "client", feature = "server"), feature = "http1"))]
Kind::User(User::ManualUpgrade) => "upgrade expected but low level API in use",
Expand Down
9 changes: 8 additions & 1 deletion src/lib.rs
Expand Up @@ -49,8 +49,10 @@
//! - `http2`: Enables HTTP/2 support.
//! - `client`: Enables the HTTP `client`.
//! - `server`: Enables the HTTP `server`.
//! - `upgrade`: Enables [HTTP Upgrades].
//!
//! [feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section
//! [Http Upgrades]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism
//!
//! # Unstable Features
//! hyper includes a set of unstable optional features that can be enabled through the use of a
Expand Down Expand Up @@ -93,7 +95,6 @@ pub mod ext;
mod mock;
pub mod rt;
pub mod service;
pub mod upgrade;

#[cfg(feature = "ffi")]
#[cfg_attr(docsrs, doc(cfg(all(feature = "ffi", hyper_unstable_ffi))))]
Expand All @@ -115,3 +116,9 @@ cfg_feature! {

pub mod server;
}

cfg_feature! {
#![feature = "upgrade"]

pub mod upgrade;
}
3 changes: 3 additions & 0 deletions src/rt/io.rs
Expand Up @@ -200,6 +200,7 @@ impl<'data> ReadBuf<'data> {
}

#[inline]
#[cfg(feature = "upgrade")]
fn remaining(&self) -> usize {
self.capacity() - self.filled
}
Expand Down Expand Up @@ -244,11 +245,13 @@ impl<'data> ReadBufCursor<'data> {
}

#[inline]
#[cfg(feature = "upgrade")]
pub(crate) fn remaining(&self) -> usize {
self.buf.remaining()
}

#[inline]
#[cfg(feature = "upgrade")]
pub(crate) fn put_slice(&mut self, buf: &[u8]) {
assert!(
self.buf.remaining() >= buf.len(),
Expand Down

0 comments on commit ef1054a

Please sign in to comment.