From f1355da72ed78c43c7d3559d5c0e216dc7400d2b Mon Sep 17 00:00:00 2001 From: Aditya Manthramurthy Date: Thu, 21 Dec 2017 17:27:33 -0800 Subject: [PATCH] Add base64 encoded MD5 output for Hash Reader (#5315) - Use it to send the Content-MD5 header correctly encoded to S3 Gateway - Fixes a bug in PutObject (including anonymous PutObject) and PutObjectPart with S3 Gateway found when testing with Mint. --- cmd/gateway/s3/gateway-s3-anonymous.go | 2 +- cmd/gateway/s3/gateway-s3.go | 4 ++-- pkg/hash/reader.go | 6 ++++++ pkg/hash/reader_test.go | 3 +++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cmd/gateway/s3/gateway-s3-anonymous.go b/cmd/gateway/s3/gateway-s3-anonymous.go index 4ac61f4db..03103cbe2 100644 --- a/cmd/gateway/s3/gateway-s3-anonymous.go +++ b/cmd/gateway/s3/gateway-s3-anonymous.go @@ -28,7 +28,7 @@ import ( // AnonPutObject creates a new object anonymously with the incoming data, func (l *s3Objects) AnonPutObject(bucket string, object string, data *hash.Reader, metadata map[string]string) (objInfo minio.ObjectInfo, e error) { - oi, err := l.anonClient.PutObject(bucket, object, data, data.Size(), data.MD5HexString(), data.SHA256HexString(), minio.ToMinioClientMetadata(metadata)) + oi, err := l.anonClient.PutObject(bucket, object, data, data.Size(), data.MD5Base64String(), data.SHA256HexString(), minio.ToMinioClientMetadata(metadata)) if err != nil { return objInfo, minio.ErrorRespToObjectError(errors.Trace(err), bucket, object) } diff --git a/cmd/gateway/s3/gateway-s3.go b/cmd/gateway/s3/gateway-s3.go index 86d186a7c..0eb22630e 100644 --- a/cmd/gateway/s3/gateway-s3.go +++ b/cmd/gateway/s3/gateway-s3.go @@ -289,7 +289,7 @@ func (l *s3Objects) GetObjectInfo(bucket string, object string) (objInfo minio.O // PutObject creates a new object with the incoming data, func (l *s3Objects) PutObject(bucket string, object string, data *hash.Reader, metadata map[string]string) (objInfo minio.ObjectInfo, err error) { - oi, err := l.Client.PutObject(bucket, object, data, data.Size(), data.MD5HexString(), data.SHA256HexString(), minio.ToMinioClientMetadata(metadata)) + oi, err := l.Client.PutObject(bucket, object, data, data.Size(), data.MD5Base64String(), data.SHA256HexString(), minio.ToMinioClientMetadata(metadata)) if err != nil { return objInfo, minio.ErrorRespToObjectError(errors.Trace(err), bucket, object) } @@ -343,7 +343,7 @@ func (l *s3Objects) NewMultipartUpload(bucket string, object string, metadata ma // PutObjectPart puts a part of object in bucket func (l *s3Objects) PutObjectPart(bucket string, object string, uploadID string, partID int, data *hash.Reader) (pi minio.PartInfo, e error) { - info, err := l.Client.PutObjectPart(bucket, object, uploadID, partID, data, data.Size(), data.MD5HexString(), data.SHA256HexString()) + info, err := l.Client.PutObjectPart(bucket, object, uploadID, partID, data, data.Size(), data.MD5Base64String(), data.SHA256HexString()) if err != nil { return pi, minio.ErrorRespToObjectError(errors.Trace(err), bucket, object) } diff --git a/pkg/hash/reader.go b/pkg/hash/reader.go index c0b569db3..832ef64cb 100644 --- a/pkg/hash/reader.go +++ b/pkg/hash/reader.go @@ -20,6 +20,7 @@ import ( "bytes" "crypto/md5" "crypto/sha256" + "encoding/base64" "encoding/hex" "errors" "hash" @@ -117,6 +118,11 @@ func (r *Reader) MD5HexString() string { return hex.EncodeToString(r.md5sum) } +// MD5Base64String returns base64 encoded MD5sum value. +func (r *Reader) MD5Base64String() string { + return base64.StdEncoding.EncodeToString(r.md5sum) +} + // SHA256HexString returns hex sha256 value. func (r *Reader) SHA256HexString() string { return hex.EncodeToString(r.sha256sum) diff --git a/pkg/hash/reader_test.go b/pkg/hash/reader_test.go index 40e5018a1..277bffc0c 100644 --- a/pkg/hash/reader_test.go +++ b/pkg/hash/reader_test.go @@ -40,6 +40,9 @@ func TestHashReaderHelperMethods(t *testing.T) { if r.SHA256HexString() != "88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589" { t.Errorf("Expected sha256hex \"88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589\", got %s", r.SHA256HexString()) } + if r.MD5Base64String() != "4vxxTEcn7pOV8yTNLn8zHw==" { + t.Errorf("Expected md5base64 \"4vxxTEcn7pOV8yTNLn8zHw==\", got \"%s\"", r.MD5Base64String()) + } if r.Size() != 4 { t.Errorf("Expected size 4, got %d", r.Size()) }