xmr-btc-swap/xmr-btc/tests/tor.rs

111 lines
3.6 KiB
Rust
Raw Normal View History

#[cfg(feature = "tor")]
mod tor_test {
use anyhow::Result;
use hyper::service::{make_service_fn, service_fn};
use reqwest::StatusCode;
use spectral::prelude::*;
2020-10-20 01:14:10 -04:00
use std::{convert::Infallible, process::Child};
use tokio::sync::oneshot::Receiver;
2020-10-20 01:14:10 -04:00
use torut::{
onion::TorSecretKeyV3,
utils::{run_tor, AutoKillChild},
};
use xmr_btc::tor::UnauthenticatedConnection;
async fn hello_world(
_req: hyper::Request<hyper::Body>,
) -> Result<hyper::Response<hyper::Body>, Infallible> {
Ok(hyper::Response::new("Hello World".into()))
}
fn start_test_service(port: u16, rx: Receiver<()>) {
let make_svc =
make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(hello_world)) });
let addr = ([127, 0, 0, 1], port).into();
let server = hyper::Server::bind(&addr).serve(make_svc);
let graceful = server.with_graceful_shutdown(async {
rx.await.ok();
});
tokio::spawn(async {
// server.await.unwrap();
if let Err(e) = graceful.await {
eprintln!("server error: {}", e);
}
});
}
2020-10-20 01:14:10 -04:00
fn run_tmp_tor() -> (Child, u16, u16) {
let control_port = if port_check::is_local_port_free(9051) {
9051
} else {
port_check::free_local_port().unwrap()
};
let proxy_port = if port_check::is_local_port_free(9050) {
9050
} else {
port_check::free_local_port().unwrap()
};
2020-10-20 01:14:10 -04:00
(
run_tor(
"tor",
&mut [
"--CookieAuthentication",
"1",
"--ControlPort",
control_port.to_string().as_str(),
"--SocksPort",
proxy_port.to_string().as_str(),
2020-10-20 01:14:10 -04:00
]
.iter(),
)
.expect("Starting tor filed"),
control_port,
proxy_port,
)
}
#[tokio::test]
async fn test_tor_control_port() -> Result<()> {
2020-10-20 01:14:10 -04:00
// start tmp tor
let (child, control_port, proxy_port) = run_tmp_tor();
let _child = AutoKillChild::new(child);
// Setup test HTTP Server
let (tx, rx) = tokio::sync::oneshot::channel::<()>();
let port = 8080;
start_test_service(port, rx);
// Connect to local Tor service
2020-10-20 01:14:10 -04:00
let mut authenticated_connection =
UnauthenticatedConnection::with_ports(proxy_port, control_port)
.init_authenticated_connection()
2020-10-20 01:14:10 -04:00
.await?;
// Expose an onion service that re-directs to the echo server.
let tor_secret_key_v3 = TorSecretKeyV3::generate();
authenticated_connection
.add_service(port, &tor_secret_key_v3)
.await?;
// Test if Tor service forwards to HTTP Server
2020-10-20 01:14:10 -04:00
let proxy = reqwest::Proxy::all(format!("socks5h://127.0.0.1:{}", proxy_port).as_str())
.expect("tor proxy should be there");
let client = reqwest::Client::builder().proxy(proxy).build().unwrap();
let onion_address = tor_secret_key_v3.public().get_onion_address().to_string();
let onion_url = format!("http://{}:8080", onion_address);
let res = client.get(&onion_url).send().await?;
assert_that(&res.status()).is_equal_to(StatusCode::OK);
let text = res.text().await?;
assert_that!(text).contains("Hello World");
// gracefully shut down server
let _ = tx.send(());
Ok(())
}
}