mirror of
https://github.com/vee1e/subidx.git
synced 2026-09-01 17:57:13 +00:00
Expose API headers across CORS boundary
Cross-origin dashboards could not read x-ratelimit-*, x-total-count, x-max-seq or x-truncated, which silently disabled the budget meter and live-feed cursor backfill on split deployments.
This commit is contained in:
parent
b56447f067
commit
a5d2e56f06
3 changed files with 10 additions and 0 deletions
|
|
@ -4,6 +4,11 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// exposedHeaders lists the API headers the browser may read on
|
||||||
|
// cross-origin responses; by default only Cache-Control, Content-Type
|
||||||
|
// and friends cross the boundary.
|
||||||
|
const exposedHeaders = "x-ratelimit-limit, x-ratelimit-remaining, retry-after, x-total-count, x-max-seq, x-truncated"
|
||||||
|
|
||||||
// corsMiddleware answers with CORS headers when the request Origin is in
|
// corsMiddleware answers with CORS headers when the request Origin is in
|
||||||
// the allow list, so a separately hosted dashboard (e.g. on Vercel) can
|
// the allow list, so a separately hosted dashboard (e.g. on Vercel) can
|
||||||
// call the API. The Origin is echoed back rather than wildcarded, and
|
// call the API. The Origin is echoed back rather than wildcarded, and
|
||||||
|
|
@ -21,6 +26,7 @@ func corsMiddleware(allowed []string, next http.Handler) http.Handler {
|
||||||
if origin == o {
|
if origin == o {
|
||||||
h := w.Header()
|
h := w.Header()
|
||||||
h.Set("Access-Control-Allow-Origin", origin)
|
h.Set("Access-Control-Allow-Origin", origin)
|
||||||
|
h.Set("Access-Control-Expose-Headers", exposedHeaders)
|
||||||
h.Add("Vary", "Origin")
|
h.Add("Vary", "Origin")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,9 @@ func TestCORS(t *testing.T) {
|
||||||
if v := rec.Header().Get("Vary"); !strings.Contains(v, "Origin") {
|
if v := rec.Header().Get("Vary"); !strings.Contains(v, "Origin") {
|
||||||
t.Errorf("Vary = %q", v)
|
t.Errorf("Vary = %q", v)
|
||||||
}
|
}
|
||||||
|
if ex := rec.Header().Get("Access-Control-Expose-Headers"); !strings.Contains(ex, "x-ratelimit-limit") || !strings.Contains(ex, "x-max-seq") {
|
||||||
|
t.Errorf("expose-headers = %q", ex)
|
||||||
|
}
|
||||||
|
|
||||||
bad := httptest.NewRequest("GET", "/v1/stats", nil)
|
bad := httptest.NewRequest("GET", "/v1/stats", nil)
|
||||||
bad.Host = "localhost"
|
bad.Host = "localhost"
|
||||||
|
|
|
||||||
1
internal/web/.gitignore
vendored
Normal file
1
internal/web/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
.vercel
|
||||||
Loading…
Add table
Add a link
Reference in a new issue