gzip middleware support

This commit is contained in:
Martin Nedopil 2024-10-18 13:12:54 +02:00
parent f94f0f5134
commit 491f6c3c3a
2 changed files with 56 additions and 0 deletions

20
docs/middleware/gzip.md Normal file
View file

@ -0,0 +1,20 @@
# Gzip compress middleware
```python
from spiderweb import SpiderwebRouter
app = SpiderwebRouter(
middleware=["spiderweb.middleware.gzip"],
)
```
When your response is big, you maybe want to reduce traffic between
server and client.
Gzip will help you. This middleware do not cover all possibilities of content compress. Brotli, deflate, zsts or other are out of scope.
This version only check if gzip method is accepted by client, size of content is greater than 500 bytes. Check if response is not already compressed and response status is between 200 and 300.
> [!NOTE]
> Minimal required version is 1.3.1

View file

@ -0,0 +1,36 @@
"""
Source code inspiration :https://github.com/colour-science/flask-compress/blob/master/flask_compress/flask_compress.py
"""
from spiderweb.middleware import SpiderwebMiddleware
from spiderweb.request import Request
from spiderweb.response import HttpResponse
import gzip
class GzipMiddleware(SpiderwebMiddleware):
algorithm = "gzip"
minimum_length = 500
def post_process(self, request: Request, response: HttpResponse, rendered_response: str) -> str:
#right status, length > 500, instance string (because FileResponse returns list of bytes ,
# not already compressed, and client accepts gzip
if not (200 <= response.status_code < 300) or \
len(rendered_response) < self.minimum_length or \
not isinstance(rendered_response, str) or \
self.algorithm in response.headers.get("Content-Encoding", "") or \
self.algorithm not in request.headers.get("Accept-Encoding", ""):
return rendered_response
zipped = gzip.compress(rendered_response.encode('UTF-8'))
response.headers["Content-Encoding"] = self.algorithm
response.headers["Content-Length"] = str(len(zipped))
return zipped