diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index 972506103a..d1b80daccf 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -320,6 +320,7 @@ func PostBlobsUploads(ctx *context.Context) { // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks func GetBlobsUpload(ctx *context.Context) { + image := ctx.PathParam("image") uuid := ctx.PathParam("uuid") upload, err := packages_model.GetBlobUploadByID(ctx, uuid) @@ -334,6 +335,7 @@ func GetBlobsUpload(ctx *context.Context) { // FIXME: undefined behavior when the uploaded content is empty: https://github.com/opencontainers/distribution-spec/issues/578 respHeaders := &containerHeaders{ + Location: fmt.Sprintf("/v2/%s/%s/blobs/uploads/%s", ctx.Package.Owner.LowerName, image, upload.ID), UploadUUID: upload.ID, Status: http.StatusNoContent, } @@ -386,7 +388,7 @@ func PatchBlobsUpload(ctx *context.Context) { UploadUUID: uploader.ID, Status: http.StatusAccepted, } - if contentRange != "" { + if uploader.Size() > 0 { respHeaders.Range = fmt.Sprintf("0-%d", uploader.Size()-1) } setResponseHeaders(ctx.Resp, respHeaders) diff --git a/tests/integration/api_packages_container_test.go b/tests/integration/api_packages_container_test.go index 8ae33dc35c..204f099bbe 100644 --- a/tests/integration/api_packages_container_test.go +++ b/tests/integration/api_packages_container_test.go @@ -297,11 +297,22 @@ func TestPackageContainer(t *testing.T) { SetHeader("Content-Range", "1-10") MakeRequest(t, req, http.StatusRequestedRangeNotSatisfiable) - contentRange := fmt.Sprintf("0-%d", len(blobContent)-1) - req.SetHeader("Content-Range", contentRange) + // first patch without Content-Range + req = NewRequestWithBody(t, "PATCH", setting.AppURL+uploadURL[1:], bytes.NewReader(blobContent[:1])). + AddTokenAuth(userToken) + resp = MakeRequest(t, req, http.StatusAccepted) + assert.NotEmpty(t, resp.Header().Get("Location")) + assert.Equal(t, "0-0", resp.Header().Get("Range")) + + // then send remaining content with Content-Range + req = NewRequestWithBody(t, "PATCH", setting.AppURL+uploadURL[1:], bytes.NewReader(blobContent[1:])). + SetHeader("Content-Range", fmt.Sprintf("1-%d", len(blobContent)-1)). + AddTokenAuth(userToken) resp = MakeRequest(t, req, http.StatusAccepted) + contentRange := fmt.Sprintf("0-%d", len(blobContent)-1) assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid")) + assert.NotEmpty(t, resp.Header().Get("Location")) assert.Equal(t, contentRange, resp.Header().Get("Range")) uploadURL = resp.Header().Get("Location") @@ -311,6 +322,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, uploadURL, resp.Header().Get("Location")) assert.Equal(t, contentRange, resp.Header().Get("Range")) pbu, err = packages_model.GetBlobUploadByID(db.DefaultContext, uuid)