aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2023-09-13 09:18:52 +0800
committerGitHub <noreply@github.com>2023-09-13 01:18:52 +0000
commit8ecdc93f8b04f2d2e2e26bedb25fde045f0aff64 (patch)
treecac2d527e43a5d5d199d536f253eab49641c04b4
parent7d56459c6c5e1c54fd6676e6ed1478039b9e21e5 (diff)
downloadgitea-8ecdc93f8b04f2d2e2e26bedb25fde045f0aff64.tar.gz
gitea-8ecdc93f8b04f2d2e2e26bedb25fde045f0aff64.zip
Fix object storage path handling (#27024)
Object storage path rules: * No single `/` or `.`, use empty string for root path * Need to use trailing `/` for a list prefix to distinguish a "dir/"
-rw-r--r--modules/storage/minio.go28
-rw-r--r--modules/storage/minio_test.go34
2 files changed, 48 insertions, 14 deletions
diff --git a/modules/storage/minio.go b/modules/storage/minio.go
index 714530ab50..b58ab67dc7 100644
--- a/modules/storage/minio.go
+++ b/modules/storage/minio.go
@@ -136,9 +136,18 @@ func NewMinioStorage(ctx context.Context, cfg *setting.Storage) (ObjectStorage,
}
func (m *MinioStorage) buildMinioPath(p string) string {
- p = util.PathJoinRelX(m.basePath, p)
+ p = strings.TrimPrefix(util.PathJoinRelX(m.basePath, p), "/") // object store doesn't use slash for root path
if p == "." {
- p = "" // minio doesn't use dot as relative path
+ p = "" // object store doesn't use dot as relative path
+ }
+ return p
+}
+
+func (m *MinioStorage) buildMinioDirPrefix(p string) string {
+ // ending slash is required for avoiding matching like "foo/" and "foobar/" with prefix "foo"
+ p = m.buildMinioPath(p) + "/"
+ if p == "/" {
+ p = "" // object store doesn't use slash for root path
}
return p
}
@@ -237,20 +246,11 @@ func (m *MinioStorage) URL(path, name string) (*url.URL, error) {
// IterateObjects iterates across the objects in the miniostorage
func (m *MinioStorage) IterateObjects(dirName string, fn func(path string, obj Object) error) error {
opts := minio.GetObjectOptions{}
- lobjectCtx, cancel := context.WithCancel(m.ctx)
- defer cancel()
-
- basePath := m.basePath
- if dirName != "" {
- // ending slash is required for avoiding matching like "foo/" and "foobar/" with prefix "foo"
- basePath = m.buildMinioPath(dirName) + "/"
- }
-
- for mObjInfo := range m.client.ListObjects(lobjectCtx, m.bucket, minio.ListObjectsOptions{
- Prefix: basePath,
+ for mObjInfo := range m.client.ListObjects(m.ctx, m.bucket, minio.ListObjectsOptions{
+ Prefix: m.buildMinioDirPrefix(dirName),
Recursive: true,
}) {
- object, err := m.client.GetObject(lobjectCtx, m.bucket, mObjInfo.Key, opts)
+ object, err := m.client.GetObject(m.ctx, m.bucket, mObjInfo.Key, opts)
if err != nil {
return convertMinioErr(err)
}
diff --git a/modules/storage/minio_test.go b/modules/storage/minio_test.go
index 56dfd9100a..c6fbb91ab4 100644
--- a/modules/storage/minio_test.go
+++ b/modules/storage/minio_test.go
@@ -31,6 +31,40 @@ func TestMinioStorageIterator(t *testing.T) {
})
}
+func TestMinioStoragePath(t *testing.T) {
+ m := &MinioStorage{basePath: ""}
+ assert.Equal(t, "", m.buildMinioPath("/"))
+ assert.Equal(t, "", m.buildMinioPath("."))
+ assert.Equal(t, "a", m.buildMinioPath("/a"))
+ assert.Equal(t, "a/b", m.buildMinioPath("/a/b/"))
+ assert.Equal(t, "", m.buildMinioDirPrefix(""))
+ assert.Equal(t, "a/", m.buildMinioDirPrefix("/a/"))
+
+ m = &MinioStorage{basePath: "/"}
+ assert.Equal(t, "", m.buildMinioPath("/"))
+ assert.Equal(t, "", m.buildMinioPath("."))
+ assert.Equal(t, "a", m.buildMinioPath("/a"))
+ assert.Equal(t, "a/b", m.buildMinioPath("/a/b/"))
+ assert.Equal(t, "", m.buildMinioDirPrefix(""))
+ assert.Equal(t, "a/", m.buildMinioDirPrefix("/a/"))
+
+ m = &MinioStorage{basePath: "/base"}
+ assert.Equal(t, "base", m.buildMinioPath("/"))
+ assert.Equal(t, "base", m.buildMinioPath("."))
+ assert.Equal(t, "base/a", m.buildMinioPath("/a"))
+ assert.Equal(t, "base/a/b", m.buildMinioPath("/a/b/"))
+ assert.Equal(t, "base/", m.buildMinioDirPrefix(""))
+ assert.Equal(t, "base/a/", m.buildMinioDirPrefix("/a/"))
+
+ m = &MinioStorage{basePath: "/base/"}
+ assert.Equal(t, "base", m.buildMinioPath("/"))
+ assert.Equal(t, "base", m.buildMinioPath("."))
+ assert.Equal(t, "base/a", m.buildMinioPath("/a"))
+ assert.Equal(t, "base/a/b", m.buildMinioPath("/a/b/"))
+ assert.Equal(t, "base/", m.buildMinioDirPrefix(""))
+ assert.Equal(t, "base/a/", m.buildMinioDirPrefix("/a/"))
+}
+
func TestS3StorageBadRequest(t *testing.T) {
if os.Getenv("CI") == "" {
t.Skip("S3Storage not present outside of CI")