Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(upgrade): add upgrade feature #3330

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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