1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-06-25 14:49:20 +02:00

Fix poll_ready call for WebSockets upgrade (#1219)

* Fix poll_ready call for WebSockets upgrade

* Poll upgrade service from H1ServiceHandler too
This commit is contained in:
Rajasekharan Vengalil
2019-12-16 23:34:25 -08:00
committed by Nikolay Kim
parent 29ac6463e1
commit 3b860ebdc7
5 changed files with 120 additions and 57 deletions

View File

@ -66,7 +66,6 @@ where
U::Error: fmt::Display,
{
Normal(InnerDispatcher<T, S, B, X, U>),
UpgradeReadiness(InnerDispatcher<T, S, B, X, U>, Request),
Upgrade(U::Future),
None,
}
@ -764,8 +763,16 @@ where
if let DispatcherState::Normal(inner) =
std::mem::replace(&mut self.inner, DispatcherState::None)
{
self.inner =
DispatcherState::UpgradeReadiness(inner, req);
let mut parts = FramedParts::with_read_buf(
inner.io,
inner.codec,
inner.read_buf,
);
parts.write_buf = inner.write_buf;
let framed = Framed::from_parts(parts);
self.inner = DispatcherState::Upgrade(
inner.upgrade.unwrap().call((req, framed)),
);
return self.poll(cx);
} else {
panic!()
@ -815,35 +822,6 @@ where
}
}
}
DispatcherState::UpgradeReadiness(ref mut inner, _) => {
let upgrade = inner.upgrade.as_mut().unwrap();
match upgrade.poll_ready(cx) {
Poll::Ready(Ok(_)) => {
if let DispatcherState::UpgradeReadiness(inner, req) =
std::mem::replace(&mut self.inner, DispatcherState::None)
{
let mut parts = FramedParts::with_read_buf(
inner.io,
inner.codec,
inner.read_buf,
);
parts.write_buf = inner.write_buf;
let framed = Framed::from_parts(parts);
self.inner = DispatcherState::Upgrade(
inner.upgrade.unwrap().call((req, framed)),
);
self.poll(cx)
} else {
panic!()
}
}
Poll::Pending => Poll::Pending,
Poll::Ready(Err(e)) => {
error!("Upgrade handler readiness check error: {}", e);
Poll::Ready(Err(DispatchError::Upgrade))
}
}
}
DispatcherState::Upgrade(ref mut fut) => {
unsafe { Pin::new_unchecked(fut) }.poll(cx).map_err(|e| {
error!("Upgrade handler error: {}", e);

View File

@ -72,7 +72,7 @@ where
Request = (Request, Framed<TcpStream, Codec>),
Response = (),
>,
U::Error: fmt::Display,
U::Error: fmt::Display + Into<Error>,
U::InitError: fmt::Debug,
{
/// Create simple tcp stream service
@ -115,7 +115,7 @@ mod openssl {
Request = (Request, Framed<SslStream<TcpStream>, Codec>),
Response = (),
>,
U::Error: fmt::Display,
U::Error: fmt::Display + Into<Error>,
U::InitError: fmt::Debug,
{
/// Create openssl based service
@ -255,7 +255,7 @@ where
X::Error: Into<Error>,
X::InitError: fmt::Debug,
U: ServiceFactory<Config = (), Request = (Request, Framed<T, Codec>), Response = ()>,
U::Error: fmt::Display,
U::Error: fmt::Display + Into<Error>,
U::InitError: fmt::Debug,
{
type Config = ();
@ -412,7 +412,7 @@ where
X: Service<Request = Request, Response = Request>,
X::Error: Into<Error>,
U: Service<Request = (Request, Framed<T, Codec>), Response = ()>,
U::Error: fmt::Display,
U::Error: fmt::Display + Into<Error>,
{
type Request = (T, Option<net::SocketAddr>);
type Response = ();
@ -440,6 +440,19 @@ where
})?
.is_ready()
&& ready;
let ready = if let Some(ref mut upg) = self.upgrade {
upg.poll_ready(cx)
.map_err(|e| {
let e = e.into();
log::error!("Http service readiness error: {:?}", e);
DispatchError::Service(e)
})?
.is_ready()
&& ready
} else {
ready
};
if ready {
Poll::Ready(Ok(()))

View File

@ -169,7 +169,7 @@ where
Request = (Request, Framed<TcpStream, h1::Codec>),
Response = (),
>,
U::Error: fmt::Display,
U::Error: fmt::Display + Into<Error>,
U::InitError: fmt::Debug,
<U::Service as Service>::Future: 'static,
{
@ -214,7 +214,7 @@ mod openssl {
Request = (Request, Framed<SslStream<TcpStream>, h1::Codec>),
Response = (),
>,
U::Error: fmt::Display,
U::Error: fmt::Display + Into<Error>,
U::InitError: fmt::Debug,
<U::Service as Service>::Future: 'static,
{
@ -335,7 +335,7 @@ where
Request = (Request, Framed<T, h1::Codec>),
Response = (),
>,
U::Error: fmt::Display,
U::Error: fmt::Display + Into<Error>,
U::InitError: fmt::Debug,
<U::Service as Service>::Future: 'static,
{
@ -493,7 +493,7 @@ where
X: Service<Request = Request, Response = Request>,
X::Error: Into<Error>,
U: Service<Request = (Request, Framed<T, h1::Codec>), Response = ()>,
U::Error: fmt::Display,
U::Error: fmt::Display + Into<Error>,
{
type Request = (T, Protocol, Option<net::SocketAddr>);
type Response = ();
@ -522,6 +522,19 @@ where
.is_ready()
&& ready;
let ready = if let Some(ref mut upg) = self.upgrade {
upg.poll_ready(cx)
.map_err(|e| {
let e = e.into();
log::error!("Http service readiness error: {:?}", e);
DispatchError::Service(e)
})?
.is_ready()
&& ready
} else {
ready
};
if ready {
Poll::Ready(Ok(()))
} else {