mirror of
https://github.com/minio/minio.git
synced 2025-11-07 21:02: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:
@@ -314,6 +314,29 @@ func (p *Path) getAllFiles(path string, fl os.FileInfo, err error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func delimiter(path, delimiter string) string {
|
||||
delimited := ""
|
||||
if !strings.Contains(path, delimiter) {
|
||||
return delimited
|
||||
}
|
||||
index := strings.Index(path, delimiter)
|
||||
if index == -1 {
|
||||
return delimited
|
||||
}
|
||||
delimitedIndex := index + len(delimiter)
|
||||
delimited = path[:delimitedIndex]
|
||||
return delimited
|
||||
}
|
||||
|
||||
func appendU(slice []string, i string) []string {
|
||||
for _, ele := range slice {
|
||||
if ele == i {
|
||||
return slice
|
||||
}
|
||||
}
|
||||
return append(slice, i)
|
||||
}
|
||||
|
||||
type ByObjectKey []mstorage.ObjectMetadata
|
||||
|
||||
func (b ByObjectKey) Len() int { return len(b) }
|
||||
@@ -350,31 +373,44 @@ func (storage *storage) ListObjects(bucket string, resources mstorage.BucketReso
|
||||
goto ret
|
||||
}
|
||||
// TODO handle resources.Marker
|
||||
if resources.Delimiter != "" {
|
||||
metadata := mstorage.ObjectMetadata{
|
||||
Bucket: bucket,
|
||||
Maxkeys: resources.Maxkeys,
|
||||
Prefix: resources.Prefix,
|
||||
Marker: resources.Marker,
|
||||
Delimiter: resources.Delimiter,
|
||||
switch true {
|
||||
case resources.Delimiter != "" && resources.Prefix == "":
|
||||
delimited := delimiter(name, resources.Delimiter)
|
||||
switch true {
|
||||
case delimited == "":
|
||||
metadata := mstorage.ObjectMetadata{
|
||||
Bucket: bucket,
|
||||
Key: name,
|
||||
Created: file.ModTime(),
|
||||
Size: file.Size(),
|
||||
ETag: bucket + "#" + name,
|
||||
}
|
||||
metadataList = append(metadataList, metadata)
|
||||
case delimited != "":
|
||||
resources.CommonPrefixes = appendU(resources.CommonPrefixes, delimited)
|
||||
}
|
||||
metadataList = append(metadataList, metadata)
|
||||
}
|
||||
if resources.Delimiter != "" && strings.HasPrefix(name, resources.Prefix) {
|
||||
metadata := mstorage.ObjectMetadata{}
|
||||
metadataList = append(metadataList, metadata)
|
||||
}
|
||||
if strings.HasPrefix(name, resources.Prefix) {
|
||||
case resources.Delimiter != "" && strings.HasPrefix(name, resources.Prefix):
|
||||
delimited := delimiter(name, resources.Delimiter)
|
||||
switch true {
|
||||
case delimited == "":
|
||||
metadata := mstorage.ObjectMetadata{
|
||||
Bucket: bucket,
|
||||
Key: name,
|
||||
Created: file.ModTime(),
|
||||
Size: file.Size(),
|
||||
ETag: bucket + "#" + name,
|
||||
}
|
||||
metadataList = append(metadataList, metadata)
|
||||
case delimited != "":
|
||||
resources.CommonPrefixes = appendU(resources.CommonPrefixes, delimited)
|
||||
}
|
||||
case strings.HasPrefix(name, resources.Prefix):
|
||||
metadata := mstorage.ObjectMetadata{
|
||||
Bucket: bucket,
|
||||
Maxkeys: resources.Maxkeys,
|
||||
Prefix: resources.Prefix,
|
||||
Marker: resources.Marker,
|
||||
Delimiter: resources.Delimiter,
|
||||
Key: name,
|
||||
Created: file.ModTime(),
|
||||
Size: file.Size(),
|
||||
ETag: bucket + "#" + name,
|
||||
Bucket: bucket,
|
||||
Key: name,
|
||||
Created: file.ModTime(),
|
||||
Size: file.Size(),
|
||||
ETag: bucket + "#" + name,
|
||||
}
|
||||
metadataList = append(metadataList, metadata)
|
||||
}
|
||||
|
||||
@@ -43,12 +43,8 @@ type BucketMetadata struct {
|
||||
}
|
||||
|
||||
type ObjectMetadata struct {
|
||||
Bucket string
|
||||
Key string
|
||||
Maxkeys int
|
||||
Prefix string
|
||||
Marker string
|
||||
Delimiter string
|
||||
Bucket string
|
||||
Key string
|
||||
|
||||
ContentType string
|
||||
Created time.Time
|
||||
|
||||
Reference in New Issue
Block a user