From 35abc92237e2c7dd2c02486cc42624a7e7c247a2 Mon Sep 17 00:00:00 2001 From: Milos Gajdos Date: Wed, 22 Nov 2023 16:06:33 +0000 Subject: [PATCH] fix: if reference exceeds the threshold return 400 and detail If the reference in the API request exceeds the threshold allowed by the reference package (NOTE: this isn't defined by distribution specification!) we return 500 back to the client. This commit makes sure we return 400 and the explanation of the error in the returned JSON payload. Signed-off-by: Milos Gajdos --- registry/api/errcode/errors.go | 13 +++++++++++-- registry/storage/cache/memory/memory.go | 6 ++++++ registry/storage/cache/redis/redis.go | 6 ++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/registry/api/errcode/errors.go b/registry/api/errcode/errors.go index 54856cc5c..a8b52c188 100644 --- a/registry/api/errcode/errors.go +++ b/registry/api/errcode/errors.go @@ -224,11 +224,20 @@ func (errs Errors) MarshalJSON() ([]byte, error) { msg = err.Code.Message() } - tmpErrs.Errors = append(tmpErrs.Errors, Error{ + tmpErr := Error{ Code: err.Code, Message: msg, Detail: err.Detail, - }) + } + + // if the detail contains error extract the error message + // otherwise json.Marshal will not serialize it at all + // https://github.com/golang/go/issues/10748 + if detail, ok := tmpErr.Detail.(error); ok { + tmpErr.Detail = detail.Error() + } + + tmpErrs.Errors = append(tmpErrs.Errors, tmpErr) } return json.Marshal(tmpErrs) diff --git a/registry/storage/cache/memory/memory.go b/registry/storage/cache/memory/memory.go index 8097939f7..f83894bf5 100644 --- a/registry/storage/cache/memory/memory.go +++ b/registry/storage/cache/memory/memory.go @@ -47,6 +47,12 @@ func NewInMemoryBlobDescriptorCacheProvider(size int) cache.BlobDescriptorCacheP func (imbdcp *inMemoryBlobDescriptorCacheProvider) RepositoryScoped(repo string) (distribution.BlobDescriptorService, error) { if _, err := reference.ParseNormalizedNamed(repo); err != nil { + if err == reference.ErrNameTooLong { + return nil, distribution.ErrRepositoryNameInvalid{ + Name: repo, + Reason: reference.ErrNameTooLong, + } + } return nil, err } diff --git a/registry/storage/cache/redis/redis.go b/registry/storage/cache/redis/redis.go index 87ec43e3f..d2596b7bc 100644 --- a/registry/storage/cache/redis/redis.go +++ b/registry/storage/cache/redis/redis.go @@ -50,6 +50,12 @@ func NewRedisBlobDescriptorCacheProvider(pool *redis.Client) cache.BlobDescripto // RepositoryScoped returns the scoped cache. func (rbds *redisBlobDescriptorService) RepositoryScoped(repo string) (distribution.BlobDescriptorService, error) { if _, err := reference.ParseNormalizedNamed(repo); err != nil { + if err == reference.ErrNameTooLong { + return nil, distribution.ErrRepositoryNameInvalid{ + Name: repo, + Reason: reference.ErrNameTooLong, + } + } return nil, err }