/// <summary> /// Write a chunk of data using the UploadChunkRequest. /// </summary> /// <param name="request">The UploadChunkRequest to make the request with.</param> /// <param name="readBuffer">The byte[] content to read from.</param> /// <param name="exceptionTrackingList">A list of exceptions to use to track progress. ChunkedUpload may retry.</param> /// <returns></returns> public virtual async Task <UploadChunkResult> GetChunkRequestResponseAsync(UploadChunkRequest request, byte[] readBuffer, ICollection <Exception> exceptionTrackingList) { var firstAttempt = true; this.uploadStream.Seek(request.RangeBegin, SeekOrigin.Begin); await this.uploadStream.ReadAsync(readBuffer, 0, request.RangeLength).ConfigureAwait(false); while (true) { using (var requestBodyStream = new MemoryStream(request.RangeLength)) { await requestBodyStream.WriteAsync(readBuffer, 0, request.RangeLength).ConfigureAwait(false); requestBodyStream.Seek(0, SeekOrigin.Begin); try { return(await request.PutAsync(requestBodyStream).ConfigureAwait(false)); } catch (ServiceException exception) { if (exception.IsMatch("generalException") || exception.IsMatch("timeout")) { if (firstAttempt) { firstAttempt = false; exceptionTrackingList.Add(exception); } else { throw; } } else if (exception.IsMatch("invalidRange")) { // Succeeded previously, but nothing to return right now return(new UploadChunkResult()); } else { throw; } } } } }
/// <summary> /// Get the series of requests needed to complete the upload session. Call <see cref="UpdateSessionStatusAsync"/> /// first to update the internal session information. /// </summary> /// <param name="options">Options to be applied to each request.</param> /// <returns>All requests currently needed to complete the upload session.</returns> public virtual IEnumerable <UploadChunkRequest> GetUploadChunkRequests(IEnumerable <Option> options = null) { foreach (var range in this.rangesRemaining) { var currentRangeBegins = range.Item1; while (currentRangeBegins <= range.Item2) { var nextChunkSize = NextChunkSize(currentRangeBegins, range.Item2); var uploadRequest = new UploadChunkRequest( this.Session.UploadUrl, this.client, options, currentRangeBegins, currentRangeBegins + nextChunkSize - 1, this.totalUploadLength); yield return(uploadRequest); currentRangeBegins += nextChunkSize; } } }
public virtual async Task <UploadChunkResult> GetChunkRequestResponseAsync(UploadChunkRequest request, byte[] readBuffer, ICollection <Exception> exceptionTrackingList) { return(await this.GetChunkRequestResponseAsync(request, exceptionTrackingList)); }