mirror of
https://github.com/versity/versitygw.git
synced 2026-01-07 12:15:18 +00:00
fix: Changes the backend.Walk implementation to return non-truncated result if both delimiter and max-keys are provided
Fixes #816 `ListObjects(V2)` used to return truncated response, if delimiter is provided and the result is limited by max-keys and the number of common prefixes is the same as `max-keys`. e.g PUT -> `foo/bar` PUT -> `foo/quxx` LIST: `max-keys=1;delim=/` -> foo/ `ListObjects(V2)` should return `foo/` as common prefix and `truncated` should be `false`. The PR makes this fix to return `non-truncated` response for the above described case.
This commit is contained in:
@@ -44,12 +44,19 @@ func Walk(ctx context.Context, fileSystem fs.FS, prefix, delimiter, marker strin
|
||||
cpmap := make(map[string]struct{})
|
||||
var objects []s3response.Object
|
||||
|
||||
// if max is 0, it should return empty non-truncated result
|
||||
if max == 0 {
|
||||
return WalkResults{
|
||||
Truncated: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var pastMarker bool
|
||||
if marker == "" {
|
||||
pastMarker = true
|
||||
}
|
||||
|
||||
pastMax := max == 0
|
||||
var pastMax bool
|
||||
var newMarker string
|
||||
var truncated bool
|
||||
|
||||
@@ -76,14 +83,6 @@ func Walk(ctx context.Context, fileSystem fs.FS, prefix, delimiter, marker strin
|
||||
return fs.SkipDir
|
||||
}
|
||||
|
||||
if pastMax {
|
||||
if len(objects) != 0 {
|
||||
newMarker = *objects[len(objects)-1].Key
|
||||
truncated = true
|
||||
}
|
||||
return fs.SkipAll
|
||||
}
|
||||
|
||||
// After this point, return skipflag instead of nil
|
||||
// so we can skip a directory without an early return
|
||||
var skipflag error
|
||||
@@ -116,7 +115,15 @@ func Walk(ctx context.Context, fileSystem fs.FS, prefix, delimiter, marker strin
|
||||
if err != nil {
|
||||
return fmt.Errorf("directory to object %q: %w", path, err)
|
||||
}
|
||||
if pastMax {
|
||||
truncated = true
|
||||
return fs.SkipAll
|
||||
}
|
||||
objects = append(objects, dirobj)
|
||||
if (len(objects) + len(cpmap)) == int(max) {
|
||||
newMarker = path
|
||||
pastMax = true
|
||||
}
|
||||
|
||||
return skipflag
|
||||
}
|
||||
@@ -160,9 +167,15 @@ func Walk(ctx context.Context, fileSystem fs.FS, prefix, delimiter, marker strin
|
||||
if err != nil {
|
||||
return fmt.Errorf("file to object %q: %w", path, err)
|
||||
}
|
||||
if pastMax {
|
||||
truncated = true
|
||||
return fs.SkipAll
|
||||
}
|
||||
|
||||
objects = append(objects, obj)
|
||||
|
||||
if max > 0 && (len(objects)+len(cpmap)) == int(max) {
|
||||
if (len(objects) + len(cpmap)) == int(max) {
|
||||
newMarker = path
|
||||
pastMax = true
|
||||
}
|
||||
|
||||
@@ -200,8 +213,13 @@ func Walk(ctx context.Context, fileSystem fs.FS, prefix, delimiter, marker strin
|
||||
if err != nil {
|
||||
return fmt.Errorf("file to object %q: %w", path, err)
|
||||
}
|
||||
if pastMax {
|
||||
truncated = true
|
||||
return fs.SkipAll
|
||||
}
|
||||
objects = append(objects, obj)
|
||||
if (len(objects) + len(cpmap)) == int(max) {
|
||||
newMarker = path
|
||||
pastMax = true
|
||||
}
|
||||
return skipflag
|
||||
@@ -222,11 +240,14 @@ func Walk(ctx context.Context, fileSystem fs.FS, prefix, delimiter, marker strin
|
||||
return skipflag
|
||||
}
|
||||
|
||||
if pastMax {
|
||||
truncated = true
|
||||
return fs.SkipAll
|
||||
}
|
||||
cpmap[cpref] = struct{}{}
|
||||
if (len(objects) + len(cpmap)) == int(max) {
|
||||
newMarker = cpref
|
||||
truncated = true
|
||||
return fs.SkipAll
|
||||
pastMax = true
|
||||
}
|
||||
|
||||
return skipflag
|
||||
@@ -252,6 +273,10 @@ func Walk(ctx context.Context, fileSystem fs.FS, prefix, delimiter, marker strin
|
||||
})
|
||||
}
|
||||
|
||||
if !truncated {
|
||||
newMarker = ""
|
||||
}
|
||||
|
||||
return WalkResults{
|
||||
CommonPrefixes: commonPrefixes,
|
||||
Objects: objects,
|
||||
|
||||
Reference in New Issue
Block a user