public void LeaseOperation(CloudBlob blob, string leaseId, LeaseAction action, int timeout) { var creds = blob.ServiceClient.Credentials; var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString())); var request = BlobRequest.Lease(transformedUri, timeout, action, leaseId); creds.SignRequest(request); request.GetResponse().Close(); }
private static void DoLeaseOperation(CloudBlob blob, string leaseId, LeaseAction action) { var credentials = blob.ServiceClient.Credentials; var request = BlobRequest.Lease(new Uri(credentials.TransformUri(blob.Uri.AbsoluteUri)), 90, action, leaseId); credentials.SignRequest(request); request.GetResponse().Close(); }
private static void DoLeaseOperation(CloudBlob blob, string leaseId, LeaseAction action) { var creds = blob.ServiceClient.Credentials; var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString())); var req = BlobRequest.Lease(transformedUri, 60, action, leaseId); creds.SignRequest(req); req.GetResponse().Close(); }
protected override void DoSave(IConcurrencyControlContext context, T obj) { if (string.IsNullOrWhiteSpace(context.ObjectId)) { throw new ArgumentNullException("context.ObjectId", "ObjectId cannot be null or empty"); } if (context is OptimisticConcurrencyContext) { CloudBlob blob = this.Container.GetBlobReference(context.ObjectId); blob.Properties.ContentType = "application/json"; var blobRequestOptions = new BlobRequestOptions() { AccessCondition = (context as OptimisticConcurrencyContext).AccessCondition }; blob.UploadText(new JavaScriptSerializer().Serialize(obj), Encoding.Default, blobRequestOptions); } else if (context is PessimisticConcurrencyContext) { if (string.IsNullOrWhiteSpace((context as PessimisticConcurrencyContext).LockId)) { throw new ArgumentNullException("context.LockId", "LockId cannot be null or empty"); } var blobProperties = new BlobProperties(); blobProperties.ContentType = "application/json"; var updateText = BlobRequest.Put( this.GetUri(context.ObjectId), BlobRequestTimeout, blobProperties, BlobType.BlockBlob, (context as PessimisticConcurrencyContext).LockId, 0); using (var stream = new StreamWriter(updateText.GetRequestStream(), Encoding.Default)) { stream.Write(new JavaScriptSerializer().Serialize(obj)); } this.Account.Credentials.SignRequest(updateText); using (var response = updateText.GetResponse()) { if (response is HttpWebResponse && !HttpStatusCode.Created.Equals((response as HttpWebResponse).StatusCode)) { TraceHelper.TraceError("Error writing leased blob '{0}': {1}", context.ObjectId, (response as HttpWebResponse).StatusDescription); throw new InvalidOperationException((response as HttpWebResponse).StatusDescription); } } } else { throw new InvalidOperationException("IConcurrencyControlContext implementation cannot be handled"); } }
/// <summary> /// Uploads the block list. /// </summary> /// <param name="blocks">The blocks to upload.</param> /// <param name="options">An object that specifies any additional options for the request.</param> /// <returns>A <see cref="TaskSequence"/> that uploads the block list.</returns> internal TaskSequence UploadBlockList(List <PutBlockListItem> blocks, BlobRequestOptions options) { if (options == null) { throw new ArgumentNullException("modifers"); } var request = ProtocolHelper.GetWebRequest(this.ServiceClient, options, (timeout) => BlobRequest.PutBlockList(this.TransformedAddress, timeout, this.Properties, null)); options.AccessCondition.ApplyCondition(request); BlobRequest.AddMetadata(request, this.Metadata); using (var memoryStream = new SmallBlockMemoryStream(Constants.DefaultBufferSize)) { BlobRequest.WriteBlockListBody(blocks, memoryStream); CommonUtils.ApplyRequestOptimizations(request, memoryStream.Length); memoryStream.Seek(0, SeekOrigin.Begin); // Compute the MD5 var md5 = System.Security.Cryptography.MD5.Create(); request.Headers[HttpRequestHeader.ContentMd5] = Convert.ToBase64String(md5.ComputeHash(memoryStream)); this.ServiceClient.Credentials.SignRequest(request); memoryStream.Seek(0, SeekOrigin.Begin); // Retrieve the stream var requestStreamTask = request.GetRequestStreamAsync(); yield return(requestStreamTask); using (Stream requestStream = requestStreamTask.Result) { // Copy the data var copyTask = new InvokeTaskSequenceTask(() => { return(memoryStream.WriteTo(requestStream)); }); yield return(copyTask); // Materialize any exceptions var scratch = copyTask.Result; Console.WriteLine(scratch); } } // Get the response var responseTask = request.GetResponseAsyncWithTimeout(this.ServiceClient, options.Timeout); yield return(responseTask); using (var response = responseTask.Result as HttpWebResponse) { ParseSizeAndLastModified(response); this.Properties.Length = 0; } }
public static void SetMetadata(this CloudBlob blob, string leaseId) { var req = BlobRequest.SetMetadata(new Uri(blob.ServiceClient.Credentials.TransformUri(blob.Uri.AbsoluteUri)), 90, leaseId); foreach (string key in blob.Metadata.Keys) { req.Headers.Add("x-ms-meta-" + key, blob.Metadata[key]); } blob.ServiceClient.Credentials.SignRequest(req); req.GetResponse().Close(); }
public static string AcquireLease(this CloudBlob blob) { var creds = blob.ServiceClient.Credentials; var transformedUri = new Uri(creds.TransformUri(blob.Uri.AbsoluteUri)); var req = BlobRequest.Lease(transformedUri, 90, LeaseAction.Acquire, null); blob.ServiceClient.Credentials.SignRequest(req); using (var response = req.GetResponse()) { return(response.Headers["x-ms-lease-id"]); } }
public static void ReleaseLease(this CloudBlob blob, string leaseId) { var creds = blob.ServiceClient.Credentials; var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString())); var req = BlobRequest.Lease(transformedUri, 0, LeaseAction.Release, leaseId); blob.ServiceClient.Credentials.SignRequest(req); using (var response = req.GetResponse()) { } }
public bool AcquireLock(PessimisticConcurrencyContext lockContext) { var request = BlobRequest.Lease(this.GetUri(lockContext.ObjectId), BlobRequestTimeout, LeaseAction.Acquire, null); this.Account.Credentials.SignRequest(request); // add extra headers not supported by SDK - not supported by emulator yet (SDK 1.7) ////request.Headers["x-ms-version"] = "2012-02-12"; ////request.Headers.Add("x-ms-lease-duration", lockContext.Duration.TotalSeconds.ToString()); try { using (var response = request.GetResponse()) { if (response is HttpWebResponse && HttpStatusCode.Created.Equals((response as HttpWebResponse).StatusCode)) { lockContext.LockId = response.Headers["x-ms-lease-id"]; return(true); } else { return(false); } } } catch (WebException e) { this._logger.LogWarning("Warning acquiring blob '{0}' lease: {1}", lockContext.ObjectId, e.Message); if (WebExceptionStatus.ProtocolError.Equals(e.Status)) { if (e.Response is HttpWebResponse) { if (HttpStatusCode.NotFound.Equals((e.Response as HttpWebResponse).StatusCode)) { lockContext.LockId = null; return(true); } else if (HttpStatusCode.Conflict.Equals((e.Response as HttpWebResponse).StatusCode)) { lockContext.LockId = null; return(false); } } throw; } return(false); } catch (Exception e) { this._logger.LogError("Error acquiring blob '{0}' lease: {1}", lockContext.ObjectId, e.Message); throw; } }
public string AcquireLease(CloudBlob blob, int timeout) { var creds = blob.ServiceClient.Credentials; var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString())); var request = BlobRequest.Lease(transformedUri, timeout, LeaseAction.Acquire, null); blob.ServiceClient.Credentials.SignRequest(request); using (var response = request.GetResponse()) { return(response.Headers["x-ms-lease-id"]); } }
/// <summary> /// Converts the source blob of a copy operation to an appropriate access URI, taking Shared Access Signature credentials into account. /// </summary> /// <param name="source">The source blob.</param> /// <returns>A URI addressing the source blob, using SAS if appropriate.</returns> internal static Uri SourceBlobToUri(ICloudBlob source) { Uri sourceUri = source.ServiceClient.Credentials.TransformUri(source.Uri); if (source.SnapshotTime.HasValue) { UriQueryBuilder builder = new UriQueryBuilder(); builder.Add("snapshot", BlobRequest.ConvertDateTimeToSnapshotString(source.SnapshotTime.Value)); sourceUri = builder.AddToUri(sourceUri); } return(sourceUri); }
public static string AcquireLease(this CloudBlob blob) { var creds = blob.ServiceClient.Credentials; var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString())); var req = BlobRequest.Lease(transformedUri, 60, // timeout (in seconds) LeaseAction.Acquire, // as opposed to "break" "release" or "renew" null); // name of the existing lease, if any blob.ServiceClient.Credentials.SignRequest(req); using (var response = req.GetResponse()) { return(response.Headers["x-ms-lease-id"]); } }
/// <summary> /// Gets the canonical name of the blob, formatted as /<account-name>/<container-name>/<blob-name>. /// If <c>ignoreSnapshotTime</c> is <c>false</c> and this blob is a snapshot, the canonical name is augmented with a /// query of the form ?snapshot=<snapshot-time>. /// <para>This is used by both Shared Access and Copy blob operations.</para> /// </summary> /// <param name="ignoreSnapshotTime">Indicates if the snapshot time is ignored.</param> /// <returns>The canonical name of the blob.</returns> private string GetCanonicalName(bool ignoreSnapshotTime) { string accountName = this.ServiceClient.Credentials.AccountName; string containerName = this.Container.Name; string blobName = this.Name; string canonicalName = string.Format("/{0}/{1}/{2}", accountName, containerName, blobName); if (!ignoreSnapshotTime && this.SnapshotTime != null) { canonicalName += "?snapshot=" + BlobRequest.ConvertDateTimeToSnapshotString(this.SnapshotTime.Value); } return(canonicalName); }
/// <summary> /// Gets the canonical name of the blob, formatted as /<account-name>/<container-name>/<blob-name>. /// If <c>ignoreSnapshotTime</c> is <c>false</c> and this blob is a snapshot, the canonical name is augmented with a /// query of the form ?snapshot=<snapshot-time>. /// <para>This is used by both Shared Access and Copy blob operations.</para> /// </summary> /// <param name="ignoreSnapshotTime">Indicates if the snapshot time is ignored.</param> /// <returns>The canonical name of the blob.</returns> private string GetCanonicalName(bool ignoreSnapshotTime) { string accountName = this.ServiceClient.Credentials.AccountName; string containerName = this.Container.Name; // Replace \ with / for uri compatibility when running under .net 4.5. string blobName = this.Name.Replace('\\', '/'); string canonicalName = string.Format(CultureInfo.InvariantCulture, "/{0}/{1}/{2}", accountName, containerName, blobName); if (!ignoreSnapshotTime && this.SnapshotTime != null) { canonicalName += "?snapshot=" + BlobRequest.ConvertDateTimeToSnapshotString(this.SnapshotTime.Value); } return(canonicalName); }
// NOTE: This method doesn't do everything that the regular UploadText does. // Notably, it doesn't update the BlobProperties of the blob (with the new // ETag and LastModifiedTimeUtc). It also, like all the methods in this file, // doesn't apply any retry logic. Use this at your own risk! public static void UploadText(this CloudBlob blob, string text, string leaseId) { string url = blob.Uri.ToString(); if (blob.ServiceClient.Credentials.NeedsTransformUri) { url = blob.ServiceClient.Credentials.TransformUri(url); } var req = BlobRequest.Put(new Uri(url), 60, new BlobProperties(), BlobType.BlockBlob, leaseId, 0); using (var writer = new StreamWriter(req.GetRequestStream())) { writer.Write(text); } blob.ServiceClient.Credentials.SignRequest(req); req.GetResponse().Close(); }
static void SetLength(CloudPageBlob blob, long newLength, int timeout = 10000) { var credentials = blob.ServiceClient.Credentials; var requestUri = blob.Uri; if (credentials.NeedsTransformUri) { requestUri = new Uri(credentials.TransformUri(requestUri.ToString())); } var request = BlobRequest.SetProperties(requestUri, timeout, blob.Properties, null, newLength); request.Timeout = timeout; credentials.SignRequest(request); using (request.GetResponse()) { } }
public void Resize_Blob(CloudPageBlob pageBlob, CloudBlobClient blobStorage, long newBlobSize) { Uri requestUri = pageBlob.Uri; if (blobStorage.Credentials.NeedsTransformUri) { requestUri = new Uri(blobStorage.Credentials.TransformUri(requestUri.ToString())); } HttpWebRequest request = BlobRequest.SetProperties(requestUri, timeout, pageBlob.Properties, null, newBlobSize); request.Timeout = timeout; blobStorage.Credentials.SignRequest(request); using (WebResponse response = request.GetResponse()) { // call succeeded }; }
public static void DoLeaseOperation(VLogger logger, CloudBlob blob, string leaseId, LeaseAction action, int AzureBlobLeaseTimeout) { try { if (blob == null || leaseId == null) { return; } var creds = blob.ServiceClient.Credentials; var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString())); var req = BlobRequest.Lease(transformedUri, AzureBlobLeaseTimeout, action, leaseId); creds.SignRequest(req); req.GetResponse().Close(); } catch (WebException e) { Utils.structuredLog(logger, "WebException", e.Message + ". DoLeaseOperation, blob: " + blob.Name + ", leaseId: " + leaseId + ", action " + action); } }
/// <summary> /// Cast out blob instance and bind it's metadata to metadata repeater /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void OnBlobDataBound(object sender, ListViewItemEventArgs e) { if (e.Item.ItemType == ListViewItemType.DataItem) { var metadataRepeater = e.Item.FindControl("blobMetadata") as Repeater; var blob = ((ListViewDataItem)e.Item).DataItem as CloudBlob; // If this blob is a snapshot, rename button to "Delete Snapshot" if (blob != null) { if (blob.SnapshotTime.HasValue) { var delBtn = e.Item.FindControl("deleteBlob") as LinkButton; if (delBtn != null) { delBtn.Text = "Delete Snapshot"; var snapshotRequest = BlobRequest.Get(new Uri(delBtn.CommandArgument), 0, blob.SnapshotTime.Value, null); delBtn.CommandArgument = snapshotRequest.RequestUri.AbsoluteUri; } var snapshotBtn = e.Item.FindControl("SnapshotBlob") as LinkButton; if (snapshotBtn != null) { snapshotBtn.Visible = false; } } if (metadataRepeater != null) { // bind to metadata metadataRepeater.DataSource = from key in blob.Metadata.AllKeys select new { Name = key, Value = blob.Metadata[key] }; metadataRepeater.DataBind(); } } } }
static string AcquireLease(CloudBlob blob) { var creds = blob.ServiceClient.Credentials; var transformedUri = new Uri(creds.TransformUri(blob.Uri.AbsoluteUri)); var req = BlobRequest.Lease(transformedUri, 10, LeaseAction.Acquire, null); req.Headers.Add("x-ms-lease-duration", "60"); creds.SignRequest(req); HttpWebResponse response; try { response = (HttpWebResponse)req.GetResponse(); } catch (WebException we) { var statusCode = ((HttpWebResponse)we.Response).StatusCode; switch (statusCode) { case HttpStatusCode.Conflict: case HttpStatusCode.NotFound: case HttpStatusCode.RequestTimeout: case HttpStatusCode.InternalServerError: return(null); default: throw; } } try { return(response.StatusCode == HttpStatusCode.Created ? response.Headers["x-ms-lease-id"] : null); } finally { response.Close(); } }
/// <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); } }
public void ReleaseLock(PessimisticConcurrencyContext lockContext) { if (string.IsNullOrWhiteSpace(lockContext.LockId)) { throw new ArgumentNullException("lockContext.LockId", "LockId cannot be null or empty"); } var request = BlobRequest.Lease(this.GetUri(lockContext.ObjectId), BlobRequestTimeout, LeaseAction.Release, lockContext.LockId); this.Account.Credentials.SignRequest(request); using (var response = request.GetResponse()) { if (response is HttpWebResponse && !HttpStatusCode.OK.Equals((response as HttpWebResponse).StatusCode)) { this._logger.LogError("Error releasing blob '{0}' lease: {1}", lockContext.ObjectId, (response as HttpWebResponse).StatusDescription); throw new InvalidOperationException((response as HttpWebResponse).StatusDescription); } } }
static bool DoLeaseOperation(CloudBlob blob, string leaseId, LeaseAction action) { var creds = blob.ServiceClient.Credentials; var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString())); var req = BlobRequest.Lease(transformedUri, 10, action, leaseId); creds.SignRequest(req); HttpWebResponse response; try { response = (HttpWebResponse)req.GetResponse(); } catch (WebException we) { var statusCode = ((HttpWebResponse)we.Response).StatusCode; switch (statusCode) { case HttpStatusCode.Conflict: case HttpStatusCode.NotFound: case HttpStatusCode.RequestTimeout: case HttpStatusCode.InternalServerError: return(false); default: throw; } } try { var expectedCode = action == LeaseAction.Break ? HttpStatusCode.Accepted : HttpStatusCode.OK; return(response.StatusCode == expectedCode); } finally { response.Close(); } }
public static string AcquireLease(VLogger logger, CloudBlockBlob blob, int AzureBlobLeaseTimeout) { try { var creds = blob.ServiceClient.Credentials; var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString())); var req = BlobRequest.Lease(transformedUri, AzureBlobLeaseTimeout, // timeout (in seconds) LeaseAction.Acquire, // as opposed to "break" "release" or "renew" null); // name of the existing lease, if any blob.ServiceClient.Credentials.SignRequest(req); using (var response = req.GetResponse()) { return(response.Headers["x-ms-lease-id"]); } } catch (WebException e) { Utils.structuredLog(logger, "WebException", e.Message + ". AcquireLease, blob: " + blob); return(null); } }
private static void DoLeaseOperation(CloudBlob blob, string leaseId, Microsoft.WindowsAzure.StorageClient.Protocol.LeaseAction action, NLog.Logger logger) { try { if (blob == null || leaseId == null) { return; } var creds = blob.ServiceClient.Credentials; var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString())); var req = BlobRequest.Lease(transformedUri, AzureBlobLeaseTimeout, action, leaseId); creds.SignRequest(req); req.GetResponse().Close(); } catch (WebException e) { if (null != logger) { logger.ErrorException("DoLeaseOperation, blob: " + blob.Name + ", leaseId: " + leaseId + ", action " + action, e); } } }
private Stream DownloadBlockFromBlob(CloudBlob blob, Block block, Queue <Block> blocksToDownload) { try { var blobGetRequest = BlobRequest.Get(blob.Uri, 60, null, null); blobGetRequest.Headers.Add("x-ms-range", string.Format(CultureInfo.InvariantCulture, "bytes={0}-{1}", block.Offset, block.Offset + block.Length - 1)); var credentials = blob.ServiceClient.Credentials; credentials.SignRequest(blobGetRequest); var response = blobGetRequest.GetResponse() as HttpWebResponse; return(response != null?response.GetResponseStream() : null); } catch { if (++block.Attempt > MaxRetries) { throw; } lock (blocksToDownload) blocksToDownload.Enqueue(block); } return(null); }
protected virtual void PessimisticControlContextWriteStrategy(IConcurrencyControlContext context, T obj) { if (string.IsNullOrWhiteSpace((context as PessimisticConcurrencyContext).LockId)) { throw new ArgumentNullException("context.LockId", "LockId cannot be null or empty"); } var blobProperties = new BlobProperties(); var binarizedObject = this.BinarizeObjectForStreaming(blobProperties, obj); var updateRequest = BlobRequest.Put( this.GetUri(context.ObjectId), BlobRequestTimeout, blobProperties, BlobType.BlockBlob, (context as PessimisticConcurrencyContext).LockId, 0); using (var writer = new BinaryWriter(updateRequest.GetRequestStream(), Encoding.Default)) { writer.Write(binarizedObject); } this.Account.Credentials.SignRequest(updateRequest); using (var response = updateRequest.GetResponse()) { if (response is HttpWebResponse && !HttpStatusCode.Created.Equals((response as HttpWebResponse).StatusCode)) { this._logger.LogError("Error writing leased blob '{0}': {1}", context.ObjectId, (response as HttpWebResponse).StatusDescription); throw new InvalidOperationException((response as HttpWebResponse).StatusDescription); } } }
/// <summary> /// Gets the page ranges impl. /// </summary> /// <param name="options">An object that specifies any additional options for the request.</param> /// <param name="setResult">The set result.</param> /// <returns>A <see cref="TaskSequence"/> for getting the page ranges.</returns> private TaskSequence GetPageRangesImpl(BlobRequestOptions options, Action <IEnumerable <PageRange> > setResult) { CommonUtils.AssertNotNull("options", options); var webRequest = ProtocolHelper.GetWebRequest(this.ServiceClient, options, (timeout) => BlobRequest.GetPageRanges(this.TransformedAddress, timeout, this.SnapshotTime, null)); BlobRequest.AddMetadata(webRequest, this.Metadata); this.ServiceClient.Credentials.SignRequest(webRequest); var task = webRequest.GetResponseAsyncWithTimeout(this.ServiceClient, options.Timeout); yield return(task); using (var webResponse = task.Result as HttpWebResponse) { var getPageRangesResponse = BlobResponse.GetPageRanges(webResponse); List <PageRange> pageRanges = new List <PageRange>(); // materialize response as we need to close the webResponse pageRanges.AddRange(getPageRangesResponse.PageRanges.ToList()); setResult(pageRanges); this.ParseSizeAndLastModified(webResponse); } }
/// <summary> /// Gets the download block list. /// </summary> /// <param name="typesOfBlocks">The types of blocks.</param> /// <param name="options">An object that specifies any additional options for the request.</param> /// <param name="setResult">The result report delegate.</param> /// <returns>A <see cref="TaskSequence"/> that gets the download block list.</returns> internal TaskSequence GetDownloadBlockList(BlockListingFilter typesOfBlocks, BlobRequestOptions options, Action <IEnumerable <ListBlockItem> > setResult) { var request = ProtocolHelper.GetWebRequest(this.ServiceClient, options, (timeout) => BlobRequest.GetBlockList(this.TransformedAddress, timeout, this.SnapshotTime, typesOfBlocks, null)); this.ServiceClient.Credentials.SignRequest(request); // Retrieve the stream var requestStreamTask = request.GetResponseAsyncWithTimeout(this.ServiceClient, options.Timeout); yield return(requestStreamTask); // Copy the data using (var response = requestStreamTask.Result as HttpWebResponse) { using (var responseStream = response.GetResponseStream()) { var blockListResponse = new GetBlockListResponse(responseStream); setResult(ParseResponse(blockListResponse)); } this.ParseSizeAndLastModified(response); } }
/// <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); } }