hyperlocal icon indicating copy to clipboard operation
hyperlocal copied to clipboard

Connection socket does not shut down cleanly

Open ratorx opened this issue 1 year ago • 1 comments

Hyper logs debug errors for every HTTP request made to a server backed by a Unix Socket.

Example output

2023-02-03T03:44:08.141436Z DEBUG hyper::proto::h1::conn: error shutting down IO: Socket is not connected (os error 57)
2023-02-03T03:44:08.141492Z DEBUG hyper::server::server::new_svc: connection error: error shutting down connection: Socket is not connected (os error 57)

Reproduction

Code:

use hyper::{service::{make_service_fn, service_fn}, Request, Body, Response};
use hyperlocal::UnixServerExt;
use std::{path::PathBuf, convert::Infallible};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

#[cfg(unix)]
#[tokio::main]
async fn main() {
    tracing_subscriber::registry()
        .with(
            tracing_subscriber::EnvFilter::try_from_default_env()
                .unwrap_or_else(|_| "debug".into()),
        )
        .with(tracing_subscriber::fmt::layer())
        .init();

    let path = PathBuf::from("/tmp/helloworld");

    let _ = tokio::fs::remove_file(&path).await;
    tokio::fs::create_dir_all(path.parent().unwrap())
        .await
        .unwrap();

    let make_service = make_service_fn(|_conn| async {
        Ok::<_, Infallible>(service_fn(handle))
    });

    hyper::Server::bind_unix(path).unwrap().serve(make_service)
        .await
        .unwrap();
}

async fn handle(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
    Ok(Response::new(Body::from("Hello World")))
}

Cargo deps:

hyper = { version = "0.14", features = ["full"] }
tokio = { version = "1.25", features = ["full"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
hyperlocal = "0.8.0"

To reproduce, run the code and connect to the socket, with e.g.

curl --unix-socket /tmp/helloworld something

Additional thoughts

It's just mildly annoying, as far as I can tell, it doesn't cause any issues. I'm fairly new to async stuff in Rust, but I tried to dig into it. I'm not even sure if this is a hyperlocal, hyper or tokio problem.

The error seems to be produced by poll_shutdown: https://github.com/hyperium/hyper/blob/499fe1f949895218c4fd2305a0eddaf24f1dd0a9/src/proto/h1/conn.rs#L720. Tracing that through, it just calls shutdown on the UnixStream. I've think it's unlikely to be a hyper problem, because that is transport agnostic and doesn't have any issues when listening on a port.

Is there something that hyperlocal could do to handle the connection socket shutdown (better)?

ratorx avatar Feb 03 '23 04:02 ratorx

Are you using OSX, or are you seeing this on a variant of Linux, or on Windows?

iamjpotts avatar Apr 01 '24 03:04 iamjpotts