mirror of
https://github.com/minio/minio.git
synced 2025-11-07 12:52:58 -05:00
Implement proper delimiter and prefix handling
With this change Minio server now responds with, delimited
'object names' in conjunction with prefix filtering
~~~
<ListBucketResult>
<Name>example-bucket</Name>
<Prefix></Prefix>
<Marker></Marker>
<MaxKeys>1000</MaxKeys>
<Delimiter>/</Delimiter>
<IsTruncated>false</IsTruncated>
<Contents>
<Key>sample.html</Key>
<LastModified>2011-02-26T01:56:20.000Z</LastModified>
<ETag>example-bucket#sample.html</ETag>
<Size>142863</Size>
<Owner>
<ID>minio</ID>
<DisplayName>minio</DisplayName>
</Owner>
<StorageClass>STANDARD</StorageClass>
</Contents>
<CommonPrefixes>
<Prefix>photos/</Prefix>
</CommonPrefixes>
</ListBucketResult>
~~~
~~~
<ListBucketResult>
<Name>example-bucket</Name>
<Prefix>photos/2006/</Prefix>
<Marker></Marker>
<MaxKeys>1000</MaxKeys>
<Delimiter>/</Delimiter>
<IsTruncated>false</IsTruncated>
<CommonPrefixes>
<Prefix>photos/2006/feb/</Prefix>
</CommonPrefixes>
<CommonPrefixes>
<Prefix>photos/2006/jan/</Prefix>
</CommonPrefixes>
</ListBucketResult>
~~~
This commit is contained in:
@@ -45,7 +45,7 @@ func (server *minioApi) listObjectsHandler(w http.ResponseWriter, req *http.Requ
|
||||
switch err := err.(type) {
|
||||
case nil: // success
|
||||
{
|
||||
response := generateObjectsListResult(bucket, objects, resources.IsTruncated)
|
||||
response := generateObjectsListResult(bucket, objects, resources)
|
||||
w.Write(writeObjectHeadersAndResponse(w, response, acceptsContentType))
|
||||
}
|
||||
case mstorage.BucketNotFound:
|
||||
|
||||
@@ -34,10 +34,8 @@ type ObjectListResponse struct {
|
||||
MaxKeys int
|
||||
Delimiter string
|
||||
IsTruncated bool
|
||||
Contents []*Item `xml:,innerxml`
|
||||
CommonPrefixes struct {
|
||||
Prefix string
|
||||
} `xml:,innerxml`
|
||||
Contents []*Item `xml:,innerxml`
|
||||
CommonPrefixes []*Prefix `xml:,innerxml`
|
||||
}
|
||||
|
||||
// Bucket list response format
|
||||
@@ -49,6 +47,10 @@ type BucketListResponse struct {
|
||||
} `xml:,innerxml` // Buckets are nested
|
||||
}
|
||||
|
||||
type Prefix struct {
|
||||
Prefix string
|
||||
}
|
||||
|
||||
// Bucket struct
|
||||
type Bucket struct {
|
||||
Name string
|
||||
|
||||
@@ -68,8 +68,9 @@ func (b ItemKey) Less(i, j int) bool { return b[i].Key < b[j].Key }
|
||||
//
|
||||
// output:
|
||||
// populated struct that can be serialized to match xml and json api spec output
|
||||
func generateObjectsListResult(bucket string, objects []mstorage.ObjectMetadata, isTruncated bool) ObjectListResponse {
|
||||
func generateObjectsListResult(bucket string, objects []mstorage.ObjectMetadata, bucketResources mstorage.BucketResourcesMetadata) ObjectListResponse {
|
||||
var contents []*Item
|
||||
var prefixes []*Prefix
|
||||
var owner = Owner{}
|
||||
var data = ObjectListResponse{}
|
||||
|
||||
@@ -78,6 +79,9 @@ func generateObjectsListResult(bucket string, objects []mstorage.ObjectMetadata,
|
||||
|
||||
for _, object := range objects {
|
||||
var content = &Item{}
|
||||
if object.Key == "" {
|
||||
continue
|
||||
}
|
||||
content.Key = object.Key
|
||||
content.LastModified = object.Created.Format(dateFormat)
|
||||
content.ETag = object.ETag
|
||||
@@ -89,7 +93,16 @@ func generateObjectsListResult(bucket string, objects []mstorage.ObjectMetadata,
|
||||
sort.Sort(ItemKey(contents))
|
||||
data.Name = bucket
|
||||
data.Contents = contents
|
||||
data.MaxKeys = MAX_OBJECT_LIST
|
||||
data.IsTruncated = isTruncated
|
||||
data.MaxKeys = bucketResources.Maxkeys
|
||||
data.Prefix = bucketResources.Prefix
|
||||
data.Delimiter = bucketResources.Delimiter
|
||||
data.Marker = bucketResources.Marker
|
||||
data.IsTruncated = bucketResources.IsTruncated
|
||||
for _, prefix := range bucketResources.CommonPrefixes {
|
||||
var prefixItem = &Prefix{}
|
||||
prefixItem.Prefix = prefix
|
||||
prefixes = append(prefixes, prefixItem)
|
||||
}
|
||||
data.CommonPrefixes = prefixes
|
||||
return data
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user