Include template not working with precompressed file_server

1. The problem I’m having:

The template “include”, in the form {{include "my/includes/head.html"}}, does not work when using file_server precompressed.

All the HTML, CSS and images have been compressed with zstd.

2. Error messages and/or full log output:

{"level":"debug","ts":1717793321.1165729,"logger":"events","msg":"event","name":"tls_get_certificate","id":"4537077c-8cb7-42b1-8516-a7b2a0b172c8","origin":"tls","data":{"client_hello":{"CipherSuites":[4865,4867,4866,49195,49199,52393,52392,49196,49200,49162,49161,49171,49172,156,157,47,53],"ServerName":"kilgore.idesmi.eu","SupportedCurves":[29,23,24,25,256,257],"SupportedPoints":"AA==","SignatureSchemes":[1027,1283,1539,2052,2053,2054,1025,1281,1537,515,513],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"RemoteAddr":{"IP":"91.187.202.242","Port":2784,"Zone":""},"LocalAddr":{"IP":"10.89.1.122","Port":443,"Zone":""}}}}                                                                                                                                                                
{"level":"debug","ts":1717793321.11661,"logger":"tls.handshake","msg":"choosing certificate","identifier":"kilgore.idesmi.eu","num_choices":1}                                                                                                                              
{"level":"debug","ts":1717793321.116627,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"kilgore.idesmi.eu","subjects":["kilgore.idesmi.eu"],"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"4556931780c56ac8f8d1946daf4deab454829e0b7b54647568c931ea10fb31cc"}                                                                                                                                                                                                                        
{"level":"debug","ts":1717793321.1166348,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"91.187.202.242","remote_port":"2784","subjects":["kilgore.idesmi.eu"],"managed":true,"expiration":1722987616,"hash":"4556931780c56ac8f8d1946daf4deab454829e0b7b54647568c931ea10fb31cc"}                                                                                                                                                                                                                                             
{"level":"debug","ts":1717793321.1477075,"logger":"http.handlers.file_server","msg":"sanitized path join","site_root":"/srv/kilgore.idesmi.eu","fs":"","request_path":"/articles/books.html","result":"/srv/kilgore.idesmi.eu/articles/books.html"}                         
{"level":"debug","ts":1717793321.147939,"logger":"http.handlers.file_server","msg":"opening compressed sidecar file","filename":"/srv/kilgore.idesmi.eu/articles/books.html.zst"}

3. Caddy version:

v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=

4. How I installed and ran Caddy:

Podman

a. System environment:

openSUSE MicroOS 20240605

b. Command:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

c. Service/unit/compose file:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

d. My complete Caddy config:

{
        email example@example.com
        admin off
        default_sni <...>
        cert_issuer acme
        cert_issuer zerossl <...>
        log {
                level WARN
        }
        order webdav before file_server
        order rate_limit before basic_auth
}

(cors) {
        @origin{args[0]} header Origin {args[0]}
        header @origin{args[0]} {
                Access-Control-Allow-Origin {args[0]}
                Access-Control-Allow-Methods "GET, HEAD, PROPFIND"
                Access-Control-Allow-Headers "Authorization, Content-Type, Depth, Range"
                Access-Control-Expose-Headers "Content-Length, Content-Type, Content-Range"
                Access-Control-Allow-Credentials true
        }
}

(ratelimit-low) {
        rate_limit {
                zone static_low {
                        match {
                                method GET
                        }
                        key static
                        events 200
                        window 1m
                }
                zone dynamic_low {
                        key {remote_host}
                        events 4
                        window 5s
                }
        }
        handle_errors 429 {
                respond "Error {err.status_code}! {err.status_text}. Try again later."
        }
}

(ratelimit-high) {
        rate_limit {
                zone static_high {
                        match {
                                method GET
                        }
                        key static
                        events 100
                        window 1s
                }
                zone dynamic_high {
                        key {remote_host}
                        events 200
                        window 2s
                }
        }
        handle_errors 429 {
                respond "Error {err.status_code}! {err.status_text}. Try again later."
        }
}

(compress) {
        encode {
                zstd
                br 2 v2
                gzip
        }
}

(privacy) {
        header {
                # disable FLoC tracking
                Permissions-Policy interest-cohort=()

                # enable HSTS
                Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

                # disable clients from sniffing the media type
                X-Content-Type-Options nosniff

                # clickjacking protection
                X-Frame-Options DENY

                # referrer header only on requests to the same origin
                Referrer-Policy same-origin

                # https://scotthelme.co.uk/content-security-policy-an-introduction/
                # " 'self' https: data: "
                Content-Security-Policy "default-src https://kilgore.idesmi.eu:443"

                # hide that we are running Caddy
                # Server ""
                -Server

                # https://scotthelme.co.uk/coop-and-coep/
                Cross-Origin-Embedder-Policy require-corp

                # https://scotthelme.co.uk/coop-and-coep/
                Cross-Origin-Opener-Policy same-origin

                #
                Cross-Origin-Resource-Policy same-site

                #
                X-Robots-Tag "noindex, noarchive, nofollow"
        }
}

(cache) {
        header {
                Cache-Control "max-age=2592000, immutable"
        }
}

kilgore.idesmi.eu {
        root * /srv/kilgore.idesmi.eu
        #import compress
        import ratelimit-high
        import privacy
        import cache
        templates
        file_server {
                precompressed zstd br
        }
}

What does "does not work " mean? The logs don’t contain any errors. AFAICT everything is working fine. Please be more specific or that’s all we can tell you is “I don’t know. Looks like nothing is wrong.”

1 Like

This is because no error is thrown.

Simply, templates don’t seem to work when using precompressed.
They are printed as text in the webpage seen in the browser.

Tested also with the hitCounter plugin.

Is your HTML file precompressed? If so, don’t. Caddy’s template can’t process the HTML as text if it’s precompressed. I don’t think it should either, it would mean having to decompress then re-compress it to be able to do anything with it. That’s wasteful.

3 Likes

Yes, the HTML files are precompressed as zstd. I will switch back to dynamic compression. Thanks!

1 Like