Esempio n. 1
0
 public static void ContentMd5Header(HttpResponseMessage response)
 {
     Assert.IsNotNull(response);
     Assert.IsNotNull(HttpResponseParsers.GetContentMD5(response));
 }
Esempio n. 2
0
        /// <summary>
        /// Gets the blob's properties from the response.
        /// </summary>
        /// <param name="response">The web response.</param>
        /// <returns>The blob's properties.</returns>
        public static BlobProperties GetProperties(HttpResponseMessage response)
        {
            CommonUtility.AssertNotNull("response", response);

            BlobProperties properties = new BlobProperties();

            if (response.Content != null)
            {
                properties.LastModified = response.Content.Headers.LastModified;
                HttpContentHeaders contentHeaders = response.Content.Headers;
                properties.ContentEncoding    = HttpWebUtility.GetHeaderValues("Content-Encoding", contentHeaders);
                properties.ContentLanguage    = HttpWebUtility.GetHeaderValues("Content-Language", contentHeaders);
                properties.ContentDisposition = HttpWebUtility.GetHeaderValues("Content-Disposition", contentHeaders);
                properties.ContentType        = HttpWebUtility.GetHeaderValues("Content-Type", contentHeaders);


                if (response.Content.Headers.ContentMD5 != null && response.Content.Headers.ContentRange == null)
                {
                    properties.ContentMD5 = HttpResponseParsers.GetContentMD5(response);
                }
                else if (!string.IsNullOrEmpty(response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.BlobContentMD5Header)))
                {
                    properties.ContentMD5 = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.BlobContentMD5Header);
                }

                string created = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.CreationTimeHeader);
                properties.Created = string.IsNullOrEmpty(created) ? (DateTimeOffset?)null : DateTimeOffset.Parse(created, CultureInfo.InvariantCulture).ToUniversalTime();

                string blobEncryption = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.ServerEncrypted);
                properties.IsServerEncrypted = string.Equals(blobEncryption, Constants.HeaderConstants.TrueHeader, StringComparison.OrdinalIgnoreCase);

                string incrementalCopy = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.IncrementalCopyHeader);
                properties.IsIncrementalCopy = string.Equals(incrementalCopy, Constants.HeaderConstants.TrueHeader, StringComparison.OrdinalIgnoreCase);

                // Get the content length. Prioritize range and x-ms over content length for the special cases.
                string contentLengthHeader = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.BlobContentLengthHeader);
                if ((response.Content.Headers.ContentRange != null) &&
                    response.Content.Headers.ContentRange.HasLength)
                {
                    properties.Length = response.Content.Headers.ContentRange.Length.Value;
                }
                else if (!string.IsNullOrEmpty(contentLengthHeader))
                {
                    properties.Length = long.Parse(contentLengthHeader);
                }
                else if (response.Content.Headers.ContentLength.HasValue)
                {
                    properties.Length = response.Content.Headers.ContentLength.Value;
                }
            }
            properties.CacheControl = HttpWebUtility.GetHeaderValues("Cache-Control", response.Headers);

            if (response.Headers.ETag != null)
            {
                properties.ETag = response.Headers.ETag.ToString();
            }

            // Get blob type
            string blobType = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.BlobType);

            if (!string.IsNullOrEmpty(blobType))
            {
                properties.BlobType = (BlobType)Enum.Parse(typeof(BlobType), blobType, true);
            }

            // Get lease properties
            properties.LeaseStatus   = GetLeaseStatus(response);
            properties.LeaseState    = GetLeaseState(response);
            properties.LeaseDuration = GetLeaseDuration(response);

            // Get sequence number
            string sequenceNumber = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.BlobSequenceNumber);

            if (!string.IsNullOrEmpty(sequenceNumber))
            {
                properties.PageBlobSequenceNumber = long.Parse(sequenceNumber, CultureInfo.InvariantCulture);
            }

            // Get committed block count
            string comittedBlockCount = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.BlobCommittedBlockCount);

            if (!string.IsNullOrEmpty(comittedBlockCount))
            {
                properties.AppendBlobCommittedBlockCount = int.Parse(comittedBlockCount, CultureInfo.InvariantCulture);
            }

            // Get the tier of the blob
            string premiumBlobTierInferredString = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.AccessTierInferredHeader);

            if (!string.IsNullOrEmpty(premiumBlobTierInferredString))
            {
                properties.BlobTierInferred = Convert.ToBoolean(premiumBlobTierInferredString);
            }

            string              blobTierString = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.AccessTierHeader);
            StandardBlobTier?   standardBlobTier;
            PremiumPageBlobTier?premiumPageBlobTier;

            BlobHttpResponseParsers.GetBlobTier(properties.BlobType, blobTierString, out standardBlobTier, out premiumPageBlobTier);
            properties.StandardBlobTier    = standardBlobTier;
            properties.PremiumPageBlobTier = premiumPageBlobTier;

            // Get the rehydration status
            string rehydrationStatusString = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.ArchiveStatusHeader);

            if (!string.IsNullOrEmpty(rehydrationStatusString))
            {
                if (Constants.RehydratePendingToHot.Equals(rehydrationStatusString))
                {
                    properties.RehydrationStatus = RehydrationStatus.PendingToHot;
                }
                else if (Constants.RehydratePendingToCool.Equals(rehydrationStatusString))
                {
                    properties.RehydrationStatus = RehydrationStatus.PendingToCool;
                }
                else
                {
                    properties.RehydrationStatus = RehydrationStatus.Unknown;
                }
            }

            if ((properties.PremiumPageBlobTier.HasValue || properties.StandardBlobTier.HasValue) && !properties.BlobTierInferred.HasValue)
            {
                properties.BlobTierInferred = false;
            }

            // Get the time the tier of the blob was last modified
            string accessTierChangeTimeString = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.AccessTierChangeTimeHeader);

            if (!string.IsNullOrEmpty(accessTierChangeTimeString))
            {
                properties.BlobTierLastModifiedTime = DateTimeOffset.Parse(accessTierChangeTimeString, CultureInfo.InvariantCulture);
            }

            return(properties);
        }
Esempio n. 3
0
        public async Task UseTransactionalMD5GetTestAsync()
        {
            BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions()
            {
                UseTransactionalMD5 = false,
            };
            BlobRequestOptions optionsWithMD5 = new BlobRequestOptions()
            {
                UseTransactionalMD5 = true,
            };

            byte[] buffer = GetRandomBuffer(3 * 1024 * 1024);
            MD5    hasher = MD5.Create();
            string md5    = Convert.ToBase64String(hasher.ComputeHash(buffer));

            string           lastCheckMD5          = null;
            int              checkCount            = 0;
            OperationContext opContextWithMD5Check = new OperationContext();

            opContextWithMD5Check.ResponseReceived += (_, args) =>
            {
                if (long.Parse(HttpResponseParsers.GetContentLength(args.Response)) >= buffer.Length)
                {
                    lastCheckMD5 = HttpResponseParsers.GetContentMD5(args.Response);
                    checkCount++;
                }
            };

            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);
                }

                checkCount = 0;
                using (Stream stream = new MemoryStream())
                {
                    lastCheckMD5 = null;
                    await blockBlob.DownloadToStreamAsync(stream, null, optionsWithNoMD5, opContextWithMD5Check);

                    Assert.IsNotNull(lastCheckMD5);

                    lastCheckMD5 = null;
                    await blockBlob.DownloadToStreamAsync(stream, null, optionsWithMD5, opContextWithMD5Check);

                    Assert.IsNotNull(lastCheckMD5);

                    lastCheckMD5 = "invalid_md5";
                    await blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithNoMD5, opContextWithMD5Check);

                    Assert.IsNull(lastCheckMD5);

                    lastCheckMD5 = "invalid_md5";
                    await blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithMD5, opContextWithMD5Check);

                    Assert.AreEqual(md5, lastCheckMD5);

                    lastCheckMD5 = "invalid_md5";
                    await blockBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoMD5, opContextWithMD5Check);

                    Assert.IsNull(lastCheckMD5);

                    StorageException storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>(
                        () => blockBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithMD5, opContextWithMD5Check),
                        "Downloading more than 4MB with transactional MD5 should not be supported");

                    Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException));

                    lastCheckMD5 = null;
                    using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithMD5, opContextWithMD5Check))
                    {
                        blobStream.CopyTo(stream);
                        Assert.IsNotNull(lastCheckMD5);
                    }

                    lastCheckMD5 = "invalid_md5";
                    using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithNoMD5, opContextWithMD5Check))
                    {
                        blobStream.CopyTo(stream);
                        Assert.IsNull(lastCheckMD5);
                    }
                }

                Assert.AreEqual(9, checkCount);

                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);
                }

                checkCount = 0;
                using (Stream stream = new MemoryStream())
                {
                    lastCheckMD5 = "invalid_md5";
                    await pageBlob.DownloadToStreamAsync(stream, null, optionsWithNoMD5, opContextWithMD5Check);

                    Assert.IsNull(lastCheckMD5);

                    StorageException storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>(
                        () => pageBlob.DownloadToStreamAsync(stream, null, optionsWithMD5, opContextWithMD5Check),
                        "Page blob will not have MD5 set by default; with UseTransactional, download should fail");

                    lastCheckMD5 = "invalid_md5";
                    await pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithNoMD5, opContextWithMD5Check);

                    Assert.IsNull(lastCheckMD5);

                    lastCheckMD5 = "invalid_md5";
                    await pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithMD5, opContextWithMD5Check);

                    Assert.AreEqual(md5, lastCheckMD5);

                    lastCheckMD5 = "invalid_md5";
                    await pageBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoMD5, opContextWithMD5Check);

                    Assert.IsNull(lastCheckMD5);

                    storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>(
                        () => pageBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithMD5, opContextWithMD5Check),
                        "Downloading more than 4MB with transactional MD5 should not be supported");

                    Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException));

                    lastCheckMD5 = null;
                    using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithMD5, opContextWithMD5Check))
                    {
                        blobStream.CopyTo(stream);
                        Assert.IsNotNull(lastCheckMD5);
                    }

                    lastCheckMD5 = "invalid_md5";
                    using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithNoMD5, opContextWithMD5Check))
                    {
                        blobStream.CopyTo(stream);
                        Assert.IsNull(lastCheckMD5);
                    }
                }

                Assert.AreEqual(9, checkCount);
            }
            finally
            {
                await container.DeleteIfExistsAsync();
            }
        }
        public void FileUseTransactionalMD5GetTestAPM()
        {
            FileRequestOptions optionsWithNoMD5 = new FileRequestOptions()
            {
                UseTransactionalMD5 = false,
            };
            FileRequestOptions optionsWithMD5 = new FileRequestOptions()
            {
                UseTransactionalMD5 = true,
            };

            byte[] buffer = GetRandomBuffer(3 * 1024 * 1024);
            MD5    hasher = MD5.Create();
            string md5    = Convert.ToBase64String(hasher.ComputeHash(buffer));

            string           lastCheckMD5          = null;
            int              checkCount            = 0;
            OperationContext opContextWithMD5Check = new OperationContext();

            opContextWithMD5Check.ResponseReceived += (_, args) =>
            {
                if (long.Parse(HttpResponseParsers.GetContentLength(args.Response)) >= buffer.Length)
                {
                    lastCheckMD5 = HttpResponseParsers.GetContentMD5(args.Response);
                    checkCount++;
                }
            };

            CloudFileShare share = GetRandomShareReference();

            try
            {
                share.Create();

                using (AutoResetEvent waitHandle = new AutoResetEvent(false))
                {
                    IAsyncResult result;
                    CloudFile    file = share.GetRootDirectoryReference().GetFileReference("file2");
                    using (Stream fileStream = file.OpenWrite(buffer.Length * 2))
                    {
                        fileStream.Write(buffer, 0, buffer.Length);
                        fileStream.Write(buffer, 0, buffer.Length);
                    }

                    checkCount = 0;
                    using (Stream stream = new MemoryStream())
                    {
                        result = file.BeginDownloadToStream(stream, null, optionsWithNoMD5, opContextWithMD5Check,
                                                            ar => waitHandle.Set(),
                                                            null);
                        waitHandle.WaitOne();
                        file.EndDownloadRangeToStream(result);
                        Assert.IsNull(lastCheckMD5);

                        result = file.BeginDownloadToStream(stream, null, optionsWithMD5, opContextWithMD5Check,
                                                            ar => waitHandle.Set(),
                                                            null);
                        waitHandle.WaitOne();
                        StorageException storageEx = TestHelper.ExpectedException <StorageException>(
                            () => file.EndDownloadRangeToStream(result),
                            "File will not have MD5 set by default; with UseTransactional, download should fail");

                        result = file.BeginDownloadRangeToStream(stream, buffer.Length, buffer.Length, null, optionsWithNoMD5, opContextWithMD5Check,
                                                                 ar => waitHandle.Set(),
                                                                 null);
                        waitHandle.WaitOne();
                        file.EndDownloadRangeToStream(result);
                        Assert.IsNull(lastCheckMD5);

                        result = file.BeginDownloadRangeToStream(stream, buffer.Length, buffer.Length, null, optionsWithMD5, opContextWithMD5Check,
                                                                 ar => waitHandle.Set(),
                                                                 null);
                        waitHandle.WaitOne();
                        file.EndDownloadRangeToStream(result);
                        Assert.AreEqual(md5, lastCheckMD5);

                        result = file.BeginDownloadRangeToStream(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoMD5, opContextWithMD5Check,
                                                                 ar => waitHandle.Set(),
                                                                 null);
                        waitHandle.WaitOne();
                        file.EndDownloadRangeToStream(result);
                        Assert.IsNull(lastCheckMD5);

                        result = file.BeginDownloadRangeToStream(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithMD5, opContextWithMD5Check,
                                                                 ar => waitHandle.Set(),
                                                                 null);
                        waitHandle.WaitOne();
                        storageEx = TestHelper.ExpectedException <StorageException>(
                            () => file.EndDownloadRangeToStream(result),
                            "Downloading more than 4MB with transactional MD5 should not be supported");
                        Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException));

                        result = file.BeginOpenRead(null, optionsWithMD5, opContextWithMD5Check,
                                                    ar => waitHandle.Set(),
                                                    null);
                        waitHandle.WaitOne();
                        using (Stream fileStream = file.EndOpenRead(result))
                        {
                            fileStream.CopyTo(stream);
                            Assert.IsNotNull(lastCheckMD5);
                        }

                        result = file.BeginOpenRead(null, optionsWithNoMD5, opContextWithMD5Check,
                                                    ar => waitHandle.Set(),
                                                    null);
                        waitHandle.WaitOne();
                        using (Stream fileStream = file.EndOpenRead(result))
                        {
                            fileStream.CopyTo(stream);
                            Assert.IsNull(lastCheckMD5);
                        }
                    }
                    Assert.AreEqual(9, checkCount);
                }
            }
            finally
            {
                share.DeleteIfExists();
            }
        }
Esempio n. 5
0
 public static void ContentChecksumHeader(HttpResponseMessage response)
 {
     Assert.IsNotNull(response);
     Assert.IsFalse(HttpResponseParsers.GetContentMD5(response) == null && HttpResponseParsers.GetContentCRC64(response) == null);
 }