An http proxy made with rust to record and replay your calls. It can help you for testing your apps.
Using :
Actix (with sessions)
Clap
Serde (and serde_json)
Awc
Env logger
I cant find a good solution for this job. Lightweight, Fast, Low Memory usage and support replay concurrency. I already made something with a playwright middleware (Typescript) to reproduces this behaviour but it slowdown tests and use huge amount of RAM/CPU. This project intend to help me replay API calls when running frontend e2e tests by externalizing what i did in the playwright middleware.
I choose Rust because I did some projects using Java, JS and Go and wanted to try another language.
- I'm not an expert in Rust so if you have ideas to improve the actual code don't hesitate.
- If you have any request for this project create an issue.
Actually I need to implement them. I'm doing them manually (boring).
- Passthrough
- Recording
- Start session
- Can make calls without issues : with/without body, handle text, json, ...
- Stop the session
- Calls are saved
- Replaying
- Start session
- Can make calls without issues : with/without body, handle text, json, ...
- Stop the session
- Add some CI. (Partial)
- Improve installation flow.
- Add testing (I'M SO BAD TO THIS NEED TO BE FIRST THING TO DO). (Golden paths)
- When record found but a call is not present allow user to passthrough instead of raising 404.
- Use a yaml file/env vars instead of CLI options.
- Allow users to replay the last identifier multiple times.
- Allow users to customize saved headers (exclude some headers, add static headers).
- Benchmark memory usage, response times
- Examples how to implement locally for playwright
- Examples how to implement using docker for playwright
- Examples how to implement in CI for playwright
Request are identified with : METHOD : URL.
- Proxy has 3 options : passthrough, recording, replaying. The mode is selected based on options you pass to the cli.
- When running in recording or replaying you need to made 2 calls: one to start the session and one to end (otherwise memory issue ?).
- When starting a session it will add a cookie to your headers to identify your session id
- Based on this session id it will retrieve records (replay), or store them in memory (record).
- Save only happen when you stop the session. In record mode save the file with suffix .snap in JSON format.
Just relay your requests nothing more
Store your request sequentially in your session. When you end the session it will save them in the file.
Get the file of the record. When you make a call it will retrieve sequentially the record based on the identifier. If a call is not found it will return a 404.
I will try to improve this flow ! :')
- Clone this repository
- Build it :
cargo build --release - Go in build directory :
cd target/release - Run
./http-replay-proxyhere
- Run the proxy :
./http-replay-proxy -f http://exemple.com -d ./snapshots/ -u - Start a session in your script :
curl -X POST http://localhost:3333/start-record/test-recordname - Make some calls through the proxy
- Stop the session :
curl -X POST http://localhost:3333/end-record - Calls should be saved in ./snapshots/test-recordname.snap
- Run the proxy :
./http-replay-proxy -f http://exemple.com -d ./snapshots/ - Start a session in your script :
curl -X POST http://localhost:3333/start-record/test-recordname - Make some calls through the proxy
- Stop the session :
curl -X POST http://localhost:3333/end-record
Usage: http-replay-proxy [OPTIONS] --forward-to <FORWARD_TO>
Options:
-l, --listen-addr <LISTEN_ADDR> [default: localhost]
-p, --port <PORT> [default: 3333]
-f, --forward-to <FORWARD_TO>
-u, --record Use this to update your snapshots
-d, --dir <RECORD_DIR> Directory where to store/to get records [default: ]
-h, --help Print help
-V, --version Print version
./http-replay-proxy -f http://exemple.com
./http-replay-proxy -f http://exemple.com -d ./dir_to_save_records -u
./http-replay-proxy -f http://exemple.com -d ./dir_to_save_records
- If you never end the record the sessions will grow in memory so it will take more RAM Usage (it keep the object with the records already stored in). Use POST on /clear-sessions to remove all
- How this is memory efficient ?
- Can I store records more efficiently (may be not human readable) to improve speed and memory usage ?
- How can I make this program as a lib to let users implements custom handlers ?
- How to make installation easy ?