/// <summary>
        /// Implements the Exists method. The attributes are updated immediately.
        /// </summary>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that checks existence.</returns>
        internal static RESTCommand <bool> ExistsImpl(ICloudBlob blob, BlobAttributes attributes, BlobRequestOptions options)
        {
            RESTCommand <bool> getCmd = new RESTCommand <bool>(blob.ServiceClient.Credentials, attributes.Uri);

            getCmd.ApplyRequestOptions(options);
            getCmd.Handler            = blob.ServiceClient.AuthenticationHandler;
            getCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            getCmd.BuildRequest       = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.GetProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, attributes.SnapshotTime, null /* accessCondition */, cnt, ctx);
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                if (resp.StatusCode == HttpStatusCode.NotFound)
                {
                    return(false);
                }

                if (resp.StatusCode == HttpStatusCode.PreconditionFailed)
                {
                    return(true);
                }

                return(HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, true, cmd, ex, ctx));
            };

            return(getCmd);
        }
        /// <summary>
        /// Generates a <see cref="RESTCommand"/> for breaking a lease.
        /// </summary>
        /// <param name="breakPeriod">The amount of time to allow the lease to remain, rounded down to seconds.
        /// If null, the break period is the remainder of the current lease, or zero for infinite leases.</param>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> implementing the break lease operation.</returns>
        internal static RESTCommand <TimeSpan> BreakLeaseImpl(ICloudBlob blob, BlobAttributes attributes, TimeSpan?breakPeriod, AccessCondition accessCondition, BlobRequestOptions options)
        {
            int?breakSeconds = null;

            if (breakPeriod.HasValue)
            {
                CommonUtils.AssertInBounds("breakPeriod", breakPeriod.Value, TimeSpan.FromSeconds(0), TimeSpan.MaxValue);
                breakSeconds = (int)breakPeriod.Value.TotalSeconds;
            }

            RESTCommand <TimeSpan> putCmd = new RESTCommand <TimeSpan>(blob.ServiceClient.Credentials, attributes.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.Handler            = blob.ServiceClient.AuthenticationHandler;
            putCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            putCmd.BuildRequest       = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Break, null /* proposedLeaseId */, null /* leaseDuration */, breakSeconds, accessCondition, cnt, ctx);
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, TimeSpan.Zero, cmd, ex, ctx);

                int?remainingLeaseTime = BlobHttpResponseParsers.GetRemainingLeaseTime(resp);
                if (!remainingLeaseTime.HasValue)
                {
                    // Unexpected result from service.
                    throw new StorageException(cmd.CurrentResult, SR.LeaseTimeNotReceived, null /* inner */);
                }

                return(TimeSpan.FromSeconds(remainingLeaseTime.Value));
            };

            return(putCmd);
        }
        /// <summary>
        /// Implementation of the StartCopyFromBlob method. Result is a BlobAttributes object derived from the response headers.
        /// </summary>
        /// <param name="source">The URI of the source blob.</param>
        /// <param name="sourceAccessCondition">An object that represents the access conditions for the source blob. If null, no condition is used.</param>
        /// <param name="destAccessCondition">An object that represents the access conditions for the destination blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <param name="setResult">A delegate for setting the BlobAttributes result.</param>
        /// <returns>A <see cref="RESTCommand"/> that starts to copy the blob.</returns>
        internal static RESTCommand <string> StartCopyFromBlobImpl(ICloudBlob blob, BlobAttributes attributes, Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options)
        {
            if (sourceAccessCondition != null && !string.IsNullOrEmpty(sourceAccessCondition.LeaseId))
            {
                throw new ArgumentException(SR.LeaseConditionOnSource, "sourceAccessCondition");
            }

            RESTCommand <string> putCmd = new RESTCommand <string>(blob.ServiceClient.Credentials, attributes.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.Handler      = blob.ServiceClient.AuthenticationHandler;
            putCmd.BuildClient  = HttpClientFactory.BuildHttpClient;
            putCmd.BuildRequest = (cmd, cnt, ctx) =>
            {
                HttpRequestMessage msg = BlobHttpRequestMessageFactory.CopyFrom(cmd.Uri, cmd.ServerTimeoutInSeconds, source, sourceAccessCondition, destAccessCondition, cnt, ctx);
                BlobHttpRequestMessageFactory.AddMetadata(msg, attributes.Metadata);
                return(msg);
            };
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, null /* retVal */, cmd, ex, ctx);
                CopyState state = BlobHttpResponseParsers.GetCopyAttributes(resp);
                attributes.Properties = BlobHttpResponseParsers.GetProperties(resp);
                attributes.Metadata   = BlobHttpResponseParsers.GetMetadata(resp);
                attributes.CopyState  = state;
                return(state.CopyId);
            };

            return(putCmd);
        }
예제 #4
0
        private RESTCommand <NullType> SetServicePropertiesImpl(ServiceProperties properties, BlobRequestOptions requestOptions)
        {
            MemoryStream memoryStream = new MemoryStream();

            try
            {
                properties.WriteServiceProperties(memoryStream);
            }
            catch (InvalidOperationException invalidOpException)
            {
                throw new ArgumentException(invalidOpException.Message, "properties");
            }

            RESTCommand <NullType> retCmd = new RESTCommand <NullType>(this.Credentials, this.BaseUri);

            retCmd.ApplyRequestOptions(requestOptions);
            retCmd.BuildRequest           = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.SetServiceProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx);
            retCmd.BuildContent           = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, null /* md5 */, cmd, ctx);
            retCmd.RetrieveResponseStream = true;
            retCmd.Handler            = this.AuthenticationHandler;
            retCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            retCmd.PreProcessResponse =
                (cmd, resp, ex, ctx) =>
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.Accepted, resp, null /* retVal */, cmd, ex, ctx);
            retCmd.ApplyRequestOptions(requestOptions);
            return(retCmd);
        }
예제 #5
0
        /// <summary>
        /// Generates a get blob request over the specified range, and checks the request for consistency.
        /// </summary>
        /// <param name="context">The testing context.</param>
        /// <param name="containerName">The name of the container.</param>
        /// <param name="blobName">The name of the blob.</param>
        /// <param name="offset">The offset to the range.</param>
        /// <param name="count">The number of elements in the range.</param>
        /// <param name="leaseId">The lease ID, or null if the blob is not leased.</param>
        /// <returns>A web request for getting a blob range.</returns>
        public static HttpRequestMessage GetBlobRangeRequest(BlobContext context, string containerName, string blobName, long offset, long?count, AccessCondition accessCondition)
        {
            bool valid = BlobTests.ContainerNameValidator(containerName) &&
                         BlobTests.BlobNameValidator(blobName) &&
                         BlobTests.LeaseIdValidator(accessCondition);

            Uri uri = BlobTests.ConstructGetUri(context.Address, containerName, blobName);
            HttpRequestMessage request   = null;
            OperationContext   opContext = new OperationContext();

            try
            {
                request = BlobHttpRequestMessageFactory.Get(uri, context.Timeout, null /* snapshot */, offset, count, ChecksumRequested.None, accessCondition, null, opContext, SharedKeyCanonicalizer.Instance, context.Credentials, null);
            }
            catch (InvalidOperationException)
            {
                if (valid)
                {
                    Assert.Fail();
                }
            }

            if (valid)
            {
                Assert.IsNotNull(request);
                Assert.IsNotNull(request.Method);
                Assert.AreEqual(HttpMethod.Get, request.Method);
                BlobTestUtils.RangeHeader(request, offset, count.HasValue ? (long?)(count.Value + offset - 1) : null);
                BlobTestUtils.LeaseIdHeader(request, accessCondition == null ? null : accessCondition.LeaseId);
            }

            return(request);
        }
        private static RESTCommand <IList <BlobBatchSubOperationResponse> > BatchImpl(BatchOperation batch, CloudBlobClient client, BlobRequestOptions requestOptions)
        {
            // ContentMD5??
            //string contentMD5 = null;

            /*if (requestOptions.UseTransactionalMD5.HasValue && requestOptions.UseTransactionalMD5.Value)
             * {
             *  contentMD5 = memoryStream.ComputeMD5Hash();
             * }*/

            RESTCommand <IList <BlobBatchSubOperationResponse> > batchCmd = new RESTCommand <IList <BlobBatchSubOperationResponse> >(client.Credentials, client.StorageUri, client.HttpClient);

            requestOptions.ApplyToStorageCommand(batchCmd);

            List <BlobBatchSubOperationResponse> results = new List <BlobBatchSubOperationResponse>();

            batchCmd.CommandLocationMode      = CommandLocationMode.PrimaryOnly;
            batchCmd.RetrieveResponseStream   = true;
            batchCmd.PreProcessResponse       = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, null /* retVal */, cmd, ex);
            batchCmd.BuildContent             = (cmd, ctx) => BlobHttpRequestMessageFactory.WriteBatchBody(client, cmd, batch, ctx);
            batchCmd.BuildRequest             = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.PrepareBatchRequest(uri, client.BufferManager, serverTimeout, batch, cnt, ctx, client.GetCanonicalizer(), client.Credentials);
            batchCmd.PostProcessResponseAsync = (cmd, resp, ctx, ct) => BlobHttpResponseParsers.BatchPostProcessAsync(results, cmd, new[] { HttpStatusCode.Accepted, HttpStatusCode.OK }, resp, ctx, ct);

            return(batchCmd);
        }
        /// <summary>
        /// Implements the FetchAttributes method. The attributes are updated immediately.
        /// </summary>
        /// <param name="blobUri">The URI of the blob.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that fetches the attributes.</returns>
        private RESTCommand <ICloudBlob> GetBlobReferenceImpl(Uri blobUri, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand <ICloudBlob> getCmd = new RESTCommand <ICloudBlob>(this.Credentials, blobUri);

            getCmd.ApplyRequestOptions(options);
            getCmd.Handler            = this.AuthenticationHandler;
            getCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            getCmd.BuildRequest       = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.GetProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, null /* snapshot */, accessCondition, cnt, ctx);
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex, ctx);
                BlobAttributes attributes = new BlobAttributes();
                attributes.Uri = blobUri;
                CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false);
                switch (attributes.Properties.BlobType)
                {
                case BlobType.BlockBlob:
                    return(new CloudBlockBlob(attributes, this));

                case BlobType.PageBlob:
                    return(new CloudPageBlob(attributes, this));

                default:
                    throw new InvalidOperationException();
                }
            };

            return(getCmd);
        }
예제 #8
0
        public async static void AcquireAndReleaseLeaseTest(BlobContext context, string containerName, string blobName)
        {
            CloudStorageAccount account   = new CloudStorageAccount(new StorageCredentials(context.Account, context.Key), false);
            CloudBlobClient     client    = new CloudBlobClient(new Uri(context.Address), account.Credentials);
            CloudBlobContainer  container = client.GetContainerReference(containerName);
            CloudBlockBlob      blob      = container.GetBlockBlobReference(blobName);

            BlobTestBase.UploadText(blob, "Text sent to cloud", Encoding.UTF8);

            // acquire a release on the blob and check LeaseStatus to be "locked"
            OperationContext   opContext   = new OperationContext();
            HttpRequestMessage blobRequest = BlobHttpRequestMessageFactory.Lease(
                blob.Uri,
                context.Timeout,
                LeaseAction.Acquire,
                null /* proposed lease ID */,
                60 /* lease duration */,
                null /* break period */,
                null /* access condition */,
                null,
                opContext,
                SharedKeyCanonicalizer.Instance,
                context.Credentials);

            string leaseId = null;

            using (HttpResponseMessage response = await BlobTestUtils.GetResponse(blobRequest, context))
            {
                leaseId = HttpResponseParsers.GetHeader(response, "x-ms-lease-id");
                Assert.AreEqual <HttpStatusCode>(response.StatusCode, HttpStatusCode.Created);
            }

            blob.FetchAttributes();
            Assert.AreEqual <LeaseStatus>(blob.Properties.LeaseStatus, LeaseStatus.Locked);

            // release the release on the blob and check LeaseStatus to be "unlocked"
            opContext   = new OperationContext();
            blobRequest = BlobHttpRequestMessageFactory.Lease(
                blob.Uri,
                context.Timeout,
                LeaseAction.Release,
                null /* proposed lease ID */,
                null /* lease duration */,
                null /* break period */,
                AccessCondition.GenerateLeaseCondition(leaseId),
                null,
                opContext,
                SharedKeyCanonicalizer.Instance,
                context.Credentials);
            using (HttpResponseMessage response = await BlobTestUtils.GetResponse(blobRequest, context))
            {
                Assert.AreEqual <HttpStatusCode>(response.StatusCode, HttpStatusCode.OK);
            }

            blob.FetchAttributes();
            Assert.AreEqual <LeaseStatus>(blob.Properties.LeaseStatus, LeaseStatus.Unlocked);

            blob.Delete();
        }
        /// <summary>
        /// Implements the DeleteBlob method.
        /// </summary>
        /// <param name="deleteSnapshotsOption">Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots.</param>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that deletes the blob.</returns>
        internal static RESTCommand <NullType> DeleteBlobImpl(ICloudBlob blob, BlobAttributes attributes, DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand <NullType> deleteCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.Uri);

            deleteCmd.ApplyRequestOptions(options);
            deleteCmd.Handler            = blob.ServiceClient.AuthenticationHandler;
            deleteCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            deleteCmd.BuildRequest       = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Delete(cmd.Uri, cmd.ServerTimeoutInSeconds, attributes.SnapshotTime, deleteSnapshotsOption, accessCondition, cnt, ctx);
            deleteCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, NullType.Value, cmd, ex, ctx);

            return(deleteCmd);
        }
        /// <summary>
        /// Implementation of the AbortCopy method. No result is produced.
        /// </summary>
        /// <param name="copyId">The copy ID of the copy operation to abort.</param>
        /// <param name="accessCondition">An object that represents the access conditions for the operation. If null, no condition is used.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="TaskSequence"/> that copies the blob.</returns>
        internal static RESTCommand <NullType> AbortCopyImpl(ICloudBlob blob, BlobAttributes attributes, string copyId, AccessCondition accessCondition, BlobRequestOptions options)
        {
            CommonUtils.AssertNotNull("copyId", copyId);

            RESTCommand <NullType> putCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.Handler            = blob.ServiceClient.AuthenticationHandler;
            putCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            putCmd.BuildRequest       = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.AbortCopy(cmd.Uri, cmd.ServerTimeoutInSeconds, copyId, accessCondition, cnt, ctx);
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex, ctx);

            return(putCmd);
        }
예제 #11
0
        /// <summary>
        /// Generates and validates a request to break a lease.
        /// </summary>
        /// <param name="context">The blob context.</param>
        /// <param name="containerName">The container name.</param>
        /// <param name="blobName">The blob name.</param>
        /// <param name="breakPeriod">The break period.</param>
        /// <returns>A web request for the operation.</returns>
        public static HttpRequestMessage BreakLeaseRequest(BlobContext context, string containerName, string blobName, int?breakPeriod, AccessCondition accessCondition)
        {
            HttpRequestMessage request;
            OperationContext   opContext = new OperationContext();

            if (blobName != null)
            {
                // blob lease
                Uri uri = BlobTests.ConstructPutUri(context.Address, containerName, blobName);
                request = BlobHttpRequestMessageFactory.Lease(
                    uri,
                    context.Timeout,
                    LeaseAction.Break,
                    null /* proposed lease ID */,
                    null /* lease duration */,
                    breakPeriod,
                    accessCondition,
                    null,
                    opContext,
                    SharedKeyCanonicalizer.Instance,
                    context.Credentials);
            }
            else
            {
                // container lease
                Uri uri = BlobClientTests.ConstructUri(context.Address, containerName);
                request = ContainerHttpRequestMessageFactory.Lease(
                    uri,
                    context.Timeout,
                    LeaseAction.Break,
                    null /* proposed lease ID */,
                    null /* lease duration */,
                    breakPeriod,
                    accessCondition,
                    null,
                    opContext,
                    SharedKeyCanonicalizer.Instance,
                    context.Credentials);
            }
            Assert.IsNotNull(request);
            Assert.AreEqual(HttpMethod.Put, request.Method);
            BlobTestUtils.VersionHeader(request, false);
            BlobTestUtils.LeaseIdHeader(request, null);
            BlobTestUtils.LeaseActionHeader(request, "break");
            BlobTestUtils.LeaseDurationHeader(request, null);
            BlobTestUtils.ProposedLeaseIdHeader(request, null);
            BlobTestUtils.BreakPeriodHeader(request, breakPeriod.HasValue ? breakPeriod.Value.ToString() : null);
            return(request);
        }
예제 #12
0
        public static HttpRequestMessage PutBlockListRequest(BlobContext context, string containerName, string blobName, BlobProperties blobProperties, AccessCondition accessCondition)
        {
            Uri uri = BlobTests.ConstructPutUri(context.Address, containerName, blobName);
            HttpRequestMessage request   = null;
            OperationContext   opContext = new OperationContext();

            request = BlobHttpRequestMessageFactory.PutBlockList(uri, context.Timeout, blobProperties, accessCondition, null, opContext, SharedKeyCanonicalizer.Instance, context.Credentials);
            Assert.IsNotNull(request);
            Assert.IsNotNull(request.Method);
            Assert.AreEqual(HttpMethod.Put, request.Method);
            BlobTestUtils.VersionHeader(request, false);
            BlobTestUtils.ContentLanguageHeader(request, null);
            BlobTestUtils.ContentMd5Header(request, null);
            return(request);
        }
예제 #13
0
        public static HttpRequestMessage PutBlobRequest(BlobContext context, string containerName, string blobName,
                                                        BlobProperties properties, BlobType blobType, byte[] content, long pageBlobSize, AccessCondition accessCondition)
        {
            bool valid = BlobTests.ContainerNameValidator(containerName) &&
                         BlobTests.BlobNameValidator(blobName) &&
                         BlobTests.PutPropertiesValidator(properties) &&
                         BlobTestUtils.ContentValidator(content);

            bool fatal = !BlobTests.PutPropertiesValidator(properties);

            Uri uri = BlobTests.ConstructPutUri(context.Address, containerName, blobName);
            HttpRequestMessage request   = null;
            OperationContext   opContext = new OperationContext();

            try
            {
                request = BlobHttpRequestMessageFactory.Put(uri, context.Timeout, properties, blobType, pageBlobSize, null, accessCondition, null, opContext,
                                                            SharedKeyCanonicalizer.Instance, context.Credentials, null);
                if (fatal)
                {
                    Assert.Fail();
                }
            }
            catch (InvalidOperationException)
            {
                if (valid)
                {
                    Assert.Fail();
                }
            }
            if (valid)
            {
                Assert.IsNotNull(request);
                Assert.IsNotNull(request.Method);
                Assert.AreEqual(HttpMethod.Put, request.Method);
                BlobTestUtils.VersionHeader(request, false);
                BlobTestUtils.ContentTypeHeader(request, null);
                BlobTestUtils.ContentDispositionHeader(request, properties.ContentDisposition);
                BlobTestUtils.ContentEncodingHeader(request, properties.ContentEncoding);
                BlobTestUtils.ContentLanguageHeader(request, null);
                BlobTestUtils.ContentMd5Header(request, null);
                BlobTestUtils.ContentCrc64Header(request, null);
                BlobTestUtils.CacheControlHeader(request, null);
                BlobTestUtils.BlobTypeHeader(request, properties.BlobType);
                BlobTestUtils.BlobSizeHeader(request, (properties.BlobType == BlobType.PageBlob) ? properties.Length : (long?)null);
            }
            return(request);
        }
예제 #14
0
        public static HttpRequestMessage GetBlockListRequest(BlobContext context, string containerName, string blobName, BlockListingFilter typesOfBlocks, AccessCondition accessCondition)
        {
            Uri uri = BlobClientTests.ConstructUri(context.Address, containerName, blobName);
            OperationContext   opContext = new OperationContext();
            HttpRequestMessage request   = BlobHttpRequestMessageFactory.GetBlockList(uri, context.Timeout, null /* snapshot */, typesOfBlocks, accessCondition, null,
                                                                                      opContext,
                                                                                      SharedKeyCanonicalizer.Instance,
                                                                                      context.Credentials);

            Assert.IsNotNull(request);
            Assert.IsNotNull(request.Method);
            Assert.AreEqual(HttpMethod.Get, request.Method);
            BlobTestUtils.RangeHeader(request, null);
            BlobTestUtils.LeaseIdHeader(request, null);
            return(request);
        }
        /// <summary>
        /// Generates a web request to use to acquire, renew, change, release or break the lease for the container.
        /// </summary>
        /// <param name="uri">The absolute URI to the container.</param>
        /// <param name="timeout">The server timeout interval, in seconds.</param>
        /// <param name="action">The lease action to perform.</param>
        /// <param name="proposedLeaseId">A lease ID to propose for the result of an acquire or change operation,
        /// or null if no ID is proposed for an acquire operation. This should be null for renew, release, and break operations.</param>
        /// <param name="leaseDuration">The lease duration, in seconds, for acquire operations.
        /// If this is -1 then an infinite duration is specified. This should be null for renew, change, release, and break operations.</param>
        /// <param name="leaseBreakPeriod">The amount of time to wait, in seconds, after a break operation before the lease is broken.
        /// If this is null then the default time is used. This should be null for acquire, renew, change, and release operations.</param>
        /// <param name="accessCondition">The access condition to apply to the request.</param>
        /// <returns>A web request to use to perform the operation.</returns>
        public static StorageRequestMessage Lease(Uri uri, int?timeout, LeaseAction action, string proposedLeaseId, int?leaseDuration, int?leaseBreakPeriod, AccessCondition accessCondition, HttpContent content, OperationContext operationContext, ICanonicalizer canonicalizer, StorageCredentials credentials)
        {
            UriQueryBuilder builder = GetContainerUriQueryBuilder();

            builder.Add(Constants.QueryConstants.Component, "lease");

            StorageRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext, canonicalizer, credentials);

            // Add Headers
            BlobHttpRequestMessageFactory.AddLeaseAction(request, action);
            BlobHttpRequestMessageFactory.AddLeaseDuration(request, leaseDuration);
            BlobHttpRequestMessageFactory.AddProposedLeaseId(request, proposedLeaseId);
            BlobHttpRequestMessageFactory.AddLeaseBreakPeriod(request, leaseBreakPeriod);

            request.ApplyAccessCondition(accessCondition);
            return(request);
        }
        /// <summary>
        /// Implements the FetchAttributes method. The attributes are updated immediately.
        /// </summary>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that fetches the attributes.</returns>
        internal static RESTCommand <NullType> FetchAttributesImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand <NullType> getCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.Uri);

            getCmd.ApplyRequestOptions(options);
            getCmd.Handler            = blob.ServiceClient.AuthenticationHandler;
            getCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            getCmd.BuildRequest       = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.GetProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, attributes.SnapshotTime, accessCondition, cnt, ctx);
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex, ctx);
                CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false);
                return(NullType.Value);
            };

            return(getCmd);
        }
        /// <summary>
        /// Generates a <see cref="RESTCommand"/> for releasing a lease.
        /// </summary>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> implementing the release lease operation.</returns>
        internal static RESTCommand <NullType> ReleaseLeaseImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options)
        {
            CommonUtils.AssertNotNull("accessCondition", accessCondition);
            if (accessCondition.LeaseId == null)
            {
                throw new ArgumentException(SR.MissingLeaseIDReleasing, "accessCondition");
            }

            RESTCommand <NullType> putCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.Handler            = blob.ServiceClient.AuthenticationHandler;
            putCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            putCmd.BuildRequest       = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Release, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, cnt, ctx);
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex, ctx);

            return(putCmd);
        }
예제 #18
0
        /// <summary>
        /// Implements the FetchAttributes method. The attributes are updated immediately.
        /// </summary>
        /// <param name="blobUri">The URI of the blob.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that fetches the attributes.</returns>
        private RESTCommand <ICloudBlob> GetBlobReferenceImpl(Uri blobUri, AccessCondition accessCondition, BlobRequestOptions options)
        {
            // If the blob Uri contains SAS credentials, we need to use those
            // credentials instead of this service client's stored credentials.
            StorageCredentials parsedCredentials;
            DateTimeOffset?    parsedSnapshot;

            blobUri = NavigationHelper.ParseBlobQueryAndVerify(blobUri, out parsedCredentials, out parsedSnapshot);
            CloudBlobClient client = parsedCredentials != null ? new CloudBlobClient(this.BaseUri, parsedCredentials) : this;

            RESTCommand <ICloudBlob> getCmd = new RESTCommand <ICloudBlob>(client.Credentials, blobUri);

            getCmd.ApplyRequestOptions(options);
            getCmd.Handler            = client.AuthenticationHandler;
            getCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            getCmd.BuildRequest       = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.GetProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, parsedSnapshot, accessCondition, cnt, ctx);
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex, ctx);

                BlobAttributes attributes = new BlobAttributes()
                {
                    Uri          = blobUri,
                    SnapshotTime = parsedSnapshot,
                };

                CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false);

                switch (attributes.Properties.BlobType)
                {
                case BlobType.BlockBlob:
                    return(new CloudBlockBlob(attributes, client));

                case BlobType.PageBlob:
                    return(new CloudPageBlob(attributes, client));

                default:
                    throw new InvalidOperationException();
                }
            };

            return(getCmd);
        }
예제 #19
0
        private RESTCommand <ServiceProperties> GetServicePropertiesImpl(BlobRequestOptions requestOptions)
        {
            RESTCommand <ServiceProperties> retCmd = new RESTCommand <ServiceProperties>(this.Credentials, this.BaseUri);

            retCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.GetServiceProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, ctx);

            retCmd.RetrieveResponseStream = true;
            retCmd.Handler            = this.AuthenticationHandler;
            retCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            retCmd.PreProcessResponse =
                (cmd, resp, ex, ctx) =>
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.OK, resp, null /* retVal */, cmd, ex, ctx);

            retCmd.PostProcessResponse = (cmd, resp, ex, ctx) =>
            {
                return(Task.Factory.StartNew(() => BlobHttpResponseParsers.ReadServiceProperties(cmd.ResponseStream)));
            };

            retCmd.ApplyRequestOptions(requestOptions);
            return(retCmd);
        }
예제 #20
0
        /// <summary>
        /// Implementation for the SetProperties method.
        /// </summary>
        /// <param name="blob">The blob object that is calling this method.</param>
        /// <param name="attributes">The blob's attributes.</param>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that sets the metadata.</returns>
        internal static RESTCommand <NullType> SetPropertiesImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand <NullType> putCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.StorageUri);

            options.ApplyToStorageCommand(putCmd);
            putCmd.Handler      = blob.ServiceClient.AuthenticationHandler;
            putCmd.BuildClient  = HttpClientFactory.BuildHttpClient;
            putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) =>
            {
                HttpRequestMessage msg = BlobHttpRequestMessageFactory.SetProperties(uri, serverTimeout, attributes.Properties, accessCondition, cnt, ctx);
                BlobHttpRequestMessageFactory.AddMetadata(msg, attributes.Metadata);
                return(msg);
            };
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex);
                CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp);
                return(NullType.Value);
            };

            return(putCmd);
        }
        /// <summary>
        /// Implementation for the SetProperties method.
        /// </summary>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that sets the metadata.</returns>
        internal static RESTCommand <NullType> SetPropertiesImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand <NullType> putCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.Handler      = blob.ServiceClient.AuthenticationHandler;
            putCmd.BuildClient  = HttpClientFactory.BuildHttpClient;
            putCmd.BuildRequest = (cmd, cnt, ctx) =>
            {
                HttpRequestMessage msg = BlobHttpRequestMessageFactory.SetProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, attributes.Properties, accessCondition, cnt, ctx);
                BlobHttpRequestMessageFactory.AddMetadata(msg, attributes.Metadata);
                return(msg);
            };
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex, ctx);
                CloudBlobSharedImpl.ParseSizeAndLastModified(attributes, resp);
                return(NullType.Value);
            };

            return(putCmd);
        }
        /// <summary>
        /// Generates a <see cref="RESTCommand"/> for acquiring a lease.
        /// </summary>
        /// <param name="leaseTime">A <see cref="TimeSpan"/> representing the span of time for which to acquire the lease,
        /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be
        /// greater than zero.</param>
        /// <param name="proposedLeaseId">A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed.</param>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> implementing the acquire lease operation.</returns>
        internal static RESTCommand <string> AcquireLeaseImpl(ICloudBlob blob, BlobAttributes attributes, TimeSpan?leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options)
        {
            int leaseDuration = -1;

            if (leaseTime.HasValue)
            {
                CommonUtils.AssertInBounds("leaseTime", leaseTime.Value, TimeSpan.FromSeconds(1), TimeSpan.MaxValue);
                leaseDuration = (int)leaseTime.Value.TotalSeconds;
            }

            RESTCommand <string> putCmd = new RESTCommand <string>(blob.ServiceClient.Credentials, attributes.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.Handler            = blob.ServiceClient.AuthenticationHandler;
            putCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            putCmd.BuildRequest       = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Acquire, proposedLeaseId, leaseDuration, null /* leaseBreakPeriod */, accessCondition, cnt, ctx);
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex, ctx);
                return(BlobHttpResponseParsers.GetLeaseId(resp));
            };

            return(putCmd);
        }
예제 #23
0
        private RESTCommand <ServiceStats> GetServiceStatsImpl(BlobRequestOptions requestOptions)
        {
            RESTCommand <ServiceStats> retCmd = new RESTCommand <ServiceStats>(this.Credentials, this.StorageUri);

            requestOptions.ApplyToStorageCommand(retCmd);
            retCmd.CommandLocationMode    = CommandLocationMode.PrimaryOrSecondary;
            retCmd.BuildRequest           = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.GetServiceStats(uri, serverTimeout, ctx);
            retCmd.RetrieveResponseStream = true;
            retCmd.Handler             = this.AuthenticationHandler;
            retCmd.BuildClient         = HttpClientFactory.BuildHttpClient;
            retCmd.PreProcessResponse  = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
            retCmd.PostProcessResponse = (cmd, resp, ctx) => Task.Factory.StartNew(() => BlobHttpResponseParsers.ReadServiceStats(cmd.ResponseStream));
            return(retCmd);
        }
예제 #24
0
        private RESTCommand <ServiceProperties> GetServicePropertiesImpl(BlobRequestOptions requestOptions)
        {
            RESTCommand <ServiceProperties> retCmd = new RESTCommand <ServiceProperties>(this.Credentials, this.StorageUri);

            retCmd.CommandLocationMode    = CommandLocationMode.PrimaryOrSecondary;
            retCmd.BuildRequest           = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.GetServiceProperties(uri, serverTimeout, ctx, this.GetCanonicalizer(), this.Credentials);
            retCmd.RetrieveResponseStream = true;
            retCmd.PreProcessResponse     =
                (cmd, resp, ex, ctx) =>
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);

            retCmd.PostProcessResponse = (cmd, resp, ctx) =>
            {
                return(Task.FromResult(BlobHttpResponseParsers.ReadServiceProperties(cmd.ResponseStream)));
            };

            requestOptions.ApplyToStorageCommand(retCmd);
            return(retCmd);
        }
예제 #25
0
        private RESTCommand <NullType> SetServicePropertiesImpl(ServiceProperties properties, BlobRequestOptions requestOptions)
        {
            MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB));

            try
            {
                properties.WriteServiceProperties(memoryStream);
            }
            catch (InvalidOperationException invalidOpException)
            {
                throw new ArgumentException(invalidOpException.Message, "properties");
            }

            RESTCommand <NullType> retCmd = new RESTCommand <NullType>(this.Credentials, this.StorageUri, this.HttpClient);

            requestOptions.ApplyToStorageCommand(retCmd);
            retCmd.BuildRequest           = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.SetServiceProperties(uri, serverTimeout, cnt, ctx, this.GetCanonicalizer(), this.Credentials);
            retCmd.BuildContent           = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, Checksum.None, cmd, ctx);
            retCmd.StreamToDispose        = memoryStream;
            retCmd.RetrieveResponseStream = true;
            retCmd.PreProcessResponse     =
                (cmd, resp, ex, ctx) =>
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, null /* retVal */, cmd, ex);
            requestOptions.ApplyToStorageCommand(retCmd);
            return(retCmd);
        }
예제 #26
0
        public async Task ClearPageRangeScenarioTest(string containerName, string blobName, HttpStatusCode?expectedError)
        {
            // 1. Create Sparse Page Blob
            int blobSize = 128 * 1024;

            BlobProperties properties = new BlobProperties()
            {
                BlobType = BlobType.PageBlob
            };
            Uri uri = BlobTests.ConstructPutUri(BlobContext.Address, containerName, blobName);
            OperationContext   opContext  = new OperationContext();
            HttpRequestMessage webRequest = BlobHttpRequestMessageFactory.Put(uri, BlobContext.Timeout, properties, BlobType.PageBlob, blobSize, null, null, null, opContext, null, null);


            using (HttpResponseMessage response = await BlobTestUtils.GetResponse(webRequest, BlobContext))
            {
                BlobTests.PutBlobResponse(response, BlobContext, expectedError);
            }

            // 2. Now upload some page ranges
            for (int m = 0; m * 512 * 4 < blobSize; m++)
            {
                int startOffset = 512 * 4 * m;
                int length      = 512;

                PageRange range = new PageRange(startOffset, startOffset + length - 1);
                opContext = new OperationContext();
                HttpRequestMessage pageRequest = BlobHttpRequestMessageFactory.PutPage(uri, BlobContext.Timeout, range, PageWrite.Update, null, null, opContext, null, null);
                HttpRequestHandler.SetContentLength(pageRequest, 512);

                byte[] content = new byte[length];
                random.NextBytes(content);

                pageRequest.Content = new ByteArrayContent(content);

                using (HttpResponseMessage pageResponse = await BlobTestUtils.GetResponse(pageRequest, BlobContext))
                {
                }
            }

            // 3. Now do a Get Page Ranges
            List <PageRange> pageRanges = new List <PageRange>();

            opContext = new OperationContext();
            HttpRequestMessage pageRangeRequest = BlobHttpRequestMessageFactory.GetPageRanges(uri, BlobContext.Timeout, null, null, null, null, null, opContext, null, null);

            using (HttpResponseMessage pageRangeResponse = await BlobTestUtils.GetResponse(pageRangeRequest, BlobContext))
            {
                IEnumerable <PageRange> ranges = await GetPageRangesResponse.ParseAsync(HttpResponseParsers.GetResponseStream(pageRangeResponse), CancellationToken.None);

                pageRanges.AddRange(ranges);
            }

            // 4. Now Clear some pages
            bool skipFlag = false;

            foreach (PageRange pRange in pageRanges)
            {
                skipFlag = !skipFlag;
                if (skipFlag)
                {
                    continue;
                }

                opContext = new OperationContext();
                HttpRequestMessage clearPageRequest = BlobHttpRequestMessageFactory.PutPage(uri, BlobContext.Timeout, pRange, PageWrite.Clear, null, null, opContext, null, null);
                HttpRequestHandler.SetContentLength(clearPageRequest, 0);
                using (HttpResponseMessage clearResponse = await BlobTestUtils.GetResponse(clearPageRequest, BlobContext))
                {
                }
            }

            // 5. Get New Page ranges and verify
            List <PageRange> newPageRanges = new List <PageRange>();

            opContext = new OperationContext();
            HttpRequestMessage newPageRangeRequest = BlobHttpRequestMessageFactory.GetPageRanges(uri, BlobContext.Timeout, null, null, null, null, null, opContext, null, null);

            using (HttpResponseMessage newPageRangeResponse = await BlobTestUtils.GetResponse(newPageRangeRequest, BlobContext))
            {
                IEnumerable <PageRange> ranges = await GetPageRangesResponse.ParseAsync(HttpResponseParsers.GetResponseStream(newPageRangeResponse), CancellationToken.None);

                newPageRanges.AddRange(ranges);
            }

            Assert.AreEqual(pageRanges.Count(), newPageRanges.Count() * 2);
            for (int l = 0; l < newPageRanges.Count(); l++)
            {
                Assert.AreEqual(pageRanges[2 * l].StartOffset, newPageRanges[l].StartOffset);
                Assert.AreEqual(pageRanges[2 * l].EndOffset, newPageRanges[l].EndOffset);
            }
        }
예제 #27
0
        /// <summary>
        /// Implements the FetchAttributes method. The attributes are updated immediately.
        /// </summary>
        /// <param name="blobUri">The URI of the blob.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that fetches the attributes.</returns>
        private RESTCommand <ICloudBlob> GetBlobReferenceImpl(StorageUri blobUri, AccessCondition accessCondition, BlobRequestOptions options)
        {
            // If the blob Uri contains SAS credentials, we need to use those
            // credentials instead of this service client's stored credentials.
            StorageCredentials parsedCredentials;
            DateTimeOffset?    parsedSnapshot;

            blobUri = NavigationHelper.ParseBlobQueryAndVerify(blobUri, out parsedCredentials, out parsedSnapshot);
            CloudBlobClient client = parsedCredentials != null ? new CloudBlobClient(this.StorageUri, parsedCredentials) : this;

            RESTCommand <ICloudBlob> getCmd = new RESTCommand <ICloudBlob>(client.Credentials, blobUri, this.HttpClient);

            options.ApplyToStorageCommand(getCmd);
            getCmd.CommandLocationMode = CommandLocationMode.PrimaryOrSecondary;
            getCmd.BuildRequest        = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.GetProperties(uri, serverTimeout,
                                                                                                                                     parsedSnapshot, accessCondition, cnt, ctx, client.GetCanonicalizer(), client.Credentials, options);
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
                BlobAttributes attributes = new BlobAttributes()
                {
                    StorageUri   = blobUri,
                    SnapshotTime = parsedSnapshot,
                };

                CloudBlob.UpdateAfterFetchAttributes(attributes, resp);

                switch (attributes.Properties.BlobType)
                {
                case BlobType.BlockBlob:
                    return(new CloudBlockBlob(attributes, client));

                case BlobType.PageBlob:
                    return(new CloudPageBlob(attributes, client));

                case BlobType.AppendBlob:
                    return(new CloudAppendBlob(attributes, client));

                default:
                    throw new InvalidOperationException();
                }
            };

            return(getCmd);
        }
        /// <summary>
        /// Implements getting the blob.
        /// </summary>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="SynchronousTask"/> that gets the stream.</returns>
        internal static RESTCommand <NullType> GetBlobImpl(ICloudBlob blob, BlobAttributes attributes, Stream destStream, long?offset, long?length, AccessCondition accessCondition, BlobRequestOptions options)
        {
            string          lockedETag            = null;
            AccessCondition lockedAccessCondition = null;

            bool   isRangeGet             = offset.HasValue;
            bool   arePropertiesPopulated = false;
            string storedMD5 = null;

            long startingOffset = offset.HasValue ? offset.Value : 0;
            long?startingLength = length;

            RESTCommand <NullType> getCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.Uri);

            getCmd.ApplyRequestOptions(options);
            getCmd.RetrieveResponseStream        = true;
            getCmd.DestinationStream             = destStream;
            getCmd.CalculateMd5ForResponseStream = !options.DisableContentMD5Validation.Value;
            getCmd.Handler        = blob.ServiceClient.AuthenticationHandler;
            getCmd.BuildClient    = HttpClientFactory.BuildHttpClient;
            getCmd.BuildRequest   = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Get(cmd.Uri, cmd.ServerTimeoutInSeconds, attributes.SnapshotTime, offset, length, options.UseTransactionalMD5.Value, accessCondition, cnt, ctx);
            getCmd.RecoveryAction = (cmd, ex, ctx) =>
            {
                if ((lockedAccessCondition == null) && !string.IsNullOrEmpty(lockedETag))
                {
                    lockedAccessCondition = AccessCondition.GenerateIfMatchCondition(lockedETag);
                    if (accessCondition != null)
                    {
                        lockedAccessCondition.LeaseId = accessCondition.LeaseId;
                    }
                }

                if (cmd.StreamCopyState != null)
                {
                    offset = startingOffset + cmd.StreamCopyState.Length;
                    if (startingLength.HasValue)
                    {
                        length = startingLength.Value - cmd.StreamCopyState.Length;
                    }
                }

                getCmd.BuildRequest = (command, cnt, context) => BlobHttpRequestMessageFactory.Get(command.Uri, command.ServerTimeoutInSeconds, attributes.SnapshotTime, offset, length, options.UseTransactionalMD5.Value && !arePropertiesPopulated, lockedAccessCondition ?? accessCondition, cnt, context);
            };

            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(offset.HasValue ? HttpStatusCode.PartialContent : HttpStatusCode.OK, resp, NullType.Value, cmd, ex, ctx);

                if (!arePropertiesPopulated)
                {
                    CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, isRangeGet);

                    if (resp.Content.Headers.ContentMD5 != null)
                    {
                        storedMD5 = Convert.ToBase64String(resp.Content.Headers.ContentMD5);
                    }

                    if (!options.DisableContentMD5Validation.Value &&
                        options.UseTransactionalMD5.Value &&
                        string.IsNullOrEmpty(storedMD5))
                    {
                        throw new StorageException(
                                  cmd.CurrentResult,
                                  SR.MD5NotPresentError,
                                  null)
                              {
                                  IsRetryable = false
                              };
                    }

                    lockedETag             = attributes.Properties.ETag;
                    arePropertiesPopulated = true;
                }

                return(NullType.Value);
            };

            getCmd.PostProcessResponse = (cmd, resp, ex, ctx) =>
            {
                long validateLength = startingLength.HasValue ? startingLength.Value : (attributes.Properties.Length - startingOffset);
                HttpResponseParsers.ValidateResponseStreamMd5AndLength(validateLength, storedMD5, cmd, cmd.StreamCopyState);
                return(Task.FromResult(NullType.Value));
            };

            return(getCmd);
        }
예제 #29
0
        private RESTCommand <ServiceStats> GetServiceStatsImpl(BlobRequestOptions requestOptions)
        {
            if (RetryPolicies.LocationMode.PrimaryOnly == requestOptions.LocationMode)
            {
                throw new InvalidOperationException(SR.GetServiceStatsInvalidOperation);
            }

            RESTCommand <ServiceStats> retCmd = new RESTCommand <ServiceStats>(this.Credentials, this.StorageUri, this.HttpClient);

            requestOptions.ApplyToStorageCommand(retCmd);
            retCmd.CommandLocationMode      = CommandLocationMode.PrimaryOrSecondary;
            retCmd.BuildRequest             = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.GetServiceStats(uri, serverTimeout, ctx, this.GetCanonicalizer(), this.Credentials);
            retCmd.RetrieveResponseStream   = true;
            retCmd.PreProcessResponse       = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
            retCmd.PostProcessResponseAsync = (cmd, resp, ctx, ct) => BlobHttpResponseParsers.ReadServiceStatsAsync(cmd.ResponseStream, ct);
            return(retCmd);
        }
예제 #30
0
        /// <summary>
        /// Generates a <see cref="RESTCommand"/> for releasing a lease.
        /// </summary>
        /// <param name="blob">The blob object that is calling this method.</param>
        /// <param name="attributes">The blob's attributes.</param>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> implementing the release lease operation.</returns>
        internal static RESTCommand <NullType> ReleaseLeaseImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options)
        {
            CommonUtility.AssertNotNull("accessCondition", accessCondition);
            if (accessCondition.LeaseId == null)
            {
                throw new ArgumentException(SR.MissingLeaseIDReleasing, "accessCondition");
            }

            RESTCommand <NullType> putCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.StorageUri);

            options.ApplyToStorageCommand(putCmd);
            putCmd.Handler            = blob.ServiceClient.AuthenticationHandler;
            putCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            putCmd.BuildRequest       = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.Lease(uri, serverTimeout, LeaseAction.Release, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, cnt, ctx);
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex);
                CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp);
                return(NullType.Value);
            };

            return(putCmd);
        }