mirror of
https://github.com/minio/minio.git
synced 2025-02-09 04:38:09 -05:00
Generate random ETag if client does not provide MD5 for PutObjectPart (#4385)
fixes #4289 fixes #4290
This commit is contained in:
parent
9136734c02
commit
28c26a9e59
@ -17,6 +17,7 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -313,24 +314,47 @@ func canonicalMetadata(metadata map[string]string) (canonical map[string]string)
|
|||||||
// uses Azure equivalent CreateBlockBlobFromReader.
|
// uses Azure equivalent CreateBlockBlobFromReader.
|
||||||
func (a *azureObjects) PutObject(bucket, object string, size int64, data io.Reader, metadata map[string]string, sha256sum string) (objInfo ObjectInfo, err error) {
|
func (a *azureObjects) PutObject(bucket, object string, size int64, data io.Reader, metadata map[string]string, sha256sum string) (objInfo ObjectInfo, err error) {
|
||||||
var sha256Writer hash.Hash
|
var sha256Writer hash.Hash
|
||||||
|
var md5sumWriter hash.Hash
|
||||||
|
|
||||||
|
var writers []io.Writer
|
||||||
|
|
||||||
|
md5sum := metadata["etag"]
|
||||||
|
delete(metadata, "etag")
|
||||||
|
|
||||||
teeReader := data
|
teeReader := data
|
||||||
|
|
||||||
if sha256sum != "" {
|
if sha256sum != "" {
|
||||||
sha256Writer = sha256.New()
|
sha256Writer = sha256.New()
|
||||||
teeReader = io.TeeReader(data, sha256Writer)
|
writers = append(writers, sha256Writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(metadata, "etag")
|
if md5sum != "" {
|
||||||
|
md5sumWriter = md5.New()
|
||||||
|
writers = append(writers, md5sumWriter)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(writers) > 0 {
|
||||||
|
teeReader = io.TeeReader(data, io.MultiWriter(writers...))
|
||||||
|
}
|
||||||
|
|
||||||
err = a.client.CreateBlockBlobFromReader(bucket, object, uint64(size), teeReader, canonicalMetadata(metadata))
|
err = a.client.CreateBlockBlobFromReader(bucket, object, uint64(size), teeReader, canonicalMetadata(metadata))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return objInfo, azureToObjectError(traceError(err), bucket, object)
|
return objInfo, azureToObjectError(traceError(err), bucket, object)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if md5sum != "" {
|
||||||
|
newMD5sum := hex.EncodeToString(md5sumWriter.Sum(nil))
|
||||||
|
if newMD5sum != md5sum {
|
||||||
|
a.client.DeleteBlob(bucket, object, nil)
|
||||||
|
return ObjectInfo{}, azureToObjectError(traceError(BadDigest{md5sum, newMD5sum}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if sha256sum != "" {
|
if sha256sum != "" {
|
||||||
newSHA256sum := hex.EncodeToString(sha256Writer.Sum(nil))
|
newSHA256sum := hex.EncodeToString(sha256Writer.Sum(nil))
|
||||||
if newSHA256sum != sha256sum {
|
if newSHA256sum != sha256sum {
|
||||||
a.client.DeleteBlob(bucket, object, nil)
|
a.client.DeleteBlob(bucket, object, nil)
|
||||||
return ObjectInfo{}, traceError(SHA256Mismatch{})
|
return ObjectInfo{}, azureToObjectError(traceError(SHA256Mismatch{}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,27 +450,54 @@ func (a *azureObjects) PutObjectPart(bucket, object, uploadID string, partID int
|
|||||||
return info, traceError(InvalidUploadID{})
|
return info, traceError(InvalidUploadID{})
|
||||||
}
|
}
|
||||||
var sha256Writer hash.Hash
|
var sha256Writer hash.Hash
|
||||||
|
var md5sumWriter hash.Hash
|
||||||
|
var etag string
|
||||||
|
|
||||||
|
var writers []io.Writer
|
||||||
|
|
||||||
if sha256sum != "" {
|
if sha256sum != "" {
|
||||||
sha256Writer = sha256.New()
|
sha256Writer = sha256.New()
|
||||||
|
writers = append(writers, sha256Writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
teeReader := io.TeeReader(data, sha256Writer)
|
if md5Hex != "" {
|
||||||
|
md5sumWriter = md5.New()
|
||||||
|
writers = append(writers, md5sumWriter)
|
||||||
|
etag = md5Hex
|
||||||
|
} else {
|
||||||
|
// Generate random ETag.
|
||||||
|
etag = getMD5Hash([]byte(mustGetUUID()))
|
||||||
|
}
|
||||||
|
|
||||||
id := azureGetBlockID(partID, md5Hex)
|
teeReader := data
|
||||||
|
|
||||||
|
if len(writers) > 0 {
|
||||||
|
teeReader = io.TeeReader(data, io.MultiWriter(writers...))
|
||||||
|
}
|
||||||
|
|
||||||
|
id := azureGetBlockID(partID, etag)
|
||||||
err = a.client.PutBlockWithLength(bucket, object, id, uint64(size), teeReader, nil)
|
err = a.client.PutBlockWithLength(bucket, object, id, uint64(size), teeReader, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return info, azureToObjectError(traceError(err), bucket, object)
|
return info, azureToObjectError(traceError(err), bucket, object)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if md5Hex != "" {
|
||||||
|
newMD5sum := hex.EncodeToString(md5sumWriter.Sum(nil))
|
||||||
|
if newMD5sum != md5Hex {
|
||||||
|
a.client.DeleteBlob(bucket, object, nil)
|
||||||
|
return PartInfo{}, azureToObjectError(traceError(BadDigest{md5Hex, newMD5sum}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if sha256sum != "" {
|
if sha256sum != "" {
|
||||||
newSHA256sum := hex.EncodeToString(sha256Writer.Sum(nil))
|
newSHA256sum := hex.EncodeToString(sha256Writer.Sum(nil))
|
||||||
if newSHA256sum != sha256sum {
|
if newSHA256sum != sha256sum {
|
||||||
return PartInfo{}, traceError(SHA256Mismatch{})
|
return PartInfo{}, azureToObjectError(traceError(SHA256Mismatch{}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info.PartNumber = partID
|
info.PartNumber = partID
|
||||||
info.ETag = md5Hex
|
info.ETag = etag
|
||||||
info.LastModified = UTCNow()
|
info.LastModified = UTCNow()
|
||||||
info.Size = size
|
info.Size = size
|
||||||
return info, nil
|
return info, nil
|
||||||
|
@ -282,6 +282,11 @@ func (api gatewayAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Re
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set("ETag", "\""+objInfo.ETag+"\"")
|
w.Header().Set("ETag", "\""+objInfo.ETag+"\"")
|
||||||
writeSuccessResponseHeadersOnly(w)
|
writeSuccessResponseHeadersOnly(w)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user