diff --git a/atlas/atlas.go b/atlas/atlas.go index 06677c651..5ea55e0a5 100644 --- a/atlas/atlas.go +++ b/atlas/atlas.go @@ -121,6 +121,10 @@ func (a *Atlas) SeedMapTile(ctx context.Context, m Map, z, x, y uint) error { return defaultAtlas.SeedMapTile(ctx, m, z, x, y) } + if len(m.Params) > 0 { + return nil + } + ctx = context.WithValue(ctx, observability.ObserveVarMapName, m.Name) // confirm we have a cache backend if a.cacher == nil { @@ -154,6 +158,10 @@ func (a *Atlas) PurgeMapTile(m Map, tile *tegola.Tile) error { return defaultAtlas.PurgeMapTile(m, tile) } + if len(m.Params) > 0 { + return nil + } + if a.cacher == nil { return ErrMissingCache } diff --git a/cache/cache.go b/cache/cache.go index d5d7609b6..a32e1b1cc 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -38,6 +38,7 @@ func ParseKey(str string) (*Key, error) { // remove the base-path and the first slash, then split the parts keyParts := strings.Split(strings.TrimLeft(str, "/"), "/") + // we're expecting a z/x/y scheme if len(keyParts) < 3 || len(keyParts) > 5 { err = ErrInvalidFileKeyParts{ diff --git a/config/config.go b/config/config.go index e4dd0ca48..aef1a70fa 100644 --- a/config/config.go +++ b/config/config.go @@ -196,6 +196,8 @@ func (c *Config) Validate() error { // check for map layer name / zoom collisions // map of layers to providers mapLayers := map[string]map[string]provider.MapLayer{} + // maps with configured parameters for logging + mapsWithCustomParams := []string{} for mapKey, m := range c.Maps { // validate any declared query parameters @@ -203,6 +205,10 @@ func (c *Config) Validate() error { return err } + if len(m.Parameters) > 0 { + mapsWithCustomParams = append(mapsWithCustomParams, string(m.Name)) + } + if _, ok := mapLayers[string(m.Name)]; !ok { mapLayers[string(m.Name)] = map[string]provider.MapLayer{} } @@ -300,6 +306,13 @@ func (c *Config) Validate() error { } } + if len(mapsWithCustomParams) > 0 { + log.Infof( + "Caching is disabled for these maps, since they have configured custom parameters: %s", + strings.Join(mapsWithCustomParams, ", "), + ) + } + // check for blacklisted headers for k := range c.Webserver.Headers { for _, v := range blacklistHeaders { diff --git a/server/middleware_tile_cache.go b/server/middleware_tile_cache.go index a187da91d..243f3d03e 100644 --- a/server/middleware_tile_cache.go +++ b/server/middleware_tile_cache.go @@ -28,6 +28,12 @@ func TileCacheHandler(a *atlas.Atlas, next http.Handler) http.Handler { return } + // ignore requests with query parameters + if r.URL.RawQuery != "" { + next.ServeHTTP(w, r) + return + } + // parse our URI into a cache key structure (remove any configured URIPrefix + "maps/" ) key, err := cache.ParseKey(strings.TrimPrefix(r.URL.Path, path.Join(URIPrefix, "maps"))) if err != nil { diff --git a/server/middleware_tile_cache_test.go b/server/middleware_tile_cache_test.go index c69b2ced7..7563839fe 100644 --- a/server/middleware_tile_cache_test.go +++ b/server/middleware_tile_cache_test.go @@ -79,3 +79,63 @@ func TestMiddlewareTileCacheHandler(t *testing.T) { t.Run(name, fn(tc)) } } + +func TestMiddlewareTileCacheHandlerIgnoreParams(t *testing.T) { + type tcase struct { + uri string + uriPrefix string + } + + fn := func(tc tcase) func(t *testing.T) { + return func(t *testing.T) { + var err error + + if tc.uriPrefix != "" { + server.URIPrefix = tc.uriPrefix + } else { + server.URIPrefix = "/" + } + + a := newTestMapWithLayers(testLayer1, testLayer2, testLayer3) + cacher, _ := memory.New(nil) + a.SetCache(cacher) + + w, router, err := doRequest(a, "GET", tc.uri, nil) + if err != nil { + t.Errorf("error making request, expected nil got %v", err) + return + } + + // we expect the cache to not being used + if w.Header().Get("Tegola-Cache") != "" { + t.Errorf("no header Tegola-Cache is expected, got %v", w.Header().Get("Tegola-Cache")) + return + } + + // play the request again + r, err := http.NewRequest("GET", tc.uri, nil) + if err != nil { + t.Errorf("error making request, expected nil got %v", err) + return + } + + w = httptest.NewRecorder() + router.ServeHTTP(w, r) + + if w.Header().Get("Tegola-Cache") != "" { + t.Errorf("no header Tegola-Cache is expected, got %v", w.Header().Get("Tegola-Cache")) + return + } + } + } + + tests := map[string]tcase{ + "map params": { + uri: "/maps/test-map/10/2/3.pbf?param=value", + }, + } + + for name, tc := range tests { + t.Run(name, fn(tc)) + } +}