diff --git a/django/middleware/common.py b/django/middleware/common.py index 5aeb746f81..3db925c894 100644 --- a/django/middleware/common.py +++ b/django/middleware/common.py @@ -120,7 +120,9 @@ class CommonMiddleware(object): if response.has_header('ETag'): return get_conditional_response( request, - etag=response['ETag'], + # get_conditional_response() requires an unquoted version + # of the response's ETag. + etag=response['ETag'].strip('"'), response=response, ) diff --git a/docs/releases/1.9.1.txt b/docs/releases/1.9.1.txt index 98569a14df..e0b3b17ff9 100644 --- a/docs/releases/1.9.1.txt +++ b/docs/releases/1.9.1.txt @@ -19,3 +19,6 @@ Bugfixes * Fixed a state bug when migrating a ``SeparateDatabaseAndState`` operation backwards (:ticket:`25896`). + +* Fixed a regression in ``CommonMiddleware`` causing ``If-None-Match`` checks + to always return HTTP 200 (:ticket:`25900`). diff --git a/tests/middleware/tests.py b/tests/middleware/tests.py index 7ccfd919cc..3e18ee7645 100644 --- a/tests/middleware/tests.py +++ b/tests/middleware/tests.py @@ -291,6 +291,16 @@ class CommonMiddlewareTest(SimpleTestCase): res = StreamingHttpResponse(['content']) self.assertFalse(CommonMiddleware().process_response(req, res).has_header('ETag')) + @override_settings(USE_ETAGS=True) + def test_if_none_match(self): + first_req = HttpRequest() + first_res = CommonMiddleware().process_response(first_req, HttpResponse('content')) + second_req = HttpRequest() + second_req.method = 'GET' + second_req.META['HTTP_IF_NONE_MATCH'] = first_res['ETag'] + second_res = CommonMiddleware().process_response(second_req, HttpResponse('content')) + self.assertEqual(second_res.status_code, 304) + # Other tests @override_settings(DISALLOWED_USER_AGENTS=[re.compile(r'foo')])