Как мне установить соединение TLS с помощью библиотеки rustls? - PullRequest
1 голос
/ 23 февраля 2020

Документация предоставляет пример - к сожалению, он не компилируется; многие вещи были переименованы, а интерфейс конструктора ClientSession изменился. Мне удалось исправить ошибки до точки, где они компилируются, но не до точки, где это работает.

Вот моя лучшая попытка получить минимальный пример для работы:

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);
    }
}

Что происходит, так это то, что программа начинает работать и прерывается через 10 секунд с ошибкой «Установленное соединение было прервано программным обеспечением на вашем хост-компьютере».

Я ожидал, что он напечатает некоторые данные на стандартный вывод, что это не так.

1 Ответ

1 голос
/ 23 февраля 2020

Существует структура с именем rustls::Stream для использования сеанса в качестве обычного потока. Это документировано на docs.rs . Вы также можете найти пример в их репозитории GitHub .

Вы можете преобразовать свой код в rustls::Stream следующим образом:

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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...