Ticket #9249: cache_ignore_cookie.patch

File cache_ignore_cookie.patch, 5.4 KB (added by Vladimir Dmitriev, 9 years ago)
  • django/conf/global_settings.py

     
    331331CACHE_BACKEND = 'locmem://'
    332332CACHE_MIDDLEWARE_KEY_PREFIX = ''
    333333CACHE_MIDDLEWARE_SECONDS = 600
     334CACHE_MIDDLEWARE_IGNORE_COOKIES = ()
    334335
    335336####################
    336337# COMMENTS         #
  • django/utils/cache.py

     
    142142    ctx = md5_constructor()
    143143    for header in headerlist:
    144144        value = request.META.get(header, None)
    145         if value is not None:
     145        if header == "HTTP_COOKIE" and len(request.COOKIES) > 0:
     146            cookies = request.COOKIES
     147            for key in cookies.keys():
     148                for re in settings.CACHE_MIDDLEWARE_IGNORE_COOKIES:
     149                    if re.search(key) and cookies.has_key(key):
     150                        del cookies[key]
     151            if len(cookies) > 0:
     152                # Builds a new header value without ignored cookies
     153                ctx.update(";".join(['%s=%s' % (k,v) for k,v in cookies.items() ]))
     154        elif value is not None:
    146155            ctx.update(value)
    147156    path = md5_constructor(iri_to_uri(request.path))
    148157    return 'views.decorators.cache.cache_page.%s.%s.%s' % (
  • docs/topics/cache.txt

     
    287287  sites using the same Django installation, set this to the name of the site,
    288288  or some other string that is unique to this Django instance, to prevent key
    289289  collisions. Use an empty string if you don't care.
     290* ``CACHE_MIDDLEWARE_IGNORE_COOKIES`` -- Tuple of compiled regular expression
     291  patterns of request cookies that should not be considered if "Cookie" is set
     292  in ``Vary`` header. See the `Using Vary headers`_ section for more on this
     293  setting.
    290294
    291295The cache middleware caches every page that doesn't have GET or POST
    292296parameters. Optionally, if the ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting is
     
    647651    def my_view(request):
    648652        # ...
    649653
     654If your application contains client-side Javascript code saving its
     655state in cookies you may meet a problem when varying on cookie makes
     656Django to cache a new copy of a page for each client cookie
     657variation. You can optionally specify those client-side cookie in an
     658optional ``CACHE_MIDDLEWARE_IGNORE_COOKIES`` setting, making Django to
     659ignore them when building a cache key thus improving hit performance
     660and memory consumption. For example, you may want to ignore Google
     661Analytics tracking cookies::
     662
     663    import re
     664    CACHE_MIDDLEWARE_IGNORE_COOKIES = (
     665        re.compile('^__utm'),
     666    )
     667
    650668The headers you pass to ``vary_on_headers`` are not case sensitive;
    651669``"User-Agent"`` is the same thing as ``"user-agent"``.
    652670
  • tests/regressiontests/cache/tests.py

     
    44# Uses whatever cache backend is set in the test settings file.
    55
    66import os
     7import re
    78import shutil
    89import tempfile
    910import time
     
    298299        self.path = '/cache/test/'
    299300        self.old_settings_key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
    300301        self.old_middleware_seconds = settings.CACHE_MIDDLEWARE_SECONDS
     302        self.old_ignore_cookies = settings.CACHE_MIDDLEWARE_IGNORE_COOKIES
    301303        settings.CACHE_MIDDLEWARE_KEY_PREFIX = 'settingsprefix'
    302304        settings.CACHE_MIDDLEWARE_SECONDS = 1
     305        settings.CACHE_MIDDLEWARE_IGNORE_COOKIES = ( re.compile(r'^testcookie$'), )
    303306
    304307    def tearDown(self):
    305308        settings.CACHE_MIDDLEWARE_KEY_PREFIX = self.old_settings_key_prefix
    306309        settings.CACHE_MIDDLEWARE_SECONDS = self.old_middleware_seconds
     310        settings.CACHE_MIDDLEWARE_IGNORE_COOKIES = self.old_ignore_cookies
    307311
    308312    def _get_request(self, path):
    309313        request = HttpRequest()
     
    355359        learn_cache_key(request, response)
    356360        self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
    357361
     362    def test_ignore_cookies(self):
     363        request = self._get_request(self.path)
     364        response = HttpResponse()
     365        response['Vary'] = 'Cookie'
     366        learn_cache_key(request, response)
     367        # Set request cookies not matched in CACHE_MIDDLEWARE_IGNORE_COOKIES
     368        request.COOKIES = { 'foo': 1, 'bar': 2 }
     369        self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.a8c87a3d8c44853d7f79474f7ffe4ad5.b4cb935fc7540cefaa961599c74eab3d')
     370        request.COOKIES = { 'foo': 1, 'bar': 2, 'testcookie': 'value' }
     371        # Ensure same key as without ignored cookie
     372        self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.a8c87a3d8c44853d7f79474f7ffe4ad5.b4cb935fc7540cefaa961599c74eab3d')
     373        request.COOKIES = { }
     374        self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
     375
    358376if __name__ == '__main__':
    359377    unittest.main()
Back to Top