Skip to content

Commit

Permalink
Update middleware to support streams.
Browse files Browse the repository at this point in the history
Created a new method to support streams. Also updated the initial if statement to support streams.
  • Loading branch information
shreyas44 committed Jun 11, 2020
1 parent cd70b60 commit 717e56c
Showing 1 changed file with 25 additions and 8 deletions.
33 changes: 25 additions & 8 deletions django_brotli/middleware.py
Expand Up @@ -28,8 +28,8 @@ class BrotliMiddleware(MiddlewareMixin):
"""

def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse:
if (response.streaming or response.has_header('Content-Encoding') or
not self._accepts_brotli_encoding(request) or len(response.content) < MIN_LEN_FOR_RESPONSE_TO_PROCESS):
if (not response.streaming and (response.has_header('Content-Encoding') or
not self._accepts_brotli_encoding(request) or len(response.content) < MIN_LEN_FOR_RESPONSE_TO_PROCESS)):
# ---------
# 1) brotlipy doesn't support streaming compression, see: https://github.com/google/brotli/issues/191
# 2) Avoid brotli if we've already got a content-encoding.
Expand All @@ -40,14 +40,24 @@ def process_response(self, request: HttpRequest, response: HttpResponse) -> Http
return response

patch_vary_headers(response, ('Accept-Encoding',))
compressed_content = brotli.compress(response.content)

# Return the compressed content only if it's actually shorter.
if len(compressed_content) >= len(response.content):
return response
if response.streaming:
compressed_content = self.compress_stream(response.streaming_content)
response.streaming_content = compressed_content

# Delete the `Content-Length` header for streaming content, because
# we won't know the compressed size until we stream it.
del response['Content-Length']
else:
compressed_content = brotli.compress(response.content)

#Return the compressed content only if it's actually shorter.
if len(compressed_content) >= len(response.content):
return response

response.content = compressed_content
response['Content-Length'] = str(len(response.content))
response.content = compressed_content
response['Content-Length'] = str(len(compressed_content))


if response.has_header('ETag'):
response['ETag'] = re.sub(r"\"$", r";br\"", response['ETag'])
Expand All @@ -56,6 +66,13 @@ def process_response(self, request: HttpRequest, response: HttpResponse) -> Http

return response

def compress_stream(self, streaming_content):
streaming_content = [line.decode('utf-8') for line in list(streaming_content)]
streaming_content = ''.join(streaming_content).encode()
streaming_content = map(lambda x: x, [brotli.compress(streaming_content)])

return streaming_content

# noinspection PyMethodMayBeStatic
def _accepts_brotli_encoding(self, request: HttpRequest) -> bool:
return bool(RE_ACCEPT_ENCODING_BROTLI.search(request.META.get('HTTP_ACCEPT_ENCODING', '')))

0 comments on commit 717e56c

Please sign in to comment.