def learn_cache_key(request, response, tags=(), cache_timeout=None, key_prefix=None, cache=None): # patched """ Learns what headers to take into account for some request path from the response object. It stores those headers in a global path registry so that later access to that path will know what headers to take into account without building the response object itself. The headers are named in the Vary header of the response, but we want to prevent response generation. The list of headers to use for cache key generation is stored in the same cache as the pages themselves. If the cache ages some data out of the cache, this just means that we have to build the response once to get at the Vary header and so at the list of headers to use for the cache key. """ if key_prefix is None: key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX if cache_timeout is None: cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS cache_key = _generate_cache_header_key(key_prefix, request) if cache is None: cache = get_cache(settings.CACHE_MIDDLEWARE_ALIAS) if response.has_header('Vary'): headerlist = ['HTTP_'+header.upper().replace('-', '_') for header in cc_delim_re.split(response['Vary'])] cache.set(cache_key, headerlist, tags, cache_timeout) # patched return _generate_cache_key(request, request.method, headerlist, key_prefix) else: # if there is no Vary header, we still need a cache key # for the request.get_full_path() cache.set(cache_key, [], tags, cache_timeout) # patched return _generate_cache_key(request, request.method, [], key_prefix)
def _try_get_cache(request: HttpRequest) -> Optional[CacheEntry]: cache_key = _generate_cache_key(request, 'GET', [], CACHE_PREFIX) if cache_key is None: return None entry = cache.get(cache_key) if entry is None and request.method == 'HEAD': cache_key = _generate_cache_key(request, 'HEAD', [], CACHE_PREFIX) entry = cache.get(cache_key) return entry
def learn_cache_key(request, response, tags=(), cache_timeout=None, key_prefix=None, cache=None): # patched """ Learns what headers to take into account for some request URL from the response object. It stores those headers in a global URL registry so that later access to that URL will know what headers to take into account without building the response object itself. The headers are named in the Vary header of the response, but we want to prevent response generation. The list of headers to use for cache key generation is stored in the same cache as the pages themselves. If the cache ages some data out of the cache, this just means that we have to build the response once to get at the Vary header and so at the list of headers to use for the cache key. """ if key_prefix is None: key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX if cache_timeout is None: cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS cache_key = _generate_cache_header_key(key_prefix, request) if cache is None: cache = caches[settings.CACHE_MIDDLEWARE_ALIAS] if response.has_header('Vary'): is_accept_language_redundant = settings.USE_I18N or settings.USE_L10N # If i18n or l10n are used, the generated cache key will be suffixed # with the current locale. Adding the raw value of Accept-Language is # redundant in that case and would result in storing the same content # under multiple keys in the cache. See #18191 for details. headerlist = [] for header in cc_delim_re.split(response['Vary']): header = header.upper().replace('-', '_') if header == 'ACCEPT_LANGUAGE' and is_accept_language_redundant: continue headerlist.append('HTTP_' + header) headerlist.sort() cache.set(cache_key, headerlist, tags, cache_timeout) # patched return _generate_cache_key(request, request.method, headerlist, key_prefix) else: # if there is no Vary header, we still need a cache key # for the request.build_absolute_uri() cache.set(cache_key, [], tags, cache_timeout) # patched return _generate_cache_key(request, request.method, [], key_prefix)
def learn_cache_key(request, response, tags=(), cache_timeout=None, key_prefix=None, cache=None): # patched """ Learns what headers to take into account for some request path from the response object. It stores those headers in a global path registry so that later access to that path will know what headers to take into account without building the response object itself. The headers are named in the Vary header of the response, but we want to prevent response generation. The list of headers to use for cache key generation is stored in the same cache as the pages themselves. If the cache ages some data out of the cache, this just means that we have to build the response once to get at the Vary header and so at the list of headers to use for the cache key. """ if key_prefix is None: key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX if cache_timeout is None: cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS cache_key = _generate_cache_header_key(key_prefix, request) if cache is None: cache = get_cache(settings.CACHE_MIDDLEWARE_ALIAS) if response.has_header('Vary'): headerlist = [ 'HTTP_' + header.upper().replace('-', '_') for header in cc_delim_re.split(response['Vary']) ] cache.set(cache_key, headerlist, tags, cache_timeout) # patched return _generate_cache_key(request, request.method, headerlist, key_prefix) else: # if there is no Vary header, we still need a cache key # for the request.get_full_path() cache.set(cache_key, [], tags, cache_timeout) # patched return _generate_cache_key(request, request.method, [], key_prefix)
def add_page_cache(request, group='default', key_prefix=None): """增加视图缓存key,清除缓存时使用,不支持reponse has_header 'Vary'""" group = group or 'page' page_cache = _page_cache_dict() if group not in page_cache: page_cache[group] = {} if request.get_full_path() in page_cache[group]: return if key_prefix is None: key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX headerkey = _generate_cache_header_key(key_prefix, request) cachekey = _generate_cache_key(request, request.method, [], key_prefix) page_cache[group][request.get_full_path()] = { 'header': headerkey, 'cache': cachekey, } _save_page_cache(page_cache)
def expire_cache(path, args=[], GET={}, HOSTNAME="127.0.0.1:8000", cache_name=None, isview=True, lang_code=None, method='GET'): if cache_name is None: cache_name = DEFAULT_CACHE_ALIAS cache = get_cache(cache_name) key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX print(key_prefix) request = HttpRequest() fake_meta = {'HTTP_HOST':HOSTNAME,} print(fake_meta['HTTP_HOST']) request.META = fake_meta request.GET = GET if isview: request.path = reverse(path, args=args) else: request.path = path language_code = lang_code or getattr(settings, 'LANGUAGE_CODE') if language_code: request.LANGUAGE_CODE = language_code header_key = _generate_cache_header_key(key_prefix, request) if not header_key: return False print(header_key) headerlist = cache.get(header_key, None) print(headerlist) if headerlist is not None: cache.set(header_key, None, 0) page_key = _generate_cache_key(request, method, headerlist, key_prefix) if not page_key: return False print(cache.get(page_key)) cache.set(page_key, None, 0) return True
def __call__(self, request: HttpRequest): response = self.get_response(request) if not (hasattr(request, '_cache_update_cache') and request._cache_update_cache): return response if response.streaming or response.status_code != 200: return response last_modified_stamp, etag = get_last_modified_and_etag(request) response['Last-Modified'] = last_modified_stamp response['ETag'] = etag response['Cache-Control'] = 'max-age=0, public, s-maxage=60' cache_key = _generate_cache_key(request, request.method, [], CACHE_PREFIX) if hasattr(response, 'render') and callable(response.render): response.add_post_render_callback(lambda rendered: cache.set( cache_key, CacheEntry(rendered, timezone.now()), PAGE_MAX_TTL)) else: cache.set(cache_key, CacheEntry(response, timezone.now()), PAGE_MAX_TTL) return response
def get_request_cache_key(request, key_prefix=None): """ Based on django.utils.cache.get_cache_key function Returns a cache key based on the request path. It can be used in the request phase because it pulls the list of headers to take into account from the global path registry and uses those to build a cache key to check against. If there is no headerlist stored, the page needs to be rebuilt, so this function returns None. This function has been refactored to be able to call get_view_cache_key in a separately way. This is needed to define a request.path_cache_key attribute (see cmsutils.middleware.I18NFetchFromCacheMiddleware). """ if key_prefix is None: key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX cache_key = _generate_cache_header_key(key_prefix, request) headerlist = cache.get(cache_key, None) if headerlist is not None: return _generate_cache_key(request, headerlist, key_prefix) else: return None
def get_page_cache_key(self, request, method='GET'): return _generate_cache_key(request, method, [], self.cache_key_prefix)
def search_for_name(request, name): def find_unique(n): exact = DocAlias.objects.filter(name=n).first() if exact: return exact.name aliases = DocAlias.objects.filter(name__startswith=n)[:2] if len(aliases) == 1: return aliases[0].name aliases = DocAlias.objects.filter(name__contains=n)[:2] if len(aliases) == 1: return aliases[0].name return None def cached_redirect(key, url): cache.set(key, url, settings.CACHE_MIDDLEWARE_SECONDS) return HttpResponseRedirect(url) n = name cache_key = _generate_cache_key(request, 'GET', [], settings.CACHE_MIDDLEWARE_KEY_PREFIX) if cache_key: url = cache.get(cache_key, None) if url: return HttpResponseRedirect(url) # chop away extension extension_split = re.search("^(.+)\.(txt|ps|pdf)$", n) if extension_split: n = extension_split.group(1) redirect_to = find_unique(name) if redirect_to: return cached_redirect( cache_key, urlreverse("ietf.doc.views_doc.document_main", kwargs={"name": redirect_to})) else: # check for embedded rev - this may be ambigious, so don't # chop it off if we don't find a match rev_split = re.search("^(.+)-([0-9]{2})$", n) if rev_split: redirect_to = find_unique(rev_split.group(1)) if redirect_to: rev = rev_split.group(2) # check if we can redirect directly to the rev if DocHistory.objects.filter(doc__docalias__name=redirect_to, rev=rev).exists(): return cached_redirect( cache_key, urlreverse("ietf.doc.views_doc.document_main", kwargs={ "name": redirect_to, "rev": rev })) else: return cached_redirect( cache_key, urlreverse("ietf.doc.views_doc.document_main", kwargs={"name": redirect_to})) # build appropriate flags based on string prefix doctypenames = DocTypeName.objects.filter(used=True) # This would have been more straightforward if document prefixes couldn't # contain a dash. Probably, document prefixes shouldn't contain a dash ... search_args = "?name=%s" % n if n.startswith("draft"): search_args += "&rfcs=on&activedrafts=on&olddrafts=on" else: for t in doctypenames: if n.startswith(t.prefix): search_args += "&doctypes=%s" % t.slug break else: search_args += "&rfcs=on&activedrafts=on&olddrafts=on" return cached_redirect( cache_key, urlreverse('ietf.doc.views_search.search') + search_args)