diff --git a/django/views/decorators/http.py b/django/views/decorators/http.py index a0d02bc8bb..b51cf9a782 100644 --- a/django/views/decorators/http.py +++ b/django/views/decorators/http.py @@ -75,7 +75,15 @@ def condition(etag_func=None, last_modified_func=None): if if_none_match or if_match: # There can be more than one ETag in the request, so we # consider the list of values. - etags = parse_etags(if_none_match or if_match) + try: + etags = parse_etags(if_none_match or if_match) + except ValueError: + # In case of invalid etag ignore all ETag headers. + # Apparently Opera sends invalidly quoted headers at times + # (we should be returning a 400 response, but that's a + # little extreme) -- this is Django bug #10681. + if_none_match = None + if_match = None # Compute values (if any) for the requested resource. if etag_func: diff --git a/tests/regressiontests/conditional_processing/models.py b/tests/regressiontests/conditional_processing/models.py index 756244ab3b..b291aed337 100644 --- a/tests/regressiontests/conditional_processing/models.py +++ b/tests/regressiontests/conditional_processing/models.py @@ -112,6 +112,11 @@ class ConditionalGet(TestCase): response = self.client.get('/condition/last_modified2/') self.assertFullResponse(response, check_etag=False) + def testInvalidETag(self): + self.client.defaults['HTTP_IF_NONE_MATCH'] = r'"\"' + response = self.client.get('/condition/etag/') + self.assertFullResponse(response, check_last_modified=False) + class ETagProcesing(TestCase): def testParsing(self):