Skip to content

Commit

Permalink
feat(http2): quickly cancel when receiving RST_STREAM
Browse files Browse the repository at this point in the history
Update Http2 proto to cancel quick when the stream is reset, on an
`RST_STREAM` frame.

Closes: #1549
  • Loading branch information
Josh Leeb-du Toit authored and seanmonstar committed Jun 25, 2018
1 parent 2a3844a commit ffdb478
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
14 changes: 14 additions & 0 deletions src/proto/h2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))) {
Expand Down Expand Up @@ -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
Expand Down
17 changes: 16 additions & 1 deletion src/proto/h2/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down

0 comments on commit ffdb478

Please sign in to comment.