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§
- DevProxy
Registry "<project>-<agent_id>"→ the container’s internalip:portits dev server is actually listening on. Cleared per-agent when that agent’s container stops (ContainerManager::stop/removeincontainer.rscallunregister_agent— see that module’scleanup_dev_proxy_routes).- Proxy
State 🔒 - Route 🔒
- One registered dev server: where to actually send the request, and
which agent owns the registration (needed so
unregister_agentcan 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-srvbinds it (checked: no otherTcpListener::bindor 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
serveso tests can drive it directly (via a real bound listener) without needing the fixedDEV_PROXY_PORTto 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.localhostis still accepted (minus port, lowercased) rather than rejected outright — an empty/missing Host is the only thing that producesNone. 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_PORTon 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.