package middleware import ( "crypto/rand" "encoding/hex" "net/http" "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" "runtime/debug" "time" ) func RequestID(c *gin.Context) { id := make([]byte, 8) rand.Read(id) reqID := hex.EncodeToString(id) c.Writer.Header().Set("X-Request-ID", reqID) c.Next() } type responseWriter struct { http.ResponseWriter status int } func (rw *responseWriter) WriteHeader(code int) { rw.status = code rw.ResponseWriter.WriteHeader(code) } func Logging(c *gin.Context) { start := time.Now() c.Next() log.Info().Msgf("%s %s %d %s", c.Request.Method, c.Request.URL.Path, c.Writer.Status(), time.Since(start)) } func Recovery(c *gin.Context) { defer func() { if err := recover(); err != nil { log.Error().Msgf("panic: %v\n%s", err, debug.Stack()) c.AbortWithStatus(http.StatusInternalServerError) } }() c.Next() } func SecurityHeaders(secure bool) gin.HandlerFunc { return func(c *gin.Context) { c.Header("X-Content-Type-Options", "nosniff") c.Header("X-Frame-Options", "DENY") c.Header("Referrer-Policy", "strict-origin-when-cross-origin") if secure { c.Header("Strict-Transport-Security", "max-age=63072000; includeSubDomains") } c.Next() } }