Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #22440 -- Updated ConditionalGetMiddleware to comply with RFC 2…

…616.
  • Loading branch information...
commit 79956d06946c881cb71958f27a12f62b9cab8de5 1 parent 6122904
@mlavin mlavin authored timgraham committed
Showing with 35 additions and 2 deletions.
  1. +7 −2 django/middleware/http.py
  2. +28 −0 tests/middleware/tests.py
View
9 django/middleware/http.py
@@ -14,7 +14,10 @@ def process_response(self, request, response):
if not response.streaming and not response.has_header('Content-Length'):
response['Content-Length'] = str(len(response.content))
- if response.has_header('ETag'):
+ # If-None-Match must be ignored if original result would be anything
+ # other than a 2XX or 304 status. 304 status would result in no change.
+ # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26
+ if 200 <= response.status_code < 300 and response.has_header('ETag'):
if_none_match = request.META.get('HTTP_IF_NONE_MATCH')
if if_none_match == response['ETag']:
# Setting the status is enough here. The response handling path
@@ -22,7 +25,9 @@ def process_response(self, request, response):
# http.conditional_content_removal()).
response.status_code = 304
- if response.has_header('Last-Modified'):
+ # If-Modified-Since must be ignored if the original result was not a 200.
+ # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25
+ if response.status_code == 200 and response.has_header('Last-Modified'):
if_modified_since = request.META.get('HTTP_IF_MODIFIED_SINCE')
if if_modified_since is not None:
if_modified_since = parse_http_date_safe(if_modified_since)
View
28 tests/middleware/tests.py
@@ -366,6 +366,19 @@ def test_if_none_match_and_different_etag(self):
self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
self.assertEqual(self.resp.status_code, 200)
+ def test_if_none_match_and_redirect(self):
+ self.req.META['HTTP_IF_NONE_MATCH'] = self.resp['ETag'] = 'spam'
+ self.resp['Location'] = '/'
+ self.resp.status_code = 301
+ self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
+ self.assertEqual(self.resp.status_code, 301)
+
+ def test_if_none_match_and_client_error(self):
+ self.req.META['HTTP_IF_NONE_MATCH'] = self.resp['ETag'] = 'spam'
+ self.resp.status_code = 400
+ self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
+ self.assertEqual(self.resp.status_code, 400)
+
@override_settings(USE_ETAGS=True)
def test_etag(self):
req = HttpRequest()
@@ -419,6 +432,21 @@ def test_if_modified_since_and_last_modified_in_the_future(self):
self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
self.assertEqual(self.resp.status_code, 200)
+ def test_if_modified_since_and_redirect(self):
+ self.req.META['HTTP_IF_MODIFIED_SINCE'] = 'Sat, 12 Feb 2011 17:38:44 GMT'
+ self.resp['Last-Modified'] = 'Sat, 12 Feb 2011 17:35:44 GMT'
+ self.resp['Location'] = '/'
+ self.resp.status_code = 301
+ self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
+ self.assertEqual(self.resp.status_code, 301)
+
+ def test_if_modified_since_and_client_error(self):
+ self.req.META['HTTP_IF_MODIFIED_SINCE'] = 'Sat, 12 Feb 2011 17:38:44 GMT'
+ self.resp['Last-Modified'] = 'Sat, 12 Feb 2011 17:35:44 GMT'
+ self.resp.status_code = 400
+ self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
+ self.assertEqual(self.resp.status_code, 400)
+
class XFrameOptionsMiddlewareTest(TestCase):
"""

0 comments on commit 79956d0

Please sign in to comment.
Something went wrong with that request. Please try again.