openssl-async 0.3.0-alpha.5

Wrappers for the OpenSSL crate to allow use in async applications
Documentation
use std::sync::Arc;

use futures::future::BoxFuture;
use futures::io::BufReader;
use futures::prelude::*;

use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
use openssl::ssl::{SslConnector, SslVerifyMode};

use openssl_async::*;

use runtime::net::{TcpListener, TcpStream};

fn start_server(
    bind: &'static str,
    handler: impl 'static + Send + Fn(SslStream<TcpStream>) -> BoxFuture<'static, ()>,
) {
    let _ = runtime::spawn(async move {
        let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
        acceptor
            .set_private_key_file("tests/key.pem", SslFiletype::PEM)
            .unwrap();
        acceptor
            .set_certificate_chain_file("tests/cert.pem")
            .unwrap();
        acceptor.check_private_key().unwrap();
        let acceptor = Arc::new(acceptor.build());
        let mut listener = TcpListener::bind(bind).unwrap();
        let mut incoming = listener.incoming();
        while let Some(connection) = incoming.next().await {
            let connection = connection.unwrap();
            let connection = acceptor.accept_async(connection).await.unwrap();
            let _ = runtime::spawn(handler(connection));
        }
    });
}

async fn client(
    addr: &'static str,
    action: impl Fn(SslStream<TcpStream>) -> BoxFuture<'static, ()>,
) {
    let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
    connector.set_verify(SslVerifyMode::NONE);
    let connector = connector.build();
    let stream = TcpStream::connect(addr).await.unwrap();
    let stream = connector
        .connect_async("example.local", stream)
        .await
        .unwrap();
    action(stream).await
}

#[runtime::test]
async fn test_server() {
    start_server("127.0.0.1:1234", |connection| {
        async {
            let (read, mut write) = connection.split();
            let mut buffered = BufReader::new(read);
            let mut buf = vec![];
            buffered.read_until(b'\n', &mut buf).await.unwrap();
            let resp = format!("Hello, {}!\n", String::from_utf8(buf).unwrap().trim_end());
            write.write_all(resp.as_str().as_bytes()).await.unwrap();
        }
            .boxed()
    });

    client("127.0.0.1:1234", |stream| {
        async {
            let (read, mut write) = stream.split();
            let mut buffered = BufReader::new(read);

            write.write_all("world\n".as_bytes()).await.unwrap();
            let mut buf = vec![];

            buffered.read_until(b'\n', &mut buf).await.unwrap();

            assert_eq!(&String::from_utf8(buf).unwrap(), "Hello, world!\n");
        }
            .boxed()
    })
    .await
}