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);
            }
        }
Beispiel #2
0
        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
        }
Beispiel #3
0
        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();
            }
        }
Beispiel #4
0
 public static void ContentChecksumHeader(HttpResponseMessage response)
 {
     Assert.IsNotNull(response);
     Assert.IsFalse(HttpResponseParsers.GetContentMD5(response) == null && HttpResponseParsers.GetContentCRC64(response) == null);
 }