Rust 生态里发起代理请求最便捷的库是 reqwest:Proxy::all 一行代码构建全局代理,交给 Client::builder 组装后,这个客户端发出的所有 HTTP 与 HTTPS 请求都会经代理转发。reqwest 基于 hyper 与 Tokio,同步、异步两种用法都支持。本文覆盖 Cargo 依赖、认证配置、SOCKS5 特性开关与超时和错误处理,给出可直接运行的完整示例。
环境准备与 Cargo 依赖
执行 cargo new proxy_demo 新建工程后,在 Cargo.toml 中加入依赖。示例使用 blocking 同步特性,代码更短、无需手动搭建 Tokio 运行时;异步项目去掉该特性后在 async fn 中 await 即可。SOCKS5 代理需要显式打开 socks 特性,这是 reqwest 最常被遗漏的一项配置,漏装后解析 socks5 地址会直接报错。
[dependencies]
reqwest = { version = "0.12", features = ["blocking", "socks"] }
- blocking 特性:提供同步客户端,示例代码无需 Tokio 运行时。
- socks 特性:启用 socks5 与 socks5h 协议前缀支持。
- TLS 后端:默认使用 native-tls,需要纯 Rust 链路可切换 rustls-tls 特性。
reqwest::Proxy 的构建方式
Proxy::all 让所有协议都走同一个代理;Proxy::http 与 Proxy::https 分别只拦截对应协议的请求,多条规则可以叠加,按声明顺序匹配。代理地址支持 http://、https:// 与 socks5:// 前缀。需要认证时在构建出的代理上调用 basic_auth 方法传入账号密码,reqwest 会自动生成 Proxy-Authorization 头;更复杂的认证方式可以实现 custom_auth 或直接添加自定义请求头。
完整代码示例
下面的例子构建了带认证与双阶段超时的代理客户端并发起请求:
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let proxy = reqwest::Proxy::all("http://127.0.0.1:8080")?
.basic_auth("user", "pass");
let client = reqwest::Client::builder()
.proxy(proxy)
.timeout(Duration::from_secs(15))
.connect_timeout(Duration::from_secs(8))
.user_agent("Mozilla/5.0")
.build()?;
let resp = client.get("https://httpbin.org/ip").send()?;
println!("状态码: {}", resp.status());
let body = resp.text()?;
println!("{}", body);
Ok(())
}
Proxy::all 与 build 都返回 Result,问号运算符会把错误向上传播,main 的返回类型因此写作 Result<(), Box<dyn std::error::Error>>。timeout 覆盖整个请求周期,connect_timeout 单独限制建连阶段,两者搭配可以让坏节点更快暴露,避免长尾请求拖垮任务。
HTTPS 与 SOCKS5 代理的支持
对 https 目标,reqwest 自动经代理发起 CONNECT 隧道,TLS 会话与目标端点直接协商,证书校验默认开启,安全性不因代理而打折。SOCKS5 场景把代理地址写成 socks5://127.0.0.1:1080;socks5h:// 前缀表示域名解析也交给代理执行,可规避本地 DNS 污染。异步用法中 Client 可以安全地跨任务共享(配合 Arc 包裹),内部连接池会自动复用经代理建立的连接,高并发采集时无需额外池化。
错误处理与注意事项
- 构建阶段报错:代理 URL 非法时 Proxy::all 直接返回 Err,注意用问号或 match 处理。
- is_connect:错误对象的该方法为真说明连接代理失败,检查地址端口与网络。
- is_timeout:请求超时,区分整体超时与建连超时两个配置再调整。
- is_status:代理或目标返回错误状态码,407 需补充 basic_auth 认证信息。
Article ID: 38
(本文仅供技术交流,请遵守法律法规)