nginx-proxy-manager-zh/backend/internal/api/middleware/cors.go

89 lines
2.0 KiB
Go

package middleware
import (
"fmt"
"net/http"
"strings"
"github.com/go-chi/chi"
)
var methodMap = []string{
http.MethodGet,
http.MethodHead,
http.MethodPost,
http.MethodPut,
http.MethodPatch,
http.MethodDelete,
http.MethodConnect,
http.MethodTrace,
}
func getRouteMethods(routes chi.Router, path string) []string {
var methods []string
tctx := chi.NewRouteContext()
for _, method := range methodMap {
if routes.Match(tctx, method, path) {
methods = append(methods, method)
}
}
return methods
}
var headersAllowedByCORS = []string{
"Authorization",
"Host",
"Content-Type",
"Connection",
"User-Agent",
"Cache-Control",
"Accept-Encoding",
"X-Jumbo-AppKey",
"X-Jumbo-SKey",
"X-Jumbo-SV",
"X-Jumbo-Timestamp",
"X-Jumbo-Version",
"X-Jumbo-Customer-Id",
}
// Cors handles cors headers
func Cors(routes chi.Router) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
methods := getRouteMethods(routes, r.URL.Path)
if len(methods) == 0 {
// no route no cors
next.ServeHTTP(w, r)
return
}
methods = append(methods, http.MethodOptions)
w.Header().Set("Access-Control-Allow-Methods", strings.Join(methods, ","))
w.Header().Set("Access-Control-Allow-Headers",
strings.Join(headersAllowedByCORS, ","),
)
next.ServeHTTP(w, r)
})
}
}
// Options handles options requests
func Options(routes chi.Router) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
methods := getRouteMethods(routes, r.URL.Path)
if len(methods) == 0 {
// no route shouldn't have options
next.ServeHTTP(w, r)
return
}
if r.Method == http.MethodOptions {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, "{}")
return
}
next.ServeHTTP(w, r)
})
}
}