diff --git a/src/proto/h2/mod.rs b/src/proto/h2/mod.rs index 8742d70c1c..de877f0bc7 100644 --- a/src/proto/h2/mod.rs +++ b/src/proto/h2/mod.rs @@ -116,6 +116,13 @@ where None => return Err(::Error::new_canceled(None::<::Error>)), } } + } else { + if let Async::Ready(reason) = + self.body_tx.poll_reset().map_err(|e| ::Error::new_h2(e))? + { + debug!("stream received RST_STREAM: {:?}", reason); + return Err(::Error::new_h2(reason.into())); + } } match try_ready!(self.stream.poll_data().map_err(|e| self.on_err(e))) { @@ -148,6 +155,13 @@ where } } } else { + if let Async::Ready(reason) = + self.body_tx.poll_reset().map_err(|e| ::Error::new_h2(e))? + { + debug!("stream received RST_STREAM: {:?}", reason); + return Err(::Error::new_h2(reason.into())); + } + match try_ready!(self.stream.poll_trailers().map_err(|e| self.on_err(e))) { Some(trailers) => { self.body_tx diff --git a/src/proto/h2/server.rs b/src/proto/h2/server.rs index 6777bfc109..d78d4a254e 100644 --- a/src/proto/h2/server.rs +++ b/src/proto/h2/server.rs @@ -174,7 +174,22 @@ where loop { let next = match self.state { H2StreamState::Service(ref mut h) => { - let res = try_ready!(h.poll().map_err(::Error::new_user_service)); + let res = match h.poll() { + Ok(Async::Ready(r)) => r, + Ok(Async::NotReady) => { + // Body is not yet ready, so we want to check if the client has sent a + // RST_STREAM frame which would cancel the current request. + if let Async::Ready(reason) = + self.reply.poll_reset().map_err(|e| ::Error::new_h2(e))? + { + debug!("stream received RST_STREAM: {:?}", reason); + return Err(::Error::new_h2(reason.into())); + } + return Ok(Async::NotReady); + } + Err(e) => return Err(::Error::new_user_service(e)), + }; + let (head, body) = res.into_parts(); let mut res = ::http::Response::from_parts(head, ()); super::strip_connection_headers(res.headers_mut());