Why caddy 2 is not able to serve static brotli files?

Okay i got one more problem. After i enable this brotli thing all my svg images stop loading and displaying in img tag. I believe it’s related to mime types.

Do all these SVG images have a Brotli sidecar as well?

Content-Type could be an issue. We are only strictly overriding the Content-Encoding in the config, but the issue could be showing up at the file server.

Does that issue (image not loading) also happen for PNG, JPEG etc. files with a Brotli sidecar?

It doesn’t happen because it doesn’t make sense to encode PNG and JPEG with brotli, but svg is basically text. I only use brotli for static text files.

Ah, now I remember why content negotiation is tricky: the Content-Type header is based on file extension, so adding .br to the extension breaks the lookup in the MIME tables.

1 Like

Yup, any solution?

I’m thinking.

It may not be ready before 2.0, but if not it can come after.

Edit: So, yes, there is a solution, but it’s a bit verbose; you can always set the Content-Type header yourself, but it’ll be different for each different kind of file you serve. Still, if it’s a pretty standard static site, there won’t be more than ~5-10 types.

How can i do it? Now i only use brotli for css, js and svg

header gets executed before handle and rewrite, so theoretically we can easily manually re-specify the Content-Type based on the request without even messing with the existing Brotli sidecar detection/rewrite. The file server should leave the manually-set Content-Type header alone, I think?

Try something like this.

@brotli {
  file {
    try_files {path}.br
  }
}
handle @brotli {
  header Content-Encoding br
  rewrite {http.matchers.file.relative}
}

@svg {
  file
  path *.svg
}
header @svg Content-Type image/svg+xml

@css {
  file
  path *.css
}
header @css Content-Type text/css

@js {
  file
  path *.js
}
header @js Content-Type text/javascript

If you wanted to be fast and dirty but risk setting the wrong Content-Type on a 404, you could skip all of the matcher declarations and just go with:

@brotli {
  file {
    try_files {path}.br
  }
}
handle @brotli {
  header Content-Encoding br
  rewrite {http.matchers.file.relative}
}

header *.svg Content-Type image/svg+xml
header *.css Content-Type text/css
header *.js  Content-Type text/javascript
1 Like

@Whitestrake Except, path matchers have to start with / if they’re inlined, i.e. header *.svg ... won’t work.

(I wonder if we should change that. But it’d presume that no first arguments would really start with *.)

That’s a good point! The quick and dirty version would have to be:

header /*.svg Content-Type image/svg+xml
header /*.css Content-Type text/css
header /*.js  Content-Type text/javascript

Should work, right?

Actually, wait, would that only match by single path element? Like they’d match /foo.svg but not /foo/bar.svg?

Maybe it just does have to be the long version. Oh well, it is a bit more accurate that way.

Correct, it’d have to be the named matcher (“long way” :slight_smile: ) – since * in the middle of a path are like globular matches.

1 Like

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

For whoever finds this in the future, this is now possible since v2.4.0, using the file_server directive’s precompressed option.

3 Likes