Caddy not sending `content-encoding: gzip` for precompressed gzip files

1. The problem I’m having:

Caddy is serving precompressed gzip files without the content-encoding: gzip header. I am not sure if this is by design or not. If it is by design how would one add the content-encoding: gzip` header to the response?

curl request/response example:

curl -vL http://localhost/Build/Web.data.gz
*   Trying 127.0.0.1:80...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /Build/Web.data.gz HTTP/1.1
> Host: localhost
> User-Agent: curl/7.84.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Content-Length: 15188528
< Content-Type: application/gzip
< Etag: "rqwkjb91jjk"
< Last-Modified: Thu, 02 Mar 2023 16:59:35 GMT
< Server: Caddy
< Date: Thu, 02 Mar 2023 17:37:58 GMT
<
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
* Failure writing output to destination
* Closing connection 0

2. Error messages and/or full log output:

No error or additional logs

3. Caddy version:

v2.6.2 h1:wKoFIxpmOJLGl3QXoo6PNbYvGW4xLEgo32GPBEjWL8o=

4. How I installed and ran Caddy:

Directly downloaded the executable and run it with caddy run --watch

a. System environment:

macOS version 13.0 (22A380)
Intel x64

b. Command:

`caddy run --watch`

d. My complete Caddy config:

localhost:80, localhost:443 {
    root * Builds/Web
    tls internal

    encode gzip zstd

    file_server {
        precompressed br gzip
    }
}

The way precompressed works is by making a request for the non-gzipped version of the file, i.e. http://localhost/Build/Web.data, and Caddy will serve that using the compressed copy on disk.

When you make a request directly for the gzipped file, Caddy will serve it as-is, with Content-Type: application/gzip.

If you make a request for the non-compressed URL, then it implies that the client wants to read the contents uncompressed. If you request .gz then it implies you want to read it as compressed (e.g. for download). It’s semantically different.

1 Like

Gotcha. Is there any way to get the content-encoding: gzip header to be written in this case? I am using a library that is specifically looking for the header and it fails without it.

You can use the header directive to set it.

Would I just put the header directives inside the file_server? I thought I had tried that and it didnt work but I could be mistaken.

No. See how the Caddyfile is structured:

1 Like

Many thanks! For anyone who finds this thread a matcher + a header directive does the trick:
header /Build/*.gz Content-Encoding gzip

3 Likes

Thank you for sharing your solution. Was this by any chance for Unity? I added the header directive but the .gz files are still being served without Content-Encoding: gzip. Here’s my Caddyfile:

{
  http_port 2014
}

localhost:2015

encode gzip

file_server {
  precompressed gzip
}

header /Build/*.gz Content-Encoding gzip

Sorry nevermind, my browser was caching the gzips.

1 Like

You nailed it. Was for Unity WebGL. Seems to work now with gzip and brotli with this change.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.