@@ -930,28 +930,7 @@ namespace Aws
930930 request.SetVersionId (handle->GetVersionId ());
931931 }
932932
933- // Wrap user's stream with checksum validator if enabled
934- std::shared_ptr<Utils::Crypto::Hash> singlePartHash;
935- std::shared_ptr<ChecksumValidatingStreamBuf> checksumWrapper;
936-
937- if (m_transferConfig.validateChecksums )
938- {
939- singlePartHash = CreateHashForAlgorithm (m_transferConfig.checksumAlgorithm );
940- auto userStreamFactory = handle->GetCreateDownloadStreamFunction ();
941-
942- request.SetResponseStreamFactory ([userStreamFactory, singlePartHash, &checksumWrapper]() -> Aws::IOStream* {
943- auto userStream = userStreamFactory ();
944- if (userStream && singlePartHash) {
945- checksumWrapper = Aws::MakeShared<ChecksumValidatingStreamBuf>(CLASS_TAG, userStream->rdbuf (), singlePartHash);
946- userStream->rdbuf (checksumWrapper.get ());
947- }
948- return userStream;
949- });
950- }
951- else
952- {
953- request.SetResponseStreamFactory (handle->GetCreateDownloadStreamFunction ());
954- }
933+ request.SetResponseStreamFactory (handle->GetCreateDownloadStreamFunction ());
955934
956935 request.SetDataReceivedEventHandler ([this , handle, partState](const Aws::Http::HttpRequest*, Aws::Http::HttpResponse*, long long progress)
957936 {
@@ -977,32 +956,55 @@ namespace Aws
977956 handle->ChangePartToCompleted (partState, getObjectOutcome.GetResult ().GetETag ());
978957 getObjectOutcome.GetResult ().GetBody ().flush ();
979958
980- // Validate checksum for single-part download
981- if (m_transferConfig.validateChecksums && singlePartHash )
959+ // Validate checksum for single-part download by reading file
960+ if (m_transferConfig.validateChecksums )
982961 {
983962 Aws::String expectedChecksum = GetChecksumFromResult (getObjectOutcome.GetResult (), m_transferConfig.checksumAlgorithm );
984963
985- if (!expectedChecksum.empty ())
964+ if (!expectedChecksum.empty () && !handle-> GetTargetFilePath (). empty () )
986965 {
987- auto calculatedResult = singlePartHash->GetHash ();
988- if (calculatedResult.IsSuccess ())
966+ auto hash = CreateHashForAlgorithm (m_transferConfig.checksumAlgorithm );
967+ Aws::IFStream fileStream (handle->GetTargetFilePath ().c_str (), std::ios::binary);
968+
969+ if (fileStream.good ())
989970 {
990- Aws::String calculatedChecksum = Utils::HashingUtils::Base64Encode (calculatedResult.GetResult ());
991- if (calculatedChecksum != expectedChecksum)
971+ const size_t bufferSize = 8192 ;
972+ char buffer[bufferSize];
973+ while (fileStream.good ())
992974 {
993- AWS_LOGSTREAM_ERROR (CLASS_TAG, " Transfer handle [" << handle->GetId ()
994- << " ] Checksum mismatch for single-part download. Expected: "
995- << expectedChecksum << " , Calculated: " << calculatedChecksum);
996- handle->ChangePartToFailed (partState);
997- handle->UpdateStatus (TransferStatus::FAILED);
998- Aws::Client::AWSError<Aws::S3::S3Errors> error (Aws::S3::S3Errors::INTERNAL_FAILURE,
999- " ChecksumMismatch" ,
1000- " Single-part download checksum validation failed" ,
1001- false );
1002- handle->SetError (error);
1003- TriggerErrorCallback (handle, error);
1004- TriggerTransferStatusUpdatedCallback (handle);
1005- return ;
975+ fileStream.read (buffer, bufferSize);
976+ std::streamsize bytesRead = fileStream.gcount ();
977+ if (bytesRead > 0 )
978+ {
979+ hash->Update (reinterpret_cast <unsigned char *>(buffer), static_cast <size_t >(bytesRead));
980+ }
981+ }
982+ fileStream.close ();
983+
984+ auto calculatedResult = hash->GetHash ();
985+ if (calculatedResult.IsSuccess ())
986+ {
987+ Aws::String calculatedChecksum = Utils::HashingUtils::Base64Encode (calculatedResult.GetResult ());
988+ if (calculatedChecksum != expectedChecksum)
989+ {
990+ AWS_LOGSTREAM_ERROR (CLASS_TAG, " Transfer handle [" << handle->GetId ()
991+ << " ] Checksum mismatch for single-part download. Expected: "
992+ << expectedChecksum << " , Calculated: " << calculatedChecksum);
993+
994+ // Delete the corrupted file
995+ Aws::FileSystem::RemoveFileIfExists (handle->GetTargetFilePath ().c_str ());
996+
997+ handle->ChangePartToFailed (partState);
998+ handle->UpdateStatus (TransferStatus::FAILED);
999+ Aws::Client::AWSError<Aws::S3::S3Errors> error (Aws::S3::S3Errors::INTERNAL_FAILURE,
1000+ " ChecksumMismatch" ,
1001+ " Single-part download checksum validation failed" ,
1002+ false );
1003+ handle->SetError (error);
1004+ TriggerErrorCallback (handle, error);
1005+ TriggerTransferStatusUpdatedCallback (handle);
1006+ return ;
1007+ }
10061008 }
10071009 }
10081010 }
0 commit comments