feat: enhance rate limiting by allowing requests to proceed when Redis is unavailable, with logging for monitoring

This commit is contained in:
Anish Sarkar 2026-02-09 03:15:27 +05:30
parent bcdfd23ea1
commit 2add106296

View file

@ -84,17 +84,27 @@ def _check_rate_limit(
"""
Check per-IP rate limit using Redis. Raises 429 if exceeded.
Uses atomic INCR + EXPIRE to avoid race conditions.
Fails open (allows request) if Redis is unavailable.
"""
client_ip = get_remote_address(request)
key = f"surfsense:auth_rate_limit:{scope}:{client_ip}"
r = _get_rate_limit_redis()
try:
r = _get_rate_limit_redis()
# Atomic: increment first, then set TTL if this is a new key
pipe = r.pipeline()
pipe.incr(key)
pipe.expire(key, window_seconds)
result = pipe.execute()
# Atomic: increment first, then set TTL if this is a new key
pipe = r.pipeline()
pipe.incr(key)
pipe.expire(key, window_seconds)
result = pipe.execute()
except (redis.exceptions.RedisError, OSError) as exc:
# Redis unavailable — fail open to preserve auth availability.
# SlowAPI middleware provides a secondary rate-limiting layer.
rate_limit_logger.warning(
f"Redis unavailable for rate limiting ({scope}), "
f"allowing request from {client_ip}: {exc}"
)
return
current_count = result[0] # INCR returns the new value