Fixed #22440 -- Updated ConditionalGetMiddleware to comply with RFC 2616.

This commit is contained in:
Mark Lavin 2014-04-14 19:44:05 -04:00 committed by Tim Graham
parent 612290400f
commit 79956d0694
2 changed files with 35 additions and 2 deletions

View File

@ -14,7 +14,10 @@ class ConditionalGetMiddleware(object):
if not response.streaming and not response.has_header('Content-Length'): if not response.streaming and not response.has_header('Content-Length'):
response['Content-Length'] = str(len(response.content)) 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_none_match = request.META.get('HTTP_IF_NONE_MATCH')
if if_none_match == response['ETag']: if if_none_match == response['ETag']:
# Setting the status is enough here. The response handling path # Setting the status is enough here. The response handling path
@ -22,7 +25,9 @@ class ConditionalGetMiddleware(object):
# http.conditional_content_removal()). # http.conditional_content_removal()).
response.status_code = 304 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_modified_since = request.META.get('HTTP_IF_MODIFIED_SINCE')
if if_modified_since is not None: if if_modified_since is not None:
if_modified_since = parse_http_date_safe(if_modified_since) if_modified_since = parse_http_date_safe(if_modified_since)

View File

@ -366,6 +366,19 @@ class ConditionalGetMiddlewareTest(TestCase):
self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp) self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
self.assertEqual(self.resp.status_code, 200) 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) @override_settings(USE_ETAGS=True)
def test_etag(self): def test_etag(self):
req = HttpRequest() req = HttpRequest()
@ -419,6 +432,21 @@ class ConditionalGetMiddlewareTest(TestCase):
self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp) self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
self.assertEqual(self.resp.status_code, 200) 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): class XFrameOptionsMiddlewareTest(TestCase):
""" """