Files
SEEN/backend/internal/middleware/cors.go
T
2026-04-10 12:06:24 +02:00

85 lines
2.0 KiB
Go

package middleware
import (
"net/http"
"strconv"
"slices"
"strings"
"github.com/gin-gonic/gin"
"github.com/tdvorak/seen/backend/internal/config"
)
func CORS(cfg config.CORSConfig) gin.HandlerFunc {
allowedOrigins := normalizeHeaderValues(cfg.AllowedOrigins)
allowedMethods := normalizeHeaderValues(cfg.AllowedMethods)
allowedHeaders := normalizeHeaderValues(cfg.AllowedHeaders)
exposedHeaders := normalizeHeaderValues(cfg.ExposedHeaders)
allowAnyOrigin := slices.Contains(allowedOrigins, "*")
allowedMethodsValue := strings.Join(allowedMethods, ", ")
allowedHeadersValue := strings.Join(allowedHeaders, ", ")
exposedHeadersValue := strings.Join(exposedHeaders, ", ")
return func(c *gin.Context) {
origin := strings.TrimSpace(c.GetHeader("Origin"))
if origin == "" {
c.Next()
return
}
if !allowAnyOrigin && !slices.Contains(allowedOrigins, origin) {
if c.Request.Method == http.MethodOptions {
c.AbortWithStatus(http.StatusForbidden)
return
}
c.Next()
return
}
if allowAnyOrigin && !cfg.AllowCredentials {
c.Header("Access-Control-Allow-Origin", "*")
} else {
c.Header("Access-Control-Allow-Origin", origin)
c.Header("Vary", "Origin")
}
c.Header("Access-Control-Allow-Methods", allowedMethodsValue)
c.Header("Access-Control-Allow-Headers", allowedHeadersValue)
if exposedHeadersValue != "" {
c.Header("Access-Control-Expose-Headers", exposedHeadersValue)
}
if cfg.AllowCredentials {
c.Header("Access-Control-Allow-Credentials", "true")
}
if cfg.MaxAge > 0 {
c.Header("Access-Control-Max-Age", formatSeconds(cfg.MaxAge.Seconds()))
}
if c.Request.Method == http.MethodOptions {
c.AbortWithStatus(http.StatusNoContent)
return
}
c.Next()
}
}
func normalizeHeaderValues(values []string) []string {
items := make([]string, 0, len(values))
for _, value := range values {
trimmed := strings.TrimSpace(value)
if trimmed == "" {
continue
}
items = append(items, trimmed)
}
return items
}
func formatSeconds(value float64) string {
return strconv.Itoa(int(value))
}