Skip to content

feat(server): configurable CORS origins for external hosts#30

Merged
DonPrus merged 3 commits intomainfrom
feat/external-hosts
Apr 18, 2026
Merged

feat(server): configurable CORS origins for external hosts#30
DonPrus merged 3 commits intomainfrom
feat/external-hosts

Conversation

@DonPrus
Copy link
Copy Markdown
Contributor

@DonPrus DonPrus commented Apr 18, 2026

Summary

  • Add --allowed-origin ORIGIN (repeatable) to nullhub serve and NULLHUB_ALLOWED_ORIGINS (comma-separated) so a hub reached via a Tailscale name or other external host is no longer rejected with "forbidden origin".
  • Thread an extra_allowed_origins list through the existing CORS guard (requestOriginAllowed / isAllowedCorsOrigin / CORS headers); built-in bind-host and local-alias handling are unchanged.
  • Validate each origin (scheme + host, no trailing slash), match the Origin header case-insensitively, and surface diagnostics for malformed CLI/env values.

Closes #26

Test plan

  • zig build test --summary all green (new cases: extras accepted for non-local and 0.0.0.0 binds, empty/invalid entries ignored, CSV copies survive freeing the source buffer, requestOriginAllowed honors configured extras).
  • Manual: bind to 0.0.0.0, add Tailscale MagicDNS origin via --allowed-origin https://hub.tailnet.ts.net, confirm Hub Web UI works through Tailscale.
  • Manual: export NULLHUB_ALLOWED_ORIGINS="https://hub.tailnet.ts.net, bad" and confirm the single invalid entry is logged and the valid one is accepted.

DonPrus added 3 commits April 17, 2026 21:12
Expose extra allowed origins to the API guard via a repeatable
`--allowed-origin` flag on `serve` and a `NULLHUB_ALLOWED_ORIGINS`
environment variable so a hub reached through a Tailscale name or
other external host is no longer rejected with "forbidden origin".

Built-in bind-host and local alias handling are unchanged; extras
are validated (scheme + host, no trailing slash) and matched
case-insensitively against the request's `Origin` header.

Closes #26
Review follow-ups for the configurable CORS origins change:

- `cli.appendOriginIfValid` now dupes each accepted origin and
  `appendOriginsFromCsv` returns the count of rejected entries, so
  `main.resolveAllowedOrigins` can free the env-var buffer and
  surface invalid `NULLHUB_ALLOWED_ORIGINS` values on stderr.
- `parseServe` warns on malformed `--allowed-origin` flags and on
  the (OOM) drop path instead of failing silently.
- Outer allowed-origin slice is freed on shutdown via
  `freeResolvedOrigins`, eliminating the leak flagged in review.
- Added a regression test covering the `0.0.0.0` bind + extra
  origin path to document current behavior.
@DonPrus DonPrus merged commit 41c5c0e into main Apr 18, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Support custom origins for external hosts

1 participant