httpd-compress
gzip response compression middleware for stdlib/httpd.
An optional module: import it, and declare the tur/zlib spice in your build.tur, and it gzips responses for clients that accept it:
:spices #map{"tur-zlib" #map{:url "https://github.com/turmeric-lang/turmeric-spices"
:ref "v0.1.0" :subdir "spices/zlib"}}
(import httpd-compress :refer [mw-compress mw-compress-with]) (compose-middleware base mw-log mw-compress)
tur/zlib is resolved like any other spice import -- from the program's declared :spices or its workspace -- so this works from an installed toolchain. It used to (load) the spice by a path relative to the turmeric checkout (../turmeric-spices/...), which resolved only in a side-by-side clone (tourist-on-stdlib-httpd-plan risk 5).
Layers on top of the M0 response-header surface (httpd-resp-header! / httpd-req-header) and the M6 binary-body setter httpd-resp-body-bytes!.
tourist-on-stdlib-httpd H4
Since: Phase H8 (M6); a module importing tur/zlib since
httpd-mw-compress-step
(httpd-mw-compress-step [conn :ptr<void> min-bytes :int] :nil)
internal: post-processing gzip pass.
When the client accepts gzip AND the response is not already encoded AND the body is at least min-bytes, gzip the body (tur/zlib) and set Content-Encoding: gzip and Vary: Accept-Encoding. Otherwise a no-op.
Since: Phase H8 (M6)
mw-compress-with
(mw-compress-with [min-bytes :int ^fat next :(fn [ptr<void>] nil)] :ptr<void>)
gzip the response body when the client accepts gzip.
Inspects Accept-Encoding for "gzip"; when present AND the response body length exceeds min-bytes AND the response is not already compressed, gzips the body via tur/zlib, sets Content-Encoding: gzip + Vary: Accept-Encoding, and rewrites the response body to the compressed bytes. Content-Length is recomputed by the writer from the new resp_body_len. Other paths pass through unchanged.
Skips entries whose handler already set a Content-Encoding header (preserves caller intent; do not double-gzip).
Should be installed as the OUTERMOST post-processing middleware so it sees the final body produced by the handler + any inner middleware.
| min-bytes | minimum response body size to compress (typical: 256) | |
| next | downstream handler closure (fat-closure :int) |
A wrapped handler closure (:ptr<void>) suitable for httpd-new / compose-middleware.
(compose-middleware base mw-log (mw-compress-with 256))
Since: Phase H8 (M6)
mw-compress
(mw-compress [^fat next :(fn [ptr<void>] nil)] :ptr<void>)
mw-compress-with default 256-byte threshold.
(mw-compress next) is equivalent to (mw-compress-with 256 next).
(compose-middleware base mw-log mw-compress)
Since: Phase H8 (M6)
Internal definitions
httpd-mw-compress-wanted?-- internal: should this response be gzipped?httpd-mw-compress-body-- internal: the response body and its length,httpd-mw-compress-body-lenhttpd-mw-compress-null?