Multipart: Minimum part size limit does not apply to the last part during CompleteMultipartUpload. (#1518) (#1538)

This commit is contained in:
Krishna Srinivas 2016-05-09 12:19:49 +05:30 committed by Harshavardhana
parent 90ea494338
commit 04a5b25929
4 changed files with 36 additions and 6 deletions

View file

@ -73,10 +73,22 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
}
// Loop through all parts, validate them and then commit to disk.
for _, part := range parts {
for i, part := range parts {
// Construct part suffix.
partSuffix := fmt.Sprintf("%.5d.%s", part.PartNumber, part.ETag)
multipartPartFile := path.Join(mpartMetaPrefix, bucket, object, uploadID, partSuffix)
var fi FileInfo
fi, err = fs.storage.StatFile(minioMetaBucket, multipartPartFile)
if err != nil {
if err == errFileNotFound {
return "", InvalidPart{}
}
return "", err
}
// All parts except the last part has to be atleast 5MB.
if (i < len(parts)-1) && !isMinAllowedPartSize(fi.Size) {
return "", PartTooSmall{}
}
var fileReader io.ReadCloser
fileReader, err = fs.storage.ReadFile(minioMetaBucket, multipartPartFile, 0)
if err != nil {

View file

@ -1244,11 +1244,14 @@ func (s *MyAPISuite) TestObjectMultipart(c *C) {
c.Assert(len(newResponse.UploadID) > 0, Equals, true)
uploadID := newResponse.UploadID
// Create a byte array of 5MB.
data := bytes.Repeat([]byte("0123456789abcdef"), 5*1024*1024/16)
hasher := md5.New()
hasher.Write([]byte("hello world"))
hasher.Write(data)
md5Sum := hasher.Sum(nil)
buffer1 := bytes.NewReader([]byte("hello world"))
buffer1 := bytes.NewReader(data)
request, err = s.newRequest("PUT", testAPIFSCacheServer.URL+"/objectmultiparts/object?uploadId="+uploadID+"&partNumber=1", int64(buffer1.Len()), buffer1)
request.Header.Set("Content-Md5", base64.StdEncoding.EncodeToString(md5Sum))
c.Assert(err, IsNil)
@ -1258,7 +1261,14 @@ func (s *MyAPISuite) TestObjectMultipart(c *C) {
c.Assert(err, IsNil)
c.Assert(response1.StatusCode, Equals, http.StatusOK)
buffer2 := bytes.NewReader([]byte("hello world"))
// Byte array one 1 byte.
data = []byte("0")
hasher = md5.New()
hasher.Write(data)
md5Sum = hasher.Sum(nil)
buffer2 := bytes.NewReader(data)
request, err = s.newRequest("PUT", testAPIFSCacheServer.URL+"/objectmultiparts/object?uploadId="+uploadID+"&partNumber=2", int64(buffer2.Len()), buffer2)
request.Header.Set("Content-Md5", base64.StdEncoding.EncodeToString(md5Sum))
c.Assert(err, IsNil)

View file

@ -1279,6 +1279,13 @@ func (s *MyAPIXLSuite) TestObjectMultipart(c *C) {
c.Assert(err, IsNil)
c.Assert(response1.StatusCode, Equals, http.StatusOK)
// Create a byte array of 1 byte.
data = []byte("0")
hasher = md5.New()
hasher.Write(data)
md5Sum = hasher.Sum(nil)
buffer2 := bytes.NewReader(data)
request, err = s.newRequest("PUT", testAPIXLServer.URL+"/objectmultiparts/object?uploadId="+uploadID+"&partNumber=2", int64(buffer2.Len()), buffer2)
request.Header.Set("Content-Md5", base64.StdEncoding.EncodeToString(md5Sum))

View file

@ -124,7 +124,7 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload
var wg = &sync.WaitGroup{}
// Loop through all parts, validate them and then commit to disk.
for _, part := range parts {
for i, part := range parts {
// Construct part suffix.
partSuffix := fmt.Sprintf("%.5d.%s", part.PartNumber, part.ETag)
multipartPartFile := path.Join(mpartMetaPrefix, bucket, object, uploadID, partSuffix)
@ -136,7 +136,8 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload
}
return "", err
}
if !isMinAllowedPartSize(fi.Size) {
// All parts except the last part has to be atleast 5MB.
if (i < len(parts)-1) && !isMinAllowedPartSize(fi.Size) {
return "", PartTooSmall{}
}
// Update metadata parts.