El uso de proxies en Rust con reqwest implica configurar un ClientBuilder con ajustes de proxy, mientras que hyper, al ser una biblioteca HTTP de nivel inferior, requiere el establecimiento manual de la conexión a través de un servidor proxy.
Los servidores proxy actúan como intermediarios para las solicitudes de red, ofreciendo beneficios como el anonimato, el acceso a contenido geo-restringido, el equilibrio de carga y el filtrado de tráfico. Los clientes HTTP asíncronos de Rust, reqwest y hyper, ofrecen diferentes enfoques para integrar la funcionalidad de proxy. reqwest ofrece soporte de alto nivel e integrado, mientras que hyper exige un control más granular sobre el proceso de conexión.
Uso de Proxies con reqwest
reqwest es un cliente HTTP popular y fácil de usar para Rust, construido sobre hyper. Simplifica tareas HTTP comunes, incluida la configuración de proxy. El ClientBuilder de reqwest proporciona métodos para configurar varios tipos de proxy.
Configuración del Proxy
Para usar un proxy con reqwest, cree una instancia de reqwest::Client usando reqwest::ClientBuilder y su método proxy(). El método proxy() acepta un objeto reqwest::Proxy, que se puede construir para diferentes esquemas de proxy:
- Proxy HTTP: Se configura usando
Proxy::http(url), para solicitudes HTTP simples. - Proxy HTTPS (método CONNECT): Se configura usando
Proxy::https(url), para solicitudes HTTPS.reqwestutiliza el métodoCONNECTpara tunelizar la conexión TLS a través del proxy. - Proxy SOCKS5: Se configura usando
Proxy::socks5(url), para servidores proxy SOCKS5. - Proxy Unificado:
Proxy::all(url)configura un único proxy para solicitudes HTTP y HTTPS.
Autenticación del Proxy
Muchos servidores proxy requieren autenticación. reqwest::Proxy soporta autenticación básica usando el método basic_auth().
Soporte de Variables de Entorno
Por defecto, el ClientBuilder de reqwest verifica automáticamente las variables de entorno HTTP_PROXY, HTTPS_PROXY y NO_PROXY. Si estas están configuradas, reqwest las usará a menos que se anulen explícitamente con ClientBuilder::no_proxy() o configurando un proxy específico.
Ejemplo: Uso de Proxy con reqwest
Este ejemplo demuestra cómo configurar reqwest para usar proxies HTTP, HTTPS y SOCKS5, incluyendo autenticación básica.
use reqwest::{Client, Error, Proxy};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Error> {
// 1. HTTP Proxy
let http_proxy_url = "http://user:password@your-http-proxy.com:8080";
let http_client = Client::builder()
.proxy(Proxy::http(http_proxy_url)?)
.timeout(Duration::from_secs(10))
.build()?;
println!("HTTP Proxy request...");
let http_res = http_client.get("http://httpbin.org/ip").send().await?;
println!("HTTP Proxy Response: {:?}", http_res.text().await?);
// 2. HTTPS Proxy (CONNECT method)
// Note: For HTTPS, the proxy URL itself might be HTTP, but it tunnels HTTPS traffic.
let https_proxy_url = "http://user:password@your-https-proxy.com:8080";
let https_client = Client::builder()
.proxy(Proxy::https(https_proxy_url)?)
.timeout(Duration::from_secs(10))
.build()?;
println!("\nHTTPS Proxy request...");
let https_res = https_client.get("https://httpbin.org/ip").send().await?;
println!("HTTPS Proxy Response: {:?}", https_res.text().await?);
// 3. SOCKS5 Proxy
let socks5_proxy_url = "socks5://user:password@your-socks5-proxy.com:1080";
let socks5_client = Client::builder()
.proxy(Proxy::socks5(socks5_proxy_url)?)
.timeout(Duration::from_secs(10))
.build()?;
println!("\nSOCKS5 Proxy request...");
let socks5_res = socks5_client.get("http://httpbin.org/ip").send().await?;
println!("SOCKS5 Proxy Response: {:?}", socks5_res.text().await?);
// 4. Unified Proxy (applies to both HTTP and HTTPS requests)
let all_proxy_url = "http://user:password@your-all-proxy.com:8080";
let all_client = Client::builder()
.proxy(Proxy::all(all_proxy_url)?)
.timeout(Duration::from_secs(10))
.build()?;
println!("\nUnified Proxy (HTTP) request...");
let all_http_res = all_client.get("http://httpbin.org/ip").send().await?;
println!("Unified Proxy (HTTP) Response: {:?}", all_http_res.text().await?);
println!("\nUnified Proxy (HTTPS) request...");
let all_https_res = all_client.get("https://httpbin.org/ip").send().await?;
println!("Unified Proxy (HTTPS) Response: {:?}", all_https_res.text().await?);
Ok(())
}
Nota: Reemplace your-http-proxy.com:8080, your-https-proxy.com:8080 y your-socks5-proxy.com:1080 con direcciones y puertos de servidores proxy reales, incluyendo user:password para proxies autenticados.
Uso de Proxies con hyper
hyper es una biblioteca HTTP de bajo nivel y alto rendimiento que constituye la base de muchas otras crates HTTP de Rust, incluida reqwest. A diferencia de reqwest, hyper no ofrece métodos de configuración de proxy directos e integrados para su cliente. En su lugar, el uso de proxy con hyper requiere la gestión manual de la conexión TCP subyacente o la integración con crates externas específicas de proxy.
Gestión Manual de Conexiones
Para usar un proxy con hyper, primero debe establecer la conexión con el servidor proxy, y luego instruir a hyper para que use esta conexión preestablecida o un conector personalizado que maneje la lógica del proxy.
Proxy HTTP para Solicitudes HTTP
Para solicitudes HTTP de texto plano a través de un proxy HTTP, el cliente establece una conexión TCP con el servidor proxy. Luego envía la solicitud HTTP directamente al proxy, especificando la URL de destino completa en la línea de solicitud (por ejemplo, GET http://target.com/path HTTP/1.1). El encabezado Host aún debe referirse al servidor de destino.
Proxy HTTP para Solicitudes HTTPS (Método CONNECT)
Para solicitudes HTTPS, el cliente primero envía una solicitud HTTP CONNECT al proxy, instruyéndole para que establezca un túnel TCP al host y puerto de destino. Una vez que el proxy responde con 200 OK, el cliente realiza el handshake TLS directamente con el servidor de destino a través del túnel establecido.
Proxy SOCKS5
Los proxies SOCKS5 operan a un nivel inferior que los proxies HTTP y soportan varios protocolos, incluyendo TCP y UDP. La integración de SOCKS5 con hyper típicamente implica el uso de una biblioteca cliente SOCKS5 dedicada (por ejemplo, tokio-socks) para establecer la conexión proxied, que luego se pasa al constructor de conexiones de hyper.
Ejemplo: Uso de Proxy con hyper (Proxy HTTP para HTTP)
Este ejemplo demuestra cómo realizar una solicitud HTTP básica a través de un proxy HTTP usando hyper construyendo manualmente la solicitud y gestionando el flujo TCP. Esto ilustra el mecanismo subyacente; para soluciones robustas, considere envolver esta lógica o usar un conector dedicado.
```rust
use hyper::{Body, Client, Request, Uri};
use hyper::client::conn::Builder;
use tokio::net::TcpStream;
use std::str::FromStr;
[tokio::main]
async fn main() -> Result<(), Box
let proxy_addr = "127.0.0.1:8080"; // Replace with your HTTP proxy address
let target_url = "http://httpbin.org/ip";
println!("Connecting to proxy: {}", proxy_addr);
let stream = TcpStream::connect(proxy_addr).await?;
// For HTTP proxy, we connect to the proxy and send the full URI in the request.
// No CONNECT method needed for plain HTTP targets.
let (mut sender, conn) = Builder::new()
.http1_only(true) // Ensure HTTP/1.1 for HTTP proxy compatibility
.handshake(stream)
.await?;
tokio::spawn(async move {
if let Err(e) = conn.await {
eprintln!("Connection error: {:?}", e);
}
});
let req = Request::builder()
.uri(Uri::from_str(target_url)?) // Absolute URI for HTTP proxy forwarding
.header("Host", "httpbin.org