public override void Handle(ServiceResponse response) { if (_inputStream is MD5Stream) { MD5Stream stream = (MD5Stream)_inputStream; if (stream.CalculatedHash == null) { stream.CalculateHash(); } if (response.Headers.ContainsKey(HttpHeaders.ContentMd5) && stream.CalculatedHash != null) { var sdkCalculatedHash = Convert.ToBase64String(stream.CalculatedHash); var ossCalculatedHash = response.Headers[HttpHeaders.ContentMd5]; if (!sdkCalculatedHash.Equals(ossCalculatedHash)) { response.Dispose(); throw new ClientException("Expected hash not equal to calculated hash"); } } } }
private static void ProcessResponseHandlers(IExecutionContext executionContext) { AmazonWebServiceResponse response = executionContext.ResponseContext.Response; IRequest request = executionContext.RequestContext.Request; IWebResponseData webResponseData = executionContext.ResponseContext.HttpResponse; bool isSse = HasSSEHeaders(webResponseData); var getObjectResponse = response as GetObjectResponse; if (getObjectResponse != null) { GetObjectRequest getObjectRequest = request.OriginalRequest as GetObjectRequest; getObjectResponse.BucketName = getObjectRequest.BucketName; getObjectResponse.Key = getObjectRequest.Key; // If ETag is present and is an MD5 hash (not a multi-part upload ETag), and no byte range is specified, // wrap the response stream in an MD5Stream. // If there is a customer encryption algorithm the etag is not an MD5. if (!string.IsNullOrEmpty(getObjectResponse.ETag) && !getObjectResponse.ETag.Contains("-") && !isSse && getObjectRequest.ByteRange == null) { string etag = getObjectResponse.ETag.Trim(etagTrimChars); byte[] expectedHash = AWSSDKUtils.HexStringToBytes(etag); HashStream hashStream = new MD5Stream(getObjectResponse.ResponseStream, expectedHash, getObjectResponse.ContentLength); getObjectResponse.ResponseStream = hashStream; } } var deleteObjectsResponse = response as DeleteObjectsResponse; if (deleteObjectsResponse != null) { if (deleteObjectsResponse.DeleteErrors != null && deleteObjectsResponse.DeleteErrors.Count > 0) { throw new DeleteObjectsException(deleteObjectsResponse as DeleteObjectsResponse); } } var putObjectResponse = response as PutObjectResponse; var putObjectRequest = request.OriginalRequest as PutObjectRequest; if (putObjectRequest != null) { // If InputStream was a MD5Stream, compare calculated hash to returned etag MD5Stream hashStream = putObjectRequest.InputStream as MD5Stream; if (hashStream != null) { if (putObjectResponse != null && !isSse) { // Stream may not have been closed, so force calculation of hash hashStream.CalculateHash(); CompareHashes(putObjectResponse.ETag, hashStream.CalculatedHash); } // Set InputStream to its original value putObjectRequest.InputStream = hashStream.GetNonWrapperBaseStream(); } } var listObjectsResponse = response as ListObjectsResponse; if (listObjectsResponse != null) { if (listObjectsResponse.IsTruncated && string.IsNullOrEmpty(listObjectsResponse.NextMarker) && listObjectsResponse.S3Objects.Count > 0) { listObjectsResponse.NextMarker = listObjectsResponse.S3Objects.Last().Key; } } var uploadPartRequest = request.OriginalRequest as UploadPartRequest; var uploadPartResponse = response as UploadPartResponse; if (uploadPartRequest != null) { if (uploadPartResponse != null) { uploadPartResponse.PartNumber = uploadPartRequest.PartNumber; } // If InputStream was a MD5Stream, compare calculated hash to returned etag MD5Stream hashStream = uploadPartRequest.InputStream as MD5Stream; if (hashStream != null) { if (uploadPartResponse != null && !isSse) { // Stream may not have been closed, so force calculation of hash hashStream.CalculateHash(); CompareHashes(uploadPartResponse.ETag, hashStream.CalculatedHash); } // Set InputStream to its original value uploadPartRequest.InputStream = hashStream.GetNonWrapperBaseStream(); } } var copyPartResponse = response as CopyPartResponse; if (copyPartResponse != null) { copyPartResponse.PartNumber = ((CopyPartRequest)request.OriginalRequest).PartNumber; } AmazonS3Client.CleanupRequest(request.OriginalRequest); }