Support comma-separated CORS_HEADER for multiple origins.

Parse CORS_HEADER as a list: * for all origins, or reflect matching
request Origin when multiple specific origins are configured. Add Vary:
Origin for the allowlist case. Update .env.example and CORS tests.
This commit is contained in:
2026-05-06 20:38:28 +00:00
parent 43d78862e3
commit 5dcd671043
4 changed files with 58 additions and 72 deletions

View File

@@ -48,6 +48,7 @@ func newFixture(t *testing.T) *fixture {
Expiry: config.ExpiryConfig{GraceDays: 30},
ReservedUsernames: []string{"admin", "root"},
RateLimitPerMin: 0, // disabled in tests
CORSOrigins: []string{"*"},
}
tmpls, _ := messages.Load("/nonexistent.yaml")
users := user.NewService(user.NewRepo(d), cfg.ReservedUsernames)
@@ -553,6 +554,29 @@ func TestDocsPage(t *testing.T) {
}
}
func TestCORSHeader(t *testing.T) {
f := newFixture(t)
resp, _ := f.get(t, "/healthz")
if got := resp.Header.Get("Access-Control-Allow-Origin"); got != "*" {
t.Errorf("expected Access-Control-Allow-Origin=*, got %q", got)
}
req, _ := http.NewRequest("OPTIONS", f.srv.URL+"/v1/pricing", nil)
req.Header.Set("Origin", "https://random-frontend.example")
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusNoContent {
t.Errorf("expected 204 on OPTIONS preflight, got %d", resp.StatusCode)
}
if got := resp.Header.Get("Access-Control-Allow-Origin"); got != "*" {
t.Errorf("expected Access-Control-Allow-Origin=*, got %q", got)
}
}
func TestBodyLimit(t *testing.T) {
f := newFixture(t)
huge := bytes.Repeat([]byte("a"), 2<<20) // 2 MiB