Skip to content

Commit 178fd90

Browse files
GiteaBotwxiaoguang
andauthored
Fix container range bug (#34725) (#34732)
Backport #34725 by wxiaoguang Fix #34724 Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
1 parent b39f7a3 commit 178fd90

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

routers/api/packages/container/container.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -313,13 +313,12 @@ func InitiateUploadBlob(ctx *context.Context) {
313313

314314
setResponseHeaders(ctx.Resp, &containerHeaders{
315315
Location: fmt.Sprintf("/v2/%s/%s/blobs/uploads/%s", ctx.Package.Owner.LowerName, image, upload.ID),
316-
Range: "0-0",
317316
UploadUUID: upload.ID,
318317
Status: http.StatusAccepted,
319318
})
320319
}
321320

322-
// https://docs.docker.com/registry/spec/api/#get-blob-upload
321+
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
323322
func GetUploadBlob(ctx *context.Context) {
324323
uuid := ctx.PathParam("uuid")
325324

@@ -333,13 +332,18 @@ func GetUploadBlob(ctx *context.Context) {
333332
return
334333
}
335334

336-
setResponseHeaders(ctx.Resp, &containerHeaders{
337-
Range: fmt.Sprintf("0-%d", upload.BytesReceived),
335+
// FIXME: undefined behavior when the uploaded content is empty: https://github.com/opencontainers/distribution-spec/issues/578
336+
respHeaders := &containerHeaders{
338337
UploadUUID: upload.ID,
339338
Status: http.StatusNoContent,
340-
})
339+
}
340+
if upload.BytesReceived > 0 {
341+
respHeaders.Range = fmt.Sprintf("0-%d", upload.BytesReceived-1)
342+
}
343+
setResponseHeaders(ctx.Resp, respHeaders)
341344
}
342345

346+
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#single-post
343347
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
344348
func UploadBlob(ctx *context.Context) {
345349
image := ctx.PathParam("image")
@@ -377,12 +381,15 @@ func UploadBlob(ctx *context.Context) {
377381
return
378382
}
379383

380-
setResponseHeaders(ctx.Resp, &containerHeaders{
384+
respHeaders := &containerHeaders{
381385
Location: fmt.Sprintf("/v2/%s/%s/blobs/uploads/%s", ctx.Package.Owner.LowerName, image, uploader.ID),
382-
Range: fmt.Sprintf("0-%d", uploader.Size()-1),
383386
UploadUUID: uploader.ID,
384387
Status: http.StatusAccepted,
385-
})
388+
}
389+
if contentRange != "" {
390+
respHeaders.Range = fmt.Sprintf("0-%d", uploader.Size()-1)
391+
}
392+
setResponseHeaders(ctx.Resp, respHeaders)
386393
}
387394

388395
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks

tests/integration/api_packages_container_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ func TestPackageContainer(t *testing.T) {
311311
resp = MakeRequest(t, req, http.StatusNoContent)
312312

313313
assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid"))
314-
assert.Equal(t, fmt.Sprintf("0-%d", len(blobContent)), resp.Header().Get("Range"))
314+
assert.Equal(t, contentRange, resp.Header().Get("Range"))
315315

316316
pbu, err = packages_model.GetBlobUploadByID(db.DefaultContext, uuid)
317317
assert.NoError(t, err)
@@ -342,7 +342,8 @@ func TestPackageContainer(t *testing.T) {
342342
resp = MakeRequest(t, req, http.StatusNoContent)
343343

344344
assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid"))
345-
assert.Equal(t, "0-0", resp.Header().Get("Range"))
345+
// FIXME: undefined behavior when the uploaded content is empty: https://github.com/opencontainers/distribution-spec/issues/578
346+
assert.Nil(t, resp.Header().Values("Range"))
346347

347348
req = NewRequest(t, "DELETE", setting.AppURL+uploadURL[1:]).
348349
AddTokenAuth(userToken)

0 commit comments

Comments
 (0)