FlorianUekermann / rustls-acme

Apache License 2.0
136 stars 27 forks source link

Unclear how to combine with `hyper`'s getting started guide #66

Closed rikhuijzer closed 3 months ago

rikhuijzer commented 3 months ago

During my CS master, one teacher always said that if something is unclear to me, I should ask since it is likely unclear to other people too. I hope it's okay to ask here too.

I've setup a server with hyper's getting started guide (https://hyper.rs/guides/1/server/hello-world/):

use std::convert::Infallible;
use std::net::SocketAddr;

use http_body_util::Full;
use hyper::body::Bytes;
use hyper::server::conn::http1;
use hyper::service::service_fn;
use hyper::{Request, Response};
use hyper_util::rt::TokioIo;
use tokio::net::TcpListener;

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 + Send + Sync>> {
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

    // We create a TcpListener and bind it to 127.0.0.1:3000
    let listener = TcpListener::bind(addr).await?;

    // We start a loop to continuously accept incoming connections
    loop {
        let (stream, _) = listener.accept().await?;

        // Use an adapter to access something implementing `tokio::io` traits as if they implement
        // `hyper::rt` IO traits.
        let io = TokioIo::new(stream);

        // Spawn a tokio task to serve multiple connections concurrently
        tokio::task::spawn(async move {
            // Finally, we bind the incoming connection to our `hello` service
            if let Err(err) = http1::Builder::new()
                // `service_fn` converts our function in a `Service`
                .serve_connection(io, service_fn(hello))
                .await
            {
                eprintln!("Error serving connection: {:?}", err);
            }
        });
    }
}

This worked fine for me, but I have so far been unable to integrate rustls-acme into it. The current examples/high_level_tokio.rs uses TcpListenerStream and next() instead of listener.accept(). Would it be a good idea for a hyper example to be added?

As a side-note, at some point I had something working but then curl responded with

curl: (1) Received HTTP/0.9 when not allowed

which is a weird issue, I think. I'm using all the latest versions according to

cargo outdated --depth=1
FlorianUekermann commented 3 months ago

Starting from the high_level_tokio example, it should be sufficient to pass the tls you get from tls_incoming.next() to hypers serve_connection. It seems like the hyper::rt::{Read,Write} traits in hyper aren't the same as in tokio, so you may have to add something like let tls = TokioIo::new(tls);.

I'll try to add a tokio example later today. If you figure it out before I do, a message with code or a PR would be much appreciated.

FlorianUekermann commented 3 months ago

I pushed and example (high_level_hyper.rs).

Btw, your curl error looks like you used curl http://example.com and served https on port 80 instead of curl https://example.com and serving on port 443.

rikhuijzer commented 3 months ago

Thanks Florian! I haven't tried it but will do so soon. I appreciate your quick response!

Btw, your curl error looks like you used curl http://example.com and served https on port 80 instead of curl https://example.com and serving on port 443.

Ouch. I could have known that. Thanks!