Преглед изворни кода

Fixed #30701 -- Updated patch_vary_headers() to handle an asterisk according to RFC 7231.

Adnan Umer пре 5 година
родитељ
комит
6805c0f99f
4 измењених фајлова са 23 додато и 5 уклоњено
  1. 8 3
      django/utils/cache.py
  2. 8 2
      docs/ref/utils.txt
  3. 5 0
      docs/releases/3.0.txt
  4. 2 0
      tests/cache/tests.py

+ 8 - 3
django/utils/cache.py

@@ -256,8 +256,9 @@ def add_never_cache_headers(response):
 def patch_vary_headers(response, newheaders):
     """
     Add (or update) the "Vary" header in the given HttpResponse object.
-    newheaders is a list of header names that should be in "Vary". Existing
-    headers in "Vary" aren't removed.
+    newheaders is a list of header names that should be in "Vary". If headers
+    contains an asterisk, then "Vary" header will consist of a single asterisk
+    '*'. Otherwise, existing headers in "Vary" aren't removed.
     """
     # Note that we need to keep the original order intact, because cache
     # implementations may rely on the order of the Vary contents in, say,
@@ -270,7 +271,11 @@ def patch_vary_headers(response, newheaders):
     existing_headers = {header.lower() for header in vary_headers}
     additional_headers = [newheader for newheader in newheaders
                           if newheader.lower() not in existing_headers]
-    response['Vary'] = ', '.join(vary_headers + additional_headers)
+    vary_headers += additional_headers
+    if '*' in vary_headers:
+        response['Vary'] = '*'
+    else:
+        response['Vary'] = ', '.join(vary_headers)
 
 
 def has_vary_header(response, header_query):

+ 8 - 2
docs/ref/utils.txt

@@ -73,8 +73,14 @@ need to distinguish caches by the ``Accept-language`` header.
 .. function:: patch_vary_headers(response, newheaders)
 
     Adds (or updates) the ``Vary`` header in the given ``HttpResponse`` object.
-    ``newheaders`` is a list of header names that should be in ``Vary``.
-    Existing headers in ``Vary`` aren't removed.
+    ``newheaders`` is a list of header names that should be in ``Vary``. If
+    headers contains an asterisk, then ``Vary`` header will consist of a single
+    asterisk ``'*'``. Otherwise, existing headers in ``Vary`` aren't removed.
+
+    .. versionchanged:: 3.0
+
+        Handling an asterisk ``'*'`` according to :rfc:`7231#section-7.1.4` was
+        added.
 
 .. function:: get_cache_key(request, key_prefix=None)
 

+ 5 - 0
docs/releases/3.0.txt

@@ -514,6 +514,11 @@ Miscellaneous
   :class:`~django.db.models.OneToOneField` ``'_id'`` attribute now unsets the
   corresponding field. Accessing the field afterwards will result in a query.
 
+* :func:`~django.utils.cache.patch_vary_headers` now handles an asterisk
+  ``'*'`` according to :rfc:`7231#section-7.1.4`, i.e. if a list of header
+  field names contains an asterisk, then the ``Vary`` header will consist of a
+  single asterisk ``'*'``.
+
 .. _deprecated-features-3.0:
 
 Features deprecated in 3.0

+ 2 - 0
tests/cache/tests.py

@@ -1625,6 +1625,8 @@ class CacheUtils(SimpleTestCase):
             (None, ('Accept-Encoding', 'COOKIE'), 'Accept-Encoding, COOKIE'),
             ('Cookie,     Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'),
             ('Cookie    ,     Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'),
+            ('*', ('Accept-Language', 'Cookie'), '*'),
+            ('Accept-Language, Cookie', ('*',), '*'),
         )
         for initial_vary, newheaders, resulting_vary in headers:
             with self.subTest(initial_vary=initial_vary, newheaders=newheaders):