@@ -113,10 +113,7 @@ func (c *Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketN
113113 }
114114 withChecksum := c .trailingHeaderSupport
115115 if withChecksum {
116- if opts .UserMetadata == nil {
117- opts .UserMetadata = make (map [string ]string , 1 )
118- }
119- opts .UserMetadata ["X-Amz-Checksum-Algorithm" ] = opts .AutoChecksum .String ()
116+ addAutoChecksumHeaders (& opts )
120117 }
121118 // Initiate a new multipart upload.
122119 uploadID , err := c .newUploadID (ctx , bucketName , objectName , opts )
@@ -240,6 +237,7 @@ func (c *Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketN
240237
241238 // Gather the responses as they occur and update any
242239 // progress bar.
240+ allParts := make ([]ObjectPart , 0 , totalPartsCount )
243241 for u := 1 ; u <= totalPartsCount ; u ++ {
244242 select {
245243 case <- ctx .Done ():
@@ -248,16 +246,17 @@ func (c *Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketN
248246 if uploadRes .Error != nil {
249247 return UploadInfo {}, uploadRes .Error
250248 }
251-
249+ allParts = append ( allParts , uploadRes . Part )
252250 // Update the totalUploadedSize.
253251 totalUploadedSize += uploadRes .Size
254252 complMultipartUpload .Parts = append (complMultipartUpload .Parts , CompletePart {
255- ETag : uploadRes .Part .ETag ,
256- PartNumber : uploadRes .Part .PartNumber ,
257- ChecksumCRC32 : uploadRes .Part .ChecksumCRC32 ,
258- ChecksumCRC32C : uploadRes .Part .ChecksumCRC32C ,
259- ChecksumSHA1 : uploadRes .Part .ChecksumSHA1 ,
260- ChecksumSHA256 : uploadRes .Part .ChecksumSHA256 ,
253+ ETag : uploadRes .Part .ETag ,
254+ PartNumber : uploadRes .Part .PartNumber ,
255+ ChecksumCRC32 : uploadRes .Part .ChecksumCRC32 ,
256+ ChecksumCRC32C : uploadRes .Part .ChecksumCRC32C ,
257+ ChecksumSHA1 : uploadRes .Part .ChecksumSHA1 ,
258+ ChecksumSHA256 : uploadRes .Part .ChecksumSHA256 ,
259+ ChecksumCRC64NVME : uploadRes .Part .ChecksumCRC64NVME ,
261260 })
262261 }
263262 }
@@ -275,15 +274,7 @@ func (c *Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketN
275274 AutoChecksum : opts .AutoChecksum ,
276275 }
277276 if withChecksum {
278- // Add hash of hashes.
279- crc := opts .AutoChecksum .Hasher ()
280- for _ , part := range complMultipartUpload .Parts {
281- cs , err := base64 .StdEncoding .DecodeString (part .Checksum (opts .AutoChecksum ))
282- if err == nil {
283- crc .Write (cs )
284- }
285- }
286- opts .UserMetadata = map [string ]string {opts .AutoChecksum .KeyCapitalized (): base64 .StdEncoding .EncodeToString (crc .Sum (nil ))}
277+ applyAutoChecksum (& opts , allParts )
287278 }
288279
289280 uploadInfo , err := c .completeMultipartUpload (ctx , bucketName , objectName , uploadID , complMultipartUpload , opts )
@@ -312,10 +303,7 @@ func (c *Client) putObjectMultipartStreamOptionalChecksum(ctx context.Context, b
312303 }
313304
314305 if ! opts .SendContentMd5 {
315- if opts .UserMetadata == nil {
316- opts .UserMetadata = make (map [string ]string , 1 )
317- }
318- opts .UserMetadata ["X-Amz-Checksum-Algorithm" ] = opts .AutoChecksum .String ()
306+ addAutoChecksumHeaders (& opts )
319307 }
320308
321309 // Calculate the optimal parts info for a given size.
@@ -342,7 +330,6 @@ func (c *Client) putObjectMultipartStreamOptionalChecksum(ctx context.Context, b
342330
343331 // Create checksums
344332 // CRC32C is ~50% faster on AMD64 @ 30GB/s
345- var crcBytes []byte
346333 customHeader := make (http.Header )
347334 crc := opts .AutoChecksum .Hasher ()
348335 md5Hash := c .md5Hasher ()
@@ -389,7 +376,6 @@ func (c *Client) putObjectMultipartStreamOptionalChecksum(ctx context.Context, b
389376 crc .Write (buf [:length ])
390377 cSum := crc .Sum (nil )
391378 customHeader .Set (opts .AutoChecksum .KeyCapitalized (), base64 .StdEncoding .EncodeToString (cSum ))
392- crcBytes = append (crcBytes , cSum ... )
393379 }
394380
395381 // Update progress reader appropriately to the latest offset
@@ -420,18 +406,21 @@ func (c *Client) putObjectMultipartStreamOptionalChecksum(ctx context.Context, b
420406
421407 // Loop over total uploaded parts to save them in
422408 // Parts array before completing the multipart request.
409+ allParts := make ([]ObjectPart , 0 , len (partsInfo ))
423410 for i := 1 ; i < partNumber ; i ++ {
424411 part , ok := partsInfo [i ]
425412 if ! ok {
426413 return UploadInfo {}, errInvalidArgument (fmt .Sprintf ("Missing part number %d" , i ))
427414 }
415+ allParts = append (allParts , part )
428416 complMultipartUpload .Parts = append (complMultipartUpload .Parts , CompletePart {
429- ETag : part .ETag ,
430- PartNumber : part .PartNumber ,
431- ChecksumCRC32 : part .ChecksumCRC32 ,
432- ChecksumCRC32C : part .ChecksumCRC32C ,
433- ChecksumSHA1 : part .ChecksumSHA1 ,
434- ChecksumSHA256 : part .ChecksumSHA256 ,
417+ ETag : part .ETag ,
418+ PartNumber : part .PartNumber ,
419+ ChecksumCRC32 : part .ChecksumCRC32 ,
420+ ChecksumCRC32C : part .ChecksumCRC32C ,
421+ ChecksumSHA1 : part .ChecksumSHA1 ,
422+ ChecksumSHA256 : part .ChecksumSHA256 ,
423+ ChecksumCRC64NVME : part .ChecksumCRC64NVME ,
435424 })
436425 }
437426
@@ -442,12 +431,7 @@ func (c *Client) putObjectMultipartStreamOptionalChecksum(ctx context.Context, b
442431 ServerSideEncryption : opts .ServerSideEncryption ,
443432 AutoChecksum : opts .AutoChecksum ,
444433 }
445- if len (crcBytes ) > 0 {
446- // Add hash of hashes.
447- crc .Reset ()
448- crc .Write (crcBytes )
449- opts .UserMetadata = map [string ]string {opts .AutoChecksum .KeyCapitalized (): base64 .StdEncoding .EncodeToString (crc .Sum (nil ))}
450- }
434+ applyAutoChecksum (& opts , allParts )
451435 uploadInfo , err := c .completeMultipartUpload (ctx , bucketName , objectName , uploadID , complMultipartUpload , opts )
452436 if err != nil {
453437 return UploadInfo {}, err
@@ -475,10 +459,7 @@ func (c *Client) putObjectMultipartStreamParallel(ctx context.Context, bucketNam
475459 opts .AutoChecksum = opts .Checksum
476460 }
477461 if ! opts .SendContentMd5 {
478- if opts .UserMetadata == nil {
479- opts .UserMetadata = make (map [string ]string , 1 )
480- }
481- opts .UserMetadata ["X-Amz-Checksum-Algorithm" ] = opts .AutoChecksum .String ()
462+ addAutoChecksumHeaders (& opts )
482463 }
483464
484465 // Cancel all when an error occurs.
@@ -510,7 +491,6 @@ func (c *Client) putObjectMultipartStreamParallel(ctx context.Context, bucketNam
510491
511492 // Create checksums
512493 // CRC32C is ~50% faster on AMD64 @ 30GB/s
513- var crcBytes []byte
514494 crc := opts .AutoChecksum .Hasher ()
515495
516496 // Total data read and written to server. should be equal to 'size' at the end of the call.
@@ -570,7 +550,6 @@ func (c *Client) putObjectMultipartStreamParallel(ctx context.Context, bucketNam
570550 crc .Write (buf [:length ])
571551 cSum := crc .Sum (nil )
572552 customHeader .Set (opts .AutoChecksum .Key (), base64 .StdEncoding .EncodeToString (cSum ))
573- crcBytes = append (crcBytes , cSum ... )
574553 }
575554
576555 wg .Add (1 )
@@ -630,18 +609,21 @@ func (c *Client) putObjectMultipartStreamParallel(ctx context.Context, bucketNam
630609
631610 // Loop over total uploaded parts to save them in
632611 // Parts array before completing the multipart request.
612+ allParts := make ([]ObjectPart , 0 , len (partsInfo ))
633613 for i := 1 ; i < partNumber ; i ++ {
634614 part , ok := partsInfo [i ]
635615 if ! ok {
636616 return UploadInfo {}, errInvalidArgument (fmt .Sprintf ("Missing part number %d" , i ))
637617 }
618+ allParts = append (allParts , part )
638619 complMultipartUpload .Parts = append (complMultipartUpload .Parts , CompletePart {
639- ETag : part .ETag ,
640- PartNumber : part .PartNumber ,
641- ChecksumCRC32 : part .ChecksumCRC32 ,
642- ChecksumCRC32C : part .ChecksumCRC32C ,
643- ChecksumSHA1 : part .ChecksumSHA1 ,
644- ChecksumSHA256 : part .ChecksumSHA256 ,
620+ ETag : part .ETag ,
621+ PartNumber : part .PartNumber ,
622+ ChecksumCRC32 : part .ChecksumCRC32 ,
623+ ChecksumCRC32C : part .ChecksumCRC32C ,
624+ ChecksumSHA1 : part .ChecksumSHA1 ,
625+ ChecksumSHA256 : part .ChecksumSHA256 ,
626+ ChecksumCRC64NVME : part .ChecksumCRC64NVME ,
645627 })
646628 }
647629
@@ -652,12 +634,8 @@ func (c *Client) putObjectMultipartStreamParallel(ctx context.Context, bucketNam
652634 ServerSideEncryption : opts .ServerSideEncryption ,
653635 AutoChecksum : opts .AutoChecksum ,
654636 }
655- if len (crcBytes ) > 0 {
656- // Add hash of hashes.
657- crc .Reset ()
658- crc .Write (crcBytes )
659- opts .UserMetadata = map [string ]string {opts .AutoChecksum .KeyCapitalized (): base64 .StdEncoding .EncodeToString (crc .Sum (nil ))}
660- }
637+ applyAutoChecksum (& opts , allParts )
638+
661639 uploadInfo , err := c .completeMultipartUpload (ctx , bucketName , objectName , uploadID , complMultipartUpload , opts )
662640 if err != nil {
663641 return UploadInfo {}, err
@@ -823,9 +801,10 @@ func (c *Client) putObjectDo(ctx context.Context, bucketName, objectName string,
823801 ExpirationRuleID : ruleID ,
824802
825803 // Checksum values
826- ChecksumCRC32 : h .Get ("x-amz-checksum-crc32" ),
827- ChecksumCRC32C : h .Get ("x-amz-checksum-crc32c" ),
828- ChecksumSHA1 : h .Get ("x-amz-checksum-sha1" ),
829- ChecksumSHA256 : h .Get ("x-amz-checksum-sha256" ),
804+ ChecksumCRC32 : h .Get (ChecksumCRC32 .Key ()),
805+ ChecksumCRC32C : h .Get (ChecksumCRC32C .Key ()),
806+ ChecksumSHA1 : h .Get (ChecksumSHA1 .Key ()),
807+ ChecksumSHA256 : h .Get (ChecksumSHA256 .Key ()),
808+ ChecksumCRC64NVME : h .Get (ChecksumCRC64NVME .Key ()),
830809 }, nil
831810}
0 commit comments