improve (s3): support for prefixes with > 1k objects (#395)

Previously filestash would only show the first 1000 objects in a given
s3 prefix.

We solve this by paginating the ListObjectsV2 responses and iterating
over all pages instead of just the first one.

Tested by manually connecting to a private s3 bucket with multiple
thousands of objects under a single prefix and verifying that all
objects are visible in the UI.
This commit is contained in:
Jay Thomason 2021-05-25 05:00:23 -07:00 committed by GitHub
parent bbe21185b6
commit 136afbeac2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -144,32 +144,32 @@ func (s S3Backend) Ls(path string) (files []os.FileInfo, err error) {
}
client := s3.New(s.createSession(p.bucket))
objs, errTmp := client.ListObjectsV2(&s3.ListObjectsV2Input{
Bucket: aws.String(p.bucket),
Prefix: aws.String(p.path),
Delimiter: aws.String("/"),
})
if errTmp != nil {
err = errTmp
return
}
for i, object := range objs.Contents {
if i == 0 && *object.Key == p.path {
continue
}
files = append(files, &File{
FName: filepath.Base(*object.Key),
FType: "file",
FTime: object.LastModified.Unix(),
FSize: *object.Size,
err = client.ListObjectsV2Pages(
&s3.ListObjectsV2Input{
Bucket: aws.String(p.bucket),
Prefix: aws.String(p.path),
Delimiter: aws.String("/"),
},
func(objs *s3.ListObjectsV2Output, lastPage bool) bool {
for i, object := range objs.Contents {
if i == 0 && *object.Key == p.path {
continue
}
files = append(files, &File{
FName: filepath.Base(*object.Key),
FType: "file",
FTime: object.LastModified.Unix(),
FSize: *object.Size,
})
}
for _, object := range objs.CommonPrefixes {
files = append(files, &File{
FName: filepath.Base(*object.Prefix),
FType: "directory",
})
}
return true
})
}
for _, object := range objs.CommonPrefixes {
files = append(files, &File{
FName: filepath.Base(*object.Prefix),
FType: "directory",
})
}
return files, err
}