From 13d37f875b25a78bbffb396a988751a9a2555d08 Mon Sep 17 00:00:00 2001 From: roger2hk Date: Wed, 10 Jul 2024 14:28:47 +0000 Subject: [PATCH] Only add the immutable `Cache-Control` header when the number of hash in the returned tile match the requested tile width --- cmd/example-mysql/main.go | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/cmd/example-mysql/main.go b/cmd/example-mysql/main.go index 202e59f1..51a1578e 100644 --- a/cmd/example-mysql/main.go +++ b/cmd/example-mysql/main.go @@ -73,10 +73,10 @@ func main() { }) http.HandleFunc("GET /tile/{level}/{index...}", func(w http.ResponseWriter, r *http.Request) { - level, index, err := parseTileLevelIndex(r.PathValue("level"), r.PathValue("index")) + level, index, width, err := parseTileLevelIndexWidth(r.PathValue("level"), r.PathValue("index")) if err != nil { w.WriteHeader(http.StatusBadRequest) - if _, werr := w.Write([]byte(err.Error())); werr != nil { + if _, werr := w.Write([]byte(fmt.Sprintf("Malformed URL: %s", err.Error()))); werr != nil { klog.Errorf("/tile/{level}/{index...}: %v", werr) } return @@ -94,7 +94,12 @@ func main() { return } - w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") + // Only add the immutable Cache-Control header when the number of hash in the returned tile match the requested tile width. + // This ensures the response will not be cached when returning a partial tile on a full tile request. + if len(tile)/32 == int(width) { + w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") + } + if _, err := w.Write(tile); err != nil { klog.Errorf("/tile/{level}/{index...}: %v", err) return @@ -120,19 +125,18 @@ func main() { } } -// parseTileLevelIndex takes level and index in string, validates and returns them in uint64. -// Note that this doesn't return any of the partial tile component. +// parseTileLevelWidthIndex takes level and index in string, validates and returns the level, index and width in uint64. // // Examples: // "/tile/0/x001/x234/067" means level 0 and index 1234067 of a full tile. // "/tile/0/x001/x234/067.p/8" means level 0, index 1234067 and width 8 of a partial tile. -func parseTileLevelIndex(level, index string) (uint64, uint64, error) { +func parseTileLevelIndexWidth(level, index string) (uint64, uint64, uint64, error) { l, err := strconv.ParseUint(level, 10, 64) if err != nil { - return 0, 0, fmt.Errorf("malformed URL: failed to parse tile level") + return 0, 0, 0, fmt.Errorf("failed to parse tile level") } - var i uint64 + var i, w uint64 switch indexPaths := strings.Split(index, "/"); len(indexPaths) { // Full tile = 3 // Partial tile = 4 @@ -142,11 +146,19 @@ func parseTileLevelIndex(level, index string) (uint64, uint64, error) { indexPath = strings.ReplaceAll(indexPath, ".p", "") i, err = strconv.ParseUint(indexPath, 10, 64) if err != nil { - return 0, 0, fmt.Errorf("malformed URL: failed to parse tile index") + return 0, 0, 0, fmt.Errorf("failed to parse tile index") + } + + w = 256 + if len(indexPaths) == 4 { + w, err = strconv.ParseUint(indexPaths[3], 10, 64) + if err != nil { + return 0, 0, 0, fmt.Errorf("failed to parse tile index") + } } default: - return 0, 0, fmt.Errorf("malformed URL: failed to parse tile index") + return 0, 0, 0, fmt.Errorf("failed to parse tile index") } - return l, i, nil + return l, i, w, nil }