gzip
Compresses context.response.body with gzip. It is a response-phase node — place it after upstream (and after any body-mutating node such as response-rewrite), before client. The node performs both the request's Accept-Encoding check and the compression itself, in process.
Configuration
All keys are optional.
| Key | Type | Default | Description |
|---|---|---|---|
types | array of strings, or "*" | ["text/html"] | Response content types to compress. "*" matches any. The response content-type is compared with parameters (;charset=...) stripped. A response without a content-type header is never compressed. |
min_length | integer ≥ 1 | 20 | Bodies shorter than this many bytes are not compressed. |
comp_level | integer 1-9 | 1 | gzip compression level. |
vary | bool | false | When true, appends Vary: Accept-Encoding to compressed responses. |
type: gzip
config:
types: ["text/html", "application/json"]
min_length: 20
comp_level: 6
vary: true
Out-of-range levels, min_length: 0, an empty types array, or a types string other than "*" are rejected at config load.
Behavior
This plugin never fails at execution time — it always exits through the success port. The response passes through unchanged when any of these hold:
- the request's
Accept-Encodingdoes not allow gzip — the token (or*) must be listed with a non-zeroqvalue; a missing header means no compression; - the response already carries a
content-encoding(never compress twice, and never compress opaque pre-encoded bytes — even for encodings featherbit does not know); - the response
content-typeis absent or does not matchtypes; - the body is shorter than
min_length.
Otherwise the body is gzip-compressed at comp_level, content-encoding: gzip is set, the stale content-length is removed (the server layer recomputes it from the compressed body), and Vary: Accept-Encoding is appended when vary is set. A codec failure logs a warning and leaves the response untouched.
Behavior notes: http_version and buffers are not supported (featherbit responses are fully buffered), and min_length is compared against the actual buffered body length rather than the upstream Content-Length header. Unlike the brotli node, the gzip node does not weaken ETag headers.
The plugin does not read or write context.message or context.errors.
Errors
This node never fails at execution time: it always returns through success, so its error port is never taken.