mirror of https://github.com/django/django.git
Fixed #26024 -- Fixed regression in ConditionalGetMiddleware ETag support.
Thanks Denis Cornehl for help with the patch.
This commit is contained in:
parent
d5b90c8e12
commit
186b6c61bf
|
@ -8,6 +8,7 @@ from django.core.mail import mail_managers
|
||||||
from django.urls import is_valid_path
|
from django.urls import is_valid_path
|
||||||
from django.utils.cache import get_conditional_response, set_response_etag
|
from django.utils.cache import get_conditional_response, set_response_etag
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
|
from django.utils.http import unquote_etag
|
||||||
from django.utils.six.moves.urllib.parse import urlparse
|
from django.utils.six.moves.urllib.parse import urlparse
|
||||||
|
|
||||||
logger = logging.getLogger('django.request')
|
logger = logging.getLogger('django.request')
|
||||||
|
@ -120,9 +121,7 @@ class CommonMiddleware(object):
|
||||||
if response.has_header('ETag'):
|
if response.has_header('ETag'):
|
||||||
return get_conditional_response(
|
return get_conditional_response(
|
||||||
request,
|
request,
|
||||||
# get_conditional_response() requires an unquoted version
|
etag=unquote_etag(response['ETag']),
|
||||||
# of the response's ETag.
|
|
||||||
etag=response['ETag'].strip('"'),
|
|
||||||
response=response,
|
response=response,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from django.utils.cache import get_conditional_response
|
from django.utils.cache import get_conditional_response
|
||||||
from django.utils.http import http_date, parse_http_date_safe
|
from django.utils.http import http_date, parse_http_date_safe, unquote_etag
|
||||||
|
|
||||||
|
|
||||||
class ConditionalGetMiddleware(object):
|
class ConditionalGetMiddleware(object):
|
||||||
|
@ -23,7 +23,7 @@ class ConditionalGetMiddleware(object):
|
||||||
if etag or last_modified:
|
if etag or last_modified:
|
||||||
return get_conditional_response(
|
return get_conditional_response(
|
||||||
request,
|
request,
|
||||||
etag=etag,
|
etag=unquote_etag(etag),
|
||||||
last_modified=last_modified,
|
last_modified=last_modified,
|
||||||
response=response,
|
response=response,
|
||||||
)
|
)
|
||||||
|
|
|
@ -253,6 +253,13 @@ def quote_etag(etag):
|
||||||
return '"%s"' % etag.replace('\\', '\\\\').replace('"', '\\"')
|
return '"%s"' % etag.replace('\\', '\\\\').replace('"', '\\"')
|
||||||
|
|
||||||
|
|
||||||
|
def unquote_etag(etag):
|
||||||
|
"""
|
||||||
|
Unquote an ETag string; i.e. revert quote_etag().
|
||||||
|
"""
|
||||||
|
return etag.strip('"').replace('\\"', '"').replace('\\\\', '\\') if etag else etag
|
||||||
|
|
||||||
|
|
||||||
def is_same_domain(host, pattern):
|
def is_same_domain(host, pattern):
|
||||||
"""
|
"""
|
||||||
Return ``True`` if the host is either an exact match or a match
|
Return ``True`` if the host is either an exact match or a match
|
||||||
|
|
|
@ -9,4 +9,5 @@ Django 1.9.2 fixes several bugs in 1.9.1.
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* ...
|
* Fixed a regression in ``ConditionalGetMiddleware`` causing ``If-None-Match`` checks
|
||||||
|
to always return HTTP 200 (:ticket:`26024`).
|
||||||
|
|
|
@ -470,6 +470,11 @@ class ConditionalGetMiddlewareTest(SimpleTestCase):
|
||||||
self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
|
self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
|
||||||
self.assertEqual(self.resp.status_code, 304)
|
self.assertEqual(self.resp.status_code, 304)
|
||||||
|
|
||||||
|
def test_if_none_match_and_same_etag_with_quotes(self):
|
||||||
|
self.req.META['HTTP_IF_NONE_MATCH'] = self.resp['ETag'] = '"spam"'
|
||||||
|
self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
|
||||||
|
self.assertEqual(self.resp.status_code, 304)
|
||||||
|
|
||||||
def test_if_none_match_and_different_etag(self):
|
def test_if_none_match_and_different_etag(self):
|
||||||
self.req.META['HTTP_IF_NONE_MATCH'] = 'spam'
|
self.req.META['HTTP_IF_NONE_MATCH'] = 'spam'
|
||||||
self.resp['ETag'] = 'eggs'
|
self.resp['ETag'] = 'eggs'
|
||||||
|
|
|
@ -158,8 +158,10 @@ class ETagProcessingTests(unittest.TestCase):
|
||||||
self.assertEqual(etags, ['', 'etag', 'e"t"ag', r'e\tag', 'weak'])
|
self.assertEqual(etags, ['', 'etag', 'e"t"ag', r'e\tag', 'weak'])
|
||||||
|
|
||||||
def test_quoting(self):
|
def test_quoting(self):
|
||||||
quoted_etag = http.quote_etag(r'e\t"ag')
|
original_etag = r'e\t"ag'
|
||||||
|
quoted_etag = http.quote_etag(original_etag)
|
||||||
self.assertEqual(quoted_etag, r'"e\\t\"ag"')
|
self.assertEqual(quoted_etag, r'"e\\t\"ag"')
|
||||||
|
self.assertEqual(http.unquote_etag(quoted_etag), original_etag)
|
||||||
|
|
||||||
|
|
||||||
class HttpDateProcessingTests(unittest.TestCase):
|
class HttpDateProcessingTests(unittest.TestCase):
|
||||||
|
|
Loading…
Reference in New Issue