The documentation provides an example — unfortunately it does not compile; a lot of stuff got renamed and the interface of the ClientSession
constructor changed. I managed to fix the errors to a point where it compiles, but not to a point where it works.
Here is my best attempt at getting the minimum example to work:
extern crate rustls;
use io::Read;
use io::Write;
use rustls::Session;
use std::io;
fn main() {
let mut socket = std::net::TcpStream::connect("www.google.com:443").unwrap();
let mut config = rustls::ClientConfig::new();
config
.root_store
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
let arc = std::sync::Arc::new(config);
let dns_name = webpki::DNSNameRef::try_from_ascii_str("www.google.com").unwrap();
let mut client = rustls::ClientSession::new(&arc, dns_name);
client.write(b"GET https://www.google.com\r\n\r\n").unwrap();
loop {
if client.wants_read() {
client.read_tls(&mut socket).unwrap();
client.process_new_packets().unwrap();
let mut plaintext = Vec::new();
client.read_to_end(&mut plaintext).unwrap();
io::stdout().write(&plaintext).unwrap();
}
if client.wants_write() {
client.write_tls(&mut socket).unwrap();
}
// For testing purposes only
std::thread::sleep_ms(1000);
}
}
What happens is that the program starts to run and aborts after 10 seconds with the error "An established connection was aborted by the software in your host machine."
I would have expected it to print some data to stdout, which it does not.
There is a struct called rustls::Stream
to use the session as a normal stream. It's documented on docs.rs. You can also find an example on their GitHub repository.
You can convert your code to use rustls::Stream
like this:
extern crate rustls; // 0.17.0
use io::Read;
use io::Write;
use std::io;
fn main() {
let mut socket = std::net::TcpStream::connect("www.google.com:443").unwrap();
let mut config = rustls::ClientConfig::new();
config
.root_store
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
let arc = std::sync::Arc::new(config);
let dns_name = webpki::DNSNameRef::try_from_ascii_str("www.google.com").unwrap();
let mut client = rustls::ClientSession::new(&arc, dns_name);
let mut stream = rustls::Stream::new(&mut client, &mut socket); // Create stream
// Instead of writing to the client, you write to the stream
stream
.write(b"GET / HTTP/1.1\r\nConnection: close\r\n\r\n")
.unwrap();
let mut plaintext = Vec::new();
stream.read_to_end(&mut plaintext).unwrap();
io::stdout().write_all(&plaintext).unwrap();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With