package infra import ( "net/http" ) // RateLimiterByKey retorna un Middleware que aplica rate limiting usando keyFunc para extraer la clave del request. // Permite limitar por API key, user ID, o cualquier dimension custom. // Cuando keyFunc devuelve "" no se aplica limit (request pasa sin tocar el bucket). // Cuando se supera el limite responde 429 con headers X-RateLimit-* y Retry-After. func RateLimiterByKey(rl *RateLimiter, keyFunc func(r *http.Request) string) Middleware { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { key := keyFunc(r) if key == "" { // Sin clave no se aplica limit. next.ServeHTTP(w, r) return } result := RateLimiterCheck(rl, key) headers := RateLimitHeaders(result, rl.burst) for k, v := range headers { w.Header()[k] = v } if !result.Allowed { HTTPErrorResponse(w, HTTPError{ Status: http.StatusTooManyRequests, Code: "rate_limited", Message: "too many requests", }) return } next.ServeHTTP(w, r) }) } }