http.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536
  1. from django.utils.http import http_date, parse_http_date_safe
  2. class ConditionalGetMiddleware(object):
  3. """
  4. Handles conditional GET operations. If the response has an ETag or
  5. Last-Modified header, and the request has If-None-Match or
  6. If-Modified-Since, the response is replaced by an HttpNotModified.
  7. Also sets the Date and Content-Length response-headers.
  8. """
  9. def process_response(self, request, response):
  10. response['Date'] = http_date()
  11. if not response.streaming and not response.has_header('Content-Length'):
  12. response['Content-Length'] = str(len(response.content))
  13. if response.has_header('ETag'):
  14. if_none_match = request.META.get('HTTP_IF_NONE_MATCH')
  15. if if_none_match == response['ETag']:
  16. # Setting the status is enough here. The response handling path
  17. # automatically removes content for this status code (in
  18. # http.conditional_content_removal()).
  19. response.status_code = 304
  20. if response.has_header('Last-Modified'):
  21. if_modified_since = request.META.get('HTTP_IF_MODIFIED_SINCE')
  22. if if_modified_since is not None:
  23. if_modified_since = parse_http_date_safe(if_modified_since)
  24. if if_modified_since is not None:
  25. last_modified = parse_http_date_safe(response['Last-Modified'])
  26. if last_modified is not None and last_modified <= if_modified_since:
  27. # Setting the status code is enough here (same reasons as
  28. # above).
  29. response.status_code = 304
  30. return response