cambios
This commit is contained in:
parent
3991237685
commit
a01050bf85
46 changed files with 3636 additions and 652 deletions
|
|
@ -1,12 +1,17 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/rss2/backend/internal/auth"
|
||||
"github.com/rss2/backend/internal/config"
|
||||
"github.com/rss2/backend/internal/logger"
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
func AuthRequired() gin.HandlerFunc {
|
||||
|
|
@ -63,23 +68,19 @@ func CORSMiddleware() gin.HandlerFunc {
|
|||
|
||||
return func(c *gin.Context) {
|
||||
origin := c.Request.Header.Get("Origin")
|
||||
|
||||
|
||||
allowed := false
|
||||
for _, o := range allowedOrigins {
|
||||
o = strings.TrimSpace(o)
|
||||
if o == "*" || o == origin {
|
||||
if o == origin {
|
||||
allowed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if allowed {
|
||||
if cfg.AllowedOrigins == "*" {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
} else {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
|
||||
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
}
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
|
||||
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
}
|
||||
|
||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
|
||||
|
|
@ -96,17 +97,101 @@ func CORSMiddleware() gin.HandlerFunc {
|
|||
|
||||
func LoggerMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
start := time.Now()
|
||||
path := c.Request.URL.Path
|
||||
raw := c.Request.URL.RawQuery
|
||||
requestID := c.GetHeader("X-Request-ID")
|
||||
if requestID == "" {
|
||||
requestID = c.GetString("request_id")
|
||||
}
|
||||
|
||||
c.Next()
|
||||
|
||||
latency := time.Since(start)
|
||||
status := c.Writer.Status()
|
||||
if status >= 400 {
|
||||
// Log error responses
|
||||
clientIP := c.ClientIP()
|
||||
method := c.Request.Method
|
||||
|
||||
if raw != "" {
|
||||
path = path + "?" + raw
|
||||
}
|
||||
|
||||
log := logger.GetLogger().With().
|
||||
Str("method", method).
|
||||
Str("path", path).
|
||||
Int("status", status).
|
||||
Str("client_ip", clientIP).
|
||||
Dur("latency", latency).
|
||||
Logger()
|
||||
|
||||
if requestID != "" {
|
||||
log = log.With().Str("request_id", requestID).Logger()
|
||||
}
|
||||
|
||||
if status >= 500 {
|
||||
log.Error().Msg("Server error")
|
||||
} else if status >= 400 {
|
||||
log.Warn().Msg("Client error")
|
||||
} else {
|
||||
log.Info().Msg("Request completed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type clientLimiter struct {
|
||||
limiter *rate.Limiter
|
||||
lastSeen time.Time
|
||||
}
|
||||
|
||||
var (
|
||||
clientLimiters = make(map[string]*clientLimiter)
|
||||
limitersMu sync.Mutex
|
||||
)
|
||||
|
||||
func RateLimitMiddleware(requestsPerMinute int) gin.HandlerFunc {
|
||||
limit := rate.Limit(requestsPerMinute) / 60
|
||||
burst := requestsPerMinute
|
||||
|
||||
return func(c *gin.Context) {
|
||||
ip := c.ClientIP()
|
||||
|
||||
limitersMu.Lock()
|
||||
cl, exists := clientLimiters[ip]
|
||||
if !exists {
|
||||
cl = &clientLimiter{limiter: rate.NewLimiter(limit, burst)}
|
||||
clientLimiters[ip] = cl
|
||||
}
|
||||
cl.lastSeen = time.Now()
|
||||
limiter := cl.limiter
|
||||
limitersMu.Unlock()
|
||||
|
||||
if !limiter.Allow() {
|
||||
c.JSON(http.StatusTooManyRequests, gin.H{"error": "Rate limit exceeded"})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
time.Sleep(10 * time.Minute)
|
||||
limitersMu.Lock()
|
||||
if cl, ok := clientLimiters[ip]; ok && time.Since(cl.lastSeen) > 10*time.Minute {
|
||||
delete(clientLimiters, ip)
|
||||
}
|
||||
limitersMu.Unlock()
|
||||
}()
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func RequestIDMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
requestID := c.GetHeader("X-Request-ID")
|
||||
if requestID == "" {
|
||||
requestID = fmt.Sprintf("%d", time.Now().UnixNano())
|
||||
}
|
||||
c.Set("request_id", requestID)
|
||||
c.Header("X-Request-ID", requestID)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue