Sniff and replay HTTP requests and responses — perfect for mocking APIs during testing.
1use std::sync::Arc;
2
3use clap::{Arg, Command};
4use owo_colors::OwoColorize;
5use proxy::start_server;
6use tokio::sync::Mutex;
7
8pub mod proxy;
9pub mod replay;
10pub mod store;
11
12#[tokio::main]
13async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
14 const BANNER: &str = r#"
15
16 ____ __
17 / __ \___ ____ / /___ ___ __
18 / /_/ / _ \/ __ \/ / __ `/ / / /
19 / _, _/ __/ /_/ / / /_/ / /_/ /
20 /_/ |_|\___/ .___/_/\__,_/\__, /
21 /_/ /____/
22
23 Sniff and replay HTTP requests and responses — perfect for mocking APIs during testing.
24 "#;
25 let matches = Command::new("replay")
26 .version(env!("CARGO_PKG_VERSION"))
27 .author("Tsiry Sandratraina <tsiry.sndr@rocksky.app>")
28 .about(&format!("{}", BANNER.magenta()))
29 .arg(
30 Arg::new("target")
31 .short('t')
32 .long("target")
33 .help("The target URL to replay the requests to"),
34 )
35 .arg(
36 Arg::new("listen")
37 .short('l')
38 .long("listen")
39 .help("The address to listen on for incoming requests")
40 .default_value("127.0.0.1:6677"),
41 )
42 .subcommand(
43 Command::new("mock")
44 .about("Read mocks from replay_mock.json and start a replay server"),
45 )
46 .get_matches();
47
48 if let Some(_) = matches.subcommand_matches("mock") {
49 let logs = store::load_logs_from_file(proxy::PROXY_LOG_FILE)?;
50 let logs = Arc::new(Mutex::new(logs));
51 let listen = matches.get_one::<String>("listen").unwrap();
52 println!(
53 "Loaded {} mocks from {}",
54 logs.lock().await.len().magenta(),
55 proxy::PROXY_LOG_FILE.magenta()
56 );
57 println!("Replay server is running on {}", listen.magenta());
58 replay::start_replay_server(logs, listen).await?;
59 return Ok(());
60 }
61
62 let target = matches.get_one::<String>("target");
63
64 if target.is_none() {
65 eprintln!("Error: Target URL is required");
66 std::process::exit(1);
67 }
68
69 let target = target.unwrap();
70 let listen = matches.get_one::<String>("listen").unwrap();
71
72 start_server(target, listen).await?;
73
74 Ok(())
75}