1 import re
2
3 from django.utils.text import compress_string
4 from django.utils.cache import patch_vary_headers
5
6 re_accepts_gzip = re.compile(r'\bgzip\b')
7
9 """
10 This middleware compresses content if the browser allows gzip compression.
11 It sets the Vary header accordingly, so that caches will base their storage
12 on the Accept-Encoding header.
13 """
15
16
17 if response.status_code != 200 or len(response.content) < 8192:
18 return response
19
20
21 if response.has_header('Content-Encoding'):
22 return response
23
24
25 ctype = response.get('Content-Type', '').lower()
26 if not "javascript" in ctype and not "text" in ctype:
27 return response
28
29 patch_vary_headers(response, ('Accept-Encoding',))
30
31
32 if response.has_header('Content-Encoding'):
33 return response
34
35
36
37 if "msie" in request.META.get('HTTP_USER_AGENT', '').lower():
38 ctype = response.get('Content-Type', '').lower()
39 if "javascript" in ctype or ctype == "application/pdf":
40 return response
41
42 ae = request.META.get('HTTP_ACCEPT_ENCODING', '')
43 if not re_accepts_gzip.search(ae):
44 return response
45
46 response.content = compress_string(response.content)
47 response['Content-Encoding'] = 'gzip'
48 response['Content-Length'] = str(len(response.content))
49 return response
50