app/django/middleware/gzip.py
author Todd Larsen <tlarsen@google.com>
Thu, 25 Sep 2008 17:17:11 +0000
changeset 202 b8b4a83788d4
parent 54 03e267d67478
permissions -rw-r--r--
A key_name controller module to collect all of the name...() functions that compose Model entity key names, plus some minor changes to other controller modules to illustrate the proposed use. Patch by: Todd Larsen Review by: Pawel Solyga Review URL: http://codereviews.googleopensourceprograms.com/804 Review URL: http://codereviews.googleopensourceprograms.com/804

import re

from django.utils.text import compress_string
from django.utils.cache import patch_vary_headers

re_accepts_gzip = re.compile(r'\bgzip\b')

class GZipMiddleware(object):
    """
    This middleware compresses content if the browser allows gzip compression.
    It sets the Vary header accordingly, so that caches will base their storage
    on the Accept-Encoding header.
    """
    def process_response(self, request, response):
        # It's not worth compressing non-OK or really short responses.
        if response.status_code != 200 or len(response.content) < 200:
            return response

        patch_vary_headers(response, ('Accept-Encoding',))

        # Avoid gzipping if we've already got a content-encoding.
        if response.has_header('Content-Encoding'):
            return response

        # Older versions of IE have issues with gzipped pages containing either
        # Javascript and PDF.
        if "msie" in request.META.get('HTTP_USER_AGENT', '').lower():
            ctype = response.get('Content-Type', '').lower()
            if "javascript" in ctype or ctype == "application/pdf":
                return response

        ae = request.META.get('HTTP_ACCEPT_ENCODING', '')
        if not re_accepts_gzip.search(ae):
            return response

        response.content = compress_string(response.content)
        response['Content-Encoding'] = 'gzip'
        response['Content-Length'] = str(len(response.content))
        return response