/// <summary> /// Implementation of the StartCopyFromBlob method. Result is a BlobAttributes object derived from the response headers. /// </summary> /// <param name="blob">The blob.</param> /// <param name="attributes">The attributes.</param> /// <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> /// <returns> /// A <see cref="RESTCommand{T}" /> that starts to copy the blob. /// </returns> /// <exception cref="System.ArgumentException">sourceAccessCondition</exception> 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.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.CopyFrom(uri, serverTimeout, source, sourceAccessCondition, destAccessCondition, ctx); putCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, attributes.Metadata); putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; 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); }
/// <summary> /// Generates a <see cref="RESTCommand{T}" /> for breaking a lease. /// </summary> /// <param name="blob">The blob.</param> /// <param name="attributes">The attributes.</param> /// <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{T}" /> 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.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Break, null /* proposedLeaseId */, null /* leaseDuration */, breakSeconds, accessCondition, ctx); putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; 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); }
private static HttpWebRequest BlobGetRequest(KeyValuePair <long, int> blockOffsetAndLength, CloudBlockBlob blob) { StorageCredentials credentials = blob.ServiceClient.Credentials; var transformedUri = credentials.TransformUri(blob.Uri); // Prepare the HttpWebRequest to download data from the chunk. HttpWebRequest blobGetRequest = BlobHttpWebRequestFactory.Get( transformedUri, Timeout, snapshot: null, offset: blockOffsetAndLength.Key, count: blockOffsetAndLength.Value, rangeContentMD5: false, accessCondition: AccessCondition.GenerateEmptyCondition(), operationContext: new OperationContext()); if (credentials.IsSharedKey) { IAuthenticationHandler authenticationHandler = new SharedKeyAuthenticationHandler( SharedKeyCanonicalizer.Instance, credentials, credentials.AccountName); authenticationHandler.SignRequest(blobGetRequest, new OperationContext()); } return(blobGetRequest); }
/// <summary> /// Implements the FetchAttributes method. The attributes are updated immediately. /// </summary> /// <param name="blobUri">The URI of the blob.</param> /// <param name="accessCondition">An 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{T}"/> 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.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetProperties(uri, serverTimeout, null /* snapshot */, accessCondition, ctx); getCmd.SignRequest = this.AuthenticationHandler.SignRequest; 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); }
/// <summary> /// Implements the DeleteBlob method. /// </summary> /// <param name="blob">The blob.</param> /// <param name="attributes">The attributes.</param> /// <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{T}" /> 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.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Delete(uri, serverTimeout, attributes.SnapshotTime, deleteSnapshotsOption, accessCondition, ctx); deleteCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; 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="blob">The blob.</param> /// <param name="attributes">The attributes.</param> /// <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="RESTCommand{T}" /> that aborts the copy. /// </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.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.AbortCopy(uri, serverTimeout, copyId, accessCondition, ctx); putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(new HttpStatusCode[] { HttpStatusCode.OK, HttpStatusCode.NoContent }, resp, NullType.Value, cmd, ex, ctx); return(putCmd); }
/// <summary> /// Implements the FetchAttributes method. The attributes are updated immediately. /// </summary> /// <param name="blob">The blob.</param> /// <param name="attributes">The 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 any additional options for the request.</param> /// <returns> /// A <see cref="RESTCommand{T}" /> 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.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetProperties(uri, serverTimeout, attributes.SnapshotTime, accessCondition, ctx); getCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; 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 web request to use to acquire, renew, change, release or break the lease for the container. /// </summary> /// <param name="uri">A <see cref="System.Uri"/> specifying the absolute URI to the container.</param> /// <param name="timeout">An integer specifying the server timeout interval.</param> /// <param name="action">A <see cref="LeaseAction"/> enumeration value indicating the lease action to perform.</param> /// <param name="proposedLeaseId">A string specifying the lease ID to propose for the result of an acquire or change operation, /// or <c>null</c> if no ID is proposed for an acquire operation. This parameter should be <c>null</c> 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 <c>null</c> 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 <c>null</c> then the default time is used. This should be <c>null</c> for acquire, renew, change, and release operations.</param> /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the condition that must be met in order for the request to proceed.</param> /// <param name="useVersionHeader">A boolean value indicating whether to set the <i>x-ms-version</i> HTTP header.</param> /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param> /// <returns>A <see cref="System.Net.HttpWebRequest"/> object.</returns> public static HttpWebRequest Lease(Uri uri, int?timeout, LeaseAction action, string proposedLeaseId, int?leaseDuration, int?leaseBreakPeriod, AccessCondition accessCondition, bool useVersionHeader, OperationContext operationContext) { UriQueryBuilder builder = GetContainerUriQueryBuilder(); builder.Add(Constants.QueryConstants.Component, "lease"); HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, useVersionHeader, operationContext); // Add Headers BlobHttpWebRequestFactory.AddLeaseAction(request, action); BlobHttpWebRequestFactory.AddLeaseDuration(request, leaseDuration); BlobHttpWebRequestFactory.AddProposedLeaseId(request, proposedLeaseId); BlobHttpWebRequestFactory.AddLeaseBreakPeriod(request, leaseBreakPeriod); request.ApplyAccessCondition(accessCondition); return(request); }
/// <summary> /// Implementation for the SetProperties method. /// </summary> /// <param name="blob">The blob.</param> /// <param name="attributes">The attributes.</param> /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the condition that must be met in order for the request to proceed. 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{T}"/> that sets the properties. /// </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.BuildRequestDelegate = (uri, builder, serverTimeout, useVersionHeader, ctx) => BlobHttpWebRequestFactory.SetProperties(uri, serverTimeout, attributes.Properties, accessCondition, useVersionHeader, ctx); putCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, attributes.Metadata); putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); CloudBlobSharedImpl.UpdateETagLMTLengthAndSequenceNumber(attributes, resp, false); return(NullType.Value); }; return(putCmd); }
/// <summary> /// Implementation for the SetProperties method. /// </summary> /// <param name="blob">The blob.</param> /// <param name="attributes">The 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 any additional options for the request.</param> /// <returns> /// A <see cref="RESTCommand{T}" /> that sets the properties. /// </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.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.SetProperties(uri, serverTimeout, attributes.Properties, accessCondition, ctx); putCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, attributes.Metadata); putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; 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{T}" /> for releasing a lease. /// </summary> /// <param name="blob">The blob.</param> /// <param name="attributes">The 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 any additional options for the request.</param> /// <returns> /// A <see cref="RESTCommand{T}" /> implementing the release lease operation. /// </returns> /// <exception cref="System.ArgumentException">accessCondition</exception> 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.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Release, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx); putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex, ctx); return(putCmd); }
/// <summary> /// Implements the FetchAttributes method. The attributes are updated immediately. /// </summary> /// <param name="blobUri">The URI of the blob.</param> /// <param name="accessCondition">An 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{T}"/> 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.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetProperties(uri, serverTimeout, parsedSnapshot, accessCondition, ctx); getCmd.SignRequest = client.AuthenticationHandler.SignRequest; 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); }
/// <summary> /// Implementation for the Exists method. /// </summary> /// <param name="blob">The blob.</param> /// <param name="attributes">The attributes.</param> /// <param name="options">An object that specifies additional options for the request.</param> /// <param name="primaryOnly">If <c>true</c>, the command will be executed against the primary location.</param> /// <returns> /// A <see cref="RESTCommand{T}" /> that checks existence. /// </returns> internal static RESTCommand <bool> ExistsImpl(ICloudBlob blob, BlobAttributes attributes, BlobRequestOptions options, bool primaryOnly) { RESTCommand <bool> getCmd = new RESTCommand <bool>(blob.ServiceClient.Credentials, attributes.StorageUri); options.ApplyToStorageCommand(getCmd); getCmd.CommandLocationMode = primaryOnly ? CommandLocationMode.PrimaryOnly : CommandLocationMode.PrimaryOrSecondary; getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetProperties(uri, serverTimeout, attributes.SnapshotTime, null /* accessCondition */, ctx); getCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { if (resp.StatusCode == HttpStatusCode.NotFound) { return(false); } HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, true, cmd, ex); CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false); return(true); }; return(getCmd); }
/// <summary> /// Generates a <see cref="RESTCommand{T}" /> for changing a lease ID. /// </summary> /// <param name="blob">The blob.</param> /// <param name="attributes">The attributes.</param> /// <param name="proposedLeaseId">The proposed new lease ID.</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{T}" /> implementing the change lease ID operation. /// </returns> /// <exception cref="System.ArgumentException">accessCondition</exception> internal static RESTCommand <string> ChangeLeaseImpl(ICloudBlob blob, BlobAttributes attributes, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options) { CommonUtility.AssertNotNull("accessCondition", accessCondition); CommonUtility.AssertNotNull("proposedLeaseId", proposedLeaseId); if (accessCondition.LeaseId == null) { throw new ArgumentException(SR.MissingLeaseIDChanging, "accessCondition"); } RESTCommand <string> putCmd = new RESTCommand <string>(blob.ServiceClient.Credentials, attributes.StorageUri); options.ApplyToStorageCommand(putCmd); putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Change, proposedLeaseId, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx); putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); return(BlobHttpResponseParsers.GetLeaseId(resp)); }; return(putCmd); }
/// <summary> /// Generates a <see cref="RESTCommand{T}" /> for acquiring a lease. /// </summary> /// <param name="blob">The blob.</param> /// <param name="attributes">The attributes.</param> /// <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{T}" /> 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.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Acquire, proposedLeaseId, leaseDuration, null /* leaseBreakPeriod */, accessCondition, ctx); putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null, cmd, ex, ctx); return(BlobHttpResponseParsers.GetLeaseId(resp)); }; return(putCmd); }
/// <summary> /// Implementation for the Exists method. /// </summary> /// <param name="blob">The blob.</param> /// <param name="attributes">The attributes.</param> /// <param name="options">An object that specifies any additional options for the request.</param> /// <returns> /// A <see cref="RESTCommand{T}" /> 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.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetProperties(uri, serverTimeout, attributes.SnapshotTime, null /* accessCondition */, ctx); getCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; 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> /// Implements getting the stream without specifying a range. /// </summary> /// <param name="blob">The blob.</param> /// <param name="attributes">The attributes.</param> /// <param name="destStream">The destination stream.</param> /// <param name="offset">The offset.</param> /// <param name="length">The length.</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{T}" /> 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.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Get(uri, serverTimeout, attributes.SnapshotTime, offset, length, options.UseTransactionalMD5.Value, accessCondition, ctx); getCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; 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.BuildRequestDelegate = (uri, builder, serverTimeout, context) => BlobHttpWebRequestFactory.Get(uri, serverTimeout, attributes.SnapshotTime, offset, length, options.UseTransactionalMD5.Value && !arePropertiesPopulated, lockedAccessCondition ?? accessCondition, 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); storedMD5 = resp.Headers[HttpResponseHeader.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(NullType.Value); }; return(getCmd); }