From 9fc6e9eb9a999895985377ba66a1d2b4fd4102fa Mon Sep 17 00:00:00 2001 From: Egor Sanin Date: Wed, 19 Nov 2025 11:10:53 -0800 Subject: [PATCH 1/2] fix: handle signed urls --- pmtiles/bucket.go | 9 ++++++++- pmtiles/bucket_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/pmtiles/bucket.go b/pmtiles/bucket.go index 612a728..2f2ee19 100644 --- a/pmtiles/bucket.go +++ b/pmtiles/bucket.go @@ -319,7 +319,14 @@ func NormalizeBucketKey(bucket string, prefix string, key string) (string, strin if strings.HasSuffix(dir, "/") { dir = dir[:len(dir)-1] } - return u.Scheme + "://" + u.Host + dir, file, nil + keyWithQuery := file + if u.RawQuery != "" { + keyWithQuery = keyWithQuery + "?" + u.RawQuery + } + if u.Fragment != "" { + keyWithQuery = keyWithQuery + "#" + u.Fragment + } + return u.Scheme + "://" + u.Host + dir, keyWithQuery, nil } fileprotocol := "file://" if string(os.PathSeparator) != "/" { diff --git a/pmtiles/bucket_test.go b/pmtiles/bucket_test.go index 7bc4004..9fdfb3a 100644 --- a/pmtiles/bucket_test.go +++ b/pmtiles/bucket_test.go @@ -44,6 +44,13 @@ func TestNormalizeHttp(t *testing.T) { assert.Equal(t, "http://example.com/foo", bucket) } +func TestNormalizeHttpWithQuery(t *testing.T) { + url := "http://example.com/foo/bar.pmtiles?X-Goog-Algorithm=GOOG4&X-Goog-Signature=abc123" + bucket, key, _ := NormalizeBucketKey("", "", url) + assert.Equal(t, "http://example.com/foo", bucket) + assert.Equal(t, "bar.pmtiles?X-Goog-Algorithm=GOOG4&X-Goog-Signature=abc123", key) +} + func TestNormalizePathPrefixServer(t *testing.T) { bucket, key, _ := NormalizeBucketKey("", "../foo", "") assert.Equal(t, "", key) @@ -84,6 +91,27 @@ func TestHttpBucketRequestNormal(t *testing.T) { assert.Nil(t, err) } +func TestHttpBucketRequestWithQuery(t *testing.T) { + mock := ClientMock{} + header := http.Header{} + header.Add("ETag", "etag") + bucket := HTTPBucket{"http://tiles.example.com/tiles", &mock} + mock.response = &http.Response{ + StatusCode: 200, + Body: io.NopCloser(strings.NewReader("abc")), + Header: header, + } + data, etag, status, err := bucket.NewRangeReaderEtag(context.Background(), "a/b/c?token=xyz", 50, 3, "") + assert.Equal(t, "http://tiles.example.com/tiles/a/b/c?token=xyz", mock.request.URL.String()) + assert.Equal(t, 200, status) + assert.Nil(t, err) + b, err := io.ReadAll(data) + assert.Nil(t, err) + assert.Equal(t, "abc", string(b)) + assert.Equal(t, "etag", etag) + assert.Nil(t, err) +} + func TestHttpBucketRequestRequestEtag(t *testing.T) { mock := ClientMock{} header := http.Header{} From a81c6b36682bc0405d369a1ca8dc0f3f189cf302 Mon Sep 17 00:00:00 2001 From: Egor Sanin Date: Wed, 19 Nov 2025 11:23:38 -0800 Subject: [PATCH 2/2] Remove fragment handling --- pmtiles/bucket.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pmtiles/bucket.go b/pmtiles/bucket.go index 2f2ee19..b5b60ab 100644 --- a/pmtiles/bucket.go +++ b/pmtiles/bucket.go @@ -323,9 +323,6 @@ func NormalizeBucketKey(bucket string, prefix string, key string) (string, strin if u.RawQuery != "" { keyWithQuery = keyWithQuery + "?" + u.RawQuery } - if u.Fragment != "" { - keyWithQuery = keyWithQuery + "#" + u.Fragment - } return u.Scheme + "://" + u.Host + dir, keyWithQuery, nil } fileprotocol := "file://"