/// <summary> /// Initializes a new instance of the <see cref="CloudQueueClient"/> class. /// </summary> /// <param name="usePathStyleUris">True to use path style Uris.</param> /// <param name="baseAddressUri">The base address Uri.</param> /// <param name="credentials">The credentials.</param> internal CloudQueueClient(bool?usePathStyleUris, Uri baseAddressUri, StorageCredentials credentials) { CommonUtils.AssertNotNull("baseAddress", baseAddressUri); CommonUtils.AssertNotNull("credentials", credentials); if (!credentials.CanSignRequest) { throw new ArgumentException(SR.CredentialsCantSignRequest, "credentials"); } this.BaseUri = baseAddressUri; if (!this.BaseUri.IsAbsoluteUri) { CommonUtils.ArgumentOutOfRange("baseAddress", baseAddressUri); } this.Timeout = Constants.DefaultClientSideTimeout; this.RetryPolicy = RetryPolicies.RetryExponential(RetryPolicies.DefaultClientRetryCount, RetryPolicies.DefaultClientBackoff); this.Credentials = credentials; if (usePathStyleUris.HasValue) { this.UsePathStyleUris = usePathStyleUris.Value; } else { // Automatically decide whether to use host style uri or path style uri this.UsePathStyleUris = CommonUtils.UsePathStyleAddressing(this.BaseUri); } }
/// <summary> /// Verifies the condition is satisfied. /// </summary> /// <param name="etag">The ETag to check.</param> /// <param name="lastModifiedTimeUtc">The last modified time UTC.</param> /// <returns><c>true</c> if the condition is satisfied, otherwise <c>false</c>.</returns> internal bool VerifyConditionHolds(string etag, DateTime lastModifiedTimeUtc) { switch (this.AccessConditionHeader.GetValueOrDefault()) { case HttpRequestHeader.IfMatch: return(this.AccessConditionValue == etag || String.Equals(this.AccessConditionValue, "*")); case HttpRequestHeader.IfNoneMatch: return(this.AccessConditionValue != etag); case HttpRequestHeader.IfModifiedSince: { var conditional = DateTime.Parse( this.AccessConditionValue, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal); return(lastModifiedTimeUtc > conditional); } case HttpRequestHeader.IfUnmodifiedSince: { var conditional = DateTime.Parse( this.AccessConditionValue, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal); return(lastModifiedTimeUtc <= conditional); } default: CommonUtils.ArgumentOutOfRange("AccessConditionHeader", this.AccessConditionHeader); return(false); } }
/// <summary> /// Implementation method for the ClearPage methods. /// </summary> /// <param name="startOffset">The start offset. Must be multiples of 512.</param> /// <param name="length">Length of the data range to be cleared. Must be multiples of 512.</param> /// <param name="options">An object that specifies any additional options for the request.</param> /// <returns>A <see cref="TaskSequence"/> that writes the pages.</returns> private TaskSequence ClearPageImpl(long startOffset, long length, BlobRequestOptions options) { CommonUtils.AssertNotNull("options", options); if (startOffset < 0 || startOffset % Protocol.Constants.PageSize != 0) { CommonUtils.ArgumentOutOfRange("startOffset", startOffset); } if (length <= 0 || length % Protocol.Constants.PageSize != 0) { CommonUtils.ArgumentOutOfRange("length", length); } PutPageProperties properties = new PutPageProperties() { Range = new PageRange(startOffset, startOffset + length - 1), PageWrite = PageWrite.Clear, }; var webRequest = ProtocolHelper.GetWebRequest( this.ServiceClient, options, (timeout) => BlobRequest.PutPage(this.TransformedAddress, timeout, properties, null)); webRequest.ContentLength = 0; // signing request needs Size to be set this.ServiceClient.Credentials.SignRequest(webRequest); // Get the response var responseTask = webRequest.GetResponseAsyncWithTimeout(this.ServiceClient, options.Timeout); yield return(responseTask); // Parse the response using (HttpWebResponse webResponse = responseTask.Result as HttpWebResponse) { this.ParseSizeAndLastModified(webResponse); } }
/// <summary> /// Constructs a <see cref="SharedAccessPermissions"/> object from a permissions string. /// </summary> /// <param name="value">The shared access permissions in string format.</param> /// <returns>A set of shared access permissions.</returns> public static SharedAccessPermissions PermissionsFromString(string value) { char[] chars = value.ToCharArray(); SharedAccessPermissions permissions = 0; foreach (char c in chars) { switch (c) { case 'r': permissions |= SharedAccessPermissions.Read; break; case 'w': permissions |= SharedAccessPermissions.Write; break; case 'd': permissions |= SharedAccessPermissions.Delete; break; case 'l': permissions |= SharedAccessPermissions.List; break; default: CommonUtils.ArgumentOutOfRange("value", value); break; } } // Incase we ever change none to be something other than 0 if (permissions == 0) { permissions |= SharedAccessPermissions.None; } return(permissions); }
/// <summary> /// Converts AccessCondition into a <see cref="ConditionHeaderKind"/> type for use as a source conditional to Copy. /// </summary> /// <param name="condition">The original condition.</param> /// <param name="header">The resulting header for the condition.</param> /// <param name="value">The value for the condition.</param> internal static void GetSourceConditions( AccessCondition condition, out Protocol.ConditionHeaderKind header, out string value) { header = Protocol.ConditionHeaderKind.None; value = null; if (condition.AccessConditionHeader != null) { switch (condition.AccessConditionHeader.GetValueOrDefault()) { case HttpRequestHeader.IfMatch: header = Protocol.ConditionHeaderKind.IfMatch; break; case HttpRequestHeader.IfNoneMatch: header = Protocol.ConditionHeaderKind.IfNoneMatch; break; case HttpRequestHeader.IfModifiedSince: header = Protocol.ConditionHeaderKind.IfModifiedSince; break; case HttpRequestHeader.IfUnmodifiedSince: header = Protocol.ConditionHeaderKind.IfUnmodifiedSince; break; default: CommonUtils.ArgumentOutOfRange("condition", condition); break; } value = condition.AccessConditionValue; } }
/// <summary> /// Implementation method for the WritePage methods. /// </summary> /// <param name="pageData">The page data.</param> /// <param name="startOffset">The start offset.</param> /// <param name="sourceStreamPosition">The beginning position of the source stream prior to execution, negative if stream is unseekable.</param> /// <param name="options">An object that specifies any additional options for the request.</param> /// <returns>A <see cref="TaskSequence"/> that writes the pages.</returns> private TaskSequence WritePageImpl(Stream pageData, long startOffset, long sourceStreamPosition, BlobRequestOptions options) { CommonUtils.AssertNotNull("options", options); long length = pageData.Length; // Logic to rewind stream on a retry // For non seekable streams we need a way to detect the retry iteration so as to only attempt to execute once. // The first attempt will have SourceStreamPosition = -1, which means the first iteration on a non seekable stream. // The second attempt will have SourceStreamPosition = -2, anything below -1 is considered an abort. Since the Impl method // does not have an execution context to be aware of what iteration is used the SourceStreamPosition is utilized as counter to // differentiate between the first attempt and a retry. if (sourceStreamPosition >= 0 && pageData.CanSeek) { if (sourceStreamPosition != pageData.Position) { pageData.Seek(sourceStreamPosition, 0); } } else if (sourceStreamPosition < -1) { throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.CannotRetryNonSeekableStreamError)); } if (startOffset % Protocol.Constants.PageSize != 0) { CommonUtils.ArgumentOutOfRange("startOffset", startOffset); } long rangeStreamOffset = pageData.CanSeek ? pageData.Position : 0; PutPageProperties properties = new PutPageProperties() { Range = new PageRange(startOffset, startOffset + length - rangeStreamOffset - 1), PageWrite = PageWrite.Update, }; if ((1 + properties.Range.EndOffset - properties.Range.StartOffset) % Protocol.Constants.PageSize != 0 || (1 + properties.Range.EndOffset - properties.Range.StartOffset) == 0) { CommonUtils.ArgumentOutOfRange("pageData", pageData); } var webRequest = ProtocolHelper.GetWebRequest( this.ServiceClient, options, (timeout) => BlobRequest.PutPage(this.TransformedAddress, timeout, properties, null)); ////BlobRequest.AddMetadata(webRequest, this.Metadata); // Retrieve the stream var requestStreamTask = webRequest.GetRequestStreamAsync(); yield return(requestStreamTask); // Copy the data using (var outputStream = requestStreamTask.Result) { var copyTask = new InvokeTaskSequenceTask(() => { return(pageData.WriteTo(outputStream)); }); yield return(copyTask); // Materialize any exceptions var scratch = copyTask.Result; } // signing request needs Size to be set this.ServiceClient.Credentials.SignRequest(webRequest); // Get the response var responseTask = webRequest.GetResponseAsyncWithTimeout(this.ServiceClient, options.Timeout); yield return(responseTask); // Parse the response using (HttpWebResponse webResponse = responseTask.Result as HttpWebResponse) { this.ParseSizeAndLastModified(webResponse); } }