hyper-tls icon indicating copy to clipboard operation
hyper-tls copied to clipboard

How can use hyper-tls for server

Open uncotion opened this issue 7 years ago • 14 comments
trafficstars

Hi, Is it possible use hyper-tls for hyper server "0.12" ?

uncotion avatar Jun 24 '18 06:06 uncotion

Not really... But I'd welcome adding some API to ease this!

seanmonstar avatar Jun 25 '18 18:06 seanmonstar

@seanmonstar I was just about to open a similar issue for this. As you're looking for a PR, do you have preferences around what this API would look like or should I submit the PR and review it then?

jbaublitz avatar Jul 31 '18 00:07 jbaublitz

I haven't thought much about it, if you want to suggest something now, I can comment, or we can just review in a PR.

seanmonstar avatar Jul 31 '18 00:07 seanmonstar

@seanmonstar My initial thoughts are, for starters, to provide From implementations from native_tls::TlsStream to hyper_tls::TlsStream and hyper_tls::MaybeHttpsStream. Even that would suffice for usage in the Server struct I type parameter based on the traits that both hyper_tls structs implement. The user could at least that way handle all of the certificate/socket address creation through native_tls. I'm looking at this as a first step as this is kind of a blocker for me right now. I think there's room for improvements and abstractions later on but this feels like a good "get this working" step for now. Does that sound good? If so, I'll start on a PR.

jbaublitz avatar Jul 31 '18 01:07 jbaublitz

Sure!

seanmonstar avatar Jul 31 '18 02:07 seanmonstar

PR #28 created. Lemme know if you have any feedback there. Thanks!

jbaublitz avatar Jul 31 '18 02:07 jbaublitz

I've gotten a working example with MaybeHttpsStream. It definitely needs some work as it is currently very verbose. Should I post my findings here or open a new issue?

jbaublitz avatar Jul 31 '18 17:07 jbaublitz

@uncotion Here is a working example of a TLS server using the updated From trait additions.

jbaublitz avatar Aug 09 '18 16:08 jbaublitz

One approach is implementing the trait hyper::server::accept::Accept (note now hyper 0.13, can't comment on any api changes.) I wrote this (part of working prototype) before coming to this issue. If I was going to go further, would probably make it generic over Accept in particular taking/using hyper::server::conn::AddrIncoming. (To finish add polish extension traits for better integration.)

jonhere avatar Jan 17 '20 13:01 jonhere

I see that Warp has an implementation of all this. Would it be an option to move that implementation here?

timbru avatar Mar 03 '20 12:03 timbru

@timbru sort of! Warp uses rustls, while this crate is currently using native-tls. However, it'd be a fine place to start, and just adapt to the native-tls types.

seanmonstar avatar Mar 03 '20 19:03 seanmonstar

@seanmonstar do you mean that it should use native-tls directly? Or could it be built on existing work in tokio-tls? I need to do more research - I am fairly new to this - but it seems to implement a lot of what is needed, and it's already a dependency.

timbru avatar Mar 04 '20 07:03 timbru

I just meet the same problem, and after searching, I found that maybe it's not hyper's duty to do, but tokio. the "tokio-rustls" crate gives a demo, https://github.com/tokio-rs/tls/blob/master/tokio-rustls/examples/server/src/main.rs, it show that after get a tcp stream, wrap it to a tls stream, and pass it to the http handler. I also found that hyper can deal with request in connection level, so i think the way is,

let acceptor = TlsAcceptor::from(Arc::new(tlsconfig));
let listener = TcpListener::bind(&"127.0.0.1:25025".to_string()).await?;

loop {
        let (tcp_stream, _) = listener.accept().await?;
        let acceptor = acceptor.clone();
        
        tokio::spawn(async move {
            let mut tls_stream = acceptor.accept(tcp_stream).await?;
            if let Err(e) = Http::new()
                .http1_keep_alive(true)
                .serve_connection(tls_stream, service_fn(custom_handler))
                .await {
                eprintln!("Error, {}", e)
            }
        });
}

Hi, Is it possible use hyper-tls for hyper server "0.12" ?

HunterGitHub avatar Sep 23 '21 09:09 HunterGitHub

Thanks to @HunterGitHub, I found tokio-rs/tls is now based upon native-tls, not rustls anymore. So, by tweaking this example , it's not too hard to make it hyper-tls compatible.

Full example linked HERE (w/details on using openssl/curl/wget)

The main two differences from @HunterGitHub's example is auto http1/http2 upgrading, and use of TokioIo.

I am really curious how and what @seanmonstar would refactor from native_tls and tokio_native_tls into hyper-hls to create the server functionality.

async fn hello(_: Request<hyper::body::Incoming>) -> Result<Response<Full<Bytes>>, Infallible> {
    Ok(Response::new(Full::new(Bytes::from("Hello, World!"))))
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Bind the server's socket
    let addr = "127.0.0.1:12345".to_string();
    let listen: TcpListener = TcpListener::bind(&addr).await?;

    let pem = include_bytes!("cert.pem");
    let key = include_bytes!("key.pem");
    let cert = Identity::from_pkcs8(pem, key)?;

    let tls_acceptor = native_tls::TlsAcceptor::builder(cert).build()?;
    let tls_acceptor = tokio_native_tls::TlsAcceptor::from(tls_acceptor);

    loop {
        let (socket, _) = listen.accept().await?;
        let tls_acceptor = tls_acceptor.clone();
        let server = auto::Builder::new(TokioExecutor::new()); //http1 or http2

        tokio::spawn(async move {
            let tls_stream = tls_acceptor.accept(socket).await.unwrap();
            let io = TokioIo::new(tls_stream);
            let service = service_fn(hello);
            server.serve_connection(io, service).await.unwrap()
        });
    }
}

cameronelliott avatar Jan 18 '24 10:01 cameronelliott