You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
56 lines
1.8 KiB
56 lines
1.8 KiB
use std::net::SocketAddr;
|
|
|
|
use hyper::StatusCode;
|
|
use sthp::proxy_request;
|
|
use tokio::net::TcpListener;
|
|
|
|
use color_eyre::Result;
|
|
use socksprox::Socks5Server;
|
|
use tokio::task::JoinHandle;
|
|
|
|
async fn start_socks_server() -> Result<(JoinHandle<()>, SocketAddr)> {
|
|
// TODO: Currently, Socks5Server does not return the port it is bound to.
|
|
// To work around this, we will use TcpListener to obtain a random available port.
|
|
// After retrieving the port, we will immediately release it.
|
|
let listener = TcpListener::bind("localhost:0").await?;
|
|
let addr = listener.local_addr()?;
|
|
let port = addr.port();
|
|
eprintln!("socks proxy will listen on port {}", port);
|
|
// release port
|
|
drop(listener);
|
|
|
|
let mut server = Socks5Server::new("localhost", port, None, None)
|
|
.await
|
|
.unwrap();
|
|
let join_handle = tokio::task::spawn(async move {
|
|
server.serve().await;
|
|
});
|
|
Ok((join_handle, addr))
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn simple_test() -> Result<()> {
|
|
let (_, socks_proxy_addr) = start_socks_server().await?;
|
|
let listener = TcpListener::bind("localhost:0").await?;
|
|
let addr = listener.local_addr()?;
|
|
let _ = tokio::task::spawn(async move {
|
|
let (stream, proxy_addr) = listener.accept().await?;
|
|
proxy_request(stream, proxy_addr, socks_proxy_addr, None, None, None).await?;
|
|
eprintln!("new connection from: {:?}", proxy_addr);
|
|
Ok::<_, color_eyre::eyre::Error>(())
|
|
});
|
|
eprintln!("http proxy will listen on {}", addr);
|
|
|
|
let client = reqwest::Client::builder()
|
|
.proxy(reqwest::Proxy::http(format!(
|
|
"http://localhost:{}",
|
|
addr.port()
|
|
))?)
|
|
.build()?;
|
|
|
|
assert_eq!(
|
|
client.get("http://example.org").send().await?.status(),
|
|
StatusCode::OK
|
|
);
|
|
Ok(())
|
|
}
|
|
|