package middleware import ( "net" "net/http" "net/url" "strings" "github.com/gin-gonic/gin" ) func CORS() gin.HandlerFunc { return func(c *gin.Context) { origin := strings.TrimSpace(c.GetHeader("Origin")) if origin != "" { if isLoopbackOrigin(origin) { c.Header("Access-Control-Allow-Origin", origin) c.Header("Vary", "Origin") c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS") c.Header("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization") c.Header("Access-Control-Expose-Headers", "Content-Length, Content-Disposition") c.Header("Access-Control-Max-Age", "86400") } else if c.Request.Method == http.MethodOptions { c.AbortWithStatus(http.StatusForbidden) return } } if c.Request.Method == http.MethodOptions { c.AbortWithStatus(http.StatusNoContent) return } c.Next() } } func isLoopbackOrigin(origin string) bool { u, err := url.Parse(origin) if err != nil { return false } if u.Scheme != "http" && u.Scheme != "https" { return false } host := strings.TrimSpace(u.Hostname()) if host == "" { return false } if strings.EqualFold(host, "localhost") { return true } ip := net.ParseIP(host) return ip != nil && ip.IsLoopback() }