listMultipart: bugfixes. (#1318)

master
Krishna Srinivas 9 years ago committed by Harshavardhana
parent 8457af5708
commit 149c6ca094
  1. 63
      object-api-multipart.go
  2. 8
      object-utils.go

@ -31,8 +31,7 @@ import (
) )
const ( const (
minioMetaVolume = ".minio" minioMetaVolume = ".minio"
slashPathSeparator = "/"
) )
// checkLeafDirectory - verifies if a given path is leaf directory if // checkLeafDirectory - verifies if a given path is leaf directory if
@ -109,14 +108,16 @@ func (o objectAPI) ListMultipartUploads(bucket, prefix, keyMarker, uploadIDMarke
recursive = false recursive = false
} }
result.IsTruncated = true result.IsTruncated = true
result.MaxUploads = maxUploads
newMaxUploads := 0 newMaxUploads := 0
prefixPath := path.Join(bucket, prefix) // not using path.Join() as it strips off the trailing '/'.
if strings.HasSuffix(prefix, slashPathSeparator) { // Also bucket should always be followed by '/' even if prefix is empty.
// Add back the slash separator removed after 'path.Join'. prefixPath := pathJoin(bucket, prefix)
prefixPath = prefixPath + slashPathSeparator
}
if recursive { if recursive {
keyMarkerPath := path.Join(keyMarker, uploadIDMarker) keyMarkerPath := ""
if keyMarker != "" {
keyMarkerPath = path.Join(bucket, keyMarker, uploadIDMarker)
}
outerLoop: outerLoop:
for { for {
fileInfos, eof, e := o.storage.ListFiles(minioMetaVolume, prefixPath, keyMarkerPath, recursive, maxUploads-newMaxUploads) fileInfos, eof, e := o.storage.ListFiles(minioMetaVolume, prefixPath, keyMarkerPath, recursive, maxUploads-newMaxUploads)
@ -125,26 +126,31 @@ func (o objectAPI) ListMultipartUploads(bucket, prefix, keyMarker, uploadIDMarke
} }
for _, fi := range fileInfos { for _, fi := range fileInfos {
keyMarkerPath = fi.Name keyMarkerPath = fi.Name
fileName := path.Base(fi.Name) // fi.Name will look like bucket/object/uploadID, extract object and uploadID.
if strings.Contains(fileName, ".") { uploadID := path.Base(fi.Name)
// fileName contains partnumber and md5sum info, skip this. objectName := strings.TrimPrefix(path.Dir(fi.Name), bucket+slashPathSeparator)
if strings.Contains(uploadID, ".") {
// contains partnumber and md5sum info, skip this.
continue continue
} }
result.Uploads = append(result.Uploads, uploadMetadata{ result.Uploads = append(result.Uploads, uploadMetadata{
Object: path.Dir(fi.Name), Object: objectName,
UploadID: fileName, UploadID: uploadID,
Initiated: fi.ModTime, Initiated: fi.ModTime,
}) })
result.NextKeyMarker = path.Dir(fi.Name) result.NextKeyMarker = objectName
result.NextUploadIDMarker = fileName result.NextUploadIDMarker = uploadID
newMaxUploads++ newMaxUploads++
if newMaxUploads == maxUploads { if newMaxUploads == maxUploads {
if eof {
result.IsTruncated = false
}
break outerLoop break outerLoop
} }
} }
if eof { if eof {
result.IsTruncated = false result.IsTruncated = false
break outerLoop break
} }
} }
if !result.IsTruncated { if !result.IsTruncated {
@ -176,21 +182,22 @@ func (o objectAPI) ListMultipartUploads(bucket, prefix, keyMarker, uploadIDMarke
var uploads []uploadMetadata var uploads []uploadMetadata
for _, fi := range fileInfos { for _, fi := range fileInfos {
leaf, entries := o.checkLeafDirectory(fi.Name) leaf, entries := o.checkLeafDirectory(fi.Name)
objectName := strings.TrimPrefix(fi.Name, bucket+slashPathSeparator)
if leaf { if leaf {
for _, entry := range entries { for _, entry := range entries {
if strings.Contains(entry.Name, ".") { if strings.Contains(entry.Name, ".") {
continue continue
} }
uploads = append(uploads, uploadMetadata{ uploads = append(uploads, uploadMetadata{
Object: strings.TrimSuffix(fi.Name, slashPathSeparator), Object: strings.TrimSuffix(objectName, slashPathSeparator),
UploadID: entry.Name, UploadID: path.Base(entry.Name),
Initiated: entry.ModTime, Initiated: entry.ModTime,
}) })
} }
continue continue
} }
uploads = append(uploads, uploadMetadata{ uploads = append(uploads, uploadMetadata{
Object: fi.Name, Object: objectName,
}) })
} }
index := 0 index := 0
@ -199,27 +206,27 @@ func (o objectAPI) ListMultipartUploads(bucket, prefix, keyMarker, uploadIDMarke
if upload.Object > keyMarker { if upload.Object > keyMarker {
break break
} }
if uploads[index].Object == keyMarker && uploadIDMarker != "" { if uploads[index].Object == keyMarker && upload.UploadID > uploadIDMarker {
if upload.UploadID > uploadIDMarker { break
break
}
} }
} }
for ; index < len(uploads); index++ { for ; index < len(uploads); index++ {
newMaxUploads++ if (len(result.Uploads) + len(result.CommonPrefixes)) == maxUploads {
if newMaxUploads == maxUploads {
break break
} }
result.NextKeyMarker = uploads[index].Object
if strings.HasSuffix(uploads[index].Object, slashPathSeparator) { if strings.HasSuffix(uploads[index].Object, slashPathSeparator) {
// for a directory entry
result.CommonPrefixes = append(result.CommonPrefixes, uploads[index].Object) result.CommonPrefixes = append(result.CommonPrefixes, uploads[index].Object)
continue continue
} }
result.NextUploadIDMarker = uploads[index].UploadID
result.Uploads = append(result.Uploads, uploads[index]) result.Uploads = append(result.Uploads, uploads[index])
} }
result.MaxUploads = newMaxUploads if index == len(uploads) {
result.IsTruncated = true
if index >= len(uploads)-1 {
result.IsTruncated = false result.IsTruncated = false
result.NextKeyMarker = ""
result.NextUploadIDMarker = ""
} }
return result, nil return result, nil
} }

@ -22,6 +22,10 @@ import (
"unicode/utf8" "unicode/utf8"
) )
const (
slashPathSeparator = "/"
)
// validBucket regexp. // validBucket regexp.
var validBucket = regexp.MustCompile(`^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$`) var validBucket = regexp.MustCompile(`^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$`)
@ -85,3 +89,7 @@ func IsValidObjectPrefix(object string) bool {
return IsValidObjectName(object) return IsValidObjectName(object)
} }
func pathJoin(path1 string, path2 string) string {
return strings.TrimSuffix(path1, slashPathSeparator) + slashPathSeparator + path2
}

Loading…
Cancel
Save