diff --git a/internal/app/middleware/swagger.go b/internal/app/middleware/swagger.go index db07e06..e26f55f 100644 --- a/internal/app/middleware/swagger.go +++ b/internal/app/middleware/swagger.go @@ -3,8 +3,10 @@ package middleware import ( "bufio" "bytes" + "mime" "net" "net/http" + "path/filepath" "strconv" "strings" @@ -12,8 +14,6 @@ import ( "github.com/gin-gonic/gin" ) -// SwaggerHandler serves Swagger UI with relaxed CSP headers and MengStack -// branding CSS injected into swagger-ui.css. func SwaggerHandler() gin.HandlerFunc { return func(c *gin.Context) { rawPath := c.Request.URL.Path @@ -37,21 +37,28 @@ func SwaggerHandler() gin.HandlerFunc { c.Writer = underlying - c.Header("X-Content-Type-Options", "nosniff") - c.Header("X-Frame-Options", "DENY") - c.Header("X-XSS-Protection", "1; mode=block") - c.Header("Referrer-Policy", "strict-origin-when-cross-origin") - c.Header("Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:") + h := underlying.Header() + h.Set("X-Content-Type-Options", "nosniff") + h.Set("X-Frame-Options", "DENY") + h.Set("X-XSS-Protection", "1; mode=block") + h.Set("Referrer-Policy", "strict-origin-when-cross-origin") + h.Set("Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:") if isCSS && crw.code == 200 && crw.buf.Len() > 0 { body := append(crw.buf.Bytes(), []byte(brandingCSS)...) - c.Header("Content-Length", strconv.Itoa(len(body))) - c.Header("Content-Type", "text/css; charset=utf-8") + h.Set("Content-Length", strconv.Itoa(len(body))) + h.Set("Content-Type", "text/css; charset=utf-8") + underlying.WriteHeader(crw.code) underlying.Write(body) return } if crw.buf.Len() > 0 { + ext := filepath.Ext(relPath) + if ct := mime.TypeByExtension(ext); ct != "" { + h.Set("Content-Type", ct) + } + h.Del("Content-Length") underlying.WriteHeader(crw.code) underlying.Write(crw.buf.Bytes()) return