61 lines
1.9 KiB
Go
61 lines
1.9 KiB
Go
|
|
package mw
|
||
|
|
|
||
|
|
import "net/http"
|
||
|
|
|
||
|
|
const (
|
||
|
|
allowedMethods = "GET, HEAD, PUT, PATCH, POST, DELETE, OPTIONS"
|
||
|
|
allowedHeaders = "Content-Type, Authorization, X-Request-ID"
|
||
|
|
)
|
||
|
|
|
||
|
|
// CORS sets cross-origin resource sharing headers for the provided origins.
|
||
|
|
// Returns 204 No Content for OPTIONS preflight requests.
|
||
|
|
// Pass the outermost origins first; an empty slice is a no-op.
|
||
|
|
func CORS(origins []string) func(http.Handler) http.Handler {
|
||
|
|
originSet := make(map[string]struct{}, len(origins))
|
||
|
|
for _, o := range origins {
|
||
|
|
originSet[o] = struct{}{}
|
||
|
|
}
|
||
|
|
|
||
|
|
return func(next http.Handler) http.Handler {
|
||
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
origin := r.Header.Get("Origin")
|
||
|
|
if origin != "" {
|
||
|
|
if _, allowed := originSet[origin]; allowed {
|
||
|
|
w.Header().Set("Access-Control-Allow-Origin", origin)
|
||
|
|
w.Header().Set("Access-Control-Allow-Methods", allowedMethods)
|
||
|
|
w.Header().Set("Access-Control-Allow-Headers", allowedHeaders)
|
||
|
|
w.Header().Set("Access-Control-Allow-Credentials", "true")
|
||
|
|
w.Header().Set("Vary", "Origin")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if r.Method == http.MethodOptions {
|
||
|
|
w.WriteHeader(http.StatusNoContent)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
next.ServeHTTP(w, r)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// CORSAllowAll is a convenience wrapper that allows any origin.
|
||
|
|
// Use only in development — never in production.
|
||
|
|
func CORSAllowAll() func(http.Handler) http.Handler {
|
||
|
|
return func(next http.Handler) http.Handler {
|
||
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
origin := r.Header.Get("Origin")
|
||
|
|
if origin == "" {
|
||
|
|
origin = "*"
|
||
|
|
}
|
||
|
|
w.Header().Set("Access-Control-Allow-Origin", origin)
|
||
|
|
w.Header().Set("Access-Control-Allow-Methods", allowedMethods)
|
||
|
|
w.Header().Set("Access-Control-Allow-Headers", allowedHeaders)
|
||
|
|
w.Header().Set("Vary", "Origin")
|
||
|
|
if r.Method == http.MethodOptions {
|
||
|
|
w.WriteHeader(http.StatusNoContent)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
next.ServeHTTP(w, r)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|