From dd53278c19d7f165cfc78ac87e17e52768bb994c Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 15 Jun 2025 09:12:44 +0800 Subject: [PATCH] fix --- routers/api/packages/container/container.go | 23 ++++++++++++------- .../api_packages_container_test.go | 5 ++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index 53f1f130f8..2316657498 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -313,13 +313,12 @@ func InitiateUploadBlob(ctx *context.Context) { setResponseHeaders(ctx.Resp, &containerHeaders{ Location: fmt.Sprintf("/v2/%s/%s/blobs/uploads/%s", ctx.Package.Owner.LowerName, image, upload.ID), - Range: "0-0", UploadUUID: upload.ID, Status: http.StatusAccepted, }) } -// https://docs.docker.com/registry/spec/api/#get-blob-upload +// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks func GetUploadBlob(ctx *context.Context) { uuid := ctx.PathParam("uuid") @@ -333,13 +332,18 @@ func GetUploadBlob(ctx *context.Context) { return } - setResponseHeaders(ctx.Resp, &containerHeaders{ - Range: fmt.Sprintf("0-%d", upload.BytesReceived), + // FIXME: undefined behavior when the uploaded content is empty: https://github.com/opencontainers/distribution-spec/issues/578 + respHeaders := &containerHeaders{ UploadUUID: upload.ID, Status: http.StatusNoContent, - }) + } + if upload.BytesReceived > 0 { + respHeaders.Range = fmt.Sprintf("0-%d", upload.BytesReceived-1) + } + setResponseHeaders(ctx.Resp, respHeaders) } +// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#single-post // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks func UploadBlob(ctx *context.Context) { image := ctx.PathParam("image") @@ -377,12 +381,15 @@ func UploadBlob(ctx *context.Context) { return } - setResponseHeaders(ctx.Resp, &containerHeaders{ + respHeaders := &containerHeaders{ Location: fmt.Sprintf("/v2/%s/%s/blobs/uploads/%s", ctx.Package.Owner.LowerName, image, uploader.ID), - Range: fmt.Sprintf("0-%d", uploader.Size()-1), UploadUUID: uploader.ID, Status: http.StatusAccepted, - }) + } + if contentRange != "" { + respHeaders.Range = fmt.Sprintf("0-%d", uploader.Size()-1) + } + setResponseHeaders(ctx.Resp, respHeaders) } // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks diff --git a/tests/integration/api_packages_container_test.go b/tests/integration/api_packages_container_test.go index 9cdd84d5ee..773a9cb8ef 100644 --- a/tests/integration/api_packages_container_test.go +++ b/tests/integration/api_packages_container_test.go @@ -311,7 +311,7 @@ func TestPackageContainer(t *testing.T) { resp = MakeRequest(t, req, http.StatusNoContent) assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid")) - assert.Equal(t, fmt.Sprintf("0-%d", len(blobContent)), resp.Header().Get("Range")) + assert.Equal(t, contentRange, resp.Header().Get("Range")) pbu, err = packages_model.GetBlobUploadByID(db.DefaultContext, uuid) assert.NoError(t, err) @@ -342,7 +342,8 @@ func TestPackageContainer(t *testing.T) { resp = MakeRequest(t, req, http.StatusNoContent) assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid")) - assert.Equal(t, "0-0", resp.Header().Get("Range")) + // FIXME: undefined behavior when the uploaded content is empty: https://github.com/opencontainers/distribution-spec/issues/578 + assert.Nil(t, resp.Header().Values("Range")) req = NewRequest(t, "DELETE", setting.AppURL+uploadURL[1:]). AddTokenAuth(userToken)