Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encode: Add zstd compression level support #6140

Merged
merged 10 commits into from
Apr 16, 2024

Conversation

dev-polymer
Copy link
Contributor

Its changes adds support zstd encoder ability to spicify compression level like is able for Gzip (and for brotli via ueffel/caddy-brotli module).

The solution appeared as a continuation of this conversation on the caddy community forum/

Notices:

  • Only for levels 1,2,3,4 supported beacuse its only supported in used zstd library and focusing on the fact that in encode gzip and brotli we can set up a different number of levels, I consider a suitable solution with the ability to configure only 4 levels
  • Without explicitly specifying a level or specifying 0, the default level 2 will be selected
  • Buffer size zstd.WithWindowSize(128<<10) is hadrcoded as before and when i try delete and trust the automatic buffer selection in the library algorithm — i have compression error in Chrome: ERR_CONTENT_DECODING on CSS files. I think no hardcode in buffer size could be logical, but if it not stabe working, it seems like a good idea to move buffer size feature to a separate task, but i make test with hardcoded zstd.WithWindowSize(512<<10) value just for intrest, and it is working ok:
    image
    ...and compress even better, but my knowledge of compression is insufficient for an informed choice of best level.

I have been running tests of this solution on a fully functional multipage website in the Chrome v122 browser.

@CLAassistant
Copy link

CLAassistant commented Mar 1, 2024

CLA assistant check
All committers have signed the CLA.

@@ -27,7 +30,9 @@ func init() {
}

// Zstd can create Zstandard encoders.
type Zstd struct{}
type Zstd struct {
Level zstd.EncoderLevel `json:"level,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add a godoc comment here to explain the possible options.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally we should built-in or caddy defined type to configure a plugin. We should use string to specify the level and check if it's one of the possible values provided by zstd.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Level should be just string. We can use a private member to specify the actual level used with type zstd.EncoderLevel.

@francislavoie francislavoie added the feature ⚙️ New feature or request label Mar 1, 2024
@francislavoie francislavoie added this to the v2.8.0 milestone Mar 1, 2024
@francislavoie francislavoie changed the title Add zstd compression level support encode: Add zstd compression level support Mar 1, 2024
@francislavoie
Copy link
Member

Please remember to sign the CLA - you might need to update your emails on your github account to match your commit, or you should update your local git config to use the correct email, and rewrite the commit's email.

Copy link
Member

@WeidiDeng WeidiDeng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To convert string to levels we can use this function.

modules/caddyhttp/encode/zstd/zstd.go Outdated Show resolved Hide resolved

// Validate validates g's configuration.
func (g Zstd) Validate() error {
if g.Level < zstd.SpeedFastest {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although their values are from 1 to 4, we shouldn't rely on this behaviour. They are defined as iota.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why gzip can check for number range is because the level is given explicitly as a number. But zstd only provides 4 constants.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would you suggest we do it then @WeidiDeng?

Copy link
Contributor Author

@dev-polymer dev-polymer Mar 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WeidiDeng , you are mostly right, but let me some explaination. I mean usage of text constants not matches caddyfile's code-style and other encoder algo's compression levels (1-9 for gzip and 1-11 for brotli).

I think about another realization, and propose for appeal to original zstd levels, not library approximation. It is 1 to 22 (or 1 to 19, excludes --ultra levels which recommended to carefull usage).

But if we implement library's way to transform caddyfile's levels to zstd levels, we will have the option to specify the level 6,7,8,9 and it will be the same value (for the current version of the used library). And it will surprise the user and it will seem that changing the level does not work (in some ranges).

Perhaps such a solution will be more universal for the long term, but now it will introduce a little confusion and crutchiness in the configuration. And even more then little: if I specify level 9 today, I will get a conditionally N% CPU load, then if the library implements level 9 to more powerfull compression, perhaps the CPU load will increase by a multiple, for example 3x N%, which may be an unpleasant surprise for a user who has updated the caddy in the future.

This is reason, why i chose to offer a version with 4 levels...

Finally, i think the best solution would be allow user to specify levels from 1 to 22 (refer to original Zstandart levels), convert it with library's method and may be we may need to specify in the documentation (or even caddy warning logs) that the recommended and future safe operating zstd levels should be 1, 3, 6 and 10 now.

WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use the strings/named options for zstd, I don't think that's weird. We can simply document them. We use named options in many places in the Caddyfile.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed new commit now, but my tests show error when level is not set in CaddyFile:

//Test results (with default 128kb zstd buffer) of 585kb minified uncompressed CSS-file
zstd (level not set) → ERR_HTTP2_PROTOCOL_ERROR (Chrome v122 browser error)
zstd fastest → 337kb 
zstd default → 294kb
zstd better → 290kb
zstd best → 286kb

Please friends suggest how to fix 😳

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably need to set a default in Provision

@mholt
Copy link
Member

mholt commented Mar 5, 2024

I can do a review as soon as the CLA is signed 😊

@francislavoie
Copy link
Member

The CLA still isn't happy, because your first commit used an email address not attached to your GitHub account.

Please rewrite the commits to change the email address on the first commit (google it, it's a simple enough operation to perform) then force-push your branch.

@dev-polymer dev-polymer force-pushed the feature/zstd_compression_level branch from 48a68c3 to 8c143e1 Compare March 6, 2024 18:11
@francislavoie francislavoie force-pushed the feature/zstd_compression_level branch from 8c143e1 to 523a531 Compare March 6, 2024 18:52
Copy link
Member

@francislavoie francislavoie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! We can merge once @WeidiDeng's feedback is addressed

fastest, default, better, best
modules/caddyhttp/encode/zstd/zstd.go Show resolved Hide resolved
@@ -27,7 +30,9 @@ func init() {
}

// Zstd can create Zstandard encoders.
type Zstd struct{}
type Zstd struct {
Level zstd.EncoderLevel `json:"level,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Level should be just string. We can use a private member to specify the actual level used with type zstd.EncoderLevel.

modules/caddyhttp/encode/zstd/zstd.go Outdated Show resolved Hide resolved
Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WeidiDeng How about now? I'm good with this if you are. 👍

@mholt mholt enabled auto-merge (squash) April 15, 2024 23:46
@polarathene
Copy link

polarathene commented Apr 16, 2024

  • Only for levels 1,2,3,4 supported beacuse its only supported in used zstd library and focusing on the fact that in encode gzip and brotli we can set up a different number of levels, I consider a suitable solution with the ability to configure only 4 levels

Will that documentation be visible/linked for the equivalent Caddy docs on the values? For those that are familiar with zstd elsewhere it's useful to have some context on what they map to without having to hunt for the information on Github :)


  • Buffer size zstd.WithWindowSize(128<<10) is hadrcoded as before and when i try delete and trust the automatic buffer selection in the library algorithm — i have compression error in Chrome: ERR_CONTENT_DECODING on CSS files. I think no hardcode in buffer size could be logical, but if it not stabe working, it seems like a good idea to move buffer size feature to a separate task, but i make test with hardcoded zstd.WithWindowSize(512<<10) value just for intrest, and it is working ok

This may vary by client, but Chrome is following guidance from RFC 8878 to limit the buffer window size to 8MB: https://issues.chromium.org/issues/40196713#comment31

Prevent OoM condition by restricting maximum window size

Unlike gzip or Brotli where the maximum window size is fixed (32KB
for zlib and 16MB for brotli
, see RFC1952 and RFC7932), zstd
allows much bigger window sizes (up to 3.75TB, see RFC8878).

This potentially exposes a user agent if the response to a request
leverages a payload with a request for a very large window descriptor.

Fortunately, the RFC8878 authors already addressed the potential issue
by allowing a user agent to 'reject a compressed frame that requires
a memory size beyond the decoder's authorized range.

The current change remedies this issue by setting a maximum allowed
window size, limiting the buffer size to 8MB as suggested by RFC8878.

https://issues.chromium.org/issues/41493659#comment4

I reproduced the issue, and it seems the decompression fails with the error code 16, which is "Frame requires too much memory for decoding".
For memory usage reasons, Chromium limits the window size to 8MB whereas curl and directly using zstd does not have that constraint.
You can most likely use https://pkg.go.dev/github.com/klauspost/compress/zstd#WithWindowSize with anything less than 1<<23, and it should fix the issue.

@mholt mholt merged commit 03e0a01 into caddyserver:master Apr 16, 2024
25 checks passed
@mholt
Copy link
Member

mholt commented Apr 16, 2024

@polarathene

Will that documentation be visible/linked for the equivalent Caddy docs on the values? For those that are familiar with zstd elsewhere it's useful to have some context on what they map to without having to hunt for the information on Github :)

Yes, our docs will explain what the possible values are, but the zstd lib we use recommends we use only those constants as the underlying meaning may change 🤷‍♂️

@polarathene
Copy link

zstd lib we use recommends we use only those constants as the underlying meaning may change 🤷‍♂️

Ah ok I see that after looking into the package docs. It supports int levels that are more familiar for zstd config but maps to the nearest supported constant mode the package offers instead.

This was already discussed earlier above, but I disagree with the conclusion since the constant modes are also subject to change just as much, so the ordinal mapping which can be more familiar should be roughly equivalent if it's maintained alongside those changes? 🤷‍♂️

It's true that the ordinal mapping would be a bit confusing without that knowledge, due to the mapped ranges producing the same output and potential for future updates to shift those range bounds. I think linking to this part of the package README might be relevant to get an approximation of the ordinal mapping that each constant mode is roughly equivalent to (assuming it's kept up to date).


The README reference also follows with a performance comparison to the CGO package (datadog/zstd) which shows notable overhead from klauspost/compress zstd implementation.

I've seen for brotli there are two external packages/modules, one that is pure Go and another that requires CGO enabled during build, but I'm not sure how feasible / compatible a zstd CGO alternative would be since unlike brotli support Caddy has official zstd already with the encode directive 😅

github-merge-queue bot pushed a commit to chezmoi-sh/atlas that referenced this pull request Jun 2, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Update | Change | OpenSSF |
|---|---|---|---|
| [caddyserver/caddy](https://github.com/caddyserver/caddy) | minor |
`2.7.6` -> `2.8.3` | [![OpenSSF
Scorecard](https://api.securityscorecards.dev/projects/github.com/caddyserver/caddy/badge)](https://securityscorecards.dev/viewer/?uri=github.com/caddyserver/caddy)
|

---

### Release Notes

<details>
<summary>caddyserver/caddy (caddyserver/caddy)</summary>

###
[`v2.8.3`](https://github.com/caddyserver/caddy/compare/v2.8.2...v2.8.3)

[Compare
Source](https://github.com/caddyserver/caddy/compare/v2.8.2...v2.8.3)

###
[`v2.8.2`](https://github.com/caddyserver/caddy/releases/tag/v2.8.2)

[Compare
Source](https://github.com/caddyserver/caddy/compare/v2.8.1...v2.8.2)

A few more fixes of reported bugs related to ARI, `try_files` with the
root path (`/`), and Caddyfile adapter detection on the CLI. See 2.8.0
release notes for details on 2.8.

#### Changelog

- [`01308b4`](https://github.com/caddyserver/caddy/commit/01308b4b)
I'm so tired of typos
- [`a63767d`](https://github.com/caddyserver/caddy/commit/a63767d3)
build(deps): bump golangci/golangci-lint-action from 5 to 6
([#&#8203;6361](https://github.com/caddyserver/caddy/issues/6361))
- [`f8a2c60`](https://github.com/caddyserver/caddy/commit/f8a2c602)
caddyhttp: properly sanitize requests for root path
([#&#8203;6360](https://github.com/caddyserver/caddy/issues/6360))
- [`b7280e6`](https://github.com/caddyserver/caddy/commit/b7280e69)
caddytls: Implement certmagic.RenewalInfoGetter
- [`15faeac`](https://github.com/caddyserver/caddy/commit/15faeacb)
cmd: fix auto-detetction of .caddyfile extension
([#&#8203;6356](https://github.com/caddyserver/caddy/issues/6356))

**Full Changelog**:
https://github.com/caddyserver/caddy/compare/v2.8.1...v2.8.2

###
[`v2.8.1`](https://github.com/caddyserver/caddy/releases/tag/v2.8.1)

[Compare
Source](https://github.com/caddyserver/caddy/compare/v2.8.0...v2.8.1)

Quick fixes for a few users related to directory permissions and matcher
parsing.

#### Changelog

- [`40c582c`](https://github.com/caddyserver/caddy/commit/40c582ce)
caddyhttp: Fix merging consecutive `client_ip` or `remote_ip` matchers
([#&#8203;6350](https://github.com/caddyserver/caddy/issues/6350))
- [`a52917a`](https://github.com/caddyserver/caddy/commit/a52917a3)
core: MkdirAll appDataDir in InstanceID with 0o700
([#&#8203;6340](https://github.com/caddyserver/caddy/issues/6340))

###
[`v2.8.0`](https://github.com/caddyserver/caddy/releases/tag/v2.8.0)

[Compare
Source](https://github.com/caddyserver/caddy/compare/v2.7.6...v2.8.0)

Caddy 2.8 is here! With hundreds of improvements, Caddy is more scalable
and capable than ever before. Featuring ACME Renewal Information (ARI)
support, HTTP/3 to proxy backends, and so much more than we can list in
a sentence, we are pleased to bring you one of the biggest Caddy updates
yet. Documentation on our website will be updated in the coming days.

We've implemented a *ton* of improvements, fixes, and awesome new
features based on your feedback. While some of them aren't particularly
visible changes, they allow Caddy to scale better and be more reliable
in demanding deployments. Many of the changes are quality-of-life
improvements we hope you'll appreciate. Then there's improvements to
[ACMEz](https://github.com/mholt/acmez),
[CertMagic](https://github.com/caddyserver/certmagic), and other
dependencies which make Caddy better that may not show up in this list.

There was a lot of code that had been documented as *deprecated* in
place for a long time, so this version introduces a few more breaking
changes than usual; please review the notes below.

Thank you to our sponsors and everyone in the community who contributed
-- over 40 of you made your first contribution for this release. We
couldn't have done it without your help. In particular, we'd like to
recognize sponsors **Stripe**, **Framer**, and **ZeroSSL** for their
positive influence which have greatly enhanced the project. Caddy 2.8 is
already being used in our sponsors' large-scale, multi-region production
deployments.

Want to join those ranks? [Sponsor the Caddy
project](https://caddyserver.com/sponsor) and benefit from development
priority, dedicated private support, and much more.

As with any server upgrades, please be sure to test and validate your
configurations in a staging or test environment before deploying to
production. Thank you and have a great day!

**:warning: Breaking changes:**

- ZeroSSL
([#&#8203;6229](https://github.com/caddyserver/caddy/issues/6229))
(this is *one* overall change, but requires some explanation):
- Up to now, Caddy used both Let's Encrypt and ZeroSSL by default to get
certificates without any configuration. In 2.8, this is changing
slightly. Due to upcoming changes to ZeroSSL accounting policies,
ZeroSSL now requires your email address to be able to access their free
ACME endpoint.
- As such, Caddy will only implicitly add the ZeroSSL issuer to your
config if you provide an email address in your Caddyfile using the
[`email` global
option](https://caddyserver.com/docs/caddyfile/options#email). (We have
already recommended this for years.) If you already do this, you don't
have to make any changes and you'll still get Let's Encrypt and ZeroSSL
automatically as defaults.
- If you use JSON to configure certificate automation policies, you will
need to ensure you use the [`acme` issuer with your `email` filled
out](https://caddyserver.com/docs/json/apps/tls/automation/policies/issuers/acme/#email),
and the [`ca`
field](https://caddyserver.com/docs/json/apps/tls/automation/policies/issuers/acme/#ca)
set to [ZeroSSL's ACME server
URL](https://zerossl.com/documentation/acme/).
- The [`zerossl`
issuer](https://caddyserver.com/docs/modules/tls.issuance.zerossl)
module is no longer ACME-capable and is now exclusively for the [ZeroSSL
API](https://zerossl.com/developer/). An API key from your ZeroSSL
account is required. (The [ZeroSSL ACME
server](https://zerossl.com/features/acme/) can still be used with the
[`acme` module](https://caddyserver.com/docs/modules/tls.issuance.acme)
pointed to ZeroSSL's ACME server. You can provide your account email
and/or EAB as well.) **If you were using the ZeroSSL issuer with an API
key, it will now start using ZeroSSL's API,** which was probably the
expected behavior anyways. The API has several advantages over the ACME
endpoint, but may require payment:
        -   Faster response times
        -   IP certificates
        -   Management tools in your ZeroSSL account dashboard
        -   Technical support
- To clarify, Let's Encrypt is still a default issuer even if you don't
provide an email address (but we have always strongly recommended to do
so).
- You can still use ZeroSSL's ACME endpoint with your own External
Account Binding (EAB) credentials.
- See notes in
[#&#8203;6229](https://github.com/caddyserver/caddy/issues/6229) for
some examples and further explanations.
- Removed support for [the `lego_deprecated` DNS provider
module](https://github.com/caddy-dns/lego-deprecated). It has been
deprecated for 4 years. Use [`caddy-dns`
modules](https://github.com/caddy-dns) instead; there are over 50 to
choose from already. They are more flexible, compile much leaner, and
are easier to implement and support. If yours is not supported it can be
easily implemented. [Sponsors at or above the Business
tier](https://caddyserver.com/sponsor) can request to have their
provider implemented for free.
- On-demand TLS: The `ask` option in the JSON has been deprecated in
favor of a permission module (Caddyfile unchanged)
([#&#8203;6055](https://github.com/caddyserver/caddy/issues/6055)),
and Caddyfile support for `permission` modules is added
([`6a02999`](https://github.com/caddyserver/caddy/commit/6a02999))
- Admin API: `Etag` (used for concurrency control) is now a header, not
a trailer. This is less efficient, but still virtually no clients
properly implement trailer support.
- For consistency, the `basicauth` Caddyfile directive has been renamed
to `basic_auth`
([#&#8203;6092](https://github.com/caddyserver/caddy/issues/6092)),
and `skip_log` has been renamed to `log_skip`. The old names will
continue to work for now, with a deprecation warning in the logs.
([#&#8203;6066](https://github.com/caddyserver/caddy/issues/6066)).
- The `basic_auth` handler no longer supports `scrypt` (deprecated for
nearly two years)
([#&#8203;6091](https://github.com/caddyserver/caddy/issues/6091))
- The `forwarded` option has been deprecated for a long time and has now
been removed from the `remote_ip` matcher. Use the `client_ip` matcher
instead.
([#&#8203;6085](https://github.com/caddyserver/caddy/issues/6085))
- Reverse proxy: The `buffer_requests`, `buffer_responses`, and
`max_buffer_size` settings have been removed after being deprecated for
14 months. Use `request_buffers` and `response_buffers` instead if you
need buffering.
- Go API: If you called `caddy.Context.AppIfConfigured()`, it now
returns an error, as part of a bug fix.
([#&#8203;6292](https://github.com/caddyserver/caddy/issues/6292))

**Notable changes:**

- acme_server: Configurable allow/deny policies
([#&#8203;5796](https://github.com/caddyserver/caddy/issues/5796))
- acme_server: Specify allowed challenge types
([#&#8203;5794](https://github.com/caddyserver/caddy/issues/5794))
- caddyfile: Plugin authors can now specify a default ordering for
directives, making manual ordering by users less necessary
([#&#8203;5865](https://github.com/caddyserver/caddy/issues/5865))
- cmd: The `--adapter` flag is not needed for config files ending with
`.caddyfile`
([#&#8203;5919](https://github.com/caddyserver/caddy/issues/5919))
- encode: More media types are now compressed by default
([#&#8203;6081](https://github.com/caddyserver/caddy/issues/6081))
- encode: Modify ETag when encoding to comply with RFC 9110 section
8.8.3
([#&#8203;5849](https://github.com/caddyserver/caddy/issues/5849))
- encode: Configurable compression level for `zstd`
([#&#8203;6140](https://github.com/caddyserver/caddy/issues/6140))
- handle_errors: Handling can now be filtered by response status code
more easily
([#&#8203;5965](https://github.com/caddyserver/caddy/issues/5965))
- http: New `fs` directive can declare a file system plugin to use
([#&#8203;5057](https://github.com/caddyserver/caddy/issues/5057))
- http: Sensitive headers in the logs are now replaced with
`["REDACTED"]` instead of empty array.
([#&#8203;5669](https://github.com/caddyserver/caddy/issues/5669))
- http: Several improvements to size logging, websockets, flushing, 1xx
statuses, and QUIC.
([#&#8203;6173](https://github.com/caddyserver/caddy/issues/6173),
[#&#8203;6175](https://github.com/caddyserver/caddy/issues/6175),
[#&#8203;6202](https://github.com/caddyserver/caddy/issues/6202),
[#&#8203;6150](https://github.com/caddyserver/caddy/issues/6150),
[#&#8203;6164](https://github.com/caddyserver/caddy/issues/6164),
[#&#8203;6168](https://github.com/caddyserver/caddy/issues/6168))
- http: Can now write access logs for a hostname to more than one logger
([#&#8203;6088](https://github.com/caddyserver/caddy/issues/6088))
- http: The `log_append` handler can add fields to the access logs
([#&#8203;6066](https://github.com/caddyserver/caddy/issues/6066))
- http: Add `uuid` field to access logs when the `{http.request.uuid}`
placeholder is used
([#&#8203;5859](https://github.com/caddyserver/caddy/issues/5859))
- http: Changed PROXY protocol libraries add TLV support
([#&#8203;5915](https://github.com/caddyserver/caddy/issues/5915))
- http: A new tracing mode writes each individual middleware handler to
logs
([#&#8203;6313](https://github.com/caddyserver/caddy/issues/6313))
- http: Access logs use a different message ("unhandled") when an HTTP
request is a no-op
([#&#8203;5182](https://github.com/caddyserver/caddy/issues/5182))
- file_server: The browse feature can now return a plaintext response
(useful for terminals)
([#&#8203;6093](https://github.com/caddyserver/caddy/issues/6093))
- file_server: File listings can dereference symlinks if enabled
([#&#8203;5973](https://github.com/caddyserver/caddy/issues/5973))
- file_server: Directory listings now include total file size
([#&#8203;6003](https://github.com/caddyserver/caddy/issues/6003))
- file_server: Can use precomputed ETags from sidecar files
([#&#8203;6222](https://github.com/caddyserver/caddy/issues/6222))
- replacer: A new `{file.*}` global placeholder is available, where `*`
is a path to a file on disk which contains a value (generally used for
secrets)
([#&#8203;5463](https://github.com/caddyserver/caddy/issues/5463))
- reverse_proxy: HTTP/3 supported to backends (experimental)
([#&#8203;6312](https://github.com/caddyserver/caddy/issues/6312))
- reverse_proxy: Active health checks can now be configured with
consecutive passes/fails to change status
([#&#8203;6154](https://github.com/caddyserver/caddy/issues/6154))
- reverse_proxy: A forward proxy can now be specified in config other
than a single env var
([#&#8203;6114](https://github.com/caddyserver/caddy/issues/6114))
- reverse_proxy: Configurable trusted root CAs is now modular
([#&#8203;6065](https://github.com/caddyserver/caddy/issues/6065))
- reverse_proxy: SRV upstreams now support failovers/grace period with
cache
([#&#8203;5832](https://github.com/caddyserver/caddy/issues/5832))
- reverse_proxy: TLS curves can now be configured (potential preparation
for post-quantum)
([#&#8203;5851](https://github.com/caddyserver/caddy/issues/5851))
- root, rewrite: A `*` matcher token is no longer required in the
Caddyfile
([#&#8203;5844](https://github.com/caddyserver/caddy/issues/5844))
- tls: Client authentication validation methods are now
modular/pluggable
([#&#8203;6050](https://github.com/caddyserver/caddy/issues/6050))
- tls: Trusted CA providers are now modular
([#&#8203;5784](https://github.com/caddyserver/caddy/issues/5784))
- tls: New `local_ip` connection matcher
([#&#8203;6074](https://github.com/caddyserver/caddy/issues/6074))
- tls: Improvements and fixes when certificate managers are configured
([#&#8203;6229](https://github.com/caddyserver/caddy/issues/6229))
- tls: Refactor the On-Demand TLS `ask` endpoint into a `permission`
module, making it pluggable
([#&#8203;6055](https://github.com/caddyserver/caddy/issues/6055))
- tls: Storage cleaning is now synced across instances that share the
storage
([#&#8203;5940](https://github.com/caddyserver/caddy/issues/5940))
- tls: Supports ACME Renewal Information (ARI) draft spec, together with
cert lifetime and OCSP/revocation status, to trigger certificate
renewals
- uri: Can now perform structured query rewrites with `uri query`
([#&#8203;6120](https://github.com/caddyserver/caddy/issues/6120),
[#&#8203;6165](https://github.com/caddyserver/caddy/issues/6165))

#### Changelog

**Full Changelog**:
https://github.com/caddyserver/caddy/compare/v2.7.6...v2.8.0

- [`ac0ad4d`](https://github.com/caddyserver/caddy/commit/ac0ad4da)
Upgrade acmeserver to github.com/go-chi/chi/v5
([#&#8203;5913](https://github.com/caddyserver/caddy/issues/5913))
- [`931656b`](https://github.com/caddyserver/caddy/commit/931656bd)
acmeserver: add policy field to define allow/deny rules
([#&#8203;5796](https://github.com/caddyserver/caddy/issues/5796))
- [`e1aa862`](https://github.com/caddyserver/caddy/commit/e1aa862e)
acmeserver: support specifying the allowed challenge types
([#&#8203;5794](https://github.com/caddyserver/caddy/issues/5794))
- [`e6f46c8`](https://github.com/caddyserver/caddy/commit/e6f46c8d)
acmeserver: Add `sign_with_root` for Caddyfile
([#&#8203;6345](https://github.com/caddyserver/caddy/issues/6345))
- [`4a0492f`](https://github.com/caddyserver/caddy/commit/4a0492f3)
admin: Make `Etag` a header, not a trailer
([#&#8203;6208](https://github.com/caddyserver/caddy/issues/6208))
- [`1217449`](https://github.com/caddyserver/caddy/commit/12174496)
admin: Use xxhash for etag
([#&#8203;6207](https://github.com/caddyserver/caddy/issues/6207))
- [`7e2510e`](https://github.com/caddyserver/caddy/commit/7e2510ef)
build(deps): bump golangci/golangci-lint-action from 4 to 5
([#&#8203;6289](https://github.com/caddyserver/caddy/issues/6289))
- [`4f3f6e3`](https://github.com/caddyserver/caddy/commit/4f3f6e35)
build(deps): bump actions/setup-go from 4 to 5
([#&#8203;6012](https://github.com/caddyserver/caddy/issues/6012))
- [`8a50f19`](https://github.com/caddyserver/caddy/commit/8a50f191)
build(deps): bump actions/upload-artifact from 3 to 4
([#&#8203;6013](https://github.com/caddyserver/caddy/issues/6013))
- [`1bf72db`](https://github.com/caddyserver/caddy/commit/1bf72db6)
build(deps): bump golang.org/x/crypto from 0.16.0 to 0.17.0
([#&#8203;5994](https://github.com/caddyserver/caddy/issues/5994))
- [`223f314`](https://github.com/caddyserver/caddy/commit/223f3143)
build(deps): bump peter-evans/repository-dispatch from 2 to 3
([#&#8203;6080](https://github.com/caddyserver/caddy/issues/6080))
- [`30d6364`](https://github.com/caddyserver/caddy/commit/30d63648)
caddyauth: Drop support for `scrypt`
([#&#8203;6091](https://github.com/caddyserver/caddy/issues/6091))
- [`f9e1115`](https://github.com/caddyserver/caddy/commit/f9e11158)
caddyauth: Rename `basicauth` to `basic_auth`
([#&#8203;6092](https://github.com/caddyserver/caddy/issues/6092))
- [`f4840cf`](https://github.com/caddyserver/caddy/commit/f4840cfe)
caddyconfig: Use empty struct instead of bool in map (close
[#&#8203;6224](https://github.com/caddyserver/caddy/issues/6224))
([#&#8203;6227](https://github.com/caddyserver/caddy/issues/6227))
- [`f6d2c29`](https://github.com/caddyserver/caddy/commit/f6d2c293)
caddyfile: Reject global request matchers earlier
([#&#8203;6339](https://github.com/caddyserver/caddy/issues/6339))
- [`c0273f1`](https://github.com/caddyserver/caddy/commit/c0273f1f)
caddyfile: Add heredoc support to `fmt` command
([#&#8203;6056](https://github.com/caddyserver/caddy/issues/6056))
- [`d9aded0`](https://github.com/caddyserver/caddy/commit/d9aded01)
caddyfile: Allow heredoc blank lines
([#&#8203;6051](https://github.com/caddyserver/caddy/issues/6051))
- [`8bbf8ec`](https://github.com/caddyserver/caddy/commit/8bbf8ec6)
caddyfile: Assert having a space after heredoc marker to simply check
([#&#8203;6117](https://github.com/caddyserver/caddy/issues/6117))
- [`c369df5`](https://github.com/caddyserver/caddy/commit/c369df5c)
caddyfile: Correctly close the heredoc when the closing marker appears
immediately
([#&#8203;6062](https://github.com/caddyserver/caddy/issues/6062))
- [`1f60328`](https://github.com/caddyserver/caddy/commit/1f60328e)
caddyfile: Fix variadic placeholder false positive when token contains
`:` ([#&#8203;5883](https://github.com/caddyserver/caddy/issues/5883))
- [`750d0b8`](https://github.com/caddyserver/caddy/commit/750d0b83)
caddyfile: Normalize & flatten all unmarshalers
([#&#8203;6037](https://github.com/caddyserver/caddy/issues/6037))
- [`9cd472c`](https://github.com/caddyserver/caddy/commit/9cd472c0)
caddyfile: Populate regexp matcher names by default
([#&#8203;6145](https://github.com/caddyserver/caddy/issues/6145))
- [`b893c8c`](https://github.com/caddyserver/caddy/commit/b893c8c5)
caddyfile: Reject directives in the place of site addresses
([#&#8203;6104](https://github.com/caddyserver/caddy/issues/6104))
- [`e7a534d`](https://github.com/caddyserver/caddy/commit/e7a534d0)
caddyfile: Reject long heredoc markers
([#&#8203;6098](https://github.com/caddyserver/caddy/issues/6098))
- [`7c48b5f`](https://github.com/caddyserver/caddy/commit/7c48b5fd)
caddyfile: Switch to slices.Equal for better performance
([#&#8203;6061](https://github.com/caddyserver/caddy/issues/6061))
- [`63d597c`](https://github.com/caddyserver/caddy/commit/63d597c0)
caddyhttp: Accept XFF header values with ports, when parsing client IP
([#&#8203;6183](https://github.com/caddyserver/caddy/issues/6183))
- [`3d7d60f`](https://github.com/caddyserver/caddy/commit/3d7d60f7)
caddyhttp: Add `uuid` to access logs when used
([#&#8203;5859](https://github.com/caddyserver/caddy/issues/5859))
- [`45132c5`](https://github.com/caddyserver/caddy/commit/45132c5b)
caddyhttp: Add plaintext response to `file_server browse`
([#&#8203;6093](https://github.com/caddyserver/caddy/issues/6093))
- [`6d97d8d`](https://github.com/caddyserver/caddy/commit/6d97d8d8)
caddyhttp: Address some Go 1.20 features
([#&#8203;6252](https://github.com/caddyserver/caddy/issues/6252))
- [`4c10a05`](https://github.com/caddyserver/caddy/commit/4c10a054)
caddyhttp: Adjust `scheme` placeholder docs
([#&#8203;5910](https://github.com/caddyserver/caddy/issues/5910))
- [`97a56d8`](https://github.com/caddyserver/caddy/commit/97a56d86)
caddyhttp: Allow `header` replacement with empty string
([#&#8203;6163](https://github.com/caddyserver/caddy/issues/6163))
- [`83ef61d`](https://github.com/caddyserver/caddy/commit/83ef61de)
caddyhttp: Apply auto HTTPS redir to all interfaces (fix
[#&#8203;6226](https://github.com/caddyserver/caddy/issues/6226))
- [`2fc620d`](https://github.com/caddyserver/caddy/commit/2fc620d3)
caddyhttp: Fix linter warning about deprecation
- [`f5344f8`](https://github.com/caddyserver/caddy/commit/f5344f8c)
caddyhttp: Fix panic when request missing ClientIPVarKey
([#&#8203;6040](https://github.com/caddyserver/caddy/issues/6040))
- [`2c48dda`](https://github.com/caddyserver/caddy/commit/2c48dda1)
caddyhttp: Only attempt to enable full duplex for HTTP/1.x
([#&#8203;6102](https://github.com/caddyserver/caddy/issues/6102))
- [`1277888`](https://github.com/caddyserver/caddy/commit/12778880)
caddyhttp: Register post-shutdown callbacks
([#&#8203;5948](https://github.com/caddyserver/caddy/issues/5948))
- [`7b48ce0`](https://github.com/caddyserver/caddy/commit/7b48ce0e)
caddyhttp: Replace sensitive headers with REDACTED (close
[#&#8203;5669](https://github.com/caddyserver/caddy/issues/5669))
- [`cc0c0cf`](https://github.com/caddyserver/caddy/commit/cc0c0cf0)
caddyhttp: Security enhancements for client IP parsing
([#&#8203;5805](https://github.com/caddyserver/caddy/issues/5805))
- [`70953e8`](https://github.com/caddyserver/caddy/commit/70953e87)
caddyhttp: Support multiple logger names per host
([#&#8203;6088](https://github.com/caddyserver/caddy/issues/6088))
- [`bde4621`](https://github.com/caddyserver/caddy/commit/bde46211)
caddyhttp: Test cases for `%2F` and `%252F`
([#&#8203;6084](https://github.com/caddyserver/caddy/issues/6084))
- [`c8559c4`](https://github.com/caddyserver/caddy/commit/c8559c44)
caddyhttp: Use sync.Pool to reduce lengthReader allocations
([#&#8203;5848](https://github.com/caddyserver/caddy/issues/5848))
- [`ddb1d2c`](https://github.com/caddyserver/caddy/commit/ddb1d2c2)
caddyhttp: add http.request.local{,.host,.port} placeholder
([#&#8203;6182](https://github.com/caddyserver/caddy/issues/6182))
- [`924010c`](https://github.com/caddyserver/caddy/commit/924010cd)
caddyhttp: close quic connections when server closes
([#&#8203;6202](https://github.com/caddyserver/caddy/issues/6202))
- [`e0daa39`](https://github.com/caddyserver/caddy/commit/e0daa39c)
caddyhttp: record num. bytes read when response writer is hijacked
([#&#8203;6173](https://github.com/caddyserver/caddy/issues/6173))
- [`654a3bb`](https://github.com/caddyserver/caddy/commit/654a3bb0)
caddyhttp: remove duplicate strings.Count in path matcher (fixes
[#&#8203;6233](https://github.com/caddyserver/caddy/issues/6233))
([#&#8203;6234](https://github.com/caddyserver/caddy/issues/6234))
- [`b568a10`](https://github.com/caddyserver/caddy/commit/b568a10d)
caddyhttp: support unix sockets in `caddy respond` command
([#&#8203;6010](https://github.com/caddyserver/caddy/issues/6010))
- [`c93e304`](https://github.com/caddyserver/caddy/commit/c93e3045)
caddyhttp: suppress flushing if the response is being buffered
([#&#8203;6150](https://github.com/caddyserver/caddy/issues/6150))
- [`52822a4`](https://github.com/caddyserver/caddy/commit/52822a41)
caddyhttp: upgrade to cel v0.20.0
([#&#8203;6161](https://github.com/caddyserver/caddy/issues/6161))
- [`224316e`](https://github.com/caddyserver/caddy/commit/224316ea)
caddyhttp: Move log WARN to INFO, reduce confusion
([#&#8203;6185](https://github.com/caddyserver/caddy/issues/6185))
- [`6dce493`](https://github.com/caddyserver/caddy/commit/6dce4934)
caddyhttp: Alter log message when request is unhandled (close
[#&#8203;5182](https://github.com/caddyserver/caddy/issues/5182))
- [`4af38e5`](https://github.com/caddyserver/caddy/commit/4af38e5a)
caddyhttp: Log 4xx as INFO; 5xx as ERROR (close
[#&#8203;6106](https://github.com/caddyserver/caddy/issues/6106))
- [`fb63e2e`](https://github.com/caddyserver/caddy/commit/fb63e2e4)
caddyhttp: New experimental handler for intercepting responses
([#&#8203;6232](https://github.com/caddyserver/caddy/issues/6232))
- [`9ba9991`](https://github.com/caddyserver/caddy/commit/9ba99914)
caddyhttp: Trace individual middleware handlers
([#&#8203;6313](https://github.com/caddyserver/caddy/issues/6313))
- [`c97292b`](https://github.com/caddyserver/caddy/commit/c97292b2)
caddypki: Allow use of root CA without a key. Fixes
[#&#8203;6290](https://github.com/caddyserver/caddy/issues/6290)
([#&#8203;6298](https://github.com/caddyserver/caddy/issues/6298))
- [`4512be4`](https://github.com/caddyserver/caddy/commit/4512be49)
caddytest: Rename adapt tests to `*.caddyfiletest` extension
([#&#8203;6119](https://github.com/caddyserver/caddy/issues/6119))
- [`4c90f14`](https://github.com/caddyserver/caddy/commit/4c90f142)
caddytest: normalize the JSON config
([#&#8203;6316](https://github.com/caddyserver/caddy/issues/6316))
- [`8d7ac18`](https://github.com/caddyserver/caddy/commit/8d7ac184)
caddytls: Ability to drop connections (close
[#&#8203;6294](https://github.com/caddyserver/caddy/issues/6294))
- [`6a02999`](https://github.com/caddyserver/caddy/commit/6a029990)
caddytls: Add Caddyfile support for on-demand permission module (close
[#&#8203;6260](https://github.com/caddyserver/caddy/issues/6260))
- [`b24ae63`](https://github.com/caddyserver/caddy/commit/b24ae63e)
caddytls: Context to DecisionFunc
([#&#8203;5923](https://github.com/caddyserver/caddy/issues/5923))
- [`d129ae6`](https://github.com/caddyserver/caddy/commit/d129ae6a)
caddytls: Evict internal certs from cache based on issuer
([#&#8203;6266](https://github.com/caddyserver/caddy/issues/6266))
- [`57c5b92`](https://github.com/caddyserver/caddy/commit/57c5b921)
caddytls: Make on-demand 'ask' permission modular
([#&#8203;6055](https://github.com/caddyserver/caddy/issues/6055))
- [`76c4cf5`](https://github.com/caddyserver/caddy/commit/76c4cf5a)
caddytls: Option to configure certificate lifetime
([#&#8203;6253](https://github.com/caddyserver/caddy/issues/6253))
- [`3609a4a`](https://github.com/caddyserver/caddy/commit/3609a4af)
caddytls: Remove shim code supporting deprecated lego-dns
([#&#8203;6231](https://github.com/caddyserver/caddy/issues/6231))
- [`dc9dd2e`](https://github.com/caddyserver/caddy/commit/dc9dd2e4)
caddytls: Still provision permission module if ask is specified
- [`4a09cf0`](https://github.com/caddyserver/caddy/commit/4a09cf0d)
caddytls: Sync distributed storage cleaning
([#&#8203;5940](https://github.com/caddyserver/caddy/issues/5940))
- [`81413ca`](https://github.com/caddyserver/caddy/commit/81413cae)
caddytls: Upgrade ACMEz to v2; support ZeroSSL API; various fixes
([#&#8203;6229](https://github.com/caddyserver/caddy/issues/6229))
- [`3ae07a7`](https://github.com/caddyserver/caddy/commit/3ae07a73)
caddytls: clientauth: leaf verifier: make trusted leaf certs source
pluggable
([#&#8203;6050](https://github.com/caddyserver/caddy/issues/6050))
- [`03f703a`](https://github.com/caddyserver/caddy/commit/03f703a0)
caddytls: verifier: caddyfile: re-add Caddyfile support
([#&#8203;6127](https://github.com/caddyserver/caddy/issues/6127))
- [`db3e19b`](https://github.com/caddyserver/caddy/commit/db3e19b7)
caddytls: fix permission requirement with AutomationPolicy
([#&#8203;6328](https://github.com/caddyserver/caddy/issues/6328))
- [`1fc151f`](https://github.com/caddyserver/caddy/commit/1fc151fa)
caddytls: remove ClientHelloSNICtxKey
([#&#8203;6326](https://github.com/caddyserver/caddy/issues/6326))
- [`e66040a`](https://github.com/caddyserver/caddy/commit/e66040a6)
caddytls: set server name in context
([#&#8203;6324](https://github.com/caddyserver/caddy/issues/6324))
- [`b359ca5`](https://github.com/caddyserver/caddy/commit/b359ca56)
ci/cd: use the build tag `nobadger` to exclude badgerdb
([#&#8203;6031](https://github.com/caddyserver/caddy/issues/6031))
- [`24b0ecc`](https://github.com/caddyserver/caddy/commit/24b0ecc3)
cmd: Add newline character to version string in CLI output
([#&#8203;5895](https://github.com/caddyserver/caddy/issues/5895))
- [`e473ae6`](https://github.com/caddyserver/caddy/commit/e473ae68)
cmd: Adjust config load logs/errors
([#&#8203;6032](https://github.com/caddyserver/caddy/issues/6032))
- [`185ed6f`](https://github.com/caddyserver/caddy/commit/185ed6fe)
cmd: Assume Caddyfile based on filename prefix and suffix
([#&#8203;5919](https://github.com/caddyserver/caddy/issues/5919))
- [`e1f4b83`](https://github.com/caddyserver/caddy/commit/e1f4b83f)
cmd: Fix panic related to config filename (fix
[#&#8203;5919](https://github.com/caddyserver/caddy/issues/5919))
- [`8f87c5d`](https://github.com/caddyserver/caddy/commit/8f87c5d9)
cmd: Only validate config is proper JSON if config slice has data
([#&#8203;6250](https://github.com/caddyserver/caddy/issues/6250))
- [`56c6b3f`](https://github.com/caddyserver/caddy/commit/56c6b3f6)
cmd: Preserve LastModified date when exporting storage
([#&#8203;5968](https://github.com/caddyserver/caddy/issues/5968))
- [`de4959f`](https://github.com/caddyserver/caddy/commit/de4959fe)
cmd: fix the output of the `Usage` section
([#&#8203;6138](https://github.com/caddyserver/caddy/issues/6138))
- [`54823f5`](https://github.com/caddyserver/caddy/commit/54823f52)
cmd: reverseproxy: log: use caddy logger
([#&#8203;6042](https://github.com/caddyserver/caddy/issues/6042))
- [`d70608b`](https://github.com/caddyserver/caddy/commit/d70608b6)
cmd: upgrade: resolve symlink of the executable
([#&#8203;5891](https://github.com/caddyserver/caddy/issues/5891))
- [`d54dcf1`](https://github.com/caddyserver/caddy/commit/d54dcf15)
cmd: use automaxprocs for better perf in containers
([#&#8203;5711](https://github.com/caddyserver/caddy/issues/5711))
- [`e1b9a9d`](https://github.com/caddyserver/caddy/commit/e1b9a9d7)
core: Add `ctx.Slogger()` which returns an `slog` logger
([#&#8203;5945](https://github.com/caddyserver/caddy/issues/5945))
- [`cbbd1df`](https://github.com/caddyserver/caddy/commit/cbbd1df9)
core: Always make AppDataDir for InstanceID
([#&#8203;5976](https://github.com/caddyserver/caddy/issues/5976))
- [`174c19a`](https://github.com/caddyserver/caddy/commit/174c19a9)
core: Apply SO_REUSEPORT to UDP sockets
([#&#8203;5725](https://github.com/caddyserver/caddy/issues/5725))
- [`46c5db9`](https://github.com/caddyserver/caddy/commit/46c5db92)
core: OnExit hooks
([#&#8203;6128](https://github.com/caddyserver/caddy/issues/6128))
- [`a747930`](https://github.com/caddyserver/caddy/commit/a7479302)
core: Support NO_COLOR env var to disable log coloring
([#&#8203;6078](https://github.com/caddyserver/caddy/issues/6078))
- [`7c82e26`](https://github.com/caddyserver/caddy/commit/7c82e265)
core: quic listener will manage the underlying socket by itself
([#&#8203;5749](https://github.com/caddyserver/caddy/issues/5749))
- [`a6a45ff`](https://github.com/caddyserver/caddy/commit/a6a45ff6)
core: AppIfConfigured returns error; consider not-yet-provisioned
modules
([#&#8203;6292](https://github.com/caddyserver/caddy/issues/6292))
- [`2ce5c65`](https://github.com/caddyserver/caddy/commit/2ce5c652)
core: Fix bug in AppIfConfigured (fix
[#&#8203;6336](https://github.com/caddyserver/caddy/issues/6336))
- [`03e0a01`](https://github.com/caddyserver/caddy/commit/03e0a010)
encode: Configurable compression level for zstd
([#&#8203;6140](https://github.com/caddyserver/caddy/issues/6140))
- [`3067074`](https://github.com/caddyserver/caddy/commit/3067074d)
encode: Improve Etag handling (fix
[#&#8203;5849](https://github.com/caddyserver/caddy/issues/5849))
- [`9ab0943`](https://github.com/caddyserver/caddy/commit/9ab09433)
encode: Slight fix for the previous commit
- [`e698ec5`](https://github.com/caddyserver/caddy/commit/e698ec51)
encode: write status immediately when status code is informational
([#&#8203;6164](https://github.com/caddyserver/caddy/issues/6164))
- [`ba58114`](https://github.com/caddyserver/caddy/commit/ba581146)
events: Add debug log
- [`7e52db8`](https://github.com/caddyserver/caddy/commit/7e52db82)
fileserver: Add .m4v for browse template icon
- [`8f9ffc5`](https://github.com/caddyserver/caddy/commit/8f9ffc58)
fileserver: Add total file size to directory listing
([#&#8203;6003](https://github.com/caddyserver/caddy/issues/6003))
- [`feb07a7`](https://github.com/caddyserver/caddy/commit/feb07a7b)
fileserver: Browse can show symlink target if enabled
([#&#8203;5973](https://github.com/caddyserver/caddy/issues/5973))
- [`b16aba5`](https://github.com/caddyserver/caddy/commit/b16aba5c)
fileserver: Enable compression for command by default
([#&#8203;5855](https://github.com/caddyserver/caddy/issues/5855))
- [`5d8b45c`](https://github.com/caddyserver/caddy/commit/5d8b45c9)
fileserver: Escape # and ? in img src (fix
[#&#8203;6237](https://github.com/caddyserver/caddy/issues/6237))
- [`f3e849e`](https://github.com/caddyserver/caddy/commit/f3e849e4)
fileserver: Implement caddyfile.Unmarshaler interface
([#&#8203;5850](https://github.com/caddyserver/caddy/issues/5850))
- [`d00824f`](https://github.com/caddyserver/caddy/commit/d00824f4)
fileserver: Improve Vary handling
([#&#8203;5849](https://github.com/caddyserver/caddy/issues/5849))
- [`362f33d`](https://github.com/caddyserver/caddy/commit/362f33da)
fileserver: New --precompressed flag
([#&#8203;5880](https://github.com/caddyserver/caddy/issues/5880))
- [`5a4374b`](https://github.com/caddyserver/caddy/commit/5a4374be)
fileserver: Preserve query during canonicalization redirect
([#&#8203;6109](https://github.com/caddyserver/caddy/issues/6109))
- [`cabb5d7`](https://github.com/caddyserver/caddy/commit/cabb5d71)
fileserver: Set "Vary: Accept-Encoding" header (see
[#&#8203;5849](https://github.com/caddyserver/caddy/issues/5849))
- [`567d96c`](https://github.com/caddyserver/caddy/commit/567d96c6)
fileserver: read etags from precomputed files
([#&#8203;6222](https://github.com/caddyserver/caddy/issues/6222))
- [`c839a98`](https://github.com/caddyserver/caddy/commit/c839a98f)
filesystem: Globally declared filesystems, `fs` directive
([#&#8203;5833](https://github.com/caddyserver/caddy/issues/5833))
- [`60abd72`](https://github.com/caddyserver/caddy/commit/60abd72c)
fix: add back text/\*
- [`b8f729b`](https://github.com/caddyserver/caddy/commit/b8f729b8)
fix: add more media types to the compressed by default list
- [`a4a64a6`](https://github.com/caddyserver/caddy/commit/a4a64a6f)
gitignore: Add rule for caddyfile.go
([#&#8203;6225](https://github.com/caddyserver/caddy/issues/6225))
- [`9fc55a9`](https://github.com/caddyserver/caddy/commit/9fc55a97)
go.mod: CVE-2023-45142 Update opentelemetry
([#&#8203;5908](https://github.com/caddyserver/caddy/issues/5908))
- [`fe2a02b`](https://github.com/caddyserver/caddy/commit/fe2a02bf)
go.mod: Upgrade quic-go to v0.39.1
- [`b49ec05`](https://github.com/caddyserver/caddy/commit/b49ec051)
go.mod: Updated quic-go to v0.40.1
([#&#8203;5983](https://github.com/caddyserver/caddy/issues/5983))
- [`ee35855`](https://github.com/caddyserver/caddy/commit/ee358550)
go.mod: update quic-go version to v0.40.0
([#&#8203;5922](https://github.com/caddyserver/caddy/issues/5922))
- [`a46ff50`](https://github.com/caddyserver/caddy/commit/a46ff50a)
go.mod: Upgrade to quic-go v0.43.0
- [`b522710`](https://github.com/caddyserver/caddy/commit/b5227106)
go.mod: Upgrade to quic-go v0.43.1
- [`dd203ad`](https://github.com/caddyserver/caddy/commit/dd203ad4)
go.mod: CertMagic v0.21.0
- [`d79c0f0`](https://github.com/caddyserver/caddy/commit/d79c0f0d)
go.mod: Upgrade dependencies
- [`abdf1ae`](https://github.com/caddyserver/caddy/commit/abdf1ae1)
go.mod: go 1.22.3
- [`258d906`](https://github.com/caddyserver/caddy/commit/258d9061)
httpcaddyfile: Add `RegisterDirectiveOrder` function for plugin authors
([#&#8203;5865](https://github.com/caddyserver/caddy/issues/5865))
- [`4181c79`](https://github.com/caddyserver/caddy/commit/4181c79a)
httpcaddyfile: Add optional status code argument to `handle_errors`
directive
([#&#8203;5965](https://github.com/caddyserver/caddy/issues/5965))
- [`2a78c9c`](https://github.com/caddyserver/caddy/commit/2a78c9c5)
httpcaddyfile: Allow nameless regexp placeholder shorthand
([#&#8203;6113](https://github.com/caddyserver/caddy/issues/6113))
- [`7984e6f`](https://github.com/caddyserver/caddy/commit/7984e6f6)
httpcaddyfile: Fix TLS automation policy merging with get_certificate
([#&#8203;5896](https://github.com/caddyserver/caddy/issues/5896))
- [`f976c84`](https://github.com/caddyserver/caddy/commit/f976c84d)
httpcaddyfile: Fix cert file decoding to load multiple PEM in one file
([#&#8203;5997](https://github.com/caddyserver/caddy/issues/5997))
- [`c2d889f`](https://github.com/caddyserver/caddy/commit/c2d889f8)
httpcaddyfile: Fix redir <to> html
([#&#8203;6001](https://github.com/caddyserver/caddy/issues/6001))
- [`c27425e`](https://github.com/caddyserver/caddy/commit/c27425ef)
httpcaddyfile: Keep deprecated `skip_log` in directive order
([#&#8203;6153](https://github.com/caddyserver/caddy/issues/6153))
- [`ac1f20b`](https://github.com/caddyserver/caddy/commit/ac1f20b9)
httpcaddyfile: Remove port from logger names
([#&#8203;5881](https://github.com/caddyserver/caddy/issues/5881))
- [`5e2f1b5`](https://github.com/caddyserver/caddy/commit/5e2f1b5c)
httpcaddyfile: Rewrite `root` and `rewrite` parsing to allow omitting
matcher
([#&#8203;5844](https://github.com/caddyserver/caddy/issues/5844))
- [`3efda6f`](https://github.com/caddyserver/caddy/commit/3efda6fb)
httpcaddyfile: Skip automate loader if disable_certs is specified (fix
[#&#8203;6148](https://github.com/caddyserver/caddy/issues/6148))
- [`da7d8cb`](https://github.com/caddyserver/caddy/commit/da7d8cb2)
httpcaddyfile: Sort skip_hosts for deterministic JSON
([#&#8203;5990](https://github.com/caddyserver/caddy/issues/5990))
- [`cb86319`](https://github.com/caddyserver/caddy/commit/cb86319b)
httpcaddyfile: Support client auth verifiers
([#&#8203;6022](https://github.com/caddyserver/caddy/issues/6022))
- [`feeb6af`](https://github.com/caddyserver/caddy/commit/feeb6af4)
httpcaddyfile: Fix expression matcher shortcut in snippets
([#&#8203;6288](https://github.com/caddyserver/caddy/issues/6288))
- [`583c585`](https://github.com/caddyserver/caddy/commit/583c585c)
httpcaddyfile: Set challenge ports when http_port or https_port are used
- [`96f638e`](https://github.com/caddyserver/caddy/commit/96f638ea)
httpredirectlistener: Only set read limit for when request is HTTP
([#&#8203;5917](https://github.com/caddyserver/caddy/issues/5917))
- [`3248e4c`](https://github.com/caddyserver/caddy/commit/3248e4c8)
logging: Add `zap.Option` support
([#&#8203;5944](https://github.com/caddyserver/caddy/issues/5944))
- [`b9c40e7`](https://github.com/caddyserver/caddy/commit/b9c40e71)
logging: Automatic `wrap` default for `filter` encoder
([#&#8203;5980](https://github.com/caddyserver/caddy/issues/5980))
- [`726a9a8`](https://github.com/caddyserver/caddy/commit/726a9a8f)
logging: Fix default access logger
([#&#8203;6251](https://github.com/caddyserver/caddy/issues/6251))
- [`01d5568`](https://github.com/caddyserver/caddy/commit/01d5568b)
logging: Implement `append` encoder, allow flatter filters config
([#&#8203;6069](https://github.com/caddyserver/caddy/issues/6069))
- [`0d44e3e`](https://github.com/caddyserver/caddy/commit/0d44e3ec)
logging: Implement `log_append` handler
([#&#8203;6066](https://github.com/caddyserver/caddy/issues/6066))
- [`91ec754`](https://github.com/caddyserver/caddy/commit/91ec7544)
logging: Inline Caddyfile syntax for `ip_mask` filter
([#&#8203;6094](https://github.com/caddyserver/caddy/issues/6094))
- [`0c01547`](https://github.com/caddyserver/caddy/commit/0c015470)
logging: support `ms` duration format and add docs
([#&#8203;6187](https://github.com/caddyserver/caddy/issues/6187))
- [`4356635`](https://github.com/caddyserver/caddy/commit/4356635d)
logging: Add support for additional logger filters other than hostname
([#&#8203;6082](https://github.com/caddyserver/caddy/issues/6082))
- [`8c2a72a`](https://github.com/caddyserver/caddy/commit/8c2a72ad)
caddyhttp: Drop `forwarded` option from `remote_ip` matcher
([#&#8203;6085](https://github.com/caddyserver/caddy/issues/6085))
- [`ed7e3c9`](https://github.com/caddyserver/caddy/commit/ed7e3c90)
caddyhttp: `query` matcher now ANDs multiple keys
([#&#8203;6054](https://github.com/caddyserver/caddy/issues/6054))
- [`387545a`](https://github.com/caddyserver/caddy/commit/387545a8)
metrics: Record request metrics on HTTP errors
([#&#8203;5979](https://github.com/caddyserver/caddy/issues/5979))
- [`e0bf179`](https://github.com/caddyserver/caddy/commit/e0bf179c)
modules: fix some typo in conments
([#&#8203;6206](https://github.com/caddyserver/caddy/issues/6206))
- [`dc12bd9`](https://github.com/caddyserver/caddy/commit/dc12bd97)
proxyprotocol: use github.com/pires/go-proxyproto
([#&#8203;5915](https://github.com/caddyserver/caddy/issues/5915))
- [`dba556f`](https://github.com/caddyserver/caddy/commit/dba556fe)
refactor: move automaxprocs init in caddycmd.Main()
- [`80acf1b`](https://github.com/caddyserver/caddy/commit/80acf1bf)
replacer: Fix escaped closing braces
([#&#8203;5995](https://github.com/caddyserver/caddy/issues/5995))
- [`7979739`](https://github.com/caddyserver/caddy/commit/79797394)
replacer: Implement `file.*` global replacements
([#&#8203;5463](https://github.com/caddyserver/caddy/issues/5463))
- [`e7336cc`](https://github.com/caddyserver/caddy/commit/e7336cc3)
replacer: use RWMutex to protect static provider
([#&#8203;6184](https://github.com/caddyserver/caddy/issues/6184))
- [`868af6a`](https://github.com/caddyserver/caddy/commit/868af6a0)
reverseproxy: Add grace_period for SRV upstreams to Caddyfile
([#&#8203;6264](https://github.com/caddyserver/caddy/issues/6264))
- [`613d544`](https://github.com/caddyserver/caddy/commit/613d544a)
reverseproxy: Accept EOF when buffering
- [`f658fd0`](https://github.com/caddyserver/caddy/commit/f658fd05)
reverseproxy: Add `tls_curves` option to HTTP transport
([#&#8203;5851](https://github.com/caddyserver/caddy/issues/5851))
- [`a9768d2`](https://github.com/caddyserver/caddy/commit/a9768d2f)
reverseproxy: Configurable forward proxy URL
([#&#8203;6114](https://github.com/caddyserver/caddy/issues/6114))
- [`0b381eb`](https://github.com/caddyserver/caddy/commit/0b381eb7)
reverseproxy: Implement modular CA provider for TLS transport
([#&#8203;6065](https://github.com/caddyserver/caddy/issues/6065))
- [`d9ff7b1`](https://github.com/caddyserver/caddy/commit/d9ff7b18)
reverseproxy: Only change Content-Length when full request is buffered
([#&#8203;5830](https://github.com/caddyserver/caddy/issues/5830))
- [`9f97df2`](https://github.com/caddyserver/caddy/commit/9f97df22)
reverseproxy: Remove long-deprecated buffering properties
- [`d93e027`](https://github.com/caddyserver/caddy/commit/d93e027e)
reverseproxy: Reuse buffered request body even if partially drained
- [`72ce78d`](https://github.com/caddyserver/caddy/commit/72ce78d9)
reverseproxy: SRV dynamic upstream failover
([#&#8203;5832](https://github.com/caddyserver/caddy/issues/5832))
- [`74949fb`](https://github.com/caddyserver/caddy/commit/74949fb0)
reverseproxy: Use xxhash instead of fnv32 for LB
([#&#8203;6203](https://github.com/caddyserver/caddy/issues/6203))
- [`b40cacf`](https://github.com/caddyserver/caddy/commit/b40cacf5)
reverseproxy: Wait for both ends of websocket to close
([#&#8203;6175](https://github.com/caddyserver/caddy/issues/6175))
- [`e65b97f`](https://github.com/caddyserver/caddy/commit/e65b97f5)
reverseproxy: configurable active health_passes and health_fails
([#&#8203;6154](https://github.com/caddyserver/caddy/issues/6154))
- [`da6a569`](https://github.com/caddyserver/caddy/commit/da6a569e)
reverseproxy: cookie should be Secure and SameSite=None when TLS
([#&#8203;6115](https://github.com/caddyserver/caddy/issues/6115))
- [`1b9042b`](https://github.com/caddyserver/caddy/commit/1b9042bc)
reverseproxy: handle buffered data during hijack
([#&#8203;6274](https://github.com/caddyserver/caddy/issues/6274))
- [`53f7035`](https://github.com/caddyserver/caddy/commit/53f70352)
reverseproxy: use context.WithoutCancel
([#&#8203;6116](https://github.com/caddyserver/caddy/issues/6116))
- [`d05d715`](https://github.com/caddyserver/caddy/commit/d05d715a)
reverseproxy: HTTP transport: fix PROXY protocol initialization
([#&#8203;6301](https://github.com/caddyserver/caddy/issues/6301))
- [`b2b29dc`](https://github.com/caddyserver/caddy/commit/b2b29dcd)
reverseproxy: Implement health_follow_redirects
([#&#8203;6302](https://github.com/caddyserver/caddy/issues/6302))
- [`e60148e`](https://github.com/caddyserver/caddy/commit/e60148ec)
reverseproxy: Pointer to struct when loading modules; remove
LazyCertPool
([#&#8203;6307](https://github.com/caddyserver/caddy/issues/6307))
- [`5f6758d`](https://github.com/caddyserver/caddy/commit/5f6758da)
reverseproxy: Support HTTP/3 transport to backend
([#&#8203;6312](https://github.com/caddyserver/caddy/issues/6312))
- [`69290d2`](https://github.com/caddyserver/caddy/commit/69290d23)
rewrite: Implement `uri query` operations
([#&#8203;6120](https://github.com/caddyserver/caddy/issues/6120))
- [`29f57fa`](https://github.com/caddyserver/caddy/commit/29f57faa)
rewrite: `uri query` replace operation
([#&#8203;6165](https://github.com/caddyserver/caddy/issues/6165))
- [`c6673ad`](https://github.com/caddyserver/caddy/commit/c6673ad4)
staticresp: Use the evaluated response body for sniffing JSON
content-type
([#&#8203;6249](https://github.com/caddyserver/caddy/issues/6249))
- [`0900844`](https://github.com/caddyserver/caddy/commit/0900844c)
templates: Clarify `include` args docs, add `.ClientIP`
([#&#8203;5898](https://github.com/caddyserver/caddy/issues/5898))
- [`4e8245d`](https://github.com/caddyserver/caddy/commit/4e8245df)
templates: Delete headers on `httpError` to reset to clean slate
([#&#8203;5905](https://github.com/caddyserver/caddy/issues/5905))
- [`18f3429`](https://github.com/caddyserver/caddy/commit/18f34290)
templates: Offically make templates extensible
([#&#8203;5939](https://github.com/caddyserver/caddy/issues/5939))
- [`f98f449`](https://github.com/caddyserver/caddy/commit/f98f449f)
templates: Add `pathEscape` template function and use it in file browser
([#&#8203;6278](https://github.com/caddyserver/caddy/issues/6278))
- [`4173e2c`](https://github.com/caddyserver/caddy/commit/4173e2c7)
tls: accept placeholders in string values of certificate loaders
([#&#8203;5963](https://github.com/caddyserver/caddy/issues/5963))
- [`ed41c92`](https://github.com/caddyserver/caddy/commit/ed41c924)
tls: add reuse_private_keys
([#&#8203;6025](https://github.com/caddyserver/caddy/issues/6025))
- [`e965b11`](https://github.com/caddyserver/caddy/commit/e965b111)
tls: modularize trusted CA providers
([#&#8203;5784](https://github.com/caddyserver/caddy/issues/5784))
- [`0b5720f`](https://github.com/caddyserver/caddy/commit/0b5720fa)
tracing: add trace_id var (`http.vars.trace_id` placeholder)
([#&#8203;6308](https://github.com/caddyserver/caddy/issues/6308))
- [`5ed8689`](https://github.com/caddyserver/caddy/commit/5ed86896)
vars: Allow overriding `http.auth.user.id` in replacer as a special case
([#&#8203;6108](https://github.com/caddyserver/caddy/issues/6108))
- [`d132584`](https://github.com/caddyserver/caddy/commit/d1325842)
vars: Make nil values act as empty string instead of `"<nil>"`
([#&#8203;6174](https://github.com/caddyserver/caddy/issues/6174))

#### New Contributors

- [@&#8203;perhapsmaple](https://github.com/perhapsmaple) made their
first contribution in
[https://github.com/caddyserver/caddy/pull/5848](https://github.com/caddyserver/caddy/pull/5848)
- [@&#8203;ddl-ebrown](https://github.com/ddl-ebrown) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/5908](https://github.com/caddyserver/caddy/pull/5908)
- [@&#8203;dlorenc](https://github.com/dlorenc) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/5949](https://github.com/caddyserver/caddy/pull/5949)
- [@&#8203;ankon](https://github.com/ankon) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/5923](https://github.com/caddyserver/caddy/pull/5923)
- [@&#8203;bmarwell](https://github.com/bmarwell) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/5971](https://github.com/caddyserver/caddy/pull/5971)
- [@&#8203;armadi1809](https://github.com/armadi1809) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/5976](https://github.com/caddyserver/caddy/pull/5976)
- [@&#8203;jum](https://github.com/jum) made their first contribution
in
[https://github.com/caddyserver/caddy/pull/5968](https://github.com/caddyserver/caddy/pull/5968)
- [@&#8203;ddemoss222](https://github.com/ddemoss222) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/5880](https://github.com/caddyserver/caddy/pull/5880)
- [@&#8203;tgeoghegan](https://github.com/tgeoghegan) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/5979](https://github.com/caddyserver/caddy/pull/5979)
- [@&#8203;steffenbusch](https://github.com/steffenbusch) made their
first contribution in
[https://github.com/caddyserver/caddy/pull/6003](https://github.com/caddyserver/caddy/pull/6003)
- [@&#8203;networkException](https://github.com/networkException) made
their first contribution in
[https://github.com/caddyserver/caddy/pull/6010](https://github.com/caddyserver/caddy/pull/6010)
- [@&#8203;insom](https://github.com/insom) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6021](https://github.com/caddyserver/caddy/pull/6021)
- [@&#8203;rithvikvibhu](https://github.com/rithvikvibhu) made their
first contribution in
[https://github.com/caddyserver/caddy/pull/6025](https://github.com/caddyserver/caddy/pull/6025)
- [@&#8203;zachgalvin](https://github.com/zachgalvin) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6022](https://github.com/caddyserver/caddy/pull/6022)
- [@&#8203;subnut](https://github.com/subnut) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6001](https://github.com/caddyserver/caddy/pull/6001)
- [@&#8203;elee1766](https://github.com/elee1766) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/5833](https://github.com/caddyserver/caddy/pull/5833)
- [@&#8203;nebez](https://github.com/nebez) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/5805](https://github.com/caddyserver/caddy/pull/5805)
- [@&#8203;bbaa-bbaa](https://github.com/bbaa-bbaa) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6056](https://github.com/caddyserver/caddy/pull/6056)
- [@&#8203;AnomalRoil](https://github.com/AnomalRoil) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/5961](https://github.com/caddyserver/caddy/pull/5961)
- [@&#8203;jcchavezs](https://github.com/jcchavezs) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6103](https://github.com/caddyserver/caddy/pull/6103)
- [@&#8203;ottenhoff](https://github.com/ottenhoff) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6115](https://github.com/caddyserver/caddy/pull/6115)
- [@&#8203;thirdkeyword](https://github.com/thirdkeyword) made their
first contribution in
[https://github.com/caddyserver/caddy/pull/6151](https://github.com/caddyserver/caddy/pull/6151)
- [@&#8203;jbrown-stripe](https://github.com/jbrown-stripe) made their
first contribution in
[https://github.com/caddyserver/caddy/pull/6161](https://github.com/caddyserver/caddy/pull/6161)
- [@&#8203;ImpostorKeanu](https://github.com/ImpostorKeanu) made their
first contribution in
[https://github.com/caddyserver/caddy/pull/6114](https://github.com/caddyserver/caddy/pull/6114)
- [@&#8203;sellskin](https://github.com/sellskin) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6193](https://github.com/caddyserver/caddy/pull/6193)
- [@&#8203;jadidbourbaki](https://github.com/jadidbourbaki) made their
first contribution in
[https://github.com/caddyserver/caddy/pull/6203](https://github.com/caddyserver/caddy/pull/6203)
- [@&#8203;reallylowest](https://github.com/reallylowest) made their
first contribution in
[https://github.com/caddyserver/caddy/pull/6206](https://github.com/caddyserver/caddy/pull/6206)
- [@&#8203;kylosus](https://github.com/kylosus) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6093](https://github.com/caddyserver/caddy/pull/6093)
- [@&#8203;hassanila](https://github.com/hassanila) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6223](https://github.com/caddyserver/caddy/pull/6223)
- [@&#8203;epelc](https://github.com/epelc) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6225](https://github.com/caddyserver/caddy/pull/6225)
- [@&#8203;danish-mehmood](https://github.com/danish-mehmood) made
their first contribution in
[https://github.com/caddyserver/caddy/pull/6227](https://github.com/caddyserver/caddy/pull/6227)
- [@&#8203;omalk98](https://github.com/omalk98) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/5919](https://github.com/caddyserver/caddy/pull/5919)
- [@&#8203;dev-polymer](https://github.com/dev-polymer) made their
first contribution in
[https://github.com/caddyserver/caddy/pull/6140](https://github.com/caddyserver/caddy/pull/6140)
- [@&#8203;coderwander](https://github.com/coderwander) made their
first contribution in
[https://github.com/caddyserver/caddy/pull/6243](https://github.com/caddyserver/caddy/pull/6243)
- [@&#8203;clauverjat](https://github.com/clauverjat) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6253](https://github.com/caddyserver/caddy/pull/6253)
- [@&#8203;apollo13](https://github.com/apollo13) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6298](https://github.com/caddyserver/caddy/pull/6298)
- [@&#8203;aliasgar55](https://github.com/aliasgar55) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6302](https://github.com/caddyserver/caddy/pull/6302)
- [@&#8203;szepeviktor](https://github.com/szepeviktor) made their
first contribution in
[https://github.com/caddyserver/caddy/pull/6311](https://github.com/caddyserver/caddy/pull/6311)
- [@&#8203;DenebTM](https://github.com/DenebTM) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6278](https://github.com/caddyserver/caddy/pull/6278)
- [@&#8203;Ranveer777](https://github.com/Ranveer777) made their first
contribution in
[https://github.com/caddyserver/caddy/pull/6345](https://github.com/caddyserver/caddy/pull/6345)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/chezmoi-sh/atlas).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zNzcuOCIsInVwZGF0ZWRJblZlciI6IjM3LjM3Ny44IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
@PoneyClairDeLune
Copy link

https://caddyserver.com/docs/caddyfile/directives/encode

The Caddyfile documentation for the encode directive wasn't updated.

@mholt
Copy link
Member

mholt commented Aug 9, 2024

Thanks for the heads up. Just pushed the docs for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature ⚙️ New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants