0

I cannot find a TLS-enabled server framework that does not require me to use a threaded, TcpStream, std::io::Read/std::io::Write-model for handling HTTP requests and responses (instead of a Future-oriented model). I think I found all the scattered pieces to implement TLS, HTTP, and Async individually, I just don't know how to combine them all.

My server proxies HTTP requests to their destination and responses back, but it can't handle HTTPS:

#[macro_use] lazy_static;
use hyper::{Body, Server, Client, Error};
use hyper::{
    client::HttpConnector,
    service::service_fn,
    service::make_service_fn,
};
use std::net::SocketAddr;
 
lazy_static! {
    static ref CLIENT: Client<HttpConnector> = Client::new();
}

async run() {
    let addr = SocketAddr::from(([127, 0, 0, 1], 8080));

    let svc = make_service_fn(|_| async {    
        Ok::<_, Error>(service_fn(|req| async move {    
            CLIENT.request(req).await
        }))
    });

    Server::bind(&addr).serve(svc).await.unwrap();
}

I have a self-signed certificate (also loaded into the client browser) and private key ready to go (via openssl and rustls), I just don't know how/where in my hyper code to use them:

use openssl::{    
    x509::X509,    
    rsa::Rsa,    
}; 

fn tls_config() -> rustls::ServerConfig {
    let cert = X509::from_pem(/* CertAuth file as bytes */)
        .unwrap()
        .to_der()
        .unwrap()
    let cert = rustls::Certificate(cert);

    let key = Rsa::private_key_from_pem(/* PrivKey file as bytes */)
        .unwrap()
        .private_key_to_der()
        .unwrap()
    let key = rustls::PrivateKey(key);
    
    let mut result = rustls::ServerConfig::new(
        rustls::NoClientAuth::new()
    );
    result.set_single_cert(vec![cert; 1], key).unwrap();

    return result;
}

Using rustls, tokio_tls, or native_tls (instead of hyper) for networking all give me both HTTP and TLS, but only at the price of losing async. Also, I don't know much about HTTPS, but I think hyper_rustls can only do client-related magic.

Is there a server-side, pre-packaged, Rust solution that gives me the best of all three worlds (HTTP + TLS + Future)? If not, is there a way I could go about implementing server-side TLS with hyper? (even just a hint would be amazing!) I would much prefer having HTTPS errors to handle than a nightmare of opaque, Future types.

springworks00
  • 104
  • 15
  • I think the `hyper-rustls` match with your requirements, otherwise you could try `actix-web` that for sure do the trix but is a whole different framework – Asya Corbeau Aug 11 '20 at 14:39
  • Sorry I meant `hyper_rustls` when I wrote `hyper_tls`, updated the question to reflect. Is there not a simple way that `actix_web` does this under the hood? Or is it more trouble than its worth to re-implement myself without a ton of framework baggage? – springworks00 Aug 11 '20 at 15:12
  • to keep it simple let assume that `actix_web` spawn a normal `TcpServer`, once an incoming peer was found wrap the `TcpStream` into a `TlsStream` (at this point you should be ready to go) and then wrap this `TlsStream` into a `SplitSink` to allow multiple owned reader/writer – Asya Corbeau Aug 11 '20 at 15:57

0 Answers0