axe/internal/middleware/requestid.go

38 lines
1.5 KiB
Go
Raw Permalink Normal View History

2026-10-18 19:07:25 +00:00
package middleware
import (
"regexp"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
// requestIDKey — ключ, под которым id лежит в контексте gin.
const requestIDKey = "request_id"
// incomingID — допустимый входящий X-Request-Id: до 64 символов из
// [A-Za-z0-9._-]. Посторонние символы (переводы строк, кавычки) в логах
// выглядели бы как подделка записей, поэтому чужой заголовок отбрасываем.
var incomingID = regexp.MustCompile(`^[A-Za-z0-9._-]{1,64}$`)
// RequestID берёт id из заголовка X-Request-Id (если он осмысленный)
// или генерирует свой, кладёт в контекст и возвращает клиенту тем же
// заголовком. Дальше этот id подхватывают access-log и логи безопасности:
// один запрос проходится по логам одной строкой.
func RequestID() gin.HandlerFunc {
return func(c *gin.Context) {
id := c.GetHeader("X-Request-Id")
if !incomingID.MatchString(id) {
id = uuid.NewString()
}
c.Set(requestIDKey, id)
c.Header("X-Request-Id", id)
c.Next()
}
}
// RequestIDFrom возвращает id текущего запроса; "" вне middleware.
func RequestIDFrom(c *gin.Context) string {
return c.GetString(requestIDKey)
}