diff --git a/internal/api/rate_limit_config.go b/internal/api/rate_limit_config.go index b54c47c1b..49da673e3 100644 --- a/internal/api/rate_limit_config.go +++ b/internal/api/rate_limit_config.go @@ -127,6 +127,19 @@ func UniversalRateLimitMiddleware(next http.Handler) http.Handler { return } + // Skip rate limiting for real-time data endpoints that are polled frequently + // These endpoints are essential for UI functionality and should not be rate limited + skipPaths := []string{ + "/api/state", // Real-time state updates + "/api/guests/metadata", // Guest metadata (polled frequently) + } + for _, path := range skipPaths { + if strings.Contains(r.URL.Path, path) { + next.ServeHTTP(w, r) + return + } + } + // Extract client IP ip := GetClientIP(r) diff --git a/internal/api/router.go b/internal/api/router.go index 2bd37a11a..467fa34d6 100644 --- a/internal/api/router.go +++ b/internal/api/router.go @@ -906,40 +906,8 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - // Apply rate limiting for API endpoints - if strings.HasPrefix(req.URL.Path, "/api/") { - // Skip rate limiting ONLY for real-time data endpoints - skipRateLimit := false - for _, path := range []string{ - "/api/state", // WebSocket updates - "/api/guests/metadata", // Guest metadata (polled frequently) - "/api/health", // Health checks - "/ws", // WebSocket - } { - if strings.Contains(req.URL.Path, path) { - skipRateLimit = true - break - } - } - - // Apply stricter rate limiting for auth endpoints (but not status checks) - if (strings.Contains(req.URL.Path, "/api/security/") && req.URL.Path != "/api/security/status") || req.URL.Path == "/api/login" { - clientIP := GetClientIP(req) - // Use auth limiter for security endpoints (10 per minute) - if !authLimiter.Allow(clientIP) { - http.Error(w, "Too many requests. Please wait before trying again.", http.StatusTooManyRequests) - LogAuditEvent("rate_limit", "", clientIP, req.URL.Path, false, "Auth rate limit exceeded") - return - } - } else if !skipRateLimit { - // Use general API limiter for other endpoints (500 per minute) - clientIP := GetClientIP(req) - if !apiLimiter.Allow(clientIP) { - http.Error(w, "Rate limit exceeded", http.StatusTooManyRequests) - return - } - } - } + // Rate limiting is now handled by UniversalRateLimitMiddleware + // No need for duplicate rate limiting logic here // Log request start := time.Now()