Proyx is an HTTP/HTTPS proxy server that can act as an MITM by dynamically generating certificates for inspected HTTPS traffic. It is built on top of hyper, provides a configurable cache for certificates, and ships with a default client implementation for relaying proxied requests.
- Transparently forwards HTTP and HTTPS requests while optionally inspecting TLS traffic when a trusted CA is provided.
- Uses a lightweight nginx-style state machine to drive the request/response lifecycle (
src/state_machine.rs). - Generates per-host certificates from a single root issuer (
src/tls.rs) and caches them in-memory viamoka. - Ships with a
DefaultClienthelper that knows how to drive HTTP/1 and HTTP/2 connections with native TLS or Rustls backends.
- Configure the proxy by editing
proxy-config.tomlor settingPROXY_CONFIGto point to another TOML file. - Build and run with Cargo (default feature enables a native TLS client):
cargo runIf you prefer rustls for outgoing connections, enable the rustls-client feature and disable native-tls-client:
cargo run --no-default-features --features rustls-client| Key | Description | Default |
|---|---|---|
address |
Socket address to bind the proxy to. | 127.0.0.1:8080 |
cache_capacity |
Certificate cache size (entries). | 1024 |
ca_dir |
Directory where the automatically generated CA certificate and key are stored. | ./proxy-ca |
log_level |
Used for tracing env filter (see main.rs, lines 40-43). |
info |
The first time the proxy starts it creates the CA under ca_dir (proxy-ca.pem and proxy-ca.key). The PEM blobs printed to stdout should be trusted by your browser/system to intercept HTTPS.
src/main.rs sets up the MITM infrastructure:
- Loads or creates the CA via
load_or_create_ca. - Builds a
MitmProxywith the optional issuer and an in-memory cache. - Spawns a
DefaultClientto relay requests to their destinations, honoring HTTP upgrades when requested. - Prints the CA certificate/key for trust installation and runs the proxy loop produced by
MitmProxy::bind.
MitmProxy(proxy-backend/src/lib.rs) exposesbindandwrap_service, handling CONNECT upgrades, TLS interception, certificate generation, request injection (inject_authority), and a sharedProxyStatefor UI consumers.state_machine::process_requestdrives every downstream request through request/intercept/IO/response stages while keeping metadata and wiring updates intoProxyState.ProxyState(proxy-backend/src/proxy_state.rs) keeps connection snapshots, live-intercept toggles, and resume waiters; it feeds the UI via tauri commands/events.default_client::DefaultClientis the outgoing HTTP client that negotiates TLS (native or rustls) and copies upgraded connections when needed.
Certificates are generated with rcgen on the fly. You can trust the CA by copying the printed PEM from startup (or the files at ca_dir). If you disable root_issuer in MitmProxy::new(None, …), the proxy will simply tunnel CONNECT requests without inspecting HTTPS.
- The workspace includes the
proxy-backendcrate that drives the MITM machinery and the Tauri UI underproyxui/src-taurithat now renders a React/Vite application fromproyxui/src. src/App.tsxwraps the tabbed layout insideConnectionProvider, which lives insrc/state/connection-store.tsx. That store hydrates fromget_connections/get_intercept_queue, listens toproxy-event, and normalizes backend snapshots into the data consumed by theSiteMapTab,RequestReplayTab, andLiveInterceptTab.- Each tab (
src/tabs/*) ships focused layouts and actions that call the accompanying Tauri commands (resume_intercept,drop_request,replay_connection,toggle_live_intercept,modify_intercept,drop_intercept, etc.) through@tauri-apps/api/coreso the UI stays in sync with backend state. - The Tauri backend (
proyxui/src-tauri/src/lib.rs) now exposes the same proxy state as commands/events, forwardsProxyEventviaapp_handle.emit("proxy-event", …), and spins up the proxy server fromMitmProxy::bindbefore launching the window. - The shell mirrors the example template: a thin
src-tauri/src/main.rscallsproyxui_lib::run(),build.rsrunstauri_build::build, andtauri.conf.jsonkeeps the v2 schema while pointing at the React build output. - Run
cargo tauri devfromproyxui/src-tauri(with the React dev server ondevUrl) to iterate, ornpm run buildfromproyxuiand thencargo tauri buildto bundle. Config::loadnow walks up the directory tree when locatingproxy-config.tomland resolvesca_dirrelative to that location so both the CLI proxy and the Tauri shell reuse the same CA directory regardless of how they were launched.
- Backend:
cargo run -p Proyxfrom the repo root will compile the proxy and start it on the address specified inproxy-config.toml(default127.0.0.1:8080). - UI:
cargo tauri dev(fromsrc-tauri) launches the Tauri window that connects to the running proxy backend. The renderer uses the HTML/JS undersrc-tauri/dist; you can replace that with your preferred front-end toolchain so long as the built files end up in the same folder. - Config changes: edit
proxy-config.tomlor setPROXY_CONFIGto point to a different file. The Tauri binary will reuse the same config and emit the CA PEM/key during startup so you can trust it in your browser.
- Live intercept controls – Resume/Drop now resolve to actual decisions so waiting requests complete, and the UI queues modified bodies in
ProxyState, yet we still need the state machine to inject the edited payload back into the resumedIncomingstream so downstream servers see the latest edits. - Replay enrichment – the replay tab already exposes headers, tags, sizes, durations, and previews emitted from
ProxyState, but we can extend this by supporting persistent replay collections, scheduling helpers, and storing response metadata so editors can rehydrate a session end-to-end. - State metadata & filtering –
ConnectionStorenow preserves tags, durations, timestamps, and size hints for richer badges and filters; future work includes virtualization/pagination, memoized selectors for large histories, and exposing header/tag facets for filtering. - Testing & tooling – add unit/integration coverage for the
ConnectionStore, tauri commands, andProxyEventwiring so UI workflows (toggle, resume, replay) stay reliable across refactors. - Documentation – keep
ui_mode_design.mdsynced with the React tabs/components, catalog the Tauri invocations, and capture how the renderer consumesproxy-eventpayloads for future contributors.