This patch release fixes regressions from 2.11.6, including a crash when proxying over HTTP/2 and streams that were cut off after a minute. If you're on 2.11.6, we recommend upgrading. It also adds support for the brand new Incremental header field (RFC 10036).
Huge thank you to our sponsors for keeping the project alive with resources, and for our maintainers who triage and assist tirelessly in this relentless new age of AI.
Highlights
-
Fixed: crash and dropped streams caused by the new idle timeouts. 2.11.6 introduced default idle read/write timeouts, which caused some problems:
-
In 2.11.6, the request body's idle deadline could outlive the handler that set it:
- Over HTTP/2, Caddy could panic with a nil pointer dereference when the reverse proxy was still reading a request body after the handler had returned. (#8101)
- Over HTTP/1.1, streaming responses to requests with a body, such as SSE clients that open the stream with a
POST, were cut off exactly 60 seconds after the body was read. (#8103)
Both are fixed in #8107. Thanks @steadytao!
-
Over HTTP/2, streaming responses that paused between writes for longer than
write_idle(1 minute by default), like quiet SSE streams, were reset with a stream error. As documented, only a write that stalls should count. Thanks @WeidiDeng! (#8118, #8119)
-
-
Fixed: placeholders for missing cookies are empty again. Since 2.11.6, places that keep unknown placeholders as written, like
respondheaders, would output{http.request.cookie.*}literally when the cookie wasn't in the request. The same happened to{http.request.tls.*}on plain HTTP requests. Both are empty again. Thanks @steadytao! (#8019) -
New: support for the
Incrementalheader field (RFC 10036). It's the standard replacement for NGINX's proprietaryX-Accel-Bufferingheader. If an upstream response hasIncremental: ?1,reverse_proxyforwards it immediately, the same asflush_interval -1, andencodestreams it instead of holding it back. Great for Mercure, SSE and other streaming apps.- If the
request_buffersorresponse_buffersoptions would prevent incremental forwarding, Caddy responds with501 Not Implementedinstead of silently buffering, as the RFC requires. - The new
proxy_status_nameoption adds aProxy-Statusheader to those responses, explaining why the message was refused.
- If the
-
Faster TLS handshakes: When nothing subscribes to certificate events and debug logging is off, CertMagic no longer builds event data for every handshake. Certificate lookup per handshake is about twice as fast, with 10 allocations instead of 15. Thanks @u5surf! (#8010)
-
Unix sockets: When a reload moves a listener (or the admin endpoint) off a Unix socket, the old socket now closes right away and its file is removed. Before, clients connecting to the old path would hang until the next garbage collection, about 2 minutes later. Thanks @littfed! (#8061)
-
Headers handler: Multiple
Set-Cookievalues in a JSON config'ssetare now sent as separate header fields, instead of being joined with commas into one field that clients can't parse. Thanks @Indra55! (#8080) -
caddy fmtno longer deletes an opening brace at the very end of the input. Thanks @n0liu! (#8047)
What's Changed
- events: tell CertMagic which events are worth emitting by @u5surf in #8010
- feat: implement the Incremental header field (RFC 10036) by @dunglas in #8020
- caddyfile: Keep an opening brace that ends the input by @n0liu in #8047
- listeners: close unix socket immediately and unlink file on reload by @littfed in #8061
- reverseproxy: stabilise half-close test by @steadytao in #8049
- caddyhttp: keep absent optional placeholders empty by @steadytao in #8019
- headers: Preserve separate Set-Cookie values by @Indra55 in #8080
- caddyhttp: end request-body deadline ownership with handler by @steadytao in #8107
- timeouts: fix idle writer terminate h2 response writers between writes by @WeidiDeng in #8119
New Contributors
Full Changelog: v2.11.6...v2.11.7