fix(server): convert panic to error if Connection::without_shutdown called on HTTP/2 conn
This commit is contained in:
13
src/error.rs
13
src/error.rs
@@ -128,6 +128,10 @@ pub(super) enum User {
|
|||||||
#[cfg(feature = "http1")]
|
#[cfg(feature = "http1")]
|
||||||
ManualUpgrade,
|
ManualUpgrade,
|
||||||
|
|
||||||
|
/// User called `server::Connection::without_shutdown()` on an HTTP/2 conn.
|
||||||
|
#[cfg(feature = "server")]
|
||||||
|
WithoutShutdownNonHttp1,
|
||||||
|
|
||||||
/// User aborted in an FFI callback.
|
/// User aborted in an FFI callback.
|
||||||
#[cfg(feature = "ffi")]
|
#[cfg(feature = "ffi")]
|
||||||
AbortedByCallback,
|
AbortedByCallback,
|
||||||
@@ -355,6 +359,11 @@ impl Error {
|
|||||||
Error::new_user(User::Body).with(cause)
|
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")]
|
#[cfg(feature = "http1")]
|
||||||
pub(super) fn new_shutdown(cause: std::io::Error) -> Error {
|
pub(super) fn new_shutdown(cause: std::io::Error) -> Error {
|
||||||
Error::new(Kind::Shutdown).with(cause)
|
Error::new(Kind::Shutdown).with(cause)
|
||||||
@@ -449,6 +458,10 @@ impl Error {
|
|||||||
Kind::User(User::NoUpgrade) => "no upgrade available",
|
Kind::User(User::NoUpgrade) => "no upgrade available",
|
||||||
#[cfg(feature = "http1")]
|
#[cfg(feature = "http1")]
|
||||||
Kind::User(User::ManualUpgrade) => "upgrade expected but low level API in use",
|
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")]
|
#[cfg(feature = "ffi")]
|
||||||
Kind::User(User::AbortedByCallback) => "operation aborted by an application callback",
|
Kind::User(User::AbortedByCallback) => "operation aborted by an application callback",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -741,10 +741,6 @@ where
|
|||||||
/// upgrade. Once the upgrade is completed, the connection would be "done",
|
/// upgrade. Once the upgrade is completed, the connection would be "done",
|
||||||
/// but it is not desired to actually shutdown the IO object. Instead you
|
/// but it is not desired to actually shutdown the IO object. Instead you
|
||||||
/// would take it back using `into_parts`.
|
/// 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<()>>
|
pub fn poll_without_shutdown(&mut self, cx: &mut task::Context<'_>) -> Poll<crate::Result<()>>
|
||||||
where
|
where
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
@@ -782,6 +778,10 @@ where
|
|||||||
|
|
||||||
/// Prevent shutdown of the underlying IO object at the end of service the request,
|
/// 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`.
|
/// 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>>>
|
pub fn without_shutdown(self) -> impl Future<Output = crate::Result<Parts<I, S>>>
|
||||||
where
|
where
|
||||||
S: Unpin,
|
S: Unpin,
|
||||||
@@ -791,7 +791,7 @@ where
|
|||||||
let mut conn = Some(self);
|
let mut conn = Some(self);
|
||||||
futures_util::future::poll_fn(move |cx| {
|
futures_util::future::poll_fn(move |cx| {
|
||||||
ready!(conn.as_mut().unwrap().poll_without_shutdown(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))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user