python / expert
Snippet
Django Conditional Response Headers mit Middleware Caching
Conditional GET Requests mit ETag/Last-Modified Headern reduzieren Bandbreite und verbessern Antwortzeiten erheblich, indem sie Servern ermöglichen anzugeben, dass der Client bereits eine gültige gecachte Version hat. Diese Middleware implementiert den serverseitigen Teil von HTTP Conditional Requests, generiert ETags aus Response-Content und gibt 304 Not Modified Responses zurück, wenn angemessen. Für hochfrequentierte Django-Anwendungen kann dieses Muster die Serverlast um 60-80% reduzieren.
snippet.py
1
import hashlib\nfrom django.utils.cache import learn_cache_key\nfrom django.utils.deprecation import MiddlewareMixin\n\nclass ConditionalCacheMiddleware(MiddlewareMixin):\n def __init__(self, get_response):\n self.get_response = get_response\n self._cache_timeout = 60 * 15\n\n def __call__(self, request):\n response = self.get_response(request)\n\n if not self._should_cache(request, response):\n return response\n\n request_etag = request.META.get('HTTP_IF_NONE_MATCH')\n response_etag = response.get('ETag')\n\n if request_etag and response_etag == request_etag:\n return self._not_modified_response(request)\n\n if hasattr(request, '_cache_key'):\n cache_key = request._cache_key\n else:\n cache_key = learn_cache_key(request, response, self._cache_timeout)\n\n response['X-Cache-Key'] = cache_key\n response['X-Cache-Hit'] = 'true' if request_etag else 'false'\n\n return response\n\n def _should_cache(self, request, response):\n return (\n request.method == 'GET' and\n response.status_code == 200 and\n not response.streaming\n )\n\n def _not_modified_response(self, request):\n response = HttpResponse(status=304)\n response['Content-Location'] = request.path\n return response
django
Erklärung
1
HTTP_IF_NONE_MATCH Header-Check
Vergleicht client-gesendeten ETag mit aktuellem Response-ETag um zu bestimmen, ob Client aktuelle Version ohne Body-Transfer hat
2
return HttpResponse(status=304)
304 Response ohne Body signalisiert Client, gecachte Version zu nutzen, reduziert Bandbreite auf nahezu Null für wiederholte Requests
3
learn_cache_key() von Django utils
Djangos eingebauter Cache-Key-Generator, der Vary-Headers, Query-Strings und Content für eindeutige Identifikation berücksichtigt
4
X-Cache-Key / X-Cache-Hit Headers
Custom Debug-Headers ermöglichen Clients und Monitoring-Systemen Cache-Verhalten zu verstehen und Misses zu diagnostizieren