Skip to content

Commit

Permalink
Fixed #22440 -- Updated ConditionalGetMiddleware to comply with RFC 2…
Browse files Browse the repository at this point in the history
…616.
  • Loading branch information
Mark Lavin authored and timgraham committed Jun 14, 2014
1 parent 6122904 commit 79956d0
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
9 changes: 7 additions & 2 deletions django/middleware/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,20 @@ 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
# automatically removes content for this status code (in
# 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)
Expand Down
28 changes: 28 additions & 0 deletions tests/middleware/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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):
"""
Expand Down

0 comments on commit 79956d0

Please sign in to comment.