Skip to content

Add webview gateway for onion-backed browsing #665

Description

@rings-auto-reviewer

Background

The browser WorkBench can now build HTTPS onion proxy routes against the Docker cluster, but it is still a request-level tool. To make onion proxy usable as a browser-like surface, we need a controlled webview/gateway layer that keeps page, subresource, and dynamic requests inside Rings instead of letting the browser fetch them directly.

This should follow the Scramjet/Ultraviolet style architecture at the abstraction level, but must not vendor or copy their AGPL implementation.

Goal

Add a workspace submodule named webview as a reusable Rings webview gateway. The module should own URL encoding, request/response policy, rewriting, cookie/header handling, and a pluggable transport boundary. The Yew frontend and MV3 extension should consume this module instead of embedding proxy logic directly in UI code.

Proposed module shape

  • Add crates/webview with package name rings-webview.
  • Keep the default core portable across native and wasm where possible.
  • Use feature gates for browser-only integration points such as Service Worker helpers or JS bootstrap assets.
  • Expose a transport trait such as WebviewTransport / GatewayTransport that accepts normalized gateway requests and returns normalized responses.
  • Provide an adapter path for the existing browser onion proxy request API first; native/local gateway adapters can come later.

Architecture

  1. Controlled origin

    • Serve proxied pages under a Rings-owned route, for example /webview/<encoded-url>.
    • Never render remote pages from their original origin directly.
  2. Gateway interception

    • In the extension/browser path, a Service Worker or equivalent gateway handler owns the proxied route prefix.
    • It decodes the target URL, builds a gateway request, sends it through the transport, rewrites the response, and returns it to the browser.
  3. URL rewriting

    • Rewrite HTML URL-bearing attributes such as href, src, action, srcset, and relevant metadata.
    • Rewrite CSS url(...) and @import references.
    • Rewrite redirect Location headers back into gateway URLs.
  4. Runtime hooks

    • Inject a small bootstrap runtime before page scripts.
    • Route fetch, XMLHttpRequest, WebSocket, EventSource, sendBeacon, Worker, and dynamic import-style URLs through the gateway where feasible.
    • Treat full JavaScript rewriting as an incremental phase, not a first-step blocker.
  5. Cookies and headers

    • Maintain a virtual cookie jar keyed by target origin/domain/path.
    • Convert upstream Set-Cookie into jar entries and attach matching Cookie headers on proxied requests.
    • Strip or rewrite browser-hostile headers such as Content-Security-Policy, X-Frame-Options, Strict-Transport-Security, and hop-by-hop headers.
    • Preserve useful headers such as content type, cache metadata, and redirects after policy normalization.
  6. Frontend integration

    • Add a Yew webview surface with a URL entry point and render area.
    • Do not use iframe as the primary architecture.
    • Keep UI state in Yew, but keep proxy/rewrite logic outside the DOM layer.
  7. Extension integration

    • Keep long-lived Rings node state in the existing extension/offscreen boundary.
    • Route webview gateway requests through the existing onion proxy transport path first.
    • Avoid direct network fetches from proxied page code.

Non-goals

  • Do not implement Chrome global proxy settings in this issue.
  • Do not build an iframe-based renderer.
  • Do not mutate already-rendered DOM as the main rewrite strategy.
  • Do not copy Scramjet or Ultraviolet code or add AGPL dependencies.

Acceptance criteria

  • crates/webview exists and is part of the root workspace as the webview submodule.
  • The module exposes typed request, response, URL, cookie, header-policy, rewrite, and transport boundaries without any-style untyped escape hatches in TS-facing code.
  • Unit tests cover URL encode/decode, same-page relative URL rewriting, CSS URL rewriting, redirect rewriting, and cookie matching.
  • A browser/wasm test or fixture proves that HTML subresources and at least fetch/XHR-style dynamic requests are rewritten through the gateway prefix.
  • The frontend can call into the webview module without embedding rewrite logic in Yew components.
  • The extension path can send a gateway request through the existing onion proxy request API.
  • No direct remote network request is intentionally emitted by proxied page resources.
  • Licensing stays clean: no vendored Scramjet/Ultraviolet implementation and no AGPL dependency is introduced.

Suggested implementation phases

  1. Core crate skeleton: target URL model, gateway request/response types, transport trait, header policy, cookie jar, and deterministic URL rewriting tests.
  2. HTML/CSS rewriting: cover static page and subresource fixtures.
  3. Browser bootstrap: hook fetch and XHR first, then expand to WebSocket/EventSource/Worker/import cases.
  4. Yew surface: add a minimal webview page that accepts a URL and renders gateway HTML.
  5. Extension/onion adapter: connect gateway requests to the existing onion proxy request path and validate with the Docker cluster.
  6. Hardening: add fixtures for redirects, cookies, CSP-heavy pages, relative base URLs, and error responses.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions