@@ -591,6 +591,7 @@ protected MultipartUpload doInitiateMultipartUpload(MultipartUploadRequest reque
591591 .key (request .getKey ())
592592 .metadata (request .getMetadata ())
593593 .tags (request .getTags ())
594+ .checksumEnabled (request .isChecksumEnabled ())
594595 .kmsKeyId (request .getKmsKeyId ())
595596 .build ();
596597 }
@@ -613,10 +614,11 @@ protected UploadPartResponse doUploadMultipartPart(MultipartUpload mpu, Multipar
613614
614615 byte [] partData = baos .toByteArray ();
615616 String etag = generateEtag (partData );
617+ String checksumValue = computeCrc32cChecksum (partData );
616618
617619 state .addPart (mpp .getPartNumber (), partData , etag );
618620
619- return new UploadPartResponse (mpp .getPartNumber (), etag , ( long ) partData .length );
621+ return new UploadPartResponse (mpp .getPartNumber (), etag , partData .length , checksumValue );
620622 } catch (Exception e ) {
621623 throw new UnknownException ("Failed to upload multipart part" , e );
622624 }
@@ -675,8 +677,9 @@ protected MultipartUploadResponse doCompleteMultipartUpload(
675677 STORAGE .put (versionedKey , blob );
676678 LATEST_VERSIONS .put (baseKey , versionId );
677679 MULTIPART_UPLOADS .remove (mpu .getId ());
680+ String checksumValue = computeCrc32cChecksum (finalData );
678681
679- return new MultipartUploadResponse (etag );
682+ return new MultipartUploadResponse (etag , checksumValue );
680683 } catch (Exception e ) {
681684 throw new UnknownException ("Failed to complete multipart upload" , e );
682685 }
@@ -696,7 +699,7 @@ protected List<UploadPartResponse> doListMultipartUpload(MultipartUpload mpu) {
696699 new UploadPartResponse (
697700 entry .getKey (),
698701 entry .getValue ().getEtag (),
699- ( long ) entry .getValue ().getData ().length ))
702+ entry .getValue ().getData ().length ))
700703 .sorted (Comparator .comparingInt (UploadPartResponse ::getPartNumber ))
701704 .collect (Collectors .toList ());
702705 }
@@ -788,6 +791,18 @@ private String generateEtag(byte[] data) {
788791 return "\" " + Integer .toHexString (java .util .Arrays .hashCode (data )) + "\" " ;
789792 }
790793
794+ private String computeCrc32cChecksum (byte [] data ) {
795+ java .util .zip .CRC32C crc32c = new java .util .zip .CRC32C ();
796+ crc32c .update (data );
797+ long value = crc32c .getValue ();
798+ byte [] checksumBytes = new byte [4 ];
799+ checksumBytes [0 ] = (byte ) (value >> 24 );
800+ checksumBytes [1 ] = (byte ) (value >> 16 );
801+ checksumBytes [2 ] = (byte ) (value >> 8 );
802+ checksumBytes [3 ] = (byte ) value ;
803+ return java .util .Base64 .getEncoder ().encodeToString (checksumBytes );
804+ }
805+
791806 private byte [] extractRange (byte [] data , Long start , Long end ) {
792807 int dataLength = data .length ;
793808
0 commit comments