Skip to content

Commit fd2e80c

Browse files
committed
fix(h2): improve I/O errors emitted by H2Upgraded
1 parent 5243570 commit fd2e80c

File tree

1 file changed

+30
-13
lines changed

1 file changed

+30
-13
lines changed

src/proto/h2/mod.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use bytes::{Buf, Bytes};
2-
use h2::{RecvStream, SendStream};
2+
use h2::{Reason, RecvStream, SendStream};
33
use http::header::{HeaderName, CONNECTION, TE, TRAILER, TRANSFER_ENCODING, UPGRADE};
44
use http::HeaderMap;
55
use pin_project_lite::pin_project;
@@ -313,7 +313,11 @@ where
313313
break buf;
314314
}
315315
Some(Err(e)) => {
316-
return Poll::Ready(Err(h2_to_io_error(e)));
316+
return Poll::Ready(match e.reason() {
317+
Some(Reason::NO_ERROR) | Some(Reason::CANCEL) => Ok(()),
318+
Some(Reason::STREAM_CLOSED) => Err(io::ErrorKind::BrokenPipe.into()),
319+
_ => Err(h2_to_io_error(e)),
320+
})
317321
}
318322
}
319323
};
@@ -335,21 +339,34 @@ where
335339
cx: &mut Context<'_>,
336340
buf: &[u8],
337341
) -> Poll<Result<usize, io::Error>> {
338-
if let Poll::Ready(reset) = self.send_stream.poll_reset(cx) {
339-
return Poll::Ready(Err(h2_to_io_error(match reset {
340-
Ok(reason) => reason.into(),
341-
Err(e) => e,
342-
})));
343-
}
344342
if buf.is_empty() {
345343
return Poll::Ready(Ok(0));
346344
}
347345
self.send_stream.reserve_capacity(buf.len());
348-
Poll::Ready(match ready!(self.send_stream.poll_capacity(cx)) {
349-
None => Ok(0),
350-
Some(Ok(cnt)) => self.send_stream.write(&buf[..cnt], false).map(|()| cnt),
351-
Some(Err(e)) => Err(h2_to_io_error(e)),
352-
})
346+
347+
let cnt = match ready!(self.send_stream.poll_capacity(cx)) {
348+
None => Some(0),
349+
Some(Ok(cnt)) => self
350+
.send_stream
351+
.write(&buf[..cnt], false)
352+
.ok()
353+
.map(|()| cnt),
354+
Some(Err(_)) => None,
355+
};
356+
357+
if let Some(cnt) = cnt {
358+
return Poll::Ready(Ok(cnt));
359+
}
360+
361+
Poll::Ready(Err(h2_to_io_error(
362+
match ready!(self.send_stream.poll_reset(cx)) {
363+
Ok(Reason::NO_ERROR) | Ok(Reason::CANCEL) | Ok(Reason::STREAM_CLOSED) => {
364+
return Poll::Ready(Err(io::ErrorKind::BrokenPipe.into()))
365+
}
366+
Ok(reason) => reason.into(),
367+
Err(e) => e,
368+
},
369+
)))
353370
}
354371

355372
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {

0 commit comments

Comments
 (0)