mod common;
use crate::common::{
build_client, build_proxy_client, fetch_subscribe, mask_text, start_http_server, start_proxy,
HELLO_WORLD,
};
use anyhow::Result;
use async_http_proxy::http_connect_tokio;
use futures_util::SinkExt;
use proxyfor::server::WEB_PREFIX;
use std::time::Duration;
use tokio::net::TcpStream;
use tokio_tungstenite::tungstenite::Message;
#[tokio::test]
async fn test_web_index() -> Result<()> {
let (proxy_addr, stop_proxy) = start_proxy(true).await?;
let client = build_client()?;
let res = client
.get(format!(
"http://localhost:{}{}",
proxy_addr.port(),
WEB_PREFIX
))
.send()
.await?;
let status = res.status();
let text = res.text().await?;
assert_eq!(status, 200);
assert!(text.contains("
proxyfor"));
let _ = stop_proxy.send(());
Ok(())
}
#[tokio::test]
async fn test_list_traffics() -> Result<()> {
let (proxy_addr, stop_proxy) = start_proxy(true).await?;
let (server_addr, stop_server) = start_http_server().await?;
let proxy_client = build_proxy_client(&proxy_addr.to_string())?;
let res = proxy_client
.get(format!("http://localhost:{}/hello", server_addr.port()))
.send()
.await?;
assert_eq!(res.status(), 200);
let res = proxy_client
.get(format!(
"http://localhost:{}/hello/gzip",
server_addr.port()
))
.send()
.await?;
assert_eq!(res.status(), 200);
let res = proxy_client
.post(format!("http://localhost:{}/echo", server_addr.port()))
.header("content-type", "text/plain")
.body(HELLO_WORLD)
.send()
.await?;
assert_eq!(res.status(), 200);
let mut output = vec![];
let client = build_client()?;
let res = client
.get(format!(
"http://localhost:{}{}/traffics",
proxy_addr.port(),
WEB_PREFIX
))
.send()
.await?;
assert_eq!(res.status(), 200);
output.push("/traffics".into());
output.push(res.text().await?);
let client = build_client()?;
let res = client
.get(format!(
"http://localhost:{}{}/traffics?markdown",
proxy_addr.port(),
WEB_PREFIX
))
.send()
.await?;
assert_eq!(res.status(), 200);
output.push("/traffics?markdown".into());
output.push(res.text().await?);
let client = build_client()?;
let res = client
.get(format!(
"http://localhost:{}{}/traffics?har",
proxy_addr.port(),
WEB_PREFIX
))
.send()
.await?;
assert_eq!(res.status(), 200);
output.push("/traffics?har".into());
output.push(res.text().await?);
let client = build_client()?;
let res = client
.get(format!(
"http://localhost:{}{}/traffics?curl",
proxy_addr.port(),
WEB_PREFIX
))
.send()
.await?;
assert_eq!(res.status(), 200);
output.push("/traffics?curl".into());
output.push(res.text().await?);
let output = output.join("\n\n");
let output = mask_text(&output);
insta::assert_snapshot!(output);
let _ = stop_server.send(());
let _ = stop_proxy.send(());
Ok(())
}
#[tokio::test]
async fn test_get_traffic() -> Result<()> {
let (proxy_addr, stop_proxy) = start_proxy(true).await?;
let (server_addr, stop_server) = start_http_server().await?;
let proxy_client = build_proxy_client(&proxy_addr.to_string())?;
let res = proxy_client
.post(format!("http://localhost:{}/echo", server_addr.port()))
.header("content-type", "text/plain")
.body(HELLO_WORLD)
.send()
.await?;
assert_eq!(res.status(), 200);
let id = 1;
let client = build_client()?;
let res = client
.get(format!(
"http://localhost:{}{}/traffic/{}",
proxy_addr.port(),
WEB_PREFIX,
id
))
.send()
.await?;
assert_eq!(res.status(), 200);
let mut output = vec!["/traffic/:id".into(), res.text().await?];
let client = build_client()?;
let res = client
.get(format!(
"http://localhost:{}{}/traffic/{}?markdown",
proxy_addr.port(),
WEB_PREFIX,
id
))
.send()
.await?;
assert_eq!(res.status(), 200);
output.push("/traffic/:id?markdown".into());
output.push(res.text().await?);
let client = build_client()?;
let res = client
.get(format!(
"http://localhost:{}{}/traffic/{}?har",
proxy_addr.port(),
WEB_PREFIX,
id
))
.send()
.await?;
assert_eq!(res.status(), 200);
output.push("/traffic/:id?har".into());
output.push(res.text().await?);
let client = build_client()?;
let res = client
.get(format!(
"http://localhost:{}{}/traffic/{}?curl",
proxy_addr.port(),
WEB_PREFIX,
id
))
.send()
.await?;
assert_eq!(res.status(), 200);
output.push("/traffic/:id?curl".into());
output.push(res.text().await?);
let output = output.join("\n\n");
let output = mask_text(&output);
insta::assert_snapshot!(output);
let _ = stop_server.send(());
let _ = stop_proxy.send(());
Ok(())
}
#[tokio::test]
async fn test_subscribe_traffics() -> Result<()> {
let (proxy_addr, stop_proxy) = start_proxy(true).await?;
let (server_addr, stop_server) = start_http_server().await?;
let proxy_client = build_proxy_client(&proxy_addr.to_string())?;
for _ in 0..2 {
let res = proxy_client
.post(format!("http://localhost:{}/echo", server_addr.port()))
.header("content-type", "text/plain")
.body(HELLO_WORLD)
.send()
.await?;
assert_eq!(res.status(), 200);
}
let output = fetch_subscribe(
&format!(
"http://localhost:{}{}/subscribe/traffics",
proxy_addr.port(),
WEB_PREFIX,
),
Duration::from_millis(1500),
)
.await?;
let output = mask_text(&output);
insta::assert_snapshot!(output);
let _ = stop_server.send(());
let _ = stop_proxy.send(());
Ok(())
}
#[tokio::test]
async fn test_subscribe_websocket() -> Result<()> {
let (proxy_addr, stop_proxy) = start_proxy(true).await?;
let (server_addr, stop_server) = start_http_server().await?;
let mut stream = TcpStream::connect(proxy_addr).await?;
http_connect_tokio(
&mut stream,
&server_addr.ip().to_string(),
server_addr.port(),
)
.await?;
let (mut ws, res) =
tokio_tungstenite::client_async(format!("ws://{}", server_addr), stream).await?;
assert_eq!(res.status(), 101);
ws.send(Message::Text("hello".to_string())).await?;
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
ws.send(Message::Text("hello".to_string())).await?;
let output = fetch_subscribe(
&format!(
"http://localhost:{}{}/subscribe/websocket/1",
proxy_addr.port(),
WEB_PREFIX,
),
Duration::from_millis(1500),
)
.await?;
let output = mask_text(&output);
insta::assert_snapshot!(output);
let _ = stop_server.send(());
let _ = stop_proxy.send(());
Ok(())
}