From e4e85a3e51066f4987a87762c9c69acda093f6ca Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 1 Nov 2020 04:51:48 +0800 Subject: Storage configuration support `[storage]` (#13314) * Fix minio bug * Add tests for storage configuration * Change the Seek flag to keep compitable minio? * Fix test when first-byte-pos of all ranges is greater than the resource length Co-authored-by: techknowlogick --- modules/lfs/content_store.go | 23 ++++++++++++++++++++++- modules/lfs/server.go | 8 ++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) (limited to 'modules/lfs') diff --git a/modules/lfs/content_store.go b/modules/lfs/content_store.go index cf0a05d644..247191a1bf 100644 --- a/modules/lfs/content_store.go +++ b/modules/lfs/content_store.go @@ -8,6 +8,7 @@ import ( "crypto/sha256" "encoding/hex" "errors" + "fmt" "io" "os" @@ -21,6 +22,21 @@ var ( errSizeMismatch = errors.New("Content size does not match") ) +// ErrRangeNotSatisfiable represents an error which request range is not satisfiable. +type ErrRangeNotSatisfiable struct { + FromByte int64 +} + +func (err ErrRangeNotSatisfiable) Error() string { + return fmt.Sprintf("Requested range %d is not satisfiable", err.FromByte) +} + +// IsErrRangeNotSatisfiable returns true if the error is an ErrRangeNotSatisfiable +func IsErrRangeNotSatisfiable(err error) bool { + _, ok := err.(ErrRangeNotSatisfiable) + return ok +} + // ContentStore provides a simple file system based storage. type ContentStore struct { storage.ObjectStorage @@ -35,7 +51,12 @@ func (s *ContentStore) Get(meta *models.LFSMetaObject, fromByte int64) (io.ReadC return nil, err } if fromByte > 0 { - _, err = f.Seek(fromByte, os.SEEK_CUR) + if fromByte >= meta.Size { + return nil, ErrRangeNotSatisfiable{ + FromByte: fromByte, + } + } + _, err = f.Seek(fromByte, io.SeekStart) if err != nil { log.Error("Whilst trying to read LFS OID[%s]: Unable to seek to %d Error: %v", meta.Oid, fromByte, err) } diff --git a/modules/lfs/server.go b/modules/lfs/server.go index 2801f8410c..b093213643 100644 --- a/modules/lfs/server.go +++ b/modules/lfs/server.go @@ -191,8 +191,12 @@ func getContentHandler(ctx *context.Context) { contentStore := &ContentStore{ObjectStorage: storage.LFS} content, err := contentStore.Get(meta, fromByte) if err != nil { - // Errors are logged in contentStore.Get - writeStatus(ctx, 404) + if IsErrRangeNotSatisfiable(err) { + writeStatus(ctx, http.StatusRequestedRangeNotSatisfiable) + } else { + // Errors are logged in contentStore.Get + writeStatus(ctx, 404) + } return } defer content.Close() -- cgit v1.2.3