mirror of
https://github.com/wweir/sower.git
synced 2026-10-20 16:53:33 +00:00
A site route always rewrote the outbound Host to the upstream host, so an upstream that validates the authority it is visited under could not sit behind one: pi-web compares Origin's host against the Host header, answers 403 to every browser-originated /api request, and the page loads while its WebSocket never connects. Add `authority = "upstream" | "client"` to a site route, defaulting to "upstream" so existing routes keep the current behavior byte for byte. "client" forwards the authority the client asked for, which is what such an upstream needs; its own allowlist must still name the public domain (pi-web's PI_WEB_ALLOWED_HOSTS), because the forwarded name is client-controlled. The key is one word on purpose: aconfig v0.19.0 title-cases the keys of an array-of-tables element, so `preserve_host` is rejected at load time — probed before the spelling was chosen. - config: SiteRoute.Authority, the AuthorityUpstream/AuthorityClient values, and SiteRoute.PreserveHost(). Validate rejects an unknown value instead of silently defaulting, since the two values differ in what the upstream sees. - cmd/sowerd: newSiteRouter feeds that flag into the siteEntry field the fake-site fallback already used. - docs: ARCHITECTURE.md and security.md record the rule, why the adaptation belongs to the edge rather than to an upstream trusting X-Forwarded-Host, and what preserving a client-controlled authority does not protect. - tests: TOML round-trip, unknown-value rejection, router plumbing, and an end-to-end handleConn case asserting the upstream sees the client's name.