mirror of
https://github.com/django/django.git
synced 2025-05-07 23:46:30 +00:00
It prevented the GZipMiddleware from compressing some data types even on more recent version of IE where the corresponding bug was fixed. Thanks Aaron Cannon for the report and Tim Graham for the review.
48 lines
1.8 KiB
Python
48 lines
1.8 KiB
Python
import re
|
|
|
|
from django.utils.text import compress_sequence, 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 attempting to compress really short responses.
|
|
if not response.streaming and len(response.content) < 200:
|
|
return response
|
|
|
|
# Avoid gzipping if we've already got a content-encoding.
|
|
if response.has_header('Content-Encoding'):
|
|
return response
|
|
|
|
patch_vary_headers(response, ('Accept-Encoding',))
|
|
|
|
ae = request.META.get('HTTP_ACCEPT_ENCODING', '')
|
|
if not re_accepts_gzip.search(ae):
|
|
return response
|
|
|
|
if response.streaming:
|
|
# Delete the `Content-Length` header for streaming content, because
|
|
# we won't know the compressed size until we stream it.
|
|
response.streaming_content = compress_sequence(response.streaming_content)
|
|
del response['Content-Length']
|
|
else:
|
|
# Return the compressed content only if it's actually shorter.
|
|
compressed_content = compress_string(response.content)
|
|
if len(compressed_content) >= len(response.content):
|
|
return response
|
|
response.content = compressed_content
|
|
response['Content-Length'] = str(len(response.content))
|
|
|
|
if response.has_header('ETag'):
|
|
response['ETag'] = re.sub('"$', ';gzip"', response['ETag'])
|
|
response['Content-Encoding'] = 'gzip'
|
|
|
|
return response
|