use async_trait::async_trait;
use slinger_mitm::{
Interceptor, InterceptorFactory, MitmConfig, MitmProxy, MitmRequest, MitmResponse, Result,
};
use std::sync::Arc;
struct CustomInterceptor;
#[async_trait]
impl Interceptor for CustomInterceptor {
async fn intercept_request(&self, request: MitmRequest) -> Result<Option<MitmRequest>> {
println!("[REQ] Session ID: {}", request.session_id());
println!("[REQ] Destination: {}", request.destination());
if let Some(source) = request.source() {
println!("[REQ] Source: {}", source);
}
println!("[REQ] Timestamp: {}", request.timestamp());
println!("[REQ] Is HTTP: {}", request.is_http());
if request.is_http() {
println!("[REQ] HTTP Method: {}", request.request().method());
println!("[REQ] HTTP URI: {}", request.request().uri());
} else {
println!(
"[REQ] Body length: {} bytes",
request.body().map(|b| b.len()).unwrap_or(0)
);
if let Some(body) = request.body() {
println!("[REQ] Data preview: {:?}", body);
}
}
println!("---");
Ok(Some(request))
}
async fn intercept_response(&self, response: MitmResponse) -> Result<Option<MitmResponse>> {
println!("[RSP] Session ID: {}", response.session_id());
println!("[RSP] Source: {}", response.source());
if let Some(destination) = response.destination() {
println!("[RSP] Destination: {}", destination);
}
println!("[RSP] Timestamp: {}", response.timestamp());
println!("[RSP] Is HTTP: {}", response.is_http());
if response.is_http() {
println!("[RSP] HTTP Status: {}", response.response().status_code());
} else {
println!(
"[RSP] Body length: {} bytes",
response.body().map(|b| b.len()).unwrap_or(0)
);
if let Some(body) = response.body() {
println!("[RSP] Data preview: {:?}", body);
}
}
println!("---");
Ok(Some(response))
}
}
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("=== Slinger MITM Proxy with Unified Traffic Interception ===\n");
let config = MitmConfig {
ca_storage_path: std::path::PathBuf::from(".slinger-mitm"),
max_connections: 1000,
connection_timeout: 30,
interceptor_timeout_secs: 60,
upstream_proxy: None,
};
let proxy = MitmProxy::new(config).await?;
let interceptor_handler = proxy.interceptor_handler();
let mut handler = interceptor_handler.write().await;
handler.add_interceptor(Arc::new(InterceptorFactory::logging()));
handler.add_interceptor(Arc::new(CustomInterceptor));
drop(handler);
println!("Starting MITM proxy with TCP interception on 127.0.0.1:4444");
println!("CA certificate: {}\n", proxy.ca_cert_path().display());
println!("To use this proxy for traffic interception:");
println!("1. Configure your application to use SOCKS5 proxy: 127.0.0.1:4444");
println!("2. The proxy will intercept and log all traffic (HTTP and raw TCP)");
println!("3. Request/response data with metadata will be shown in the console\n");
println!("Features:");
println!("- MitmRequest/MitmResponse contain: session_id, source/destination, timestamp, body");
println!("- session_id allows you to correlate requests with their responses");
println!("- Same interceptor handles both HTTP and non-HTTP protocols");
println!("- Use is_http() to detect protocol type\n");
proxy.start("127.0.0.1:1080").await?;
Ok(())
}