Merge pull request #5 from martinnedopil/gzip

Gzip Middleware
This commit is contained in:
Joe Kaufeld 2024-10-30 00:33:37 -04:00 committed by GitHub
commit 0cd1bed62c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 57 additions and 0 deletions

View file

@ -9,5 +9,6 @@
- [csrf](middleware/csrf.md)
- [cors](middleware/cors.md)
- [pydantic](middleware/pydantic.md)
- [gizp](middleware/gzip.md)
- [writing your own](middleware/custom_middleware.md)
- [databases](db.md)

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