Skip to content

feat(dev-server): support headers custom HTTP response headers (#143) - #183

Merged
lukekania merged 1 commit into
milestone/v0.11.0-builder-parityfrom
feat/dev-server-custom-headers
Jun 8, 2026
Merged

feat(dev-server): support headers custom HTTP response headers (#143)#183
lukekania merged 1 commit into
milestone/v0.11.0-builder-parityfrom
feat/dev-server-custom-headers

Conversation

@lukekania

Copy link
Copy Markdown
Owner

Closes #143.

Goal

Support angular.json's dev-server headers option so projects can configure custom HTTP response headers in dev — production-like security headers (CSP, Cross-Origin-Opener-Policy), CORS headers, cache-control overrides, etc. Previously the option was silently dropped.

Changes

  • packages/builder/schemas/dev-server.json — declare headers as an object of header name to string value.
  • packages/builder/src/serve/options.ts — serialize the map into a --headers '{...}' JSON arg, trimming header names and dropping empty-name / non-string entries.
  • crates/cli/src/main.rs — add a --headers flag plus parse_header_overrides(), which rejects malformed JSON, non-objects, and non-string values with a clear error rather than dropping them silently.
  • crates/cli/src/serve_cmd.rs — thread the parsed pairs into DevServerConfig.
  • crates/dev-server/ — new CustomHeaders type:
    • validates each header once at startup; invalid entries are dropped with a warn instead of failing every request;
    • applied to every served response — static assets, the SPA-fallback index.html, and the SSE live-reload stream;
    • never overrides headers the server sets itself: Content-Type and Cache-Control on files, plus Connection / Access-Control-Allow-Origin on SSE.

Headers are applied only in the Rust dev server, so proxy-forwarded responses keep their upstream headers untouched — no change needed in the Node proxy, which is transparent.

Definition of done

  • "headers": { "Cross-Origin-Opener-Policy": "same-origin" } results in the dev server emitting that header on every HTML/JS/asset response — covered by integration tests.
  • Headers do not leak into proxy-forwarded responses (they never run in the proxy path).

Note on Cache-Control

The issue lists "cache-control overrides" as a motivating use case, but its Scope section says not to override headers the server sets itself. Live reload depends on Cache-Control: no-cache, so a user Cache-Control entry is skipped (documented in code and the schema). Happy to revisit if overriding it is desired.

Tests

  • dev-server: 8 new integration cases (static / index / SPA / SSE emission, Content-Type and Cache-Control not clobbered, multi-header, no-headers) + 6 new CustomHeaders unit tests.
  • CLI: 5 new parse_header_overrides cases.
  • builder: 4 new translateOptions vitest cases.
  • cargo clippy, tsc --noEmit clean; version bumped 0.10.14 → 0.10.15.

The dev-server `headers` option in angular.json was silently dropped, so
apps relying on production-like security headers in dev (CSP, COOP) or
testing CORS scenarios had no way to configure them.

- `dev-server.json`: add `headers` (object of name to string value).
- `serve/options.ts`: serialize the map into a `--headers` JSON arg,
  trimming names and dropping empty-name / non-string entries.
- `serve_cmd.rs` / `main.rs`: parse the `--headers` JSON object and
  thread the name/value pairs into `DevServerConfig`.
- `dev-server`: new `CustomHeaders` type applies the configured headers
  to every served response — static assets, the SPA-fallback
  index.html, and the SSE live-reload stream. Headers the server sets
  itself (`Content-Type`, `Cache-Control`, and the SSE-specific
  `Connection` / `Access-Control-Allow-Origin`) are never overridden.

Headers are applied only in the Rust dev server, so proxy-forwarded
responses keep their upstream headers untouched.

Bump version to 0.10.15.
@lukekania
lukekania merged commit 93c8749 into milestone/v0.11.0-builder-parity Jun 8, 2026
6 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.

1 participant