internal async static Task <StorageException> PopulateStorageExceptionFromHttpResponseMessage(HttpResponseMessage response, RequestResult currentResult, CancellationToken token, Func <Stream, HttpResponseMessage, string, CancellationToken, Task <StorageExtendedErrorInformation> > parseError) { if (!response.IsSuccessStatusCode) { try { currentResult.HttpStatusMessage = response.ReasonPhrase; currentResult.HttpStatusCode = (int)response.StatusCode; currentResult.ServiceRequestID = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(response.Headers, Constants.HeaderConstants.RequestIdHeader); string tempDate = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(response.Headers, Constants.HeaderConstants.Date); currentResult.RequestDate = string.IsNullOrEmpty(tempDate) ? DateTime.Now.ToString("R", CultureInfo.InvariantCulture) : tempDate; if (response.Headers.ETag != null) { currentResult.Etag = response.Headers.ETag.ToString(); } if (response.Content != null && response.Content.Headers.ContentMD5 != null) { currentResult.ContentMd5 = Convert.ToBase64String(response.Content.Headers.ContentMD5); } if (response.Content != null && HttpResponseParsers.GetContentCRC64(response) != null) { currentResult.ContentCrc64 = HttpResponseParsers.GetContentCRC64(response); } currentResult.ErrorCode = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(response.Headers, Constants.HeaderConstants.StorageErrorCodeHeader); } catch (Exception) { // no op } try { Stream errStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); if (parseError != null) { currentResult.ExtendedErrorInformation = await parseError(errStream, response, response.Content.Headers.ContentType.ToString(), token).ConfigureAwait(false); } else { currentResult.ExtendedErrorInformation = await StorageExtendedErrorInformation.ReadFromStreamAsync(errStream, token).ConfigureAwait(false); } } catch (Exception) { // no op } return(new StorageException(currentResult, response.ReasonPhrase, null)); } else { return(null); } }
private static void PopulateRequestResult(RequestResult reqResult, HttpResponseMessage response) { reqResult.HttpStatusMessage = response.ReasonPhrase; reqResult.HttpStatusCode = (int)response.StatusCode; #if !WINDOWS_RT if (response.Headers != null) { reqResult.ServiceRequestID = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(response.Headers, Constants.HeaderConstants.RequestIdHeader); reqResult.RequestDate = response.Headers.Date.HasValue ? response.Headers.Date.Value.UtcDateTime.ToString("R", CultureInfo.InvariantCulture) : null; reqResult.Etag = response.Headers.ETag?.ToString(); reqResult.ErrorCode = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(response.Headers, Constants.HeaderConstants.StorageErrorCodeHeader); } if (response.Content != null && response.Content.Headers != null) { reqResult.ContentMd5 = response.Content.Headers.ContentMD5 != null?Convert.ToBase64String(response.Content.Headers.ContentMD5) : null; reqResult.ContentCrc64 = HttpResponseParsers.GetContentCRC64(response); reqResult.IngressBytes += response.Content.Headers.ContentLength.HasValue ? (long)response.Content.Headers.ContentLength : 0; } #endif }
public async Task UseTransactionalCRC64GetTestAsync() { BlobRequestOptions optionsWithNoCRC64 = new BlobRequestOptions() { ChecksumOptions = new ChecksumOptions { UseTransactionalCRC64 = false } }; BlobRequestOptions optionsWithCRC64 = new BlobRequestOptions() { ChecksumOptions = new ChecksumOptions { UseTransactionalCRC64 = true } }; byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); Crc64Wrapper hasher = new Crc64Wrapper(); hasher.UpdateHash(buffer, 0, buffer.Length); string crc64 = hasher.ComputeHash(); string lastCheckCRC64 = null; OperationContext opContextWithCRC64Check = new OperationContext(); opContextWithCRC64Check.ResponseReceived += (_, args) => { if (long.Parse(HttpResponseParsers.GetContentLength(args.Response)) >= buffer.Length) { lastCheckCRC64 = HttpResponseParsers.GetContentCRC64(args.Response); } }; OperationContext opContextWithCRC64CheckAndInjectedFailure = new OperationContext(); opContextWithCRC64CheckAndInjectedFailure.ResponseReceived += (_, args) => { args.Response.Headers.Remove(Constants.HeaderConstants.ContentCrc64Header); args.Response.Headers.TryAddWithoutValidation(Constants.HeaderConstants.ContentCrc64Header, "dummy"); if (long.Parse(HttpResponseParsers.GetContentLength(args.Response)) >= buffer.Length) { lastCheckCRC64 = HttpResponseParsers.GetContentCRC64(args.Response); } }; CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); using (Stream blobStream = await blockBlob.OpenWriteAsync()) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } using (Stream stream = new MemoryStream()) { //lastCheckCRC64 = null; //blockBlob.DownloadToStream(stream, null, optionsWithNoCRC64, opContextWithCRC64Check); //Assert.IsNotNull(lastCheckCRC64); //lastCheckCRC64 = null; //blockBlob.DownloadToStream(stream, null, optionsWithCRC64, opContextWithCRC64Check); //Assert.IsNotNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; await blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; await blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); await TestHelper.ExpectedExceptionAsync <StorageException>( () => blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithCRC64, opContextWithCRC64CheckAndInjectedFailure), "Calculated CRC64 does not match existing property" ); lastCheckCRC64 = "invalid_CRC64"; await blockBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); StorageException storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => blockBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithCRC64, opContextWithCRC64Check), "Downloading more than 4MB with transactional CRC64 should not be supported"); Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); lastCheckCRC64 = null; using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithCRC64, opContextWithCRC64Check)) { blobStream.CopyTo(stream); Assert.IsNotNull(lastCheckCRC64); } lastCheckCRC64 = "invalid_CRC64"; using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithNoCRC64, opContextWithCRC64Check)) { blobStream.CopyTo(stream); Assert.IsNull(lastCheckCRC64); } } CloudPageBlob pageBlob = container.GetPageBlobReference("blob3"); using (Stream blobStream = await pageBlob.OpenWriteAsync(buffer.Length * 2)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } using (Stream stream = new MemoryStream()) { lastCheckCRC64 = "invalid_CRC64"; await pageBlob.DownloadToStreamAsync(stream, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); StorageException storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadToStreamAsync(stream, null, optionsWithCRC64, opContextWithCRC64Check), "Page blob will not have CRC64 set by default; with UseTransactional, download should fail"); lastCheckCRC64 = "invalid_CRC64"; await pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; await pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithCRC64, opContextWithCRC64CheckAndInjectedFailure), "Calculated CRC64 does not match existing property" ); lastCheckCRC64 = "invalid_CRC64"; await pageBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithCRC64, opContextWithCRC64Check), "Downloading more than 4MB with transactional CRC64 should not be supported"); Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); lastCheckCRC64 = null; using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithCRC64, opContextWithCRC64Check)) { blobStream.CopyTo(stream); Assert.IsNotNull(lastCheckCRC64); } lastCheckCRC64 = "invalid_CRC64"; using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithNoCRC64, opContextWithCRC64Check)) { blobStream.CopyTo(stream); Assert.IsNull(lastCheckCRC64); } } } finally { await container.DeleteIfExistsAsync(); } }
public static void ContentChecksumHeader(HttpResponseMessage response) { Assert.IsNotNull(response); Assert.IsFalse(HttpResponseParsers.GetContentMD5(response) == null && HttpResponseParsers.GetContentCRC64(response) == null); }