Closed
Description
Version
hyper = {version="1.5.0", features=["http1", "server"]}
# other dependencies
tokio = {version="1.41.1", features=["full"]}
hyper-util = {version = "0.1.10", features = ["full"]}
Platform
Output from uname --all
:
Linux computer 6.7.11-200.fc39.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Mar 27 16:50:39 UTC 2024 x86_64 GNU/Linux
Description
hyper::Error::is_timeout
returns false
on a HeaderTimeout
.
On an HTTP/1.1 server, when I set a timeout with header_read_timeout
, a slow client will cause a HeaderTimeout
error.
Calling is_timeout
on the error should return true
, but it returns false
.
To reproduce:
use std::convert::Infallible;
use std::net::SocketAddr;
use hyper::server::conn::http1;
use hyper::service::service_fn;
use hyper::Response;
use hyper_util::rt::{TokioIo, TokioTimer};
use tokio::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let addr = SocketAddr::from(([127, 0, 0, 1], 1234));
let listener = tokio::net::TcpListener::bind(addr).await?;
loop {
let (stream, _) = listener.accept().await?;
let io = TokioIo::new(stream);
let r: Result<Response<String>, Infallible> = Ok(Response::new("hello".to_string()));
tokio::task::spawn(async move {
if let Err(e) = http1::Builder::new()
.timer(TokioTimer::new())
.header_read_timeout(Duration::from_secs(1))
.serve_connection(io, service_fn(|_| async { r.clone() }))
.await
{
println!("Is {e:?} a timeout? {}", e.is_timeout());
}
});
}
}
Open a TCP socket (nc localhost 1234
) and hold it open for a second. This triggers the timeout, and the program prints Is hyper::Error(HeaderTimeout) a timeout? false
.