Skip to content

Commit

Permalink
fix(server): convert panic to error if Connection::without_shutdown c…
Browse files Browse the repository at this point in the history
…alled on HTTP/2 conn
  • Loading branch information
seanmonstar committed Sep 15, 2021
1 parent c88011d commit ea3e228
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
13 changes: 13 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ pub(super) enum User {
#[cfg(feature = "http1")]
ManualUpgrade,

/// User called `server::Connection::without_shutdown()` on an HTTP/2 conn.
#[cfg(feature = "server")]
WithoutShutdownNonHttp1,

/// User aborted in an FFI callback.
#[cfg(feature = "ffi")]
AbortedByCallback,
Expand Down Expand Up @@ -355,6 +359,11 @@ impl Error {
Error::new_user(User::Body).with(cause)
}

#[cfg(feature = "server")]
pub(super) fn new_without_shutdown_not_h1() -> Error {
Error::new(Kind::User(User::WithoutShutdownNonHttp1))
}

#[cfg(feature = "http1")]
pub(super) fn new_shutdown(cause: std::io::Error) -> Error {
Error::new(Kind::Shutdown).with(cause)
Expand Down Expand Up @@ -449,6 +458,10 @@ impl Error {
Kind::User(User::NoUpgrade) => "no upgrade available",
#[cfg(feature = "http1")]
Kind::User(User::ManualUpgrade) => "upgrade expected but low level API in use",
#[cfg(feature = "server")]
Kind::User(User::WithoutShutdownNonHttp1) => {
"without_shutdown() called on a non-HTTP/1 connection"
}
#[cfg(feature = "ffi")]
Kind::User(User::AbortedByCallback) => "operation aborted by an application callback",
}
Expand Down
10 changes: 5 additions & 5 deletions src/server/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,10 +741,6 @@ where
/// upgrade. Once the upgrade is completed, the connection would be "done",
/// but it is not desired to actually shutdown the IO object. Instead you
/// would take it back using `into_parts`.
///
/// Use [`poll_fn`](https://docs.rs/futures/0.1.25/futures/future/fn.poll_fn.html)
/// and [`try_ready!`](https://docs.rs/futures/0.1.25/futures/macro.try_ready.html)
/// to work with this function; or use the `without_shutdown` wrapper.
pub fn poll_without_shutdown(&mut self, cx: &mut task::Context<'_>) -> Poll<crate::Result<()>>
where
S: Unpin,
Expand Down Expand Up @@ -782,6 +778,10 @@ where

/// Prevent shutdown of the underlying IO object at the end of service the request,
/// instead run `into_parts`. This is a convenience wrapper over `poll_without_shutdown`.
///
/// # Error
///
/// This errors if the underlying connection protocol is not HTTP/1.
pub fn without_shutdown(self) -> impl Future<Output = crate::Result<Parts<I, S>>>
where
S: Unpin,
Expand All @@ -791,7 +791,7 @@ where
let mut conn = Some(self);
futures_util::future::poll_fn(move |cx| {
ready!(conn.as_mut().unwrap().poll_without_shutdown(cx))?;
Poll::Ready(Ok(conn.take().unwrap().into_parts()))
Poll::Ready(conn.take().unwrap().try_into_parts().ok_or_else(crate::Error::new_without_shutdown_not_h1))
})
}

Expand Down

0 comments on commit ea3e228

Please sign in to comment.