Skip to content

Commit 97704b5

Browse files
authored
fix: not return UnexpectedEof when server drops without close_notify (#847)
* feat: not return UnexpectedEof when server drops without close_notify * propogate EoF to client if server drops without go_away
1 parent 27d1272 commit 97704b5

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

src/proto/connection.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,9 +482,11 @@ where
482482
// without error
483483
//
484484
// See https://github.com/hyperium/hyper/issues/3427
485-
if self.streams.is_server()
486-
&& self.streams.is_buffer_empty()
485+
if self.streams.is_buffer_empty()
487486
&& matches!(kind, io::ErrorKind::UnexpectedEof)
487+
&& (self.streams.is_server()
488+
|| self.error.as_ref().map(|f| f.reason() == Reason::NO_ERROR)
489+
== Some(true))
488490
{
489491
*self.state = State::Closed(Reason::NO_ERROR, Initiator::Library);
490492
return Ok(());

tests/h2-tests/tests/client_request.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,6 +1913,8 @@ async fn receive_settings_frame_twice_with_second_one_non_empty() {
19131913
join(srv, h2).await;
19141914
}
19151915

1916+
// If the server has not sent a go_away message before dropping the connection
1917+
// make sure the UnexpectedEof error is propogated.
19161918
#[tokio::test]
19171919
async fn server_drop_connection_unexpectedly_return_unexpected_eof_err() {
19181920
h2_support::trace_init!();
@@ -1953,6 +1955,44 @@ async fn server_drop_connection_unexpectedly_return_unexpected_eof_err() {
19531955
join(srv, h2).await;
19541956
}
19551957

1958+
#[tokio::test]
1959+
async fn server_drop_connection_after_go_away() {
1960+
h2_support::trace_init!();
1961+
let (io, mut srv) = mock::new();
1962+
1963+
let srv = async move {
1964+
let settings = srv.assert_client_handshake().await;
1965+
assert_default_settings!(settings);
1966+
srv.recv_frame(
1967+
frames::headers(1)
1968+
.request("GET", "https://http2.akamai.com/")
1969+
.eos(),
1970+
)
1971+
.await;
1972+
srv.send_frame(frames::go_away(1)).await;
1973+
tokio::time::sleep(Duration::from_millis(50)).await;
1974+
srv.close_without_notify();
1975+
};
1976+
1977+
let h2 = async move {
1978+
let (mut client, h2) = client::handshake(io).await.unwrap();
1979+
tokio::spawn(async move {
1980+
let request = Request::builder()
1981+
.uri("https://http2.akamai.com/")
1982+
.body(())
1983+
.unwrap();
1984+
let _res = client
1985+
.send_request(request, true)
1986+
.unwrap()
1987+
.0
1988+
.await
1989+
.expect("request");
1990+
});
1991+
let _ = h2.await.unwrap();
1992+
};
1993+
join(srv, h2).await;
1994+
}
1995+
19561996
const SETTINGS: &[u8] = &[0, 0, 0, 4, 0, 0, 0, 0, 0];
19571997
const SETTINGS_ACK: &[u8] = &[0, 0, 0, 4, 1, 0, 0, 0, 0];
19581998

0 commit comments

Comments
 (0)