diff --git a/src/error.rs b/src/error.rs index 9ad4c0e5b3..cd2c8c2da3 100644 --- a/src/error.rs +++ b/src/error.rs @@ -240,6 +240,11 @@ impl Error { /// Returns true if the error was caused by a timeout. pub fn is_timeout(&self) -> bool { + #[cfg(any(all(feature = "http1", feature = "server"), feature = "ffi"))] + return matches!(self.inner.kind, Kind::HeaderTimeout) + || self.find_source::().is_some(); + + #[cfg(not(any(all(feature = "http1", feature = "server"), feature = "ffi")))] self.find_source::().is_some() } diff --git a/tests/server.rs b/tests/server.rs index f72cf62702..b83a1ad41f 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -2861,6 +2861,40 @@ fn http1_trailer_recv_fields() { ); } +#[tokio::test] +async fn http1_timeout_error() { + let (listener, addr) = setup_tcp_listener(); + + let j = tokio::spawn(async move { + let (socket, _) = listener.accept().await.expect("accept"); + let socket = TokioIo::new(socket); + + if let Err(e) = http1::Builder::new() + .timer(TokioTimer) + .header_read_timeout(Duration::from_secs(1)) + .serve_connection(socket, HelloWorld) + .await + { + Some(e.is_timeout()) + } else { + None + } + }); + + let tcp = TokioIo::new(connect_async(addr).await); + let (_client, conn) = hyper::client::conn::http1::Builder::new() + .handshake::<_, Empty>(tcp) + .await + .expect("http handshake"); + + tokio::spawn(async move { + conn.await.expect_err("client conn fail"); + }); + + TokioTimer.sleep(Duration::from_secs(2)).await; + assert_eq!(j.await.unwrap(), Some(true)); +} + // ------------------------------------------------- // the Server that is used to run all the tests with // -------------------------------------------------