aboutsummaryrefslogtreecommitdiff
path: root/weed/s3api/s3api_objects_list_handlers.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/s3api/s3api_objects_list_handlers.go')
-rw-r--r--weed/s3api/s3api_objects_list_handlers.go67
1 files changed, 44 insertions, 23 deletions
diff --git a/weed/s3api/s3api_objects_list_handlers.go b/weed/s3api/s3api_objects_list_handlers.go
index 78b77a044..b2ad915b9 100644
--- a/weed/s3api/s3api_objects_list_handlers.go
+++ b/weed/s3api/s3api_objects_list_handlers.go
@@ -47,10 +47,6 @@ func (s3a *S3ApiServer) ListObjectsV2Handler(w http.ResponseWriter, r *http.Requ
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidMaxKeys)
return
}
- if delimiter != "" && delimiter != "/" {
- s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented)
- return
- }
marker := continuationToken
if continuationToken == "" {
@@ -103,10 +99,6 @@ func (s3a *S3ApiServer) ListObjectsV1Handler(w http.ResponseWriter, r *http.Requ
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidMaxKeys)
return
}
- if delimiter != "" && delimiter != "/" {
- s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented)
- return
- }
response, err := s3a.listFilerEntries(bucket, originalPrefix, maxKeys, marker, delimiter)
@@ -171,22 +163,51 @@ func (s3a *S3ApiServer) listFilerEntries(bucket string, originalPrefix string, m
cursor.maxKeys--
}
} else {
- storageClass := "STANDARD"
- if v, ok := entry.Extended[s3_constants.AmzStorageClass]; ok {
- storageClass = string(v)
+ var delimiterFound bool
+ if delimiter != "" {
+ // keys that contain the same string between the prefix and the first occurrence of the delimiter are grouped together as a commonPrefix.
+ // extract the string between the prefix and the delimiter and add it to the commonPrefixes if it's unique.
+ fullPath := fmt.Sprintf("%s/%s", dir, entry.Name)[len(bucketPrefix):]
+ delimitedPath := strings.SplitN(fullPath, delimiter, 2)
+ if len(delimitedPath) == 2 {
+
+ // S3 clients expect the delimited prefix to contain the delimiter.
+ delimitedPrefix := delimitedPath[0] + delimiter
+
+ for i := range commonPrefixes {
+ if commonPrefixes[i].Prefix == delimitedPrefix {
+ delimiterFound = true
+ break
+ }
+ }
+
+ if !delimiterFound {
+ commonPrefixes = append(commonPrefixes, PrefixEntry{
+ Prefix: delimitedPrefix,
+ })
+ cursor.maxKeys--
+ delimiterFound = true
+ }
+ }
+ }
+ if !delimiterFound {
+ storageClass := "STANDARD"
+ if v, ok := entry.Extended[s3_constants.AmzStorageClass]; ok {
+ storageClass = string(v)
+ }
+ contents = append(contents, ListEntry{
+ Key: fmt.Sprintf("%s/%s", dir, entry.Name)[len(bucketPrefix):],
+ LastModified: time.Unix(entry.Attributes.Mtime, 0).UTC(),
+ ETag: "\"" + filer.ETag(entry) + "\"",
+ Size: int64(filer.FileSize(entry)),
+ Owner: CanonicalUser{
+ ID: fmt.Sprintf("%x", entry.Attributes.Uid),
+ DisplayName: entry.Attributes.UserName,
+ },
+ StorageClass: StorageClass(storageClass),
+ })
+ cursor.maxKeys--
}
- contents = append(contents, ListEntry{
- Key: fmt.Sprintf("%s/%s", dir, entry.Name)[len(bucketPrefix):],
- LastModified: time.Unix(entry.Attributes.Mtime, 0).UTC(),
- ETag: "\"" + filer.ETag(entry) + "\"",
- Size: int64(filer.FileSize(entry)),
- Owner: CanonicalUser{
- ID: fmt.Sprintf("%x", entry.Attributes.Uid),
- DisplayName: entry.Attributes.UserName,
- },
- StorageClass: StorageClass(storageClass),
- })
- cursor.maxKeys--
}
})
if doErr != nil {