def _get_conditional_response(self, request, etag, last_modified): """Mimics ConditionalGetMiddleware""" return get_conditional_response( request, etag=etag, last_modified=last_modified, )
def process_response(self, request, response): """ Calculate the ETag, if needed. When the status code of the response is 404, it may redirect to a path with an appended slash if should_redirect_with_slash() returns True. """ # If the given URL is "Not Found", then check if we should redirect to # a path with a slash appended. if response.status_code == 404: if self.should_redirect_with_slash(request): return self.response_redirect_class( self.get_full_path_with_slash(request)) if settings.USE_ETAGS: if not response.has_header('ETag'): set_response_etag(response) if response.has_header('ETag'): return get_conditional_response( request, etag=response['ETag'], response=response, ) return response
def process_response(self, request, response): """ Calculate the ETag, if needed. When the status code of the response is 404, it may redirect to a path with an appended slash if should_redirect_with_slash() returns True. """ # If the given URL is "Not Found", then check if we should redirect to # a path with a slash appended. if response.status_code == 404: if self.should_redirect_with_slash(request): return self.response_redirect_class(self.get_full_path_with_slash(request)) if settings.USE_ETAGS and self.needs_etag(response): if not response.has_header('ETag'): set_response_etag(response) if response.has_header('ETag'): return get_conditional_response( request, etag=response['ETag'], response=response, ) # Add the Content-Length header to non-streaming responses if not # already set. if not response.streaming and not response.has_header('Content-Length'): response['Content-Length'] = str(len(response.content)) return response
def inner(request, *args, **kwargs): # Compute values (if any) for the requested resource. def get_last_modified(): if last_modified_func: dt = last_modified_func(request, *args, **kwargs) if dt: return timegm(dt.utctimetuple()) # The value from etag_func() could be quoted or unquoted. res_etag = etag_func(request, *args, **kwargs) if etag_func else None res_etag = quote_etag(res_etag) if res_etag is not None else None res_last_modified = get_last_modified() response = get_conditional_response( request, etag=res_etag, last_modified=res_last_modified, ) if response is None: response = func(request, *args, **kwargs) # 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: response.setdefault('ETag', res_etag) return response
def inner(request, *args, **kwargs): # Compute values (if any) for the requested resource. def get_last_modified(): if last_modified_func: dt = last_modified_func(request, *args, **kwargs) if dt: if not timezone.is_aware(dt): dt = timezone.make_aware(dt, datetime.timezone.utc) return int(dt.timestamp()) # The value from etag_func() could be quoted or unquoted. res_etag = etag_func(request, *args, **kwargs) if etag_func else None res_etag = quote_etag(res_etag) if res_etag is not None else None res_last_modified = get_last_modified() response = get_conditional_response( request, etag=res_etag, last_modified=res_last_modified, ) if response is None: response = func(request, *args, **kwargs) # 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.headers["Last-Modified"] = http_date(res_last_modified) if res_etag: response.headers.setdefault("ETag", res_etag) return response
def detail_view(self, request, **kwargs): # Exit early if there are any issues self.check_parameter_validity() if helpers.is_draft_requested(request): return super().detail_view(request, pk=None) # Return a cached response if one is available cached_data = cache.PageCache.get( page_id=self.get_object_id(), lang=translation.get_language(), region=request.GET.get('region'), ) if cached_data: cached_response = helpers.CachedResponse(cached_data) cached_response['etag'] = cached_data.get('etag', None) return get_conditional_response( request=request, etag=cached_response['etag'], response=cached_response, ) # No cached response available response = super().detail_view(request, pk=None) if response.status_code == 200: # Reuse the already-fetched object to populate the cache cache.CachePopulator.populate_async(self.get_object()) # No etag is set for this response because creating one is expensive. # If API caching is enabled, one will be added to the cached version # created above. return response
def inner(request, *args, **kwargs): # Compute values (if any) for the requested resource. def get_last_modified(): if last_modified_func: dt = last_modified_func(request, *args, **kwargs) if dt: return timegm(dt.utctimetuple()) # The value from etag_func() could be quoted or unquoted. res_etag = etag_func(request, *args, **kwargs) if etag_func else None res_etag = quote_etag(res_etag) if res_etag is not None else None res_last_modified = get_last_modified() response = get_conditional_response( request, etag=res_etag, last_modified=res_last_modified, ) if response is None: response = func(request, *args, **kwargs) # 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: response.setdefault('ETag', res_etag) return response
def wrapped_func(self, request, *args, **kwargs): response_format = self.perform_content_negotiation(request)[0].format etag_user = (':'+str(request.user.pk or 0)) if response_format == 'api' else '' raw_etag = '%s%s:%s:%s' % (response_format, etag_user, get_language(), (etag_func(request) if permissions else MapUpdate.current_cache_key())) if base_mapdata_check and self.base_mapdata: raw_etag += ':%d' % request.user_permissions.can_access_base_mapdata etag = quote_etag(raw_etag) response = get_conditional_response(request, etag=etag) if response is None: cache_key = 'mapdata:api:'+request.path_info[5:].replace('/', '-').strip('-')+':'+raw_etag if cache_parameters is not None: for param, type_ in cache_parameters.items(): value = int(param in request.GET) if type_ == bool else type_(request.GET.get(param)) cache_key += ':'+urlsafe_base64_encode(str(value).encode()).decode() data = request_cache.get(cache_key) if data is not None: response = Response(data) if response is None: with GeometryMixin.dont_keep_originals(): response = func(self, request, *args, **kwargs) if cache_parameters is not None and response.status_code == 200: request_cache.set(cache_key, response.data, 900) if response.status_code == 200: response['ETag'] = etag response['Cache-Control'] = 'no-cache' return response
def get(self, request, *args, **kwargs): """Mixin implementation of django.views.decorators.http.condition""" # Resolve etag and last_modified etag = self.get_etag(request) etag = quote_etag(etag) if etag is not None else None last_modified = self.get_last_modified(request) last_modified = timegm( last_modified.utctimetuple()) if last_modified else None # Check request headers response = get_conditional_response(request, etag=etag, last_modified=last_modified) if response: return response # If we need get new data, do that response = super().get(request, *args, **kwargs) # Set relevant headers on the response if they don't already exist. if last_modified and not response.has_header('Last-Modified'): response['Last-Modified'] = http_date(last_modified) if etag and not response.has_header('ETag'): response['ETag'] = etag return response
def dispatch(self, *args, **kwargs): if ('service_name' not in self.request.GET or helpers.is_draft_requested(self.request)): return super().dispatch(*args, **kwargs) cached_page = cache.PageCache.get(slug=self.kwargs['slug'], params={ 'service_name': self.request.GET['service_name'], 'lang': translation.get_language(), 'region': self.request.GET.get('region'), }) if cached_page: cached_response = helpers.CachedResponse(cached_page) cached_response['etag'] = cached_page.get('etag', None) response = get_conditional_response( request=self.request, etag=cached_response['etag'], response=cached_response, ) else: response = super().dispatch(*args, **kwargs) if response.status_code == 200: # No etag is set in this response. this is because creating an # etag is expensive. It will be present on the next retrieved # from the cache though. cache.CachePopulator.populate_async(self.get_object()) return response
def process_response(self, request, response): """ Calculate the ETag, if needed. When the status code of the response is 404, it may redirect to a path with an appended slash if should_redirect_with_slash() returns True. """ # If the given URL is "Not Found", then check if we should redirect to # a path with a slash appended. if response.status_code == 404: if self.should_redirect_with_slash(request): return self.response_redirect_class( self.get_full_path_with_slash(request)) if settings.USE_ETAGS and self.needs_etag(response): if not response.has_header('ETag'): set_response_etag(response) if response.has_header('ETag'): return get_conditional_response( request, etag=unquote_etag(response['ETag']), response=response, ) # Add the Content-Length header to non-streaming responses if not # already set. if not response.streaming and not response.has_header( 'Content-Length'): response['Content-Length'] = str(len(response.content)) return response
def inner(request, *args, **kwargs): # Compute values (if any) for the requested resource. def get_last_modified(): if last_modified_func: dt = last_modified_func(request, *args, **kwargs) if dt: return timegm(dt.utctimetuple()) res_etag = etag_func(request, *args, ** kwargs) if etag_func else None res_last_modified = get_last_modified() response = get_conditional_response( request, etag=res_etag, last_modified=res_last_modified, ) 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'] = quote_etag(res_etag) return response
def process_response(self, request, response): if not response.streaming and not response.has_header('Content-Length'): response['Content-Length'] = str(len(response.content)) # It's too late to prevent an unsafe request with a 412 response, and # for a HEAD request, the response body is always empty so computing # an accurate ETag isn't possible. if request.method != 'GET': return response if self.needs_etag(response) and not response.has_header('ETag'): set_response_etag(response) etag = response.get('ETag') last_modified = response.get('Last-Modified') if last_modified: last_modified = parse_http_date_safe(last_modified) if etag or last_modified: return get_conditional_response( request, etag=etag, last_modified=last_modified, response=response, ) return response
def __call__(self, request: HttpRequest): if settings.DEBUG: response = self.get_response(request) response['Cache-Control'] = 'max-age=0, private, must-revalidate' response[SFI_CACHE_HEADER] = 'DEBUG_BYPASS' return response if not request.path.startswith( PAGE_CACHE_URLS) or not self._is_request_cacheable(request): response = self.get_response(request) response['Cache-Control'] = 'max-age=0, private, must-revalidate' response[SFI_CACHE_HEADER] = 'BYPASS' return response last_modified = get_last_modified_stamp() last_modified_stamp, etag = get_last_modified_and_etag(request) # Try getting a Not Modified response. response = get_conditional_response( request, etag, timegm(last_modified.utctimetuple())) if response: response[SFI_CACHE_HEADER] = 'NON_MODIFIED' return response # Lookup cache entry = self._try_get_cache(request) if entry and entry.created_date > last_modified: response = entry.response response[SFI_CACHE_HEADER] = 'HIT' return response request._cache_update_cache = True response = self.get_response(request) response[SFI_CACHE_HEADER] = 'MISS' return response
def wrapped_func(self, request, *args, **kwargs): response_format = self.perform_content_negotiation( request)[0].format etag_user = ( ':' + str(request.user.pk or 0)) if response_format == 'api' else '' raw_etag = '%s%s:%s:%s' % (response_format, etag_user, get_language(), (etag_func(request) if permissions else MapUpdate.current_cache_key())) etag = quote_etag(raw_etag) response = get_conditional_response(request, etag=etag) if response is None: cache_key = 'mapdata:api:' + request.path_info[5:].replace( '/', '-').strip('-') + ':' + raw_etag if cache_parameters is not None: for param, type_ in cache_parameters.items(): value = int( param in request.GET) if type_ == bool else type_( request.GET.get(param)) cache_key += ':' + urlsafe_base64_encode( str(value).encode()).decode() data = cache.get(cache_key) if data is not None: response = Response(data) if response is None: response = func(self, request, *args, **kwargs) if cache_parameters is not None and response.status_code == 200: cache.set(cache_key, response.data, 300) response['ETag'] = etag response['Cache-Control'] = 'no-cache' return response
def inner(request, *args, **kwargs): # Compute values (if any) for the requested resource. def get_last_modified(): if last_modified_func: dt = last_modified_func(request, *args, **kwargs) if dt: return timegm(dt.utctimetuple()) res_etag = etag_func(request, *args, **kwargs) if etag_func else None res_last_modified = get_last_modified() response = get_conditional_response( request, etag=res_etag, last_modified=res_last_modified, ) 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'] = quote_etag(res_etag) return response
def process_response(self, request, response): """ Calculate the ETag, if needed. When the status code of the response is 404, it may redirect to a path with an appended slash if should_redirect_with_slash() returns True. """ # If the given URL is "Not Found", then check if we should redirect to # a path with a slash appended. if response.status_code == 404: if self.should_redirect_with_slash(request): return self.response_redirect_class(self.get_full_path_with_slash(request)) if settings.USE_ETAGS: if not response.has_header('ETag'): set_response_etag(response) if response.has_header('ETag'): return get_conditional_response( request, etag=unquote_etag(response['ETag']), response=response, ) return response
def _image(self, request, pk=None): source = self.get_object() last_modified = int(os.path.getmtime(source.filepath)) response = get_conditional_response(request, last_modified=last_modified) if response is None: response = HttpResponse(open(source.filepath, 'rb'), content_type=mimetypes.guess_type(source.name)[0]) response['Last-Modified'] = http_date(last_modified) return response
def condition_response(self, request): instance = self.get_object() last_modified = getattr(instance, "last_modified_on", None) return get_conditional_response( request, etag=None, last_modified=last_modified, )
def fetch_query_results(request, name): if request.method == "OPTIONS": response = HttpResponse(status=204) else: if name == "single_card_details" and \ "HTTP_X_TWITCH_EXTENSION_VERSION" not in request.META: # 2017-01-18 emergency fix return HttpResponse(status=204) parameterized_query = _get_query_and_params(request, name) if issubclass(parameterized_query.__class__, HttpResponse): return parameterized_query last_modified = parameterized_query.result_as_of if last_modified: last_modified = timegm(last_modified.utctimetuple()) response = None is_cache_hit = parameterized_query.result_available if is_cache_hit: _trigger_if_stale(parameterized_query) # Try to return a minimal response response = get_conditional_response(request, last_modified=last_modified) if not response: if request.method == "HEAD": response = HttpResponse(204) else: # Resort to a full response response = _fetch_query_results(parameterized_query, user=request.user) # Add Last-Modified header if response.status_code in (200, 204, 304): response["Last-Modified"] = http_date(last_modified) # Add Cache-Control headers if parameterized_query.is_personalized or parameterized_query.has_premium_values: patch_cache_control(response, no_cache=True, private=True) else: patch_cache_control(response, no_cache=True, public=True) # Add CORS header if permitted - can be replaced by middleware in future origin = urlparse(request.META.get("HTTP_ORIGIN", "")) if origin.netloc in settings.ANALYTICS_CORS_ORIGIN_WHITELIST: response["Access-Control-Allow-Origin"] = origin.geturl() response["Access-Control-Allow-Methods"] = "GET, HEAD, OPTIONS" response["Access-Control-Allow-Headers"] = ", ".join( settings.ANALYTICS_CORS_HEADER_WHITELIST) # Always patch vary header so browsers do not cache CORS patch_vary_headers(response, ["Origin"]) return response
def _image(self, request, pk=None): source = self.get_object() last_modified = int(os.path.getmtime(source.filepath)) response = get_conditional_response(request, last_modified=last_modified) if response is None: response = HttpResponse(open(source.filepath, 'rb'), content_type=mimetypes.guess_type( source.name)[0]) response['Last-Modified'] = http_date(last_modified) return response
def process_response(self, request, response): if (not response.streaming and not response.has_header('Content-Length')): response['Content-Length'] = str( # pragma: no cover len(response.content)) etag = response.get('ETag') if etag: return get_conditional_response( request, etag=unquote_etag(etag), response=response, ) return response
def dispatch(self, request, *args, **kwargs): response = super(LastModifiedMixin, self).dispatch(request, *args, **kwargs) # NOTE: remove microseconds so that comparison will pass, # since microseconds are not included in the last-modified header last_modified = self.last_modified() if last_modified: last_modified = self.last_modified().replace(microsecond=0) response['Last-Modified'] = last_modified.strftime('%a, %d %b %Y %H:%M:%S GMT') last_modified = last_modified.timestamp() return get_conditional_response(request, last_modified=last_modified, response=response)
def process_response(self, request, response): response["Date"] = http_date() if not response.streaming and not response.has_header("Content-Length"): response["Content-Length"] = str(len(response.content)) etag = response.get("ETag") last_modified = response.get("Last-Modified") if last_modified: last_modified = parse_http_date_safe(last_modified) if etag or last_modified: return get_conditional_response(request, etag=etag, last_modified=last_modified, response=response) return response
def process_request(self, request): self.key_prefix = self.get_key_prefix(request) request._cache_cache_timeout = int(self.cache_timeout) response = super().process_request(request) if response: etag = response.get('ETag') last_modified = response.get('Last-Modified') if not (etag or last_modified): return response response = get_conditional_response( request, etag=etag, last_modified=last_modified and parse_http_date_safe(last_modified), response=response, ) response['Last-Modified'] = last_modified return response
def view_func(request, **kwargs): response = real_view_func(request, **kwargs) if request.method != 'GET': return response etag = response.get('ETag') last_modified = response.get('Last-Modified') if last_modified: last_modified = parse_http_date_safe(last_modified) if etag or last_modified: return get_conditional_response( request, etag=etag, last_modified=last_modified, response=response, ) return response
def process_response(self, request, response): response['Date'] = http_date() if not response.streaming and not response.has_header('Content-Length'): response['Content-Length'] = str(len(response.content)) etag = response.get('ETag') last_modified = response.get('Last-Modified') if last_modified: last_modified = parse_http_date_safe(last_modified) if etag or last_modified: return get_conditional_response( request, etag=unquote_etag(etag), last_modified=last_modified, response=response, ) return response
def _wrapped_view_func(request, *args, **kwargs): response = view_func(request, *args, **kwargs) # no cache but allow store for etag compare patch_cache_control(response, private=True, no_cache=True, max_age=0) # conditonal response on GET and HEAD only if request.method not in ('GET', 'HEAD'): return response # set etag set_response_etag(response) etag = response.get('ETag') # conditonal response return get_conditional_response(request, etag=etag, last_modified=None, response=response)
def process_response(self, request, response): response['Date'] = http_date() if not response.streaming and not response.has_header('Content-Length'): response['Content-Length'] = str(len(response.content)) etag = response.get('ETag') last_modified = response.get('Last-Modified') if last_modified: last_modified = parse_http_date_safe(last_modified) if etag or last_modified: return get_conditional_response( request, etag=etag, last_modified=last_modified, response=response, ) return response
def get_conditional_response(request, response=None): if not (response and hasattr(cache, 'get_conditional_response')): # Django 1.8 does not have such method, can't do anything return response last_modified = response.get('Last-Modified') conditional_response = cache.get_conditional_response( request, last_modified=http.parse_http_date_safe(last_modified), response=response, ) if conditional_response is response: return response headers = { header: response[header] for header in rfc7232_headers if header in response } for header, value in headers.items(): conditional_response[header] = value return conditional_response
def dispatch(self, request, *args, **kwargs): # NOTE: this doesn't actually skip view processing, # but without it we could return a not modified for a non-200 response response = super(LastModifiedMixin, self).dispatch(request, *args, **kwargs) last_modified = self.last_modified() if last_modified: # remove microseconds so that comparison will pass, # since microseconds are not included in the last-modified header last_modified = self.last_modified().replace(microsecond=0) response['Last-Modified'] = last_modified.strftime( '%a, %d %b %Y %H:%M:%S GMT') # convert the same way django does so that they will # compare correctly last_modified = calendar.timegm(last_modified.utctimetuple()) return get_conditional_response(request, last_modified=last_modified, response=response)
def process_response(self, request, response): # It's too late to prevent an unsafe request with a 412 response, and # for a HEAD request, the response body is always empty so computing # an accurate ETag isn't possible. if request.method != "GET": return response if self.needs_etag(response) and not response.has_header("ETag"): set_response_etag(response) etag = response.get("ETag") last_modified = response.get("Last-Modified") last_modified = last_modified and parse_http_date_safe(last_modified) if etag or last_modified: return get_conditional_response(request, etag=etag, last_modified=last_modified, response=response) return response
def process_response(self, request, response): # 加上时间头 response['Date'] = http_date() # 不是文件流并且没有长度header则补上 if not response.streaming and not response.has_header('Content-Length'): response['Content-Length'] = str(len(response.content)) # 获得本次response的内容标示ETag etag = response.get('ETag') last_modified = response.get('Last-Modified') if last_modified: last_modified = parse_http_date_safe(last_modified) if etag or last_modified: return get_conditional_response( request, etag=unquote_etag(etag), last_modified=last_modified, response=response, ) return response
def process_response(self, request, response): """ Calculate the ETag, if needed. When the status code of the response is 404, it may redirect to a path with an appended slash if should_redirect_with_slash() returns True. """ # If the given URL is "Not Found", then check if we should redirect to # a path with a slash appended. if response.status_code == 404: if self.should_redirect_with_slash(request): return self.response_redirect_class( self.get_full_path_with_slash(request)) if settings.USE_ETAGS and self.needs_etag(response): warnings.warn( "The USE_ETAGS setting is deprecated in favor of " "ConditionalGetMiddleware which sets the ETag regardless of " "the setting. CommonMiddleware won't do ETag processing in " "Django 2.1.", RemovedInDjango21Warning, ) if not response.has_header("ETag"): set_response_etag(response) if response.has_header("ETag"): return get_conditional_response( request, etag=response["ETag"], response=response, ) # Add the Content-Length header to non-streaming responses if not # already set. if not response.streaming and not response.has_header( "Content-Length"): response["Content-Length"] = str(len(response.content)) return response
def detail_view(self, request, **kwargs): # Exit early if there are any issues self.check_parameter_validity() draft_version = helpers.is_draft_requested(request) langs = [] if translation.get_language(): langs.append(translation.get_language()) langs.append('en-gb') # Return a cached response if one is available for lang in langs: cached_data = cache.PageCache.get(page_id=self.object_id, lang=lang, draft_version=draft_version) if cached_data: cached_response = helpers.CachedResponse(cached_data) cached_response['etag'] = cached_data.get('etag', None) return get_conditional_response( request=request, etag=cached_response['etag'], response=cached_response, ) logger.warn('Page cache miss') page = self.get_object() if type(page) not in MODELS_SERIALIZERS_MAPPING: # page that exists has been requested, but it's not serializable. E.g, it's a folder page return Response(status=204) else: cache.CachePopulator.populate_async(self.get_object()) # super().detail_view can take several seconds due to unoptimized database reads - so lots of # resources get used but ultimately will timeout return Response(status=501)
def get(self, request, *args, **kwargs): """Mixin implementation of django.views.decorators.http.condition""" # Resolve etag and last_modified etag = self.get_etag(request) etag = quote_etag(etag) if etag is not None else None last_modified = self.get_last_modified(request) last_modified = timegm(last_modified.utctimetuple()) if last_modified else None # Check request headers response = get_conditional_response(request, etag=etag, last_modified=last_modified) if response: return response # If we need get new data, do that response = super().get(request, *args, **kwargs) # Set relevant headers on the response if they don't already exist. if last_modified and not response.has_header('Last-Modified'): response['Last-Modified'] = http_date(last_modified) if etag and not response.has_header('ETag'): response['ETag'] = etag return response
def process_response(self, request, response): """ Calculate the ETag, if needed. When the status code of the response is 404, it may redirect to a path with an appended slash if should_redirect_with_slash() returns True. """ # If the given URL is "Not Found", then check if we should redirect to # a path with a slash appended. if response.status_code == 404: if self.should_redirect_with_slash(request): return self.response_redirect_class(self.get_full_path_with_slash(request)) if settings.USE_ETAGS and self.needs_etag(response): warnings.warn( "The USE_ETAGS setting is deprecated in favor of " "ConditionalGetMiddleware which sets the ETag regardless of " "the setting. CommonMiddleware won't do ETag processing in " "Django 2.1.", RemovedInDjango21Warning ) if not response.has_header('ETag'): set_response_etag(response) if response.has_header('ETag'): return get_conditional_response( request, etag=response['ETag'], response=response, ) # Add the Content-Length header to non-streaming responses if not # already set. if not response.streaming and not response.has_header('Content-Length'): response['Content-Length'] = str(len(response.content)) return response
import logging
def not_modified(request, etag=None, last_modified=None): return get_conditional_response( request, etag=etag, last_modified=timegm(last_modified.utctimetuple()) ) is not None
from django.utils.cache import get_conditional_response