@@ -231,7 +231,7 @@ func GetRepositoryList(ctx *context.Context) {
231231// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#mounting-a-blob-from-another-repository 
232232// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#single-post 
233233// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks 
234- func  InitiateUploadBlob (ctx  * context.Context ) {
234+ func  PostBlobsUploads (ctx  * context.Context ) {
235235	image  :=  ctx .PathParam ("image" )
236236
237237	mount  :=  ctx .FormTrim ("mount" )
@@ -313,14 +313,13 @@ 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  
323- func  GetUploadBlob (ctx  * context.Context ) {
321+ // https://github. com/opencontainers/distribution- spec/blob/main/spec.md#pushing-a- blob-in-chunks  
322+ func  GetBlobsUpload (ctx  * context.Context ) {
324323	uuid  :=  ctx .PathParam ("uuid" )
325324
326325	upload , err  :=  packages_model .GetBlobUploadByID (ctx , uuid )
@@ -333,15 +332,20 @@ 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 
344- func  UploadBlob (ctx  * context.Context ) {
348+ func  PatchBlobsUpload (ctx  * context.Context ) {
345349	image  :=  ctx .PathParam ("image" )
346350
347351	uploader , err  :=  container_service .NewBlobUploader (ctx , ctx .PathParam ("uuid" ))
@@ -377,16 +381,19 @@ 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 
389- func  EndUploadBlob (ctx  * context.Context ) {
396+ func  PutBlobsUpload (ctx  * context.Context ) {
390397	image  :=  ctx .PathParam ("image" )
391398
392399	digest  :=  ctx .FormTrim ("digest" )
@@ -455,7 +462,7 @@ func EndUploadBlob(ctx *context.Context) {
455462}
456463
457464// https://docs.docker.com/registry/spec/api/#delete-blob-upload 
458- func  CancelUploadBlob (ctx  * context.Context ) {
465+ func  DeleteBlobsUpload (ctx  * context.Context ) {
459466	uuid  :=  ctx .PathParam ("uuid" )
460467
461468	_ , err  :=  packages_model .GetBlobUploadByID (ctx , uuid )
@@ -479,16 +486,15 @@ func CancelUploadBlob(ctx *context.Context) {
479486}
480487
481488func  getBlobFromContext (ctx  * context.Context ) (* packages_model.PackageFileDescriptor , error ) {
482- 	d  :=  ctx .PathParam ("digest" )
483- 
484- 	if  digest .Digest (d ).Validate () !=  nil  {
489+ 	d  :=  digest .Digest (ctx .PathParam ("digest" ))
490+ 	if  d .Validate () !=  nil  {
485491		return  nil , container_model .ErrContainerBlobNotExist 
486492	}
487493
488494	return  workaroundGetContainerBlob (ctx , & container_model.BlobSearchOptions {
489495		OwnerID : ctx .Package .Owner .ID ,
490496		Image :   ctx .PathParam ("image" ),
491- 		Digest :  d ,
497+ 		Digest :  string ( d ) ,
492498	})
493499}
494500
@@ -528,9 +534,8 @@ func GetBlob(ctx *context.Context) {
528534
529535// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#deleting-blobs 
530536func  DeleteBlob (ctx  * context.Context ) {
531- 	d  :=  ctx .PathParam ("digest" )
532- 
533- 	if  digest .Digest (d ).Validate () !=  nil  {
537+ 	d  :=  digest .Digest (ctx .PathParam ("digest" ))
538+ 	if  d .Validate () !=  nil  {
534539		apiErrorDefined (ctx , errBlobUnknown )
535540		return 
536541	}
@@ -546,7 +551,7 @@ func DeleteBlob(ctx *context.Context) {
546551}
547552
548553// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-manifests 
549- func  UploadManifest (ctx  * context.Context ) {
554+ func  PutManifest (ctx  * context.Context ) {
550555	reference  :=  ctx .PathParam ("reference" )
551556
552557	mci  :=  & manifestCreationInfo {
@@ -602,18 +607,18 @@ func UploadManifest(ctx *context.Context) {
602607}
603608
604609func  getBlobSearchOptionsFromContext (ctx  * context.Context ) (* container_model.BlobSearchOptions , error ) {
605- 	reference  :=  ctx .PathParam ("reference" )
606- 
607610	opts  :=  & container_model.BlobSearchOptions {
608611		OwnerID :    ctx .Package .Owner .ID ,
609612		Image :      ctx .PathParam ("image" ),
610613		IsManifest : true ,
611614	}
612615
613- 	if  digest .Digest (reference ).Validate () ==  nil  {
614- 		opts .Digest  =  reference 
616+ 	reference  :=  ctx .PathParam ("reference" )
617+ 	if  d  :=  digest .Digest (reference ); d .Validate () ==  nil  {
618+ 		opts .Digest  =  string (d )
615619	} else  if  referencePattern .MatchString (reference ) {
616620		opts .Tag  =  reference 
621+ 		opts .OnlyLead  =  true 
617622	} else  {
618623		return  nil , container_model .ErrContainerBlobNotExist 
619624	}
@@ -730,7 +735,7 @@ func serveBlob(ctx *context.Context, pfd *packages_model.PackageFileDescriptor)
730735}
731736
732737// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#content-discovery 
733- func  GetTagList (ctx  * context.Context ) {
738+ func  GetTagsList (ctx  * context.Context ) {
734739	image  :=  ctx .PathParam ("image" )
735740
736741	if  _ , err  :=  packages_model .GetPackageByName (ctx , ctx .Package .Owner .ID , packages_model .TypeContainer , image ); err  !=  nil  {
0 commit comments