Skip to content

Commit 7636bd5

Browse files
azrk8s-infra-cherrypick-robot
authored andcommitted
fix when multipart fetching and the server does not return content length
Signed-off-by: Adrien Delorme <[email protected]>
1 parent 948bd66 commit 7636bd5

3 files changed

Lines changed: 16 additions & 3 deletions

File tree

core/content/helpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func Copy(ctx context.Context, cw Writer, or io.Reader, size int64, expected dig
200200
}
201201
if size != 0 && copied < size-ws.Offset {
202202
// Short writes would return its own error, this indicates a read failure
203-
return fmt.Errorf("failed to read expected number of bytes: %w", io.ErrUnexpectedEOF)
203+
return fmt.Errorf("short read: expected %d bytes but got %d: %w", size-ws.Offset, copied, io.ErrUnexpectedEOF)
204204
}
205205
if err := cw.Commit(ctx, size, expected, opts...); err != nil {
206206
if errors.Is(err, ErrReset) {

core/remotes/docker/fetcher.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,10 @@ func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string,
480480
})
481481

482482
remaining, _ := strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 0)
483+
if remaining <= chunkSize {
484+
parallelism = 1
485+
}
486+
483487
if parallelism > 1 {
484488
// If we have a content length, we can use multiple requests to fetch
485489
// the content in parallel. This will make download of bigger bodies

core/remotes/docker/fetcher_test.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ func TestFetcherOpenParallel(t *testing.T) {
133133
size := int64(3 * 1024 * 1024)
134134
content := make([]byte, size)
135135
rand.New(rand.NewSource(1)).Read(content)
136+
sendContentLength := true
136137

137138
f := dockerFetcher{
138139
&dockerBase{
@@ -179,12 +180,16 @@ func TestFetcherOpenParallel(t *testing.T) {
179180
}
180181

181182
if len(rng) == 0 {
182-
rw.Header().Set("content-length", strconv.Itoa(len(content)))
183+
if sendContentLength {
184+
rw.Header().Set("content-length", strconv.Itoa(len(content)))
185+
}
183186
_, _ = rw.Write(content)
184187
} else {
185188
b := content[rng[0].start : rng[0].start+rng[0].length]
186189
rw.Header().Set("content-range", rng[0].contentRange(size))
187-
rw.Header().Set("content-length", strconv.Itoa(len(b)))
190+
if sendContentLength {
191+
rw.Header().Set("content-length", strconv.Itoa(len(b)))
192+
}
188193
_, _ = rw.Write(b)
189194
}
190195

@@ -237,6 +242,10 @@ func TestFetcherOpenParallel(t *testing.T) {
237242

238243
checkReader(25)
239244

245+
sendContentLength = false
246+
checkReader(25)
247+
sendContentLength = true
248+
240249
ignoreContentRange = true
241250
checkReader(25)
242251
ignoreContentRange = false

0 commit comments

Comments
 (0)