如何使用 rustls 库建立 TLS 连接? [英] How do I make a TLS connection using the rustls library?

查看:60
本文介绍了如何使用 rustls 库建立 TLS 连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

文档 提供了一个示例——不幸的是它不能编译;很多东西都被重命名了,ClientSession 构造函数的接口也发生了变化.我设法将错误修复到可以编译的程度,但不能修复到可以工作的程度.

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

发生的情况是程序开始运行并在 10 秒后中止,并显示错误已建立的连接被主机中的软件中止."

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.

推荐答案

有一个名为 rustls::Stream 的结构体可以将会话用作普通流.它记录在 docs.rs 上.您还可以在 在他们的 GitHub 存储库中找到示例.

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.

您可以像这样转换您的代码以使用 rustls::Stream:

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

这篇关于如何使用 rustls 库建立 TLS 连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆