package middleware import ( "net/http" "github.com/noderunners/nip05api/internal/config" ) // CORS sets Access-Control-Allow-Origin based on the CORS_HEADER env var. // // Supports "*" (allow all), a single origin, or a comma-separated list. // When multiple origins are configured the middleware reflects the request // Origin back if it matches one of the allowed values (the HTTP spec forbids // sending more than one origin in the header). func CORS(cfg *config.Config) func(http.Handler) http.Handler { allowAll := len(cfg.CORSOrigins) == 1 && cfg.CORSOrigins[0] == "*" allowed := make(map[string]bool, len(cfg.CORSOrigins)) for _, o := range cfg.CORSOrigins { allowed[o] = true } return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var origin string if allowAll { origin = "*" } else { reqOrigin := r.Header.Get("Origin") if allowed[reqOrigin] { origin = reqOrigin } } if origin != "" { h := w.Header() h.Set("Access-Control-Allow-Origin", origin) h.Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") h.Set("Access-Control-Allow-Headers", "Content-Type, X-API-Key, Authorization") h.Set("Access-Control-Max-Age", "86400") if !allowAll { h.Set("Vary", "Origin") } } if r.Method == http.MethodOptions { w.WriteHeader(http.StatusNoContent) return } next.ServeHTTP(w, r) }) } }