Beispiel #1
0
 def _get_conditional_response(self, request, etag, last_modified):
     """Mimics ConditionalGetMiddleware"""
     return get_conditional_response(
         request,
         etag=etag,
         last_modified=last_modified,
     )
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
        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
Beispiel #5
0
        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
Beispiel #7
0
        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
Beispiel #8
0
        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
Beispiel #9
0
    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
Beispiel #10
0
 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
Beispiel #11
0
    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
Beispiel #12
0
        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
Beispiel #13
0
    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
Beispiel #14
0
    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
Beispiel #15
0
        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
Beispiel #16
0
        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
Beispiel #17
0
    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
Beispiel #18
0
 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
Beispiel #19
0
 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,
     )
Beispiel #20
0
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
Beispiel #21
0
 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
Beispiel #22
0
 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
Beispiel #23
0
    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)
Beispiel #24
0
    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
Beispiel #25
0
 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
Beispiel #26
0
        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
Beispiel #27
0
    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)
Beispiel #29
0
    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
Beispiel #30
0
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
Beispiel #31
0
    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)
Beispiel #32
0
    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
Beispiel #33
0
    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
Beispiel #34
0
    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
Beispiel #35
0
    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)
Beispiel #36
0
    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
Beispiel #38
0
import logging
Beispiel #39
0
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
Beispiel #40
0
from django.utils.cache import get_conditional_response