Caddy file-server failing to serve .gz files?

1. Output of caddy version:

v2.5.2 h1:eCJdLyEyAGzuQTa5Mh3gETnYWDClo1LjtQm2q9RNZrs=

2. How I run Caddy:

a. System environment:

Oracle Linux Server 8.6 aarch64 on Oracle Cloud

b. Command:

caddy start

and subsequently after editing the caddyfile

caddy reload

c. Service/unit/compose file:

Just running caddy start in the directory with my caddyfile

d. My complete Caddy config:

roanv.nl {
	#tls /etc/ssl/certs/certificate.pem /etc/ssl/private/key.pem
	respond "Nothing to see here, move along!"
}

pl3xmap.roanv.nl {
	root * /mnt/data/purpur/plugins/Pl3xMap/web
	file_server
}

3. The problem I’m having:

Bit of a weird issue, hard to explain as well

Bit of background first:
I am trying to serve files from a few different map viewers, main one being https://pl3xmap.roanv.nl/
Pl3xmap renders it’s own maps and outputs the data (including webpage) to a web folder
It includes it’s own internal webserver to show this rendered data.

Notice how those coordinates at the bottom are completely broken, same thing for the data in the bottom left.

4. Error messages and/or full log output:

No errors from caddy, site loads (and works) fine except this specific issue
Firefox error:
Uncaught (in promise) SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
Chrome error:
Uncaught (in promise) SyntaxError: Unexpected token '', "� �"... is not valid JSON

5. What I already tried:

I shot the pl3xmap developer a message, they responded with:
your server doesn't seem to support gzip, its reading the raw binary from the .gz files instead of decompressing them

It looks like Caddy is failing to render a few .gz files that supply that specific data to the web frontend.
(Probaby less relevant, but some info on those files: Pl3xMap File Protocol · BillyGalbreath/Pl3xMap Wiki · GitHub )
This does work when I simply reverse-proxy pl3xmaps internal webserver through caddy

I did see the precompressed file-server & encode directives, I don’t think they are relevant here though.
Nevertheless, I did give them a try, no dice.

tbh, I’m pretty stumped on this issue :sweat_smile:

Edit:
I did of course search through these forums and google/ddg for related issues, most things I found seemed severely outdated or not applicable to this issue though.

1 Like

I’m not sure I follow – nearly all the resources for that page are .gz files and they render fine. Where do the coordinates come from, exactly?

web/tiles/blocks.gz and web/tiles/world/biomes.gz
It seems like caddy is trying to read those JSON files without decompressing them first?

Hmm, so there’s no difference for me between this (blocks.gz):

$ curl -v 'https://pl3xmap.roanv.nl/tiles/blocks.gz' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0' -H 'Accept: */*' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate, br' -H 'Referer: https://pl3xmap.roanv.nl/' -H 'Connection: keep-alive' -H 'Sec-Fetch-Dest: empty' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Site: same-origin' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache' -H 'TE: trailers'

and this (a tile):

$ curl -v 'https://pl3xmap.roanv.nl/tiles/world/0/blockinfo/-3_1.pl3xmap.gz' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0' -H 'Accept: */*' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate, br' -H 'Referer: https://pl3xmap.roanv.nl/?world=world&renderer=basic&zoom=0&x=0&z=5' -H 'Connection: keep-alive' -H 'Sec-Fetch-Dest: empty' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Site: same-origin' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache' -H 'TE: trailers'

(These curl commands are from going to the devtools in the browser and right-clicking the request, then click Copy → Copy as cURL)

They both respond appropriately as gzip content, you can see that from the content-type header.

Caddy appears to be doing its job right. Caddy hasn’t been configured to decompress these. The application is requesting a .gz file, not gzipped content (which would respond with a content-encoding header). Right now, the way the client application is working, the client is supposed to do the decompression.

Hmm, interesting
I don’t know what could be going wrong here then

On somebody else’s apache server with the same service it works fine https://map.pl3x.net

apache: https://map.pl3x.net/tiles/blocks.gz (json data is displayed)
caddy: https://pl3xmap.roanv.nl/tiles/blocks.gz (.gz file gets downloaded)

Running the curl command on the request for the biomes.gz file:

Apache:

HTTP/1.1 200 OK
< Date: Thu, 18 Aug 2022 16:29:42 GMT
< Server: Apache/2.4.54 (Debian)
< Content-Encoding: gzip
< Cache-Control: max-age=0, must-revalidate, no-cache
< Accept-Ranges: bytes
< ETag: "1660375614840"
< Last-Modified: Sat, 13 Aug 2022 07:26:54 GMT
< Content-Type: application/json
< Content-Length: 1932
< Keep-Alive: timeout=5, max=100
< Connection: Keep-Alive

Caddy:

< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Content-Length: 1931
< Content-Type: application/gzip
< Etag: "rgt1vg1hn"
< Last-Modified: Thu, 18 Aug 2022 09:47:40 GMT
< Server: Caddy
< Date: Thu, 18 Aug 2022 16:29:22 GMT
<

Apache responds with Content-Encoding: gzip and Content-Type: application/json
My Caddy setup only has Content-Type: application/gzip

Now to find out how I can configure this correctly :stuck_out_tongue:

What is the apache config?

<VirtualHost *:443>
        ServerName map.pl3x.net
        DocumentRoot /home/pl3x/www/map.pl3x.net/
        <Directory /home/pl3x/www/map.pl3x.net/>
                Options Indexes FollowSymLinks
                AllowOverride All
                Require all granted
        </Directory>
        <FilesMatch "(\.gz)$">
                Header set Content-Encoding gzip
                Header append Vary Accept-Encoding
        </FilesMatch>
        SSLEngine On
        Include /etc/letsencrypt/options-ssl-apache.conf
        SSLCertificateFile /etc/letsencrypt/live/map.pl3x.net/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/map.pl3x.net/privkey.pem
</VirtualHost>

Apachy server is not mine, this part makes it pretty clear what is needed :sweat_smile:

        <FilesMatch "(\.gz)$">
                Header set Content-Encoding gzip
                Header append Vary Accept-Encoding
        </FilesMatch>

Ah yeah, so just do:

header Content-Encoding gzip

See if that helps.

1 Like

That would set content-encoding for every file right?

I need to only set that for gzipped files

Currently having a scroll through the docs again :stuck_out_tongue:

Figured it out, had to use handle to change the header for files with the .gz prefix

pl3xmap.roanv.nl {
	root * /mnt/data/purpur/plugins/Pl3xMap/web
	file_server
	@gz {
		path *.gz
	}
	handle @gz {
		header Content-Encoding gzip
	}

}

Thanks for your help!

1 Like

To simplify, I’d write it like this:

pl3xmap.roanv.nl {
	root * /mnt/data/purpur/plugins/Pl3xMap/web

	@gz path *.gz
	header @gz Content-Encoding gzip

	file_server
}
3 Likes

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