Hyper: How to bind to a unix domain socket?

Created on 7 Jan 2020  路  5Comments  路  Source: hyperium/hyper

I've saw this example code: https://github.com/hyperium/hyper/pull/1702#issuecomment-437186302 but there is no more serve_incoming method on Http.

Is it still possible to bind to a uds without the use of an additional crate? If yes, how?
I'm using:

tokio = { version = "0.2", features = ["full"] }
hyper = { version = "0.13.1", features = ["stream"] }

I've also tried:

let unix_listener = UnixListener::bind(socket_path)?;
let server = Server::builder(unix_listener.incoming());
server.serve(service).await?;

But unix_listener.incoming is not implementing the Accept trait, required by serve.

Most helpful comment

@seanmonstar Thanks, it works! Since this question has popped up from time to time, do you think it would be worth it to have an example file on how to do this?

All 5 comments

@FedericoPonzi there's https://github.com/softprops/hyperlocal but I was not able to get it work with the newest hyper.

I would love it if the authors of hyper would make it a native feature so that it can be kept up-to-date with hyper's ongoing releases.

But unix_listener.incoming is not implementing the Accept trait, required by serve.

You can use hyper::server::accept::from_stream:

let unix_listener = UnixListener::bind(socket_path)?;
let acceptor = hyper::server::accept::from_stream(unix_listener.incoming());
let server = Server::builder(acceptor);
server.serve(service).await?;

use tokio::net::UnixListener;
{
let path = "/root/test.sock";
if let Err(err) = fs::remove_file(path) {
if err.kind() != io::ErrorKind::NotFound {
eprintln!(".......");
}
}
let unix_listener = UnixListener::bind(path).unwrap();
let acceptor = hyper::server::accept::from_stream(unix_listener.incoming());
// For every connection, we must make a Service to handle all
// incoming HTTP requests on said connection.
let make_svc = make_service_fn(|_conn| {

    async { Ok::<_, Infallible>(service_fn(hello)) }
});
let server_i = Server::builder(acceptor);
let server = server_i.serve(make_svc);

server.await?;

Ok(())}

29 | let acceptor = hyper::server::accept::from_stream(unix_listener.incoming());
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait futures::Stream is not implemented for future_ex::future_ex::tokio::net::unix::Incoming<'_>

@seanmonstar Thanks, it works! Since this question has popped up from time to time, do you think it would be worth it to have an example file on how to do this?

By the way, the tokio API changed slightly for 1.0.

use tokio::net::UnixListener;
use tokio_stream::wrappers::UnixListenerStream;

let unix_listener = UnixListener::bind(socket_path).expect("Failed to bind UNIX socket");
let stream = UnixListenerStream::new(unix_listener);
let acceptor = hyper::server::accept::from_stream(stream);
let server = Server::builder(acceptor).serve(make_service);
Was this page helpful?
0 / 5 - 0 ratings

Related issues

hwchen picture hwchen  路  3Comments

klausi picture klausi  路  3Comments

crackcomm picture crackcomm  路  5Comments

reem picture reem  路  3Comments

FGRibreau picture FGRibreau  路  4Comments