Exercices Concepts Web & Django Rate limiter comme middleware Django
🎉

Bravo!

Avancé 🧠 Fondamentaux 30 XP 0 personnes ont réussi

Rate limiter comme middleware Django

Le rate limiting (limitation de debit), c'est le videur de ton API : il limite le nombre de requêtes qu'un client peut faire dans un intervalle de temps. Ca protege contre les abus et les attaques par deni de service.

Dans une vraie application Django, on utiliserait django-ratelimit ou DRF throttling. Mais le principe reste le meme : pour chaque adresse IP, on garde en mémoire les timestamps des dernières requêtes.

L'adresse IP du client est accessible dans Django via request.META.get('REMOTE_ADDR').

Écris un middleware RateLimitMiddleware (new style) qui :
- Dans __init__, recoit get_response, max_requests (défaut 10) et window_seconds (défaut 60)
- Stocke self.requests = {} (IP vers liste de timestamps)
- Dans __call__ :
1. Recupere l'IP avec request.META.get('REMOTE_ADDR', 'unknown')
2. Nettoie les timestamps plus vieux que la fenetre
3. Si le quota est depasse, retourne directement un JsonResponse avec {'error': 'Rate limit exceeded'} et status 429 (sans appeler get_response)
4. Sinon, enregistre le timestamp et continue normalement

Exemple :

import time
mw = RateLimitMiddleware(lambda r: HttpResponse('ok'), max_requests=2, window_seconds=60)
req = HttpRequest()
req.META['REMOTE_ADDR'] = '1.2.3.4'
mw(req) # OK
mw(req) # OK
resp = mw(req) # 429 Rate limit exceeded

Tests (3/4)

Première requête OK
import time
mw = RateLimitMiddleware(lambda r: HttpResponse('ok'), max_requests=3, window_seconds=60)
req = HttpRequest()
req.META['REMOTE_ADDR'] = '1.2.3.4'
resp = mw(req)
assert resp.status_code == 200
Quota depasse
import time
mw = RateLimitMiddleware(lambda r: HttpResponse('ok'), max_requests=2, window_seconds=60)
req = HttpRequest()
req.META['REMOTE_ADDR'] = '1.2.3.4'
mw(req)
mw(req)
resp = mw(req)
assert resp.status_code == 429
IPs independantes
import time
mw = RateLimitMiddleware(lambda r: HttpResponse('ok'), max_requests=1, window_seconds=60)
req1 = HttpRequest()
req1.META['REMOTE_ADDR'] = '1.1.1.1'
mw(req1)
req2 = HttpRequest()
req2.META['REMOTE_ADDR'] = '2.2.2.2'
resp = mw(req2)
assert resp.status_code == 200

+ 0 tests cachés

Indices (3 disponibles)

solution.py