Rust SOCKS5代理库hyper-socks2的使用,实现高性能HTTP/SOCKS5代理与隧道功能
Rust SOCKS5代理库hyper-socks2的使用,实现高性能HTTP/SOCKS5代理与隧道功能
hyper-socks2是一个为hyper库设计的SOCKS5连接器。
安装
在项目目录中运行以下Cargo命令:
cargo add hyper-socks2
或者在Cargo.toml中添加以下行:
hyper-socks2 = "0.9.1"
使用示例
下面是一个完整的示例,展示如何使用hyper-socks2创建SOCKS5代理客户端:
use hyper::{Body, Client, Request};
use hyper_socks2::SocksConnector;
use tokio::runtime::Runtime;
async fn make_request() -> Result<(), Box<dyn std::error::Error>> {
// 创建SOCKS5连接器
let socks_connector = SocksConnector::new("127.0.0.1:1080")?;
// 使用SOCKS连接器创建hyper客户端
let client = Client::builder().build::<_, Body>(socks_connector);
// 创建HTTP请求
let req = Request::builder()
.uri("http://example.com")
.body(Body::empty())?;
// 发送请求
let res = client.request(req).await?;
println!("Response status: {}", res.status());
Ok(())
}
fn main() {
// 创建Tokio运行时
let rt = Runtime::new().unwrap();
// 执行异步请求
rt.block_on(make_request()).unwrap();
}
高级用法
带认证的SOCKS5代理
use hyper::{Body, Client, Request};
use hyper_socks2::SocksConnector;
use tokio::runtime::Runtime;
async fn make_auth_request() -> Result<(), Box<dyn std::error::Error>> {
// 创建带认证的SOCKS5连接器
let socks_connector = SocksConnector::new("127.0.0.1:1080")?
.with_username_password("username", "password");
let client = Client::builder().build::<_, Body>(socks_connector);
let req = Request::builder()
.uri("http://example.com")
.body(Body::empty())?;
let res = client.request(req).await?;
println!("Response status: {}", res.status());
Ok(())
}
fn main() {
let rt = Runtime::new().unwrap();
rt.block_on(make_auth_request()).unwrap();
}
完整示例代码
以下是一个更完整的示例,同时包含基本用法和认证用法:
use hyper::{Body, Client, Request, Response};
use hyper_socks2::SocksConnector;
use tokio::runtime::Runtime;
// 基本SOCKS5代理示例
async fn basic_proxy_example() -> Result<Response<Body>, Box<dyn std::error::Error>> {
// 创建SOCKS5连接器,指向本地1080端口
let socks_connector = SocksConnector::new("127.0.0.1:1080")?;
// 构建hyper客户端
let client = Client::builder().build::<_, Body>(socks_connector);
// 创建HTTP GET请求
let req = Request::builder()
.uri("http://example.com")
.body(Body::empty())?;
// 发送请求并返回响应
client.request(req).await.map_err(|e| e.into())
}
// 带认证的SOCKS5代理示例
async fn auth_proxy_example() -> Result<Response<Body>, Box<dyn std::error::Error>> {
// 创建带用户名密码认证的SOCKS5连接器
let socks_connector = SocksConnector::new("127.0.0.1:1080")?
.with_username_password("myuser", "mypassword");
let client = Client::builder().build::<_, Body>(socks_connector);
let req = Request::builder()
.uri("http://example.com")
.body(Body::empty())?;
client.request(req).await.map_err(|e| e.into())
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Running basic SOCKS5 proxy example...");
let basic_res = basic_proxy_example().await?;
println!("Basic proxy response status: {}", basic_res.status());
println!("\nRunning authenticated SOCKS5 proxy example...");
let auth_res = auth_proxy_example().await?;
println!("Authenticated proxy response status: {}", auth_res.status());
Ok(())
}
许可证
hyper-socks2遵循以下许可证之一:
- Apache License 2.0
- MIT
您可以选择其中任何一种。
1 回复
hyper-socks2: Rust高性能HTTP/SOCKS5代理与隧道库
介绍
hyper-socks2是一个基于hyper和tokio-socks的Rust库,提供了高性能的HTTP和SOCKS5代理功能,支持构建代理服务器和隧道客户端。它特别适合需要网络代理功能的Rust应用程序。
主要特性
- 支持SOCKS5代理协议
- 支持HTTP代理
- 异步/高性能实现
- 易于集成的API设计
- 支持隧道功能
使用方法
添加依赖
首先在Cargo.toml中添加依赖:
[dependencies]
hyper-socks2 = "0.7"
tokio = { version = "1.0", features = ["full"] }
hyper = "0.14"
基本示例:通过SOCKS5代理发起HTTP请求
use hyper::{Client, Request, Body};
use hyper_socks2::SocksConnector;
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 创建SOCKS5连接器
let socks_connector = SocksConnector {
proxy_addr: "127.0.0.1:1080".parse()?,
auth: None, // 如果需要认证: Some(("username".into(), "password".into()))
};
// 创建基于SOCKS的HTTP客户端
let client = Client::builder().build::<_, Body>(socks_connector);
// 创建请求
let req = Request::builder()
.uri("http://example.com")
.body(Body::empty())?;
// 发送请求
let res = client.request(req).await?;
println!("Status: {}", res.status());
Ok(())
}
代理服务器示例
use hyper::{Body, Request, Response, Server};
use hyper::service::{make_service_fn, service_fn};
use hyper_socks2::SocksProxy;
use std::convert::Infallible;
async fn handle(req: Request<Body>) -> Result<Response<Body>, Infallible> {
// 处理请求的逻辑
Ok(Response::new(Body::from("Hello via SOCKS5 proxy!")))
}
#[tokio::main]
async fn main() {
let addr = ([127, 0, 0, 1], 1080).into();
let make_svc = make_service_fn(|_conn| async {
Ok::<_, Infallible>(service_fn(handle))
});
let server = Server::bind(&addr)
.serve(SocksProxy::new(make_svc));
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
}
隧道客户端示例
use hyper_socks2::tunnel::{Tunnel, TunnelConfig};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = TunnelConfig {
proxy_addr: "127.0.0.1:1080".parse()?,
target_addr: "example.com:80".to_string(),
auth: None,
};
let mut tunnel = Tunnel::connect(config).await?;
// 通过隧道发送数据
tunnel.write_all(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n").await?;
// 读取响应
let mut buf = [0; 1024];
let n = tunnel.read(&mut buf).await?;
println!("Response: {}", String::from_utf8_lossy(&buf[..n]));
Ok(())
}
高级用法
自定义超时设置
use std::time::Duration;
use hyper_socks2::SocksConnector;
let socks_connector = SocksConnector {
proxy_addr: "127.0.0.1:1080".parse().unwrap(),
auth: None,
connect_timeout: Some(Duration::from_secs(10)),
};
使用认证
let socks_connector = SocksConnector {
proxy_addr: "127.0.0.1:1080".parse().unwrap(),
auth: Some(("username".into(), "password".into())),
..Default::default()
};
注意事项
- 确保代理服务器已正确配置并运行
- 对于生产环境,考虑添加适当的错误处理和日志记录
- 性能关键应用可能需要调整连接池大小等参数
hyper-socks2为Rust应用程序提供了强大而灵活的代理功能,可以轻松集成到现有项目中。
完整示例代码
完整的HTTP代理客户端示例
use hyper::{Client, Request, Body, Method};
use hyper_socks2::SocksConnector;
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 配置SOCKS5代理连接器
let socks_connector = SocksConnector {
proxy_addr: "127.0.0.1:1080".parse()?,
auth: Some(("user".into(), "pass".into())), // 认证信息
connect_timeout: Some(std::time::Duration::from_secs(5)), // 设置超时
};
// 创建HTTP客户端
let client = Client::builder()
.build::<_, Body>(socks_connector);
// 构建GET请求
let req = Request::builder()
.method(Method::GET)
.uri("https://www.rust-lang.org")
.header("User-Agent", "hyper-socks2-example")
.body(Body::empty())?;
// 发送请求并获取响应
let res = client.request(req).await?;
println!("Response status: {}", res.status());
// 读取响应体
let body_bytes = hyper::body::to_bytes(res.into_body()).await?;
println!("Response body length: {} bytes", body_bytes.len());
Ok(())
}
完整的SOCKS5代理服务器示例
use hyper::{Body, Request, Response, Server};
use hyper::service::{make_service_fn, service_fn};
use hyper_socks2::SocksProxy;
use std::{convert::Infallible, net::SocketAddr};
async fn proxy_handler(req: Request<Body>) -> Result<Response<Body>, Infallible> {
// 简单的请求处理逻辑
match req.uri().path() {
"/" => Ok(Response::new(Body::from("Welcome to SOCKS5 proxy server"))),
_ => Ok(Response::builder()
.status(404)
.body(Body::from("Not Found"))
.unwrap())
}
}
#[tokio::main]
async fn main() {
// 设置服务器地址
let addr: SocketAddr = ([127, 0, 0, 1], 1080).into();
println!("Starting SOCKS5 proxy server on {}", addr);
// 创建服务
let make_svc = make_service_fn(|_conn| async {
Ok::<_, Infallible>(service_fn(proxy_handler))
});
// 创建并运行服务器
let server = Server::bind(&addr)
.serve(SocksProxy::new(make_svc));
if let Err(e) = server.await {
eprintln!("Server error: {}", e);
}
}
完整的隧道客户端示例
use hyper_socks2::tunnel::{Tunnel, TunnelConfig};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 隧道配置
let config = TunnelConfig {
proxy_addr: "127.0.0.1:1080".parse()?,
target_addr: "www.google.com:80".to_string(),
auth: Some(("proxyuser".to_string(), "proxypass".to_string())),
};
println!("Connecting to target via SOCKS5 tunnel...");
// 建立隧道连接
let mut tunnel = Tunnel::connect(config).await?;
println!("Tunnel established. Sending HTTP request...");
// 准备HTTP请求
let http_request = "GET / HTTP/1.1\r\n\
Host: www.google.com\r\n\
User-Agent: hyper-socks2-tunnel-example\r\n\
Connection: close\r\n\r\n";
// 通过隧道发送请求
tunnel.write_all(http_request.as_bytes()).await?;
// 读取响应
let mut response = Vec::new();
let mut buf = [0; 1024];
loop {
let n = tunnel.read(&mut buf).await?;
if n == 0 {
break;
}
response.extend_from_slice(&buf[..n]);
}
println!("Received {} bytes of response", response.len());
println!("First 200 bytes of response:\n{}",
String::from_utf8_lossy(&response[..200.min(response.len())]));
Ok(())
}