Fixed #27344 -- Made ConditionalGetMiddleware only process GET requests.

This commit is contained in:
Kevin Christopher Henry 2016-10-13 00:31:48 -04:00 committed by Tim Graham
parent a4e9e834e3
commit 2327fad54e
2 changed files with 31 additions and 0 deletions

View File

@ -18,6 +18,12 @@ class ConditionalGetMiddleware(MiddlewareMixin):
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))
# It's too late to prevent an unsafe request with a 412 response, and
# for a HEAD request, the response body is always empty so computing
# an accurate ETag isn't possible.
if request.method != 'GET':
return response
if self.needs_etag(response) and not response.has_header('ETag'): if self.needs_etag(response) and not response.has_header('ETag'):
set_response_etag(response) set_response_etag(response)

View File

@ -629,6 +629,31 @@ class ConditionalGetMiddlewareTest(SimpleTestCase):
self.assertEqual(new_response.cookies, self.resp.cookies) self.assertEqual(new_response.cookies, self.resp.cookies)
self.assertNotIn('Content-Language', new_response) self.assertNotIn('Content-Language', new_response)
def test_no_unsafe(self):
"""
ConditionalGetMiddleware shouldn't return a conditional response on an
unsafe request. A response has already been generated by the time
ConditionalGetMiddleware is called, so it's too late to return a 412
Precondition Failed.
"""
get_response = ConditionalGetMiddleware().process_response(self.req, self.resp)
etag = get_response['ETag']
put_request = RequestFactory().put('/', HTTP_IF_MATCH=etag)
put_response = HttpResponse(status=200)
conditional_get_response = ConditionalGetMiddleware().process_response(put_request, put_response)
self.assertEqual(conditional_get_response.status_code, 200) # should never be a 412
def test_no_head(self):
"""
ConditionalGetMiddleware shouldn't compute and return an ETag on a
HEAD request since it can't do so accurately without access to the
response body of the corresponding GET.
"""
request = RequestFactory().head('/')
response = HttpResponse(status=200)
conditional_get_response = ConditionalGetMiddleware().process_response(request, response)
self.assertNotIn('ETag', conditional_get_response)
class XFrameOptionsMiddlewareTest(SimpleTestCase): class XFrameOptionsMiddlewareTest(SimpleTestCase):
""" """