private async Task UploadPart(string chunkUploadUrl, FilePart part, string filename, CancellationToken cancellationToken) { try { HttpRequestMessage partRequest = ComposePartUpload(chunkUploadUrl, part, filename); await executePartUploadRequest(partRequest, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) when(!cancellationToken.IsCancellationRequested) { // If the task was cancelled but a cancel wasn't requested, then consider it a timeout throw new TimeoutException(); } }
private HttpRequestMessage ComposePartUpload(string chunkUploadUrl, FilePart part, string filename) { string uploadUri = part.GetComposedUploadUrl(chunkUploadUrl); var requestMessage = new HttpRequestMessage(HttpMethod.Post, uploadUri); var content = new StreamContentWithProgress(part.Bytes.GetStream(), updateProgress); requestMessage.Content = content; if (!raw) { var multiPartContent = new MultipartFormDataContent(); content.Headers.Add("Content-Type", "application/octet-stream"); multiPartContent.Add(content, "Filedata", filename); requestMessage.Content = multiPartContent; } return(requestMessage); }
private async Task AttemptPartUploadWithRetry(Func <FilePart, Task> attemptUpload, FilePart part, int retryCount) { for (int attempts = 0; attempts <= retryCount; attempts++) { try { await attemptUpload(part).ConfigureAwait(false); lock (completedBytes) { completedBytes.Add(part.Offset, part.Length); } return; } catch (UploadException uploadException) when(uploadException.IsInvalidUploadId) { throw; } catch (Exception) { if (attempts >= retryCount) { throw; } } } throw new UploadException("Shouldn't get here", UploadStatusCode.Unknown); }
//exception boundary: chunk upload exceptions should be propagated to here but no farther private Task <PartUploadResult> AttemptPartUploadWithRetry(Func <FilePart, Task> attemptUpload, FilePart part, int retryCount) { if (retryCount < 0) { return(TaskFromResult(PartUploadResult.Error)); } return(attemptUpload(part).ContinueWith(uploadTask => { if (uploadTask.Exception != null) { // Always back out progress if part fails updateProgress(part.Length * -1); if (retryCount > 0) { return AttemptPartUploadWithRetry(attemptUpload, part, retryCount - 1).Result; } else { return PartUploadResult.Exception(uploadTask.Exception.Unwrap()); } } else { return PartUploadResult.Success; } })); }
private Task UploadPart(string chunkUploadUrl, FilePart part) { return(executePartUploadRequest(ComposePartUpload(chunkUploadUrl, part)) .ContinueWith(task => task.Rethrow())); }