mirror of
https://github.com/minio/minio.git
synced 2024-12-26 07:05:55 -05:00
Merge pull request #218 from harshavardhana/pr_out_implement_proper_delimiter_and_prefix_handling
This commit is contained in:
commit
20dc738b67
@ -45,7 +45,7 @@ func (server *minioApi) listObjectsHandler(w http.ResponseWriter, req *http.Requ
|
|||||||
switch err := err.(type) {
|
switch err := err.(type) {
|
||||||
case nil: // success
|
case nil: // success
|
||||||
{
|
{
|
||||||
response := generateObjectsListResult(bucket, objects, resources.IsTruncated)
|
response := generateObjectsListResult(bucket, objects, resources)
|
||||||
w.Write(writeObjectHeadersAndResponse(w, response, acceptsContentType))
|
w.Write(writeObjectHeadersAndResponse(w, response, acceptsContentType))
|
||||||
}
|
}
|
||||||
case mstorage.BucketNotFound:
|
case mstorage.BucketNotFound:
|
||||||
|
@ -34,10 +34,8 @@ type ObjectListResponse struct {
|
|||||||
MaxKeys int
|
MaxKeys int
|
||||||
Delimiter string
|
Delimiter string
|
||||||
IsTruncated bool
|
IsTruncated bool
|
||||||
Contents []*Item `xml:,innerxml`
|
Contents []*Item `xml:,innerxml`
|
||||||
CommonPrefixes struct {
|
CommonPrefixes []*Prefix `xml:,innerxml`
|
||||||
Prefix string
|
|
||||||
} `xml:,innerxml`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bucket list response format
|
// Bucket list response format
|
||||||
@ -49,6 +47,10 @@ type BucketListResponse struct {
|
|||||||
} `xml:,innerxml` // Buckets are nested
|
} `xml:,innerxml` // Buckets are nested
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Prefix struct {
|
||||||
|
Prefix string
|
||||||
|
}
|
||||||
|
|
||||||
// Bucket struct
|
// Bucket struct
|
||||||
type Bucket struct {
|
type Bucket struct {
|
||||||
Name string
|
Name string
|
||||||
|
@ -68,8 +68,9 @@ func (b ItemKey) Less(i, j int) bool { return b[i].Key < b[j].Key }
|
|||||||
//
|
//
|
||||||
// output:
|
// output:
|
||||||
// populated struct that can be serialized to match xml and json api spec 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 contents []*Item
|
||||||
|
var prefixes []*Prefix
|
||||||
var owner = Owner{}
|
var owner = Owner{}
|
||||||
var data = ObjectListResponse{}
|
var data = ObjectListResponse{}
|
||||||
|
|
||||||
@ -78,6 +79,9 @@ func generateObjectsListResult(bucket string, objects []mstorage.ObjectMetadata,
|
|||||||
|
|
||||||
for _, object := range objects {
|
for _, object := range objects {
|
||||||
var content = &Item{}
|
var content = &Item{}
|
||||||
|
if object.Key == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
content.Key = object.Key
|
content.Key = object.Key
|
||||||
content.LastModified = object.Created.Format(dateFormat)
|
content.LastModified = object.Created.Format(dateFormat)
|
||||||
content.ETag = object.ETag
|
content.ETag = object.ETag
|
||||||
@ -89,7 +93,16 @@ func generateObjectsListResult(bucket string, objects []mstorage.ObjectMetadata,
|
|||||||
sort.Sort(ItemKey(contents))
|
sort.Sort(ItemKey(contents))
|
||||||
data.Name = bucket
|
data.Name = bucket
|
||||||
data.Contents = contents
|
data.Contents = contents
|
||||||
data.MaxKeys = MAX_OBJECT_LIST
|
data.MaxKeys = bucketResources.Maxkeys
|
||||||
data.IsTruncated = isTruncated
|
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
|
return data
|
||||||
}
|
}
|
||||||
|
@ -314,6 +314,29 @@ func (p *Path) getAllFiles(path string, fl os.FileInfo, err error) error {
|
|||||||
return nil
|
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
|
type ByObjectKey []mstorage.ObjectMetadata
|
||||||
|
|
||||||
func (b ByObjectKey) Len() int { return len(b) }
|
func (b ByObjectKey) Len() int { return len(b) }
|
||||||
@ -350,31 +373,44 @@ func (storage *storage) ListObjects(bucket string, resources mstorage.BucketReso
|
|||||||
goto ret
|
goto ret
|
||||||
}
|
}
|
||||||
// TODO handle resources.Marker
|
// TODO handle resources.Marker
|
||||||
if resources.Delimiter != "" {
|
switch true {
|
||||||
metadata := mstorage.ObjectMetadata{
|
case resources.Delimiter != "" && resources.Prefix == "":
|
||||||
Bucket: bucket,
|
delimited := delimiter(name, resources.Delimiter)
|
||||||
Maxkeys: resources.Maxkeys,
|
switch true {
|
||||||
Prefix: resources.Prefix,
|
case delimited == "":
|
||||||
Marker: resources.Marker,
|
metadata := mstorage.ObjectMetadata{
|
||||||
Delimiter: resources.Delimiter,
|
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)
|
case resources.Delimiter != "" && strings.HasPrefix(name, resources.Prefix):
|
||||||
}
|
delimited := delimiter(name, resources.Delimiter)
|
||||||
if resources.Delimiter != "" && strings.HasPrefix(name, resources.Prefix) {
|
switch true {
|
||||||
metadata := mstorage.ObjectMetadata{}
|
case delimited == "":
|
||||||
metadataList = append(metadataList, metadata)
|
metadata := mstorage.ObjectMetadata{
|
||||||
}
|
Bucket: bucket,
|
||||||
if strings.HasPrefix(name, resources.Prefix) {
|
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{
|
metadata := mstorage.ObjectMetadata{
|
||||||
Bucket: bucket,
|
Bucket: bucket,
|
||||||
Maxkeys: resources.Maxkeys,
|
Key: name,
|
||||||
Prefix: resources.Prefix,
|
Created: file.ModTime(),
|
||||||
Marker: resources.Marker,
|
Size: file.Size(),
|
||||||
Delimiter: resources.Delimiter,
|
ETag: bucket + "#" + name,
|
||||||
Key: name,
|
|
||||||
Created: file.ModTime(),
|
|
||||||
Size: file.Size(),
|
|
||||||
ETag: bucket + "#" + name,
|
|
||||||
}
|
}
|
||||||
metadataList = append(metadataList, metadata)
|
metadataList = append(metadataList, metadata)
|
||||||
}
|
}
|
||||||
|
@ -43,12 +43,8 @@ type BucketMetadata struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ObjectMetadata struct {
|
type ObjectMetadata struct {
|
||||||
Bucket string
|
Bucket string
|
||||||
Key string
|
Key string
|
||||||
Maxkeys int
|
|
||||||
Prefix string
|
|
||||||
Marker string
|
|
||||||
Delimiter string
|
|
||||||
|
|
||||||
ContentType string
|
ContentType string
|
||||||
Created time.Time
|
Created time.Time
|
||||||
|
Loading…
Reference in New Issue
Block a user