Compress responses
The compress middleware since v0.1 compresses responses with gzip when the client
accepts it. HTML, CSS, JavaScript and JSON usually shrink to a fraction of their size.
Brotli and zstd are planned for v0.4.
Before you start
Section titled “Before you start”If your backend already compresses its responses, you do not need this middleware: responses
that already have a Content-Encoding are passed on unchanged.
Configure the middleware
Section titled “Configure the middleware”listeners: web: { address: ":80" } websecure: { address: ":443", tls: {} }
certificates: example: cert_file: /etc/rdock/certs/example.pem key_file: /etc/rdock/certs/example.key
routes: app: match: "Host(`app.example.com`)" service: app middlewares: [gzip]
services: app: backends: [{ address: "app:3000" }]
middlewares: gzip: type: compress| Setting | Default | Meaning |
|---|---|---|
algorithms |
[gzip] |
Algorithms offered. Only gzip works in this version. |
min_size |
1KiB |
Responses whose Content-Length is smaller are not compressed. |
content_types |
built-in list | Media types to compress. Setting it replaces the built-in list. |
br and zstd are accepted by the configuration model, but in this version rdock validate
reports them as “brotli and zstd compression: not supported in this version (planned for
v0.4)”, and rdock run refuses the configuration until you remove them.
Which responses are compressed
Section titled “Which responses are compressed”Compression uses an allow-list of media types. When content_types is empty, these are
compressed:
text/*, application/json, application/javascript, application/x-javascript,
application/xml, application/xhtml+xml, application/rss+xml, application/atom+xml,
application/ld+json, application/manifest+json, application/vnd.api+json,
application/wasm, image/svg+xml, font/ttf, font/otf.
In your own list, type/* covers a whole type, for example text/*. Parameters such as
; charset=utf-8 are ignored when comparing.
A response is left as it is when any of these holds:
- It is a server-sent event stream (
text/event-stream) or gRPC (application/grpc…). These are never compressed, even if your list includes them, because buffering would break them. - It answers a
HEADrequest. - Its status is 1xx, 204, 206 (partial content) or 304, or it has a
Content-Range. - It already has a
Content-Encodingother thanidentity. - Its
Content-Lengthis belowmin_size. A response without a length, for example a chunked stream, is compressed when its type allows it. - The client’s
Accept-Encodingdoes not accept gzip.gzip,x-gzipand*count, and aq=0value means “not accepted”.
What changes on a compressed response
Section titled “What changes on a compressed response”Content-Encoding: gzipis set;Content-LengthandAccept-Rangesare removed.- A strong
ETagbecomes weak (W/"…"), because the bytes differ from the uncompressed ones. Vary: Accept-Encodingis added to every response that could have been compressed, also when this client did not ask for gzip, so caches keep the two versions apart.- The body is compressed chunk by chunk as it arrives, so long responses keep flowing.
Check that it worked
Section titled “Check that it worked”curl -s -o /dev/null -D - -H 'Accept-Encoding: gzip' https://app.example.com/For an HTML page of 1 KiB or more the response headers include Content-Encoding: gzip and
vary: Accept-Encoding. Without the Accept-Encoding header, the same request returns the
uncompressed page with vary: Accept-Encoding only.