mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
handler: CopyObject should save metadata. (#1698)
- Content-Type - Content-Encoding - ETag Fixes #1682
This commit is contained in:
parent
00d0558131
commit
9fdb69563d
@ -492,7 +492,12 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
||||
writeErrorResponse(w, r, apiErr, r.URL.Path)
|
||||
return
|
||||
}
|
||||
md5Sum, err := api.ObjectAPI.PutObject(bucket, object, -1, fileBody, nil)
|
||||
|
||||
// Save metadata.
|
||||
metadata := make(map[string]string)
|
||||
// Nothing to store right now.
|
||||
|
||||
md5Sum, err := api.ObjectAPI.PutObject(bucket, object, -1, fileBody, metadata)
|
||||
if err != nil {
|
||||
errorIf(err, "Unable to create object.")
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
|
@ -85,6 +85,10 @@ func newMultipartUploadCommon(storage StorageAPI, bucket string, object string,
|
||||
if !IsValidObjectName(object) {
|
||||
return "", ObjectNameInvalid{Bucket: bucket, Object: object}
|
||||
}
|
||||
// No metadata is set, allocate a new one.
|
||||
if meta == nil {
|
||||
meta = make(map[string]string)
|
||||
}
|
||||
// This lock needs to be held for any changes to the directory contents of ".minio/multipart/object/"
|
||||
nsMutex.Lock(minioMetaBucket, pathJoin(mpartMetaPrefix, bucket, object))
|
||||
defer nsMutex.Unlock(minioMetaBucket, pathJoin(mpartMetaPrefix, bucket, object))
|
||||
|
@ -28,13 +28,14 @@ type BucketInfo struct {
|
||||
|
||||
// ObjectInfo - object info.
|
||||
type ObjectInfo struct {
|
||||
Bucket string
|
||||
Name string
|
||||
ModTime time.Time
|
||||
ContentType string
|
||||
MD5Sum string
|
||||
Size int64
|
||||
IsDir bool
|
||||
Bucket string
|
||||
Name string
|
||||
ModTime time.Time
|
||||
Size int64
|
||||
IsDir bool
|
||||
MD5Sum string
|
||||
ContentType string
|
||||
ContentEncoding string
|
||||
}
|
||||
|
||||
// ListPartsInfo - various types of object resources.
|
||||
|
@ -404,8 +404,16 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
|
||||
// Size of object.
|
||||
size := objInfo.Size
|
||||
|
||||
// Save metadata.
|
||||
metadata := make(map[string]string)
|
||||
// Save other metadata if available.
|
||||
metadata["content-type"] = objInfo.ContentType
|
||||
metadata["content-encoding"] = objInfo.ContentEncoding
|
||||
// Do not set `md5sum` as CopyObject will not keep the
|
||||
// same md5sum as the source.
|
||||
|
||||
// Create the object.
|
||||
md5Sum, err := api.ObjectAPI.PutObject(bucket, object, size, readCloser, nil)
|
||||
md5Sum, err := api.ObjectAPI.PutObject(bucket, object, size, readCloser, metadata)
|
||||
if err != nil {
|
||||
errorIf(err, "Unable to create an object.")
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
|
@ -624,6 +624,7 @@ func (s *MyAPIXLSuite) TestPutBucket(c *C) {
|
||||
|
||||
}
|
||||
|
||||
// Tests copy object.
|
||||
func (s *MyAPIXLSuite) TestCopyObject(c *C) {
|
||||
request, err := s.newRequest("PUT", testAPIXLServer.URL+"/put-object-copy", 0, nil)
|
||||
c.Assert(err, IsNil)
|
||||
@ -635,6 +636,7 @@ func (s *MyAPIXLSuite) TestCopyObject(c *C) {
|
||||
|
||||
buffer1 := bytes.NewReader([]byte("hello world"))
|
||||
request, err = s.newRequest("PUT", testAPIXLServer.URL+"/put-object-copy/object", int64(buffer1.Len()), buffer1)
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
response, err = client.Do(request)
|
||||
@ -657,8 +659,8 @@ func (s *MyAPIXLSuite) TestCopyObject(c *C) {
|
||||
c.Assert(response.StatusCode, Equals, http.StatusOK)
|
||||
object, err := ioutil.ReadAll(response.Body)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
c.Assert(string(object), Equals, "hello world")
|
||||
c.Assert(response.Header.Get("Content-Type"), Equals, "application/json")
|
||||
}
|
||||
|
||||
func (s *MyAPIXLSuite) TestPutObject(c *C) {
|
||||
|
@ -37,11 +37,12 @@ type MultipartPartInfo struct {
|
||||
// MultipartObjectInfo - contents of the multipart metadata file after
|
||||
// CompleteMultipartUpload() is called.
|
||||
type MultipartObjectInfo struct {
|
||||
Parts []MultipartPartInfo
|
||||
ModTime time.Time
|
||||
Size int64
|
||||
MD5Sum string
|
||||
ContentType string
|
||||
Parts []MultipartPartInfo
|
||||
ModTime time.Time
|
||||
Size int64
|
||||
MD5Sum string
|
||||
ContentType string
|
||||
ContentEncoding string
|
||||
// Add more fields here.
|
||||
}
|
||||
|
||||
@ -212,6 +213,7 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload
|
||||
// Save successfully calculated md5sum.
|
||||
metadata.MD5Sum = s3MD5
|
||||
metadata.ContentType = objMeta["content-type"]
|
||||
metadata.ContentEncoding = objMeta["content-encoding"]
|
||||
|
||||
// Save modTime as well as the current time.
|
||||
metadata.ModTime = time.Now().UTC()
|
||||
|
@ -250,6 +250,7 @@ func (xl xlObjects) getObjectInfo(bucket, object string) (objInfo ObjectInfo, er
|
||||
objInfo.ModTime = info.ModTime
|
||||
objInfo.MD5Sum = info.MD5Sum
|
||||
objInfo.ContentType = info.ContentType
|
||||
objInfo.ContentEncoding = info.ContentEncoding
|
||||
} else {
|
||||
metadata := make(map[string]string)
|
||||
offset := int64(0) // To read entire content
|
||||
@ -276,6 +277,7 @@ func (xl xlObjects) getObjectInfo(bucket, object string) (objInfo ObjectInfo, er
|
||||
objInfo.ModTime = fi.ModTime
|
||||
objInfo.MD5Sum = metadata["md5Sum"]
|
||||
objInfo.ContentType = contentType
|
||||
objInfo.ContentEncoding = metadata["content-encoding"]
|
||||
}
|
||||
return objInfo, nil
|
||||
}
|
||||
@ -315,6 +317,10 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io.
|
||||
Object: object,
|
||||
}
|
||||
}
|
||||
// No metadata is set, allocate a new one.
|
||||
if metadata == nil {
|
||||
metadata = make(map[string]string)
|
||||
}
|
||||
nsMutex.Lock(bucket, object)
|
||||
defer nsMutex.Unlock(bucket, object)
|
||||
|
||||
@ -348,11 +354,13 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io.
|
||||
}
|
||||
|
||||
newMD5Hex := hex.EncodeToString(md5Writer.Sum(nil))
|
||||
// md5Hex representation.
|
||||
var md5Hex string
|
||||
if len(metadata) != 0 {
|
||||
md5Hex = metadata["md5Sum"]
|
||||
// Update the md5sum if not set with the newly calculated one.
|
||||
if len(metadata["md5Sum"]) == 0 {
|
||||
metadata["md5Sum"] = newMD5Hex
|
||||
}
|
||||
|
||||
// md5Hex representation.
|
||||
md5Hex := metadata["md5Sum"]
|
||||
if md5Hex != "" {
|
||||
if newMD5Hex != md5Hex {
|
||||
if err = safeCloseAndRemove(fileWriter); err != nil {
|
||||
@ -361,6 +369,7 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io.
|
||||
return "", BadDigest{md5Hex, newMD5Hex}
|
||||
}
|
||||
}
|
||||
|
||||
err = fileWriter.Close()
|
||||
if err != nil {
|
||||
if clErr := safeCloseAndRemove(fileWriter); clErr != nil {
|
||||
@ -369,7 +378,7 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io.
|
||||
return "", toObjectErr(err, bucket, object)
|
||||
}
|
||||
|
||||
// check if an object is present as one of the parent dir.
|
||||
// Check if an object is present as one of the parent dir.
|
||||
if err = xl.parentDirIsObject(bucket, path.Dir(object)); err != nil {
|
||||
return "", toObjectErr(err, bucket, object)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user