Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
450 views
in Technique[技术] by (71.8m points)

Rust: how to use async-std + TLS + HTTP Proxy(http tunnel)?

I purchased an http proxy(supported http tunnel), but have no rust example code, I try to use the crate surf, but not found the proxy way, I have to implement it by myself. following is my code:

use async_std::task::block_on;
use std::error::Error;
use std::result::Result;
use futures::{AsyncWriteExt, AsyncReadExt};

use async_tls::TlsConnector;
use async_std::net::TcpStream;

const PROXY: &str = "200.200.200.200:8000"; // this is proxy / http tunnel / example IP

async fn http_get_with_proxy(url: &str, proxy: &str) -> Result<String, Box<dyn Error>> {

    // 1. make proxy to build connection to target host
    let mut stream = TcpStream::connect(proxy).await?;
    let r = stream.write_all(format!("CONNECT www.domain.com:443 HTTP/1.1

").as_bytes()).await?;

    // 2. start SSL handshake process, resuse TCP stream.
    let connector = TlsConnector::default();
    let mut tls_stream = connector.connect("www.example.com", stream).await?;

    // 3. send data with SSL protocal to proxy, proxy will forward data to target.
    let r = tls_stream.write_all(format!("GET https://www.example.com/ HTTP/1.1

").as_bytes()).await?;
    let mut buf = String::new();

    // 4. recv data from proxy.
    let r = tls_stream.read_to_string(&mut buf).await;
    Ok(buf)
}

fn main() {
    let r = block_on( http_get_with_proxy("https://www.example.com/", PROXY));
    dbg!(r);
}

got error:

[src/main.rs:35] r = Err(
    Custom {
        kind: InvalidData,
        error: CorruptMessage,
    },
)

I don't know what went wrong.

question from:https://stackoverflow.com/questions/65650805/rust-how-to-use-async-std-tls-http-proxyhttp-tunnel

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm not an a rust expert, but I see that there are errors on the protocol level:

... CONNECT www.domain.com:443 HTTP/1.1

 ...

First, it should be not . More importantly, one must wait for the HTTP response of the proxy and only establish the TLS connection after one got the full response. Otherwise the plain HTTP response of the proxy will be interpreted as reply inside the TLS handshake and thus the handshake will fail. See also Wikipedia for a short example of this handshake.

... GET https://www.example.com/ HTTP/1.1

 ...

This is not a valid HTTP/1.1 request. It is missing at least the Host header and the request line should only contain the path / and not the full URL.

If you really want to implement HTTP yourself instead of using libraries, please study the actual standards instead of second-guessing how the protocol might work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...