package infra import ( "net/http" "sync" "time" ) // rateLimiterClient mantiene el estado de un bucket para una clave concreta. type rateLimiterClient struct { tokens float64 lastSeen time.Time } // RateLimiter mantiene el estado token-bucket de todos los clientes en memoria. // rate son los tokens recargados por segundo, burst es la capacidad maxima del bucket. // El campo clients es un mapa key -> bucket protegido por mu. type RateLimiter struct { rate float64 burst int mu sync.Mutex clients map[string]*rateLimiterClient } // RateLimitConfig parametriza el middleware de rate limiting. // KeyFunc extrae la clave del request (nil = IP del cliente). // CleanupInterval controla la frecuencia del GC de entries inactivas (0 = no GC). type RateLimitConfig struct { RequestsPerSecond float64 BurstSize int KeyFunc func(r *http.Request) string CleanupInterval time.Duration } // RateLimitResult es el resultado de evaluar un request contra el limiter. // Allowed indica si el request puede pasar. // Remaining son los tokens restantes en el bucket despues del check. // ResetAt es el momento en que el bucket vuelve a estar lleno. // RetryAfter son los segundos hasta que se pueda reintentar (0 si Allowed). type RateLimitResult struct { Allowed bool Remaining int ResetAt time.Time RetryAfter float64 }