@@ -825,6 +825,33 @@ namespace Aws
825825 return rangeStream.str ();
826826 }
827827
828+ static bool VerifyContentRange (const Aws::String& requestedRange, const Aws::String& responseContentRange)
829+ {
830+ if (requestedRange.empty () || responseContentRange.empty ())
831+ {
832+ return false ;
833+ }
834+
835+ if (requestedRange.find (" bytes=" ) != 0 )
836+ {
837+ return false ;
838+ }
839+ Aws::String requestRange = requestedRange.substr (6 );
840+
841+ if (responseContentRange.find (" bytes " ) != 0 )
842+ {
843+ return false ;
844+ }
845+ Aws::String responseRange = responseContentRange.substr (6 );
846+ size_t slashPos = responseRange.find (' /' );
847+ if (slashPos != Aws::String::npos)
848+ {
849+ responseRange = responseRange.substr (0 , slashPos);
850+ }
851+
852+ return requestRange == responseRange;
853+ }
854+
828855 void TransferManager::DoSinglePartDownload (const std::shared_ptr<TransferHandle>& handle)
829856 {
830857 auto queuedParts = handle->GetQueuedParts ();
@@ -1091,7 +1118,6 @@ namespace Aws
10911118 const std::shared_ptr<const Aws::Client::AsyncCallerContext>& context)
10921119 {
10931120 AWS_UNREFERENCED_PARAM (client);
1094- AWS_UNREFERENCED_PARAM (request);
10951121
10961122 std::shared_ptr<TransferHandleAsyncContext> transferContext =
10971123 std::const_pointer_cast<TransferHandleAsyncContext>(std::static_pointer_cast<const TransferHandleAsyncContext>(context));
@@ -1110,6 +1136,37 @@ namespace Aws
11101136 }
11111137 else
11121138 {
1139+ if (request.RangeHasBeenSet ())
1140+ {
1141+ const auto & requestedRange = request.GetRange ();
1142+ const auto & responseContentRange = outcome.GetResult ().GetContentRange ();
1143+
1144+ if (!responseContentRange.empty ())
1145+ {
1146+ if (!VerifyContentRange (requestedRange, responseContentRange))
1147+ {
1148+ Aws::Client::AWSError<Aws::S3::S3Errors> error (Aws::S3::S3Errors::INTERNAL_FAILURE,
1149+ " ContentRangeMismatch" ,
1150+ " ContentRange in response does not match requested range" ,
1151+ false );
1152+ AWS_LOGSTREAM_ERROR (CLASS_TAG, " Transfer handle [" << handle->GetId ()
1153+ << " ] ContentRange mismatch. Requested: [" << requestedRange
1154+ << " ] Received: [" << responseContentRange << " ]" );
1155+ handle->ChangePartToFailed (partState);
1156+ handle->SetError (error);
1157+ TriggerErrorCallback (handle, error);
1158+ handle->Cancel ();
1159+
1160+ if (partState->GetDownloadBuffer ())
1161+ {
1162+ m_bufferManager.Release (partState->GetDownloadBuffer ());
1163+ partState->SetDownloadBuffer (nullptr );
1164+ }
1165+ return ;
1166+ }
1167+ }
1168+ }
1169+
11131170 if (handle->ShouldContinue ())
11141171 {
11151172 Aws::IOStream* bufferStream = partState->GetDownloadPartStream ();
0 commit comments