Skip to main content

Module ui_bridge

Module ui_bridge 

Source
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-dir directory, 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 Origin header 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> and http://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 plain ws:// because it is bound to 127.0.0.1 and 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§

RemoteRedwireTarget
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.
RemoteRedwireTargetSpec
Host / port / TLS triple parsed from a red:// / reds:// URI — the connection-independent part of RemoteRedwireTarget (no CA bytes), so it can derive PartialEq for 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::shutdown aborts the serve task on drop of the join handle’s runtime; prefer shutdown().await for an orderly teardown.
UiBridgeConfig
Configuration for spawn_ui_bridge.

Enums§

UiTarget
How red ui should connect the browser to a target URI.

Functions§

classify_ui_target
Classify a red ui target URI into the bridge backend it requires.
loopback_ws_origin_allowed
Exact-match, default-deny Origin gate for the loopback /redwire upgrade (ADR 0036, adapted for loopback). An absent Origin is rejected (a browser always sends one); a present origin must appear verbatim in allowed. 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 is 127.0.0.1-bound, so plain ws:// 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 to ws_url directly. A window.REDDB_WS_URL config 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 returned UiBridge carries the resolved address and a clean-shutdown handle.
spawn_ui_bridge_remote
Like spawn_ui_bridge but 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 to target, and the byte stream is pumped through transparently.