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

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(())
}