Beispiel #1
0
    def process_response(self, request, response):

        # Cache the response if all the required conditions are met.
        # Response must be marked for updating by the
        # ``FetchFromCacheMiddleware`` having a cache get miss, the
        # user must not be authenticated, the HTTP status must be OK
        # and the response mustn't include an expiry age, incicating it
        # shouldn't be cached.
        marked_for_update = getattr(request, "_update_cache", False)
        anon = hasattr(request, "user") and not request.user.is_authenticated()
        valid_status = response.status_code == 200
        timeout = get_max_age(response)
        if timeout is None:
            timeout = settings.CACHE_MIDDLEWARE_SECONDS
        if anon and valid_status and marked_for_update and timeout:
            cache_key = cache_key_prefix(request) + request.get_full_path()
            _cache_set = lambda r: cache_set(cache_key, r.content, timeout)
            if callable(getattr(response, "render", None)):
                response.add_post_render_callback(_cache_set)
            else:
                _cache_set(response)

        # Second phase rendering for non-cached template code and
        # content. Split on the delimiter the ``nevercache`` tag
        # wrapped its contents in, and render only the content
        # enclosed by it, to avoid possible template code injection.
        token = nevercache_token()
        try:
            token = token.encode('utf-8')
        except AttributeError:
            pass
        parts = response.content.split(token)
        content_type = response.get("content-type", "")
        if content_type.startswith("text") and len(parts) > 1:
            # Restore csrf token from cookie - check the response
            # first as it may be being set for the first time.
            csrf_token = None
            try:
                csrf_token = response.cookies[settings.CSRF_COOKIE_NAME].value
            except KeyError:
                try:
                    csrf_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
                except KeyError:
                    pass
            if csrf_token:
                request.META["CSRF_COOKIE"] = csrf_token
            context = RequestContext(request)
            for i, part in enumerate(parts):
                if i % 2:
                    part = Template(part).render(context).encode("utf-8")
                parts[i] = part
            response.content = b"".join(parts)
            response["Content-Length"] = len(response.content)
            if hasattr(request, '_messages'):
                # Required to clear out user messages.
                request._messages.update(response)
        return response
Beispiel #2
0
    def process_response(self, request, response):

        # Cache the response if all the required conditions are met.
        # Response must be marked for updating by the
        # ``FetchFromCacheMiddleware`` having a cache get miss, the
        # user must not be authenticated, the HTTP status must be OK
        # and the response mustn't include an expiry age, incicating it
        # shouldn't be cached.
        marked_for_update = getattr(request, "_update_cache", False)
        anon = hasattr(request, "user") and not request.user.is_authenticated()
        valid_status = response.status_code == 200
        timeout = get_max_age(response)
        if timeout is None:
            timeout = settings.CACHE_MIDDLEWARE_SECONDS
        if anon and valid_status and marked_for_update and timeout:
            cache_key = cache_key_prefix(request) + request.get_full_path()
            _cache_set = lambda r: cache_set(cache_key, r.content, timeout)
            if callable(getattr(response, "render", None)):
                response.add_post_render_callback(_cache_set)
            else:
                _cache_set(response)

        # Second phase rendering for non-cached template code and
        # content. Split on the delimiter the ``nevercache`` tag
        # wrapped its contents in, and render only the content
        # enclosed by it, to avoid possible template code injection.
        token = nevercache_token()
        try:
            token = token.encode('utf-8')
        except AttributeError:
            pass
        parts = response.content.split(token)
        content_type = response.get("content-type", "")
        if content_type.startswith("text") and len(parts) > 1:
            # Restore csrf token from cookie - check the response
            # first as it may be being set for the first time.
            csrf_token = None
            try:
                csrf_token = response.cookies[settings.CSRF_COOKIE_NAME].value
            except KeyError:
                try:
                    csrf_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
                except KeyError:
                    pass
            if csrf_token:
                request.META["CSRF_COOKIE"] = csrf_token
            context = RequestContext(request)
            for i, part in enumerate(parts):
                if i % 2:
                    part = Template(part).render(context).encode("utf-8")
                parts[i] = part
            response.content = b"".join(parts)
            response["Content-Length"] = len(response.content)
            if hasattr(request, '_messages'):
                # Required to clear out user messages.
                request._messages.update(response)
        return response
Beispiel #3
0
 def nevercache(parser, token):
     """
     Tag for two phased rendering. Converts enclosed template
     code and content into text, which gets rendered separately
     in ``mezzanine.core.middleware.UpdateCacheMiddleware``.
     This is to bypass caching for the enclosed code and content.
     """
     text = []
     end_tag = "endnevercache"
     tag_mapping = {
         TOKEN_TEXT: ("", ""),
         TOKEN_VAR: ("{{", "}}"),
         TOKEN_BLOCK: ("{%", "%}"),
         TOKEN_COMMENT: ("{#", "#}"),
     }
     delimiter = nevercache_token()
     while parser.tokens:
         token = parser.next_token()
         if token.token_type == TOKEN_BLOCK and token.contents == end_tag:
             return TextNode(delimiter + "".join(text) + delimiter)
         start, end = tag_mapping[token.token_type]
         text.append("%s%s%s" % (start, token.contents, end))
     parser.unclosed_block_tag(end_tag)
Beispiel #4
0
 def nevercache(parser, token):
     """
     Tag for two phased rendering. Converts enclosed template
     code and content into text, which gets rendered separately
     in ``mezzanine.core.middleware.UpdateCacheMiddleware``.
     This is to bypass caching for the enclosed code and content.
     """
     text = []
     end_tag = "endnevercache"
     tag_mapping = {
         TOKEN_TEXT: ("", ""),
         TOKEN_VAR: ("{{", "}}"),
         TOKEN_BLOCK: ("{%", "%}"),
         TOKEN_COMMENT: ("{#", "#}"),
     }
     delimiter = nevercache_token()
     while parser.tokens:
         token = parser.next_token()
         if token.token_type == TOKEN_BLOCK and token.contents == end_tag:
             return TextNode(delimiter + "".join(text) + delimiter)
         start, end = tag_mapping[token.token_type]
         text.append("%s%s%s" % (start, token.contents, end))
     parser.unclosed_block_tag(end_tag)
Beispiel #5
0
    def process_response(self, request, response):

        # Caching is only applicable for text-based, non-streaming
        # responses. We also skip it for non-200 statuses during
        # development, so that stack traces are correctly rendered.
        is_text = response.get("content-type", "").startswith("text")
        valid_status = response.status_code == 200
        streaming = getattr(response, "streaming", False)
        if not is_text or streaming or (settings.DEBUG and not valid_status):
            return response

        # Cache the response if all the required conditions are met.
        # Response must be marked for updating by the
        # ``FetchFromCacheMiddleware`` having a cache get miss, the
        # user must not be authenticated, the HTTP status must be OK
        # and the response mustn't include an expiry age, indicating it
        # shouldn't be cached.
        marked_for_update = getattr(request, "_update_cache", False)
        anon = hasattr(request, "user") and not is_authenticated(request.user)
        timeout = get_max_age(response)
        if timeout is None:
            timeout = settings.CACHE_MIDDLEWARE_SECONDS
        if anon and valid_status and marked_for_update and timeout:
            cache_key = cache_key_prefix(request) + request.get_full_path()
            _cache_set = lambda r: cache_set(cache_key, r.content, timeout)
            if callable(getattr(response, "render", None)):
                response.add_post_render_callback(_cache_set)
            else:
                _cache_set(response)

        # Second phase rendering for non-cached template code and
        # content. Split on the delimiter the ``nevercache`` tag
        # wrapped its contents in, and render only the content
        # enclosed by it, to avoid possible template code injection.
        token = nevercache_token()
        try:
            token = token.encode('utf-8')
        except AttributeError:
            pass
        parts = response.content.split(token)
        # Restore csrf token from cookie - check the response
        # first as it may be being set for the first time.
        csrf_token = None
        try:
            csrf_token = response.cookies[settings.CSRF_COOKIE_NAME].value
        except KeyError:
            try:
                csrf_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
            except KeyError:
                pass
        if csrf_token:
            request.META["CSRF_COOKIE"] = csrf_token
        context = RequestContext(request)
        for i, part in enumerate(parts):
            if i % 2:
                part = Template(part).render(context).encode("utf-8")
            parts[i] = part
        response.content = b"".join(parts)
        response["Content-Length"] = len(response.content)
        if hasattr(request, '_messages'):
            # Required to clear out user messages.
            request._messages.update(response)
        # Response needs to be run-through the CSRF middleware again so
        # that if there was a {% csrf_token %} inside of the nevercache
        # the cookie will be correctly set for the the response
        csrf_mw_name = "django.middleware.csrf.CsrfViewMiddleware"
        if csrf_mw_name in get_middleware_setting():
            response.csrf_processing_done = False
            csrf_mw = CsrfViewMiddleware()
            csrf_mw.process_response(request, response)
        return response
Beispiel #6
0
    def process_response(self, request, response):

        # Caching is only applicable for text-based, non-streaming
        # responses. We also skip it for non-200 statuses during
        # development, so that stack traces are correctly rendered.
        is_text = response.get("content-type", "").startswith("text")
        valid_status = response.status_code == 200
        streaming = getattr(response, "streaming", False)
        if not is_text or streaming or (settings.DEBUG and not valid_status):
            return response

        # Cache the response if all the required conditions are met.
        # Response must be marked for updating by the
        # ``FetchFromCacheMiddleware`` having a cache get miss, the
        # user must not be authenticated, the HTTP status must be OK
        # and the response mustn't include an expiry age, indicating it
        # shouldn't be cached.
        marked_for_update = getattr(request, "_update_cache", False)
        anon = hasattr(request, "user") and not request.user.is_authenticated()
        timeout = get_max_age(response)
        if timeout is None:
            timeout = settings.CACHE_MIDDLEWARE_SECONDS
        if anon and valid_status and marked_for_update and timeout:
            cache_key = cache_key_prefix(request) + request.get_full_path()
            _cache_set = lambda r: cache_set(cache_key, r.content, timeout)
            if callable(getattr(response, "render", None)):
                response.add_post_render_callback(_cache_set)
            else:
                _cache_set(response)

        # Second phase rendering for non-cached template code and
        # content. Split on the delimiter the ``nevercache`` tag
        # wrapped its contents in, and render only the content
        # enclosed by it, to avoid possible template code injection.
        token = nevercache_token()
        try:
            token = token.encode('utf-8')
        except AttributeError:
            pass
        parts = response.content.split(token)
        # Restore csrf token from cookie - check the response
        # first as it may be being set for the first time.
        csrf_token = None
        try:
            csrf_token = response.cookies[settings.CSRF_COOKIE_NAME].value
        except KeyError:
            try:
                csrf_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
            except KeyError:
                pass
        if csrf_token:
            request.META["CSRF_COOKIE"] = csrf_token
        context = RequestContext(request)
        for i, part in enumerate(parts):
            if i % 2:
                part = Template(part).render(context).encode("utf-8")
            parts[i] = part
        response.content = b"".join(parts)
        response["Content-Length"] = len(response.content)
        if hasattr(request, '_messages'):
            # Required to clear out user messages.
            request._messages.update(response)
        # Response needs to be run-through the CSRF middleware again so
        # that if there was a {% csrf_token %} inside of the nevercache
        # the cookie will be correctly set for the the response
        csrf_mw_name = "django.middleware.csrf.CsrfViewMiddleware"
        if csrf_mw_name in MIDDLEWARE_SETTING:
            response.csrf_processing_done = False
            csrf_mw = CsrfViewMiddleware()
            csrf_mw.process_response(request, response)
        return response