Skip to main content

Module dev_proxy

Module dev_proxy 

Source
Expand description

Native reverse proxy for container-agent dev servers.

Routes http://<project>-<agent_id>.localhost:{DEV_PROXY_PORT}/... to whatever internal ip:port that agent’s dev server registered via the RegisterDevServer MCP tool (the HTTP endpoint backing that tool lives in crates/srv/src/server/app_api/dev_server.rs; this module owns the routing table and the proxy server itself). See docs/specs/SPEC_NATIVE_CONTAINER_DEV_PROXY_2026_09_19.md.

Deliberately NOT a general-purpose reverse proxy (spec §4): Host-header → backend address is the entire feature. No path routing, no TLS, no auth, no rate limiting, no websocket upgrade handling.

Structs§

DevProxyRegistry
"<project>-<agent_id>" → the container’s internal ip:port its dev server is actually listening on. Cleared per-agent when that agent’s container stops (ContainerManager::stop/remove in container.rs call unregister_agent — see that module’s cleanup_dev_proxy_routes).
ProxyState 🔒
Route 🔒
One registered dev server: where to actually send the request, and which agent owns the registration (needed so unregister_agent can remove exactly this agent’s entries — see its doc comment for why a plain string-suffix match on the routing key isn’t safe).

Constants§

DEV_PROXY_PORT
Fixed local port the proxy listens on. Chosen for this PR — nothing else in agentmux-srv binds it (checked: no other TcpListener::bind or config default references 8090 anywhere in this crate). See spec §5.

Functions§

not_found_response 🔒
proxy_handler 🔒
The one handler this proxy has. Reads Host, looks up the backend, forwards the request (method/headers/body, streamed both ways so a large response body — or a long-lived one — isn’t buffered whole in memory), and streams the response back unchanged.
router
Builds the proxy’s axum router. Split out from serve so tests can drive it directly (via a real bound listener) without needing the fixed DEV_PROXY_PORT to be free.
routing_key_from_host
Host header → routing key. "pulse-korp.localhost:8090" and "pulse-korp.localhost" both become "pulse-korp". A Host that isn’t .localhost is still accepted (minus port, lowercased) rather than rejected outright — an empty/missing Host is the only thing that produces None. Whether the key actually resolves to anything is the registry lookup’s job, not this function’s; either way the caller gets a clear “no dev server registered for <key>” 404, never a confusing hostname-format error.
serve
Binds DEV_PROXY_PORT on loopback and serves the proxy until the process exits. Spawned once at srv startup (main.rs). A bind failure (e.g. the port is already in use on this machine) is logged and the proxy is simply unavailable for this run — never fatal to srv startup; dev-server routing is an additive convenience, not core functionality.