gzip middleware support
This commit is contained in:
parent
f94f0f5134
commit
491f6c3c3a
2 changed files with 56 additions and 0 deletions
20
docs/middleware/gzip.md
Normal file
20
docs/middleware/gzip.md
Normal 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
|
||||
|
36
spiderweb/middleware/gzip.py
Normal file
36
spiderweb/middleware/gzip.py
Normal 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
|
||||
|
Loading…
Add table
Reference in a new issue