def test_generate_cache_header_key(self): """ A test backported from Django stable/1.7.x to show that our patch to take the HOST header into account when generating cache middleware keys works. """ host = 'www.example.com' path = '/cache/test/' factory = RequestFactory(HTTP_HOST=host) request = factory.get(path) response = HttpResponse() key_prefix = 'localprefix' # Expect None if no headers have been set yet. self.assertEqual(get_cache_key(request), None) # Set headers to an empty list. learn_cache_key(request, response) self.assertEqual( get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.' '18a03f9c9649f7d684af5db3524f5c99.d41d8cd98f00b204e9800998ecf8427e' ) # Verify that a specified key_prefix is taken into account. learn_cache_key(request, response, key_prefix=key_prefix) self.assertEqual( get_cache_key(request, key_prefix=key_prefix), 'views.decorators.cache.cache_page.localprefix.GET.' '18a03f9c9649f7d684af5db3524f5c99.d41d8cd98f00b204e9800998ecf8427e' )
def test_learn_cache_key(self): request = self._get_request(self.path, 'HEAD') response = HttpResponse() response['Vary'] = 'Pony' # Make sure that the Vary header is added to the key hash learn_cache_key(request, response) self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.HEAD.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
def test_learn_cache_key(self): request = self._get_request(self.path) response = HttpResponse() response['Vary'] = 'Pony' # Make sure that the Vary header is added to the key hash learn_cache_key(request, response) self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
def test_get_cache_key(self): request = self._get_request(self.path) response = HttpResponse() key_prefix = 'localprefix' # Expect None if no headers have been set yet. self.assertEqual(get_cache_key(request), None) # Set headers to an empty list. learn_cache_key(request, response) self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e') # Verify that a specified key_prefix is taken in to account. learn_cache_key(request, response, key_prefix=key_prefix) self.assertEqual(get_cache_key(request, key_prefix=key_prefix), 'views.decorators.cache.cache_page.localprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
def test_get_cache_key(self): request = self._get_request(self.path) response = HttpResponse() key_prefix = 'localprefix' # Expect None if no headers have been set yet. self.assertEqual(get_cache_key(request), None) # Set headers to an empty list. learn_cache_key(request, response) self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e') # Verify that a specified key_prefix is taken in to account. learn_cache_key(request, response, key_prefix=key_prefix) self.assertEqual(get_cache_key(request, key_prefix=key_prefix), 'views.decorators.cache.cache_page.localprefix.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
def process_response(self, request, response): """Sets the cache, if needed.""" if not self._should_update_cache(request, response): # We don't need to update the cache, just return. return response if not response.status_code == 200: return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout == None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response patch_response_headers(response, timeout) if timeout: cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback( lambda r: self.cache.set(cache_key, r, timeout) ) else: self.cache.set(cache_key, response, timeout) return response
def test_cache_key_no_i18n (self): settings.USE_I18N = False request = self._get_request() lang = translation.get_language() response = HttpResponse() key = learn_cache_key(request, response) self.assertFalse(key.endswith(lang), "Cache keys shouldn't include the language name when i18n is inactive")
def process_response(self, request, response): """Sets the cache, if needed.""" # never cache headers + ETag add_never_cache_headers(response) if not hasattr( request, '_cache_update_cache') or not request._cache_update_cache: # We don't need to update the cache, just return. return response if request.method != 'GET': # This is a stronger requirement than above. It is needed # because of interactions between this middleware and the # HTTPMiddleware, which throws the body of a HEAD-request # away before this middleware gets a chance to cache it. return response if not response.status_code == 200: return response # use the precomputed cache_key if request._cache_middleware_key: cache_key = request._cache_middleware_key else: cache_key = learn_cache_key(request, response, self.cache_timeout, self.key_prefix) # include the orig_time information within the cache cache.set(cache_key, (time.time(), response), self.cache_timeout) return response
def process_response(self, request, response): """Sets the cache, if needed.""" if not self._should_update_cache(request, response): # We don't need to update the cache, just return. return response if not response.status_code == 200: return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout == None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response patch_response_headers(response, timeout) if timeout: cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback( lambda r: self.cache.set(cache_key, r, timeout)) else: self.cache.set(cache_key, response, timeout) return response
def process_response(self, request, response): """Set the cache, if needed.""" if not self._should_update_cache(request, response): # We don't need to update the cache, just return. return response if response.streaming or response.status_code not in (200, 304): return response # Don't cache responses that set a user-specific (and maybe security # sensitive) cookie in response to a cookie-less request. if not request.COOKIES and response.cookies and has_vary_header(response, 'Cookie'): return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout is None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response patch_response_headers(response, timeout) if timeout and response.status_code == 200: cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback( lambda r: self.cache.set(cache_key, r, timeout) ) else: self.cache.set(cache_key, response, timeout) return response
def process_response(self, request, response): if not self._should_update_cache(request, response): return response if response.streaming or response.status_code != 200: return response if not request.COOKIES and response.cookies and has_vary_header(response, 'Cookie'): return response if (request.path.startswith('/admin/') or request.path.startswith('/sitemap') or request.path[-12:] == '/rss/yandex/' or request.path == 'sidebar.json'): return response timeout = get_max_age(response) if timeout is None: timeout = self.cache_timeout elif timeout == 0: return response #patch_response_headers(response, 5) if timeout: cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback(lambda r: self.cache.set(cache_key, r, timeout)) else: self.cache.set(cache_key, response, timeout) return response
def process_response(self, request, response): "Sets the cache, if needed." if not hasattr( request, '_cache_update_cache') or not request._cache_update_cache: # We don't need to update the cache, just return. return response try: if 'no-cache' in response['Cache-Control']: # Told not to cache, just return return response except KeyError: pass if request.method != 'GET': # This is a stronger requirement than above. It is needed # because of interactions between this middleware and the # HTTPMiddleware, which throws the body of a HEAD-request # away before this middleware gets a chance to cache it. return response if not response.status_code == 200: return response patch_response_headers(response, self.cache_timeout) cache_key = learn_cache_key(request, response, self.cache_timeout, self.key_prefix) cache.set(cache_key, response, self.cache_timeout) return response
def process_response(self, request, response): """Sets the cache, if needed.""" if not self._should_update_cache(request, response): # We don't need to update the cache, just return. return response if response.streaming or response.status_code != 200: return response # Don't cache responses that set a user-specific (and maybe security # sensitive) cookie in response to a cookie-less request. if not request.COOKIES and response.cookies and has_vary_header(response, 'Cookie'): return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout is None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response patch_response_headers(response, timeout) if timeout: cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback( lambda r: self.cache.set(cache_key, r, timeout) ) else: self.cache.set(cache_key, response, timeout) return response
def process_response(self, request, response): """Sets the cache, if needed.""" if not self._should_update_cache(request, response): # We don't need to update the cache, just return. return response if request.method != 'GET': # This is a stronger requirement than above. It is needed # because of interactions between this middleware and the # HTTPMiddleware, which throws the body of a HEAD-request # away before this middleware gets a chance to cache it. return response if not response.status_code == 200: return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout == None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response patch_response_headers(response, timeout) if timeout: cache_key = learn_cache_key(request, response, timeout, self.key_prefix) cache.set(cache_key, response, timeout) return response
def process_response(self, request, response): """Sets the cache, if needed.""" if not hasattr( request, '_cache_update_cache') or not request._cache_update_cache: # We don't need to update the cache, just return. return response if not response.status_code == 200: return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout == None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response patch_response_headers(response, timeout) if timeout: cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) self.cache.set(cache_key, response, timeout) return response
def process_response(self, request, response): """Sets the cache, if needed.""" if not hasattr(request, '_cache_update_cache') or not request._cache_update_cache: # We don't need to update the cache, just return. return response if request.method != 'GET': # This is a stronger requirement than above. It is needed # because of interactions between this middleware and the # HTTPMiddleware, which throws the body of a HEAD-request # away before this middleware gets a chance to cache it. return response if not response.status_code == 200: return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout == None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response if self.patch_headers: patch_response_headers(response, timeout) if timeout: if callable(self.key_prefix): key_prefix = self.key_prefix(request) else: key_prefix = self.key_prefix cache_key = learn_cache_key(request, response, timeout, key_prefix) cache.set(cache_key, response, timeout) return response
def process_response(self, request, response): """Sets the cache, if needed.""" # never cache headers + ETag add_never_cache_headers(response) if not hasattr(request, '_cache_update_cache') or not request._cache_update_cache: # We don't need to update the cache, just return. return response if request.method != 'GET': # This is a stronger requirement than above. It is needed # because of interactions between this middleware and the # HTTPMiddleware, which throws the body of a HEAD-request # away before this middleware gets a chance to cache it. return response if not response.status_code == 200: return response # use the precomputed cache_key if request._cache_middleware_key: cache_key = request._cache_middleware_key else: cache_key = learn_cache_key(request, response, self.cache_timeout, self.key_prefix) # include the orig_time information within the cache cache.set(cache_key, (time.time(), response), self.cache_timeout) return response
def process_response(self, request, response): # determine which db tables (read/write) have been touched in this # request/response, update the read table -> *cache_keys mapping # accordingly, # also flush appropriate cache_keys for views that read from tables # that were written by this request # TODO: a simple way (GET request) to invalidate certain cached views # TODO: cache only if not settings.DEBUG (do we really want to cache # while developing??? # TODO: can we speed this up??? # TODO: default cache timeout # TODO: bulk delete, bulk set??? # TODO: django.db.connection.queries doesn't work when # not settings.DEBUG!!! :( now the connnection is patched with a # connection_created signal, needs a better patch # if updating cache, also update the cache table -> *cache_keys mapping if self._will_update_cache(request, response): cache_key = learn_cache_key(request, response, self._get_timeout(response), self.key_prefix, cache=self.cache) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback( lambda r: self.get_and_set_readtables(cache_key) ) else: self.get_and_set_readtables(cache_key) logger.debug('Updating readtables for cache_key: {0}' .format(cache_key)) # # flush appropriate parts of the cache written = (self.write_table_regex.finditer(q['sql']) for q in connection.queries if not (q['sql'].startswith("SELECT") or q['sql'].startswith('QUERY = u\'SELECT'))) writtentables = [] for w in itertools.chain(*written): if w is not None: if w.group(1) not in writtentables: writtentables.append(w.group(1)) # TODO: use iterators instead if len(writtentables): cache_keys_for_deletion = list( set(reduce(lambda x, y: x + y, [self.cache.get(self.cache_table_key.format(w), []) for w in writtentables]) ) ) logger.debug('Flushing cache keys \n{0}' .format("\n".join(cache_keys_for_deletion))) map(self.cache.delete, cache_keys_for_deletion) # return super(UpdateCacheMiddleware, self).process_response(request, response)
def test_cache_key_i18n(self): settings.USE_I18N = True request = self._get_request() lang = translation.get_language() response = HttpResponse() key = learn_cache_key(request, response) self.assertTrue(key.endswith(lang), "Cache keys should include the language name when i18n is active") key2 = get_cache_key(request) self.assertEqual(key, key2)
def process_response(self, request, response): if request.COOKIES.get( 'view_uncached') == 'true' and request.user.is_authenticated: return response else: middleware_cache_tags = self.cache_tags if self.cache_tags else [] if not self._should_update_cache(request, response): return response if response.streaming or response.status_code not in (200, 304): return response # Don't cache responses that set a user-specific (and maybe security # sensitive) cookie in response to a cookie-less request. if not request.COOKIES and response.cookies and has_vary_header( response, 'Cookie'): return response # Don't cache a response with 'Cache-Control: private' if 'private' in response.get('Cache-Control', ()): return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout is None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response patch_response_headers(response, timeout) if response.has_header('X-Additional-Cache-Tags'): middleware_cache_tags = response.__getitem__( 'X-Additional-Cache-Tags').split(",") + self.cache_tags if timeout and response.status_code == 200: cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) # add this cache_key to a cache_keys cache with tags cache.add_cache_key(request, cache_key, tags=middleware_cache_tags) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback( lambda r: self.cache.set(cache_key, r, timeout)) else: self.cache.set(cache_key, response, timeout) return response
def index(request): tasks = cache.get(TASKS_KEY) if not tasks: time.sleep(2) # simulate a slow query. tasks = Task.objects.order_by("id") cache.set(TASKS_KEY, tasks) c = {'tasks': tasks} c.update(csrf(request)) response = render_to_response('index.html', c) global VIEW_KEY VIEW_KEY = learn_cache_key(request, response) return response
def cacheatron(request, response, keys): """ Cache responses to specific keysets for purging :param request: Django request object :param reponse: Full response object :param keys: Array of keysets to add the cache key to :return Response object """ cache_key = learn_cache_key(request, response) for key in keys: key.add(cache_key) return response
def process_response(self, request, response): """Sets the cache, if needed.""" # TODO if not self._should_update_cache(request, response): # We don't need to update the cache, just return. return response # 不是流响应,不是200码 if response.streaming or response.status_code != 200: return response # Don't cache responses that set a user-specific (and maybe security # sensitive) cookie in response to a cookie-less request. # 请求没有cookie,但是处理过程中设置了cookie,并且Vary包含了Cookie,直接返回 # 分析:因为缓存服务器收到请求是没有Cookie的,然后返回的告诉他类似的请求根据Cookie # 来判断是否使用缓存,这样,下一个没有Cookie的人访问该URL则会拿到之前的人 # 的Cookie中的数据 if not request.COOKIES and response.cookies and has_vary_header( response, 'Cookie'): return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. # 首先使用response中设置的max_age(根据Cache-Control部分),如果没有设置 # 则使用setting中的. # 分析:setting中的是最后的依据,如果设置过则按照设置过的来 timeout = get_max_age(response) if timeout is None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response # 设置ETag, Last-Modified, Expires 和 Cache-Control的max-age部分,都用于缓存控制 patch_response_headers(response, timeout) if timeout: # 拿到cache——key,该方法设置了header_key,返回的是page_key cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) # 如果有render,则设置回调,在render之后缓存. if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback( lambda r: self.cache.set(cache_key, r, timeout)) else: self.cache.set(cache_key, response, timeout) return response
def process_response(self, request, response): """Sets the cache, if needed.""" if (not hasattr(request, '_cache_update_cache') or not request._cache_update_cache): # We don't need to update the cache, just return. return response if request.method != 'GET': # This is a stronger requirement than above. It is needed # because of interactions between this middleware and the # HTTPMiddleware, which throws the body of a HEAD-request # away before this middleware gets a chance to cache it. return response if not response.status_code == 200: return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout is None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response if self.patch_headers: patch_response_headers(response, timeout) if timeout: if callable(self.key_prefix): key_prefix = self.key_prefix(request) else: key_prefix = self.key_prefix if self.post_process_response: response = self.post_process_response(response, request) with RequestPath(request, self.only_get_keys, self.forget_get_keys): cache_key = learn_cache_key(request, response, timeout, key_prefix) if self.remember_all_urls: self.remember_url(request, cache_key, timeout) self.cache.set(cache_key, response, timeout) if self.post_process_response_always: response = self.post_process_response_always(response, request) return response
def process_response(self, request, response): "Sets the cache, if needed." if not hasattr(request, '_cache_update_cache') or not request._cache_update_cache: # We don't need to update the cache, just return. return response if not request.META['REQUEST_METHOD'] == 'GET': # This is a stronger requirement than above. It is needed # because of interactions between this middleware and the # HTTPMiddleware, which throws the body of a HEAD-request # away before this middleware gets a chance to cache it. return response if not response.status_code == 200: return response patch_response_headers(response, self.cache_timeout) cache_key = learn_cache_key(request, response, self.cache_timeout, self.key_prefix) cache.set(cache_key, response, self.cache_timeout) return response
def process_response(self, request, response): """Set the cache, if needed.""" if not self._should_update_cache(request, response): # We don't need to update the cache, just return. return response if response.streaming or response.status_code not in (200, 304): return response # Don't cache responses that set a user-specific (and maybe security # sensitive) cookie in response to a cookie-less request. if (not request.COOKIES and response.cookies and has_vary_header(response, "Cookie")): return response # Don't cache a response with 'Cache-Control: private' if "private" in response.get("Cache-Control", ()): return response # Page timeout takes precedence over the "max-age" and the default # cache timeout. timeout = self.page_timeout if timeout is None: # The timeout from the "max-age" section of the "Cache-Control" # header takes precedence over the default cache timeout. timeout = get_max_age(response) if timeout is None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't cache. return response patch_response_headers(response, timeout) if timeout and response.status_code == 200: cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) if hasattr(response, "render") and callable(response.render): response.add_post_render_callback( lambda r: self.cache.set(cache_key, r, timeout)) else: self.cache.set(cache_key, response, timeout) return response
def process_response(self, request, response): """Sets the cache, if needed.""" if not self._should_update_cache(request, response): # We don't need to update the cache, just return. return response if not response.status_code == 200: return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout == None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response patch_response_headers(response, timeout) user = request.user try: github_prefix = user.social_auth.get( provider='github').extra_data['username'] except: github_prefix = '' try: bitbucket_prefix = user.social_auth.get( provider='bitbucket').extra_data['username'] except: bitbucket_prefix = '' custom_prefix = '.'.join((hashlib.md5(github_prefix).hexdigest(), hashlib.md5(bitbucket_prefix).hexdigest())) if timeout: cache_key = learn_cache_key(request, response, timeout, custom_prefix, cache=self.cache) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback( lambda r: self.cache.set(cache_key, r, timeout)) else: self.cache.set(cache_key, response, timeout) return response
def process_response(self, request, response): if request.path != '/status': cache_entry = Model('cache').facade.get_or_create( request.build_absolute_uri()) cache_entry.requests += 1 cache_entry.save() if not (hasattr(request, '_cache_update_cache') and request._cache_update_cache): return response response['Object-Cache'] = 'MISS' if response.streaming or response.status_code not in (200, 304): return response if not request.COOKIES and response.cookies and has_vary_header( response, 'Cookie'): return response if 'private' in response.get('Cache-Control', ()): return response timeout = get_max_age(response) if timeout is None: timeout = self.cache_timeout elif timeout == 0: return response patch_response_headers(response, timeout) if timeout and response.status_code == 200: cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback( lambda r: self.cache.set(cache_key, r, timeout)) else: self.cache.set(cache_key, response, timeout) return response
def process_response(self, request, response): """Sets the cache, if needed.""" if not hasattr(request, '_cache_update_cache') or not request._cache_update_cache: # We don't need to update the cache, just return. return response if not response.status_code == 200: return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout == None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response patch_response_headers(response, timeout) if timeout: cache_key = learn_cache_key(request, response, timeout, self.key_prefix) self.cache.set(cache_key, response, timeout) return response
def process_response(self, request, response): """Sets the cache, if needed.""" if not self._should_update_cache(request, response): # We don't need to update the cache, just return. return response if not response.status_code == 200: return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout == None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response patch_response_headers(response, timeout) user = request.user try: github_prefix = user.social_auth.get(provider='github').extra_data['username'] except: github_prefix = '' try: bitbucket_prefix=user.social_auth.get(provider='bitbucket').extra_data['username'] except: bitbucket_prefix = '' custom_prefix = '.'.join((hashlib.md5(github_prefix).hexdigest(),hashlib.md5(bitbucket_prefix).hexdigest())) if timeout: cache_key = learn_cache_key(request, response, timeout, custom_prefix, cache=self.cache) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback( lambda r: self.cache.set(cache_key, r, timeout) ) else: self.cache.set(cache_key, response, timeout) return response
"""
def process_response(self, request, response): if not wagtailcache_settings['WAGTAIL_CACHE']: return response if not self._should_update_cache(request, response): # We don't need to update the cache, just return. return response # Check if the response is cacheable # Don't cache private or no-cache responses. # Do cache 200, 301, 302, 304, and 404 codes so that wagtail doesn't have to repeatedly look up these URLs in the database. # Don't cache streaming responses. is_cacheable = \ 'no-cache' not in response.get('Cache-Control', ()) and \ 'private' not in response.get('Cache-Control', ()) and \ response.status_code in (200, 301, 302, 304, 404) and \ not response.streaming # Don't cache 200 responses that set a user-specific cookie in response to a cookie-less request (e.g. CSRF tokens). if is_cacheable and response.status_code == 200: is_cacheable = not (not request.COOKIES and response.cookies and has_vary_header(response, 'Cookie')) # Allow the user to override our caching decision. for fn in hooks.get_hooks('is_response_cacheable'): result = fn(response, is_cacheable) if isinstance(result, bool): is_cacheable = result # If we are not allowed to cache the response, just return. if not is_cacheable: # Add a response header to indicate this was intentionally not cached. if wagtailcache_settings['WAGTAIL_CACHE_HEADER']: response[ wagtailcache_settings['WAGTAIL_CACHE_HEADER']] = 'skip' return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the cache's default. timeout = get_max_age(response) if timeout is None: timeout = _wagcache.default_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response patch_response_headers(response, timeout) if timeout: cache_key = learn_cache_key(request, response, timeout, None, cache=_wagcache) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback( lambda r: _wagcache.set(cache_key, r, timeout)) else: _wagcache.set(cache_key, response, timeout) # Add a response header to indicate this was a cache miss. if wagtailcache_settings['WAGTAIL_CACHE_HEADER']: response[ wagtailcache_settings['WAGTAIL_CACHE_HEADER']] = 'miss' return response
# sensitive) cookie in response to a cookie-less request. if not request.COOKIES and response.cookies and has_vary_header(response, 'Cookie'): return response # Try to get the timeout from the "max-age" section of the "Cache- # Control" header before reverting to using the default cache_timeout # length. timeout = get_max_age(response) if timeout is None: timeout = self.cache_timeout elif timeout == 0: # max-age was set to 0, don't bother caching. return response patch_response_headers(response, timeout) if timeout and response.status_code == 200: cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback( lambda r: self.cache.set(cache_key, r, timeout) ) else: self.cache.set(cache_key, response, timeout) return response class FetchFromCacheMiddleware(MiddlewareMixin): """ Request-phase cache middleware that fetches a page from the cache. Must be used as part of the two-part update/fetch cache middleware. FetchFromCacheMiddleware must be the last piece of middleware in MIDDLEWARE
def process_response(self, request: WSGIRequest, response: HttpResponse) -> HttpResponse: if not wagtailcache_settings.WAGTAIL_CACHE: return response if getattr(request, "_wagtailcache_skip", False): # If we should skip this response, add header and return. _patch_header(response, Status.SKIP) return response if not getattr(request, "_wagtailcache_update", False): # We don't need to update the cache, just return. return response # Check if the response is cacheable # Don't cache private or no-cache responses. # Do cache 200, 301, 302, 304, and 404 codes so that wagtail doesn't # have to repeatedly look up these URLs in the database. # Don't cache streaming responses. is_cacheable = (CacheControl.NOCACHE.value not in response.get( "Cache-Control", "") and CacheControl.PRIVATE.value not in response.get( "Cache-Control", "") and response.status_code in (200, 301, 302, 304, 404) and not response.streaming) # Don't cache 200 responses that set a user-specific cookie in response # to a cookie-less request (e.g. CSRF tokens). if is_cacheable and response.status_code == 200: is_cacheable = not (not request.COOKIES and response.cookies and has_vary_header(response, "Cookie")) # Allow the user to override our caching decision. for fn in hooks.get_hooks("is_response_cacheable"): result = fn(response, is_cacheable) if isinstance(result, bool): is_cacheable = result # If we are not allowed to cache the response, just return. if not is_cacheable: # Add response header to indicate this was intentionally not cached. _patch_header(response, Status.SKIP) return response # Try to get the timeout from the ``max-age`` section of the # ``Cache-Control`` header before reverting to using the cache's # default. timeout = get_max_age(response) if timeout is None: timeout = self._wagcache.default_timeout patch_response_headers(response, timeout) if timeout: cache_key = learn_cache_key(request, response, timeout, None, cache=self._wagcache) if isinstance(response, SimpleTemplateResponse): response.add_post_render_callback( lambda r: self._wagcache.set(cache_key, r, timeout)) else: self._wagcache.set(cache_key, response, timeout) # Add a response header to indicate this was a cache miss. _patch_header(response, Status.MISS) return response
def get(self, request, *args, **kwargs): response = super(ArticleDetailView, self).get(request, *args, **kwargs) # self.object.increase_views() cache_keys.add(learn_cache_key(request, response)) return response