protomaps / go-pmtiles

Single-file executable tool for working with PMTiles archives
https://docs.protomaps.com/pmtiles/cli
BSD 3-Clause "New" or "Revised" License
370 stars 51 forks source link

[feature] Set cache headers #8

Closed eddy-geek closed 2 years ago

eddy-geek commented 2 years ago

It seems that tiles are not cached (trying on latest chrome, linux)

Looking at others they all set cache-control:

bdon commented 2 years ago

Are you using a reverse proxy in front of the go-pmtiles http server such as nginx or caddy?

We can add some configurable settings for Cache-Control, but it may be hard to make it flexible enough for all use cases. In any case: real, production use of the go-pmtiles server will likely need SSL termination somewhere to support HTTP/2, so there are two general approaches:

1) keep go-pmtiles minimal with the expectation that it is used in conjunction with a frontend server like nginx or even structure it as a Caddy plugin - that server can handle the more detailed production HTTP stuff like SSL, caching headers, CORS and eTags 2) Expect that go-pmtiles serves tiles directly to the browser with no intermediary, in which case we should design a way to configure all that; but this is a significant increase in scope

For an example of a parallel project to accomplish almost the same thing, see https://github.com/consbio/mbtileserver

eddy-geek commented 2 years ago

You are right. I am inded using an nginx reverse proxy for https, and I made it add aggressive Cache-Control headers with the last line here:

location /tile/ {
    proxy_pass  http://127.0.0.1:8077/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    add_header Cache-Control "max-age=31536000, stale-while-revalidate=31536000, stale-if-error=31536000" always;
}
bdon commented 2 years ago

In https://github.com/protomaps/go-pmtiles/commit/82ab855965337a9497eb6d1ff1026c125b8c2a7d I added a note that it's recommended to run go-pmtiles behind a reverse proxy.

We could add more HTTP and SSL related configuration to the go code, but it will likely never be enough to cover all production situations, and programs like NGINX are well established and specific to that job. The header configuration I'm leaving in is related to --cors since that's necessary for using go-pmtiles on localhost.

Do you think this is a good enough approach? One counterexample I can think of is if HTTP headers are customized on the upstream storage system like S3 that are then passed down in tile responses, but I'm having a hard time coming up with a specific need for this.

eddy-geek commented 2 years ago

Frankly I don't have a strong opinion.

A random idea, maybe collaborate with that mbtileserver project to share this common "boilerplate"?

Anyway, as a user, I have it working with nginx now, so feel free to close this :-)

bdon commented 2 years ago

@eddy-geek in my experience Caddy is a good nginx alternative with a simple way to set up TLS. But as you can see from the configuration for mbtileserv, certificates are inherently complex so I'd prefer to keep them out of this code, KISS indeed.

Thanks!