Understanding Implementation of `tokio-rustls` for `hyper` server

Hi,

I am implementing rustls for hyper using tokio-rustls using this example. Everything is working perfectly. But I am not able to understand certain things.

Here is the code snippet

let incoming_tls_stream = tcp_listener
    .incoming()
    .map_err(|e| error(format!("Incoming failed: {:?}", e)))
    .and_then(move |s| {
        tls_acceptor
            .accept(s)
            .map_err(|e| {
                error(format!("TLS Error: {:?}", e))
            })
    })
    .boxed();

let service_https = make_service_fn(|_| async { Ok::<_, io::Error>(service_fn(https_handler)) });
let server_https = Server::builder(HyperAcceptor {
    acceptor: incoming_tls_stream,
}).serve(service_https);

server_https.await?;

First thing I am not understating is why HyperAcceptor { acceptor: incoming_tls_stream } is passed in to Server::builder() where we may pass tcp_listener.incoming()

HyperAcceptor struct and implementation is as belows:

struct HyperAcceptor<'a> {
    acceptor: Pin<Box<dyn Stream<Item = Result<TlsStream<TcpStream>, io::Error>> + 'a>>,
}

impl hyper::server::accept::Accept for HyperAcceptor<'_> {

    type Conn = TlsStream<TcpStream>;
    type Error = io::Error;

    fn poll_accept(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
    ) -> Poll<Option<Result<Self::Conn, Self::Error>>> {
        Pin::new(&mut self.acceptor).poll_next(cx)
    }
}

I am not able to understand what does this implemented struct does and why?

If anyone can help me understand this. It would be of great help.

Hyper allows multiple backends. In the examples case it is for dealing with accepting connections which are coded by structures that implement the trait hyper::server::accept::Accept.

tcp_listener.incoming() alone does not preform encryption so extra is needed.

Note: the example isn't good for high use (public) servers as only one accept is performed at a time and the code makes the handshake (tls_acceptor.accept) be part of this step.

1 Like

Many Thanks for the explanation. :+1:

As you said that this example isn't good for public servers as only one accept is performed at a time. Can you guide to some resource which can help to lean more on this and proper tls implementation so that the server can be used for public uses also.