From f2d79f1900280d53994ab2b896c672d1095e74fc Mon Sep 17 00:00:00 2001 From: immanuwell Date: Mon, 25 May 2026 17:45:45 +0400 Subject: [PATCH] fix: preserve nested repository paths in proxy prefetch --- proxy/proxyserver/prefetch.go | 2 +- proxy/proxyserver/server_test.go | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/proxy/proxyserver/prefetch.go b/proxy/proxyserver/prefetch.go index 9a5cde202..c51937690 100644 --- a/proxy/proxyserver/prefetch.go +++ b/proxy/proxyserver/prefetch.go @@ -82,7 +82,7 @@ type DefaultTagParser struct{} // ParseTag implements the TagParser interface. // Expects tag strings in the format //. func (p *DefaultTagParser) ParseTag(tag string) (namespace, name string, err error) { - parts := strings.Split(tag, "/") + parts := strings.SplitN(tag, "/", 3) if len(parts) < 3 { return "", "", fmt.Errorf("invalid tag format: %s", tag) } diff --git a/proxy/proxyserver/server_test.go b/proxy/proxyserver/server_test.go index a5160ad3d..3b8a017eb 100644 --- a/proxy/proxyserver/server_test.go +++ b/proxy/proxyserver/server_test.go @@ -216,6 +216,39 @@ func TestPrefetchV1(t *testing.T) { require.NoError(err) } +func TestPrefetchV1NestedRepositoryPath(t *testing.T) { + require := require.New(t) + + mocks, cleanup := newServerMocks(t) + defer cleanup() + + addr := mocks.startServer() + + repo := "kraken-test" + namespace := "preheat" + tag := "team/service/abcdef:v1.0.0" + + layers := core.DigestListFixture(3) + manifest, bs := dockerutil.ManifestFixture(layers[0], layers[1], layers[2]) + + b, err := json.Marshal(prefetchBody{ + Tag: fmt.Sprintf("%s/%s/%s", repo, namespace, tag), + TraceId: "abc", + }) + require.NoError(err) + + tagRequest := url.QueryEscape(fmt.Sprintf("%s/%s", namespace, tag)) + mocks.tagClient.EXPECT().Get(tagRequest).Return(manifest, nil) + mocks.originClient.EXPECT().DownloadBlob(gomock.Any(), namespace, manifest, mockutil.MatchWriter(bs)).Return(nil) + mocks.originClient.EXPECT().DownloadBlob(gomock.Any(), namespace, layers[1], io.Discard).Return(nil) + mocks.originClient.EXPECT().DownloadBlob(gomock.Any(), namespace, layers[2], io.Discard).Return(nil) + + _, err = httputil.Post( + fmt.Sprintf("http://%s/proxy/v1/registry/prefetch", addr), + httputil.SendBody(bytes.NewReader(b))) + require.NoError(err) +} + func TestPrefetchV2(t *testing.T) { require := require.New(t)