Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
De117 opened this issue Nov 9, 2024 · 0 comments · May be fixed by #3781
Open

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

De117 opened this issue Nov 9, 2024 · 0 comments · May be fixed by #3781
Labels
A-error Area: error handling C-bug Category: bug. Something is wrong. This is bad! E-easy Effort: easy. A task that would be a great starting point for a new contributor.

Comments

@De117
Copy link

De117 commented Nov 9, 2024

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.

@De117 De117 added the C-bug Category: bug. Something is wrong. This is bad! label Nov 9, 2024
@seanmonstar seanmonstar added E-easy Effort: easy. A task that would be a great starting point for a new contributor. A-error Area: error handling labels Nov 9, 2024
@T-aian T-aian linked a pull request Nov 10, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-error Area: error handling C-bug Category: bug. Something is wrong. This is bad! E-easy Effort: easy. A task that would be a great starting point for a new contributor.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants