Fixed #28104 -- Prevented condition decorator from setting ETag/Last-Modified headers for non-safe requests.
This commit is contained in:
parent
268a646353
commit
37c9b81ebc
|
@ -70,9 +70,9 @@ def condition(etag_func=None, last_modified_func=None):
|
|||
|
||||
This decorator will either pass control to the wrapped view function or
|
||||
return an HTTP 304 response (unmodified) or 412 response (precondition
|
||||
failed), depending upon the request method. In either case, it will add the
|
||||
generated ETag and Last-Modified headers to the response if it doesn't
|
||||
already have them.
|
||||
failed), depending upon the request method. In either case, the decorator
|
||||
will add the generated ETag and Last-Modified headers to the response if
|
||||
the headers aren't already set and if the request's method is safe.
|
||||
"""
|
||||
def decorator(func):
|
||||
@wraps(func)
|
||||
|
@ -98,11 +98,13 @@ def condition(etag_func=None, last_modified_func=None):
|
|||
if response is None:
|
||||
response = func(request, *args, **kwargs)
|
||||
|
||||
# Set relevant headers on the response if they don't already exist.
|
||||
if res_last_modified and not response.has_header('Last-Modified'):
|
||||
response['Last-Modified'] = http_date(res_last_modified)
|
||||
if res_etag and not response.has_header('ETag'):
|
||||
response['ETag'] = res_etag
|
||||
# Set relevant headers on the response if they don't already exist
|
||||
# and if the request method is safe.
|
||||
if request.method in ('GET', 'HEAD'):
|
||||
if res_last_modified and not response.has_header('Last-Modified'):
|
||||
response['Last-Modified'] = http_date(res_last_modified)
|
||||
if res_etag and not response.has_header('ETag'):
|
||||
response['ETag'] = res_etag
|
||||
|
||||
return response
|
||||
|
||||
|
|
|
@ -66,6 +66,10 @@ last time the resource was modified, or ``None`` if the resource doesn't
|
|||
exist. The function passed to the ``etag`` decorator should return a string
|
||||
representing the `ETag`_ for the resource, or ``None`` if it doesn't exist.
|
||||
|
||||
The decorator sets the ``ETag`` and ``Last-Modified`` headers on the response
|
||||
if they are not already set by the view and if the request's method is safe
|
||||
(``GET`` or ``HEAD``).
|
||||
|
||||
.. versionchanged:: 1.11
|
||||
|
||||
In older versions, the return value from ``etag_func()`` was interpreted as
|
||||
|
@ -198,6 +202,14 @@ to compute the ETag and last modification values in all situations. In fact,
|
|||
you **should** use the same functions, so that the same values are returned
|
||||
every time.
|
||||
|
||||
.. admonition:: Validator headers with non-safe request methods
|
||||
|
||||
The ``condition`` decorator only sets validator headers (``ETag`` and
|
||||
``Last-Modified``) for safe HTTP methods, i.e. ``GET`` and ``HEAD``. If you
|
||||
wish to return them in other cases, set them in your view. See
|
||||
:rfc:`7231#section-4.3.4` to learn about the distinction between setting a
|
||||
validator header in response to requests made with ``PUT`` versus ``POST``.
|
||||
|
||||
Comparison with middleware conditional processing
|
||||
=================================================
|
||||
|
||||
|
|
|
@ -19,10 +19,14 @@ class ConditionalGet(SimpleTestCase):
|
|||
def assertFullResponse(self, response, check_last_modified=True, check_etag=True):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.content, FULL_RESPONSE.encode())
|
||||
if check_last_modified:
|
||||
self.assertEqual(response['Last-Modified'], LAST_MODIFIED_STR)
|
||||
if check_etag:
|
||||
self.assertEqual(response['ETag'], ETAG)
|
||||
if response.request['REQUEST_METHOD'] in ('GET', 'HEAD'):
|
||||
if check_last_modified:
|
||||
self.assertEqual(response['Last-Modified'], LAST_MODIFIED_STR)
|
||||
if check_etag:
|
||||
self.assertEqual(response['ETag'], ETAG)
|
||||
else:
|
||||
self.assertNotIn('Last-Modified', response)
|
||||
self.assertNotIn('ETag', response)
|
||||
|
||||
def assertNotModified(self, response):
|
||||
self.assertEqual(response.status_code, 304)
|
||||
|
|
Loading…
Reference in New Issue