package errors_handler import ( "fmt" "github.com/gin-gonic/gin" "net/http" "net/url" "strings" ) // Handler renders the same application shell with the actual HTTP error code. // It owns its entry data rather than using process-global mutable template state. type Handler struct{ entry []byte } func New(entry []byte) *Handler { return &Handler{entry: entry} } func (h *Handler) GetErrorsPage(c *gin.Context, status int) { c.Header("Cache-Control", "no-store") c.Data(status, "text/html; charset=utf-8", h.entry) } func (h *Handler) RegisterGetErrorRoutes(r *gin.Engine, statuses []int) { for _, code := range statuses { serve := func(c *gin.Context) { h.GetErrorsPage(c, code) } path := fmt.Sprintf("/errors/%d", code) r.GET(path, serve) r.HEAD(path, serve) } } func (h *Handler) APIAccessMiddleware() gin.HandlerFunc { return func(c *gin.Context) { if strings.HasPrefix(c.Request.URL.Path, "/api/") { referer := c.GetHeader("Referer") if referer != "" { parsed, err := url.Parse(referer) if err != nil || parsed.Host != c.Request.Host { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"code": 403, "msg": "Cross-origin API request denied", "data": nil}) return } } } c.Next() } }