Rust Tunnel Proxy: reqwest and isahc

Rust reqwest and isahc HTTP clients integrating 16Yun Crawler Proxy.

16Yun Engineering TeamMay 1, 20261 min read

reqwest

reqwest is Rust's most popular HTTP client, configuring proxies via Proxy::all. Note: reqwest does not support injecting custom headers during HTTPS CONNECT, making HTTPS Proxy-Tunnel ineffective.

use reqwest::{Proxy, Client};
use std::env;
 
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let host = env::var("PROXY_HOST").unwrap_or_else(|_| "t.16yun.cn".into());
    let port = env::var("PROXY_PORT").unwrap_or_else(|_| "31111".into());
    let user = env::var("PROXY_USERNAME").unwrap_or_else(|_| "user".into());
    let pass = env::var("PROXY_PASSWORD").unwrap_or_else(|_| "password".into());
 
    let proxy_url = format!("http://{}:{}@{}:{}", user, pass, host, port);
    let proxy = Proxy::all(&proxy_url)?;
 
    let client = Client::builder()
        .proxy(proxy)
        .timeout(std::time::Duration::from_secs(15))
        .build()?;
 
    let resp = client.get("https://httpbin.org/ip").send().await?;
    println!("{}", resp.text().await?);
 
    Ok(())
}

Proxy-Tunnel Limitations

// HTTP Proxy-Tunnel (valid)
let resp = client.get("http://httpbin.org/ip")
    .header("Proxy-Tunnel", "rust-demo")
    .send().await?;
 
// HTTPS Proxy-Tunnel (invalid — reqwest does not support custom headers during CONNECT)
let resp = client.get("https://httpbin.org/ip")
    .header("Proxy-Tunnel", "rust-demo") // This header is not sent during CONNECT
    .send().await?;
ScenarioreqwestDescription
A: Force Switchpool_max_idle_per_host(0)Disable connection pool
B: Keep IPDefault behaviorReuse connection
C-HTTP: Proxy-Tunnel.header("Proxy-Tunnel", ...)Send as request header
C-HTTPS: Proxy-TunnelNo (Not supported)Cannot inject headers during CONNECT

For HTTPS Proxy-Tunnel, consider Go (Transport.ProxyConnectHeader) or Python httpx (httpx.Proxy(headers=...)).

isahc

isahc is built on libcurl and supports more proxy features:

use isahc::{HttpClient, Request, auth::Authentication};
use std::env;
 
fn main() -> Result<(), isahc::Error> {
    let host = env::var("PROXY_HOST").unwrap_or_else(|_| "t.16yun.cn".into());
    let port = env::var("PROXY_PORT").unwrap_or_else(|_| "31111".into());
    let user = env::var("PROXY_USERNAME").unwrap_or_else(|_| "user".into());
    let pass = env::var("PROXY_PASSWORD").unwrap_or_else(|_| "password".into());
 
    let client = HttpClient::builder()
        .proxy(Some(format!("http://{}:{}", host, port).parse().unwrap()))
        .proxy_authentication(Authentication::basic(user, pass))
        .timeout(std::time::Duration::from_secs(15))
        .build()?;
 
    let resp = client.get("https://httpbin.org/ip")?;
    println!("{}", resp.text()?);
 
    Ok(())
}

reqwest vs isahc

Featurereqwestisahc
Async SupportYes (native async)Yes
Underlying Libraryhyperlibcurl
HTTPS TunnelNoYes (via libcurl)
EcosystemMost popularSmaller
API StyleRust standardcurl-like

Need an enterprise proxy plan?

We can tailor architecture to your target domains, concurrency, and reliability goals.