Expand description
Local red ui bridge: serves the UI bundle and fronts the embedded
engine over RedWire-over-WebSocket for file:// targets (issue #1042,
ADR 0047/0049). Public so the red ui CLI command can drive it.
Local red ui bridge — the tracer-bullet spine of the red-ui
integration (issue #1042, PRD #1041; ADR 0047 bridge, ADR 0049
RedWire-over-WS transport, ADR 0036 WS edge).
red ui --server file://<path> opens a graphical UI in the browser
against a local .rdb. This module is the process that makes that
work: a single loopback (127.0.0.1) HTTP server that
- serves the UI bundle (a
--ui-dirdirectory, or the checked-in minimal fixture page when none is given), and - mounts
/redwire— a RedWire-over-WebSocket endpoint over the embedded engine opened from the file. The WS data channel is bridged into the same async-transport ↔ sync-engine seam the internet WS edge uses ([super::ws_edge::run_ws_session], ADR 0036). This serves RedWire over the embedded engine — it is not a proxy of the HTTP surface.
Security (ADR 0036, adapted for loopback):
- Origin allowlist, default-deny. WebSocket is not covered by
CORS, so the upgrade validates the
Originheader against an explicit, exact-match allowlist ([loopback_ws_origin_allowed]). The list is seeded with the bridge’s own served origins (http://127.0.0.1:<port>andhttp://localhost:<port>), so the served page can connect and a cross-site page cannot. - WSS-only is relaxed. The internet edge requires TLS
([
super::ws_edge::ws_upgrade_decision]); the loopback bridge accepts plainws://because it is bound to127.0.0.1and never leaves the host. This is the one rule that differs from the internet edge, and it is deliberate.
The bridge is session-scoped: [UiBridge::shutdown] tears the server
down cleanly (graceful shutdown of the listener + the serve task), so
closing the UI / interrupting the command leaves no orphaned process.
Structs§
- Remote
Redwire Target - A remote RedWire endpoint the bridge fronts for a
red:///reds://target (issue #1044, ADR 0047 bridge, ADR 0049 transport). The local loopback WS endpoint pumps its data channel straight into a fresh TCP (or TLS) connection to this host — the UI is unaware that the engine lives in another process / container. - Remote
Redwire Target Spec - Host / port / TLS triple parsed from a
red:///reds://URI — the connection-independent part ofRemoteRedwireTarget(no CA bytes), so it can derivePartialEqfor classification tests. - UiBridge
- A running loopback UI bridge. Holds the bound address plus the handles
needed to shut the serve task down cleanly. Dropping it without
calling
Self::shutdownaborts the serve task on drop of the join handle’s runtime; prefershutdown().awaitfor an orderly teardown. - UiBridge
Config - Configuration for
spawn_ui_bridge.
Enums§
- UiTarget
- How
red uishould connect the browser to a target URI.
Functions§
- classify_
ui_ target - Classify a
red uitarget URI into the bridge backend it requires. - loopback_
ws_ origin_ allowed - Exact-match, default-deny Origin gate for the loopback
/redwireupgrade (ADR 0036, adapted for loopback). An absentOriginis rejected (a browser always sends one); a present origin must appear verbatim inallowed. Kept pure so the policy is unit-tested without a live socket. The WSS-only rule of the internet edge does not apply here — the bridge is127.0.0.1-bound, so plainws://is accepted. - spawn_
direct_ ui_ server - Serve the UI bundle for a direct
red+wss:///red+ws://target (ADR 0047). No loopback WS relay is started — the browser connects tows_urldirectly. Awindow.REDDB_WS_URLconfig is injected into HTML responses so the UI page knows the target without user input. - spawn_
ui_ bridge - Bind a loopback HTTP server that serves the UI bundle and mounts the
RedWire-over-WS endpoint over
server’s embedded engine, then spawn its serve loop. Returns once the listener is bound; the returnedUiBridgecarries the resolved address and a clean-shutdown handle. - spawn_
ui_ bridge_ remote - Like
spawn_ui_bridgebut fronting a remote RedWire endpoint (red:///reds://, issue #1044) rather than the embedded engine. The served UI still talks only to the loopback WS endpoint; each WS session opens a fresh TCP/TLS connection totarget, and the byte stream is pumped through transparently.