Search code examples
rustrust-tokio

Read from TlsStream<TcpStream> using `tokio-rustls` in Rust


I am using rustls, and want to read TlsStream to a buffer likewise we read TcpStream. Here is what I am doing:

let acceptor = TlsAcceptor::from(Arc::new(config));

let fut = async {

    let mut listener = TcpListener::bind(&addr).await?;

    loop {

        let (stream, peer_addr) = listener.accept().await?;
        let acceptor = acceptor.clone();

        let fut = async move {

            let mut stream = acceptor.accept(stream).await?;

            //// CURRENTLY THIS .read() is throwing error in compiler
            println!("Stream: {:?}", stream.read(&mut [0; 1024]));

            Ok(()) as io::Result<()>
        };

        handle.spawn(fut.unwrap_or_else(|err| eprintln!("{:?}", err)));
    }
};

It throws error

'error[E0599]: no method named `read` found for struct `tokio_rustls::server::TlsStream<tokio::net::tcp::stream::TcpStream>` in the current scope'

I am looking to read from TlsStream generated using tokio-rustls to buffer.


Solution

  • As your error message describes, there's a trait AsyncReadExt that's implemented for the type, but not imported into scope. To be able to use the read method of that trait, you need to import the trait; for this trait, this is typically done by importing the tokio prelude:

    use tokio::prelude::*;
    
    // or you can explicitly import just AsyncReadExt, but I'd recommend the above
    use tokio::io::AsyncReadExt;
    

    In addition, you need to specifically await the result from read(), since it returns a future. You also need to use a buffer in a separate variable, since that's where the read data is stored.

    let mut buffer = [0; 1024];
    let byte_count = stream.read(&mut buffer).await;
    //                                       ^^^^^^
    println!("Stream: {:?}", &buffer[0..byte_count]);