Skip to content

hyper::Error::is_timeout returns false on a HeaderTimeout. #3780

Closed
@De117

Description

@De117

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-errorArea: error handlingC-bugCategory: bug. Something is wrong. This is bad!E-easyEffort: easy. A task that would be a great starting point for a new contributor.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions