From d3516916aa0f8ed4e7a4ee99c7d09f6c5a5d567a Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Wed, 18 Jun 2025 21:58:51 -0700 Subject: [PATCH] Fix fetch always adding range to requests Add condition for adding range header to avoid unnecessary header when parallel pull is not being used. Some registries do not properly handle the range header. Signed-off-by: Derek McGowan --- core/remotes/docker/fetcher.go | 8 +++++--- core/remotes/docker/fetcher_test.go | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/core/remotes/docker/fetcher.go b/core/remotes/docker/fetcher.go index 9388d8479e..e32b73b353 100644 --- a/core/remotes/docker/fetcher.go +++ b/core/remotes/docker/fetcher.go @@ -442,7 +442,7 @@ func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string, chunkSize := int64(r.performances.ConcurrentLayerFetchBuffer) parallelism := int64(r.performances.MaxConcurrentDownloads) - if chunkSize < minChunkSize { + if chunkSize < minChunkSize || req.body != nil { parallelism = 1 } log.G(ctx).WithField("initial_parallelism", r.performances.MaxConcurrentDownloads). @@ -452,7 +452,9 @@ func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string, Debug("fetching layer") req.setMediaType(mediatype) req.header.Set("Accept-Encoding", "zstd;q=1.0, gzip;q=0.8, deflate;q=0.5") - req.setOffset(offset) + if parallelism > 1 || offset > 0 { + req.setOffset(offset) + } if err := r.Acquire(ctx, 1); err != nil { return nil, err @@ -478,7 +480,7 @@ func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string, }) remaining, _ := strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 0) - if parallelism > 1 && req.body == nil { + if parallelism > 1 { // If we have a content length, we can use multiple requests to fetch // the content in parallel. This will make download of bigger bodies // faster, at the cost of parallelism more requests and max diff --git a/core/remotes/docker/fetcher_test.go b/core/remotes/docker/fetcher_test.go index 147d410104..3deca502b9 100644 --- a/core/remotes/docker/fetcher_test.go +++ b/core/remotes/docker/fetcher_test.go @@ -50,6 +50,10 @@ func TestFetcherOpen(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { if start > 0 { rw.Header().Set("content-range", fmt.Sprintf("bytes %d-127/128", start)) + } else if r.Header.Get("Range") == "bytes=0-" { + // Simulate registries which do not support range requests + rw.WriteHeader(http.StatusBadRequest) + return } rw.Header().Set("content-length", strconv.Itoa(len(content[start:]))) _, _ = rw.Write(content[start:])