public async Task UploadFile(string folderName, string fileName, Stream stream) { await TestConnection(); UploadProgress?.SetTotal(stream.Length); UploadProgress?.ChangeState(UploadState.PendingUpload); var url = await CreateNestedFoldersIfNeeded(folderName); url += $"/{fileName}"; var request = CreateFtpWebRequest(url, WebRequestMethods.Ftp.UploadFile, keepAlive: true); var readBuffer = new byte[DefaultBufferSize]; int count; var requestStream = request.GetRequestStream(); while ((count = await stream.ReadAsync(readBuffer, 0, readBuffer.Length)) != 0) { await requestStream.WriteAsync(readBuffer, 0, count); UploadProgress?.UpdateUploaded(count); } requestStream.Flush(); requestStream.Close(); UploadProgress?.ChangeState(UploadState.PendingResponse); var response = await request.GetResponseAsync(); response.Dispose(); UploadProgress?.ChangeState(UploadState.Done); }
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) { return(Task.Run(async() => { var buffer = new byte[DefaultBufferSize]; _uploadProgress?.ChangeState(UploadState.PendingUpload); using (_content) { while (true) { var length = await _content.ReadAsync(buffer, 0, buffer.Length); if (length <= 0) { break; } _uploadProgress?.UpdateUploaded(length); Uploaded += length; await stream.WriteAsync(buffer, 0, length); _uploadProgress?.ChangeState(UploadState.Uploading); } } _uploadProgress?.ChangeState(UploadState.PendingResponse); })); }
private async Task PutBlock(Stream baseStream, HttpClient client, string url, long length, int retryCount) { // saving the position if we need to retry var position = baseStream.Position; using (var subStream = new SubStream(baseStream, offset: 0, length: length)) { var now = SystemTime.UtcNow; // stream is disposed by the HttpClient var content = new ProgressableStreamContent(subStream, UploadProgress) { Headers = { { "x-ms-date", now.ToString("R") }, { "x-ms-version", AzureStorageVersion }, { "Content-Length", subStream.Length.ToString(CultureInfo.InvariantCulture) } } }; client.DefaultRequestHeaders.Authorization = CalculateAuthorizationHeaderValue(HttpMethods.Put, url, content.Headers); try { var response = await client.PutAsync(url, content, CancellationToken); if (response.IsSuccessStatusCode) { return; } if (response.StatusCode == HttpStatusCode.RequestEntityTooLarge || response.StatusCode == HttpStatusCode.Conflict || response.StatusCode == HttpStatusCode.BadRequest) { throw StorageException.FromResponseMessage(response); } if (retryCount == MaxRetriesForMultiPartUpload) { throw StorageException.FromResponseMessage(response); } } catch (Exception) { if (retryCount == MaxRetriesForMultiPartUpload) { throw; } } // revert the uploaded count before retry UploadProgress?.UpdateUploaded(-content.Uploaded); } // wait for one second before trying again to send the request // maybe there was a network issue? await Task.Delay(1000); CancellationToken.ThrowIfCancellationRequested(); // restore the stream position before retrying baseStream.Position = position; await PutBlock(baseStream, client, url, length, ++retryCount); }
private async Task UploadPart(Stream baseStream, HttpClient client, string url, long length, int retryCount) { // saving the position if we need to retry var position = baseStream.Position; using (var subStream = new SubStream(baseStream, offset: 0, length: length)) { var now = SystemTime.UtcNow; var payloadHash = RavenAwsHelper.CalculatePayloadHash(subStream); var payloadTreeHash = RavenAwsHelper.CalculatePayloadTreeHash(subStream); // stream is disposed by the HttpClient var content = new ProgressableStreamContent(subStream, UploadProgress) { Headers = { { "x-amz-glacier-version", "2012-06-01" }, { "x-amz-date", RavenAwsHelper.ConvertToString(now) }, { "x-amz-content-sha256", payloadHash }, { "x-amz-sha256-tree-hash", payloadTreeHash }, { "Content-Range", $"bytes {position}-{position+length-1}/*" }, { "Content-Length", subStream.Length.ToString(CultureInfo.InvariantCulture) } } }; var headers = ConvertToHeaders(content.Headers); client.DefaultRequestHeaders.Authorization = CalculateAuthorizationHeaderValue(HttpMethods.Put, url, now, headers); try { var response = await client.PutAsync(url, content, CancellationToken); if (response.IsSuccessStatusCode) { return; } if (retryCount == MaxRetriesForMultiPartUpload) { throw StorageException.FromResponseMessage(response); } } catch (Exception) { if (retryCount == MaxRetriesForMultiPartUpload) { throw; } } // revert the uploaded count before retry UploadProgress?.UpdateUploaded(-content.Uploaded); } // wait for one second before trying again to send the request // maybe there was a network issue? await Task.Delay(1000); CancellationToken.ThrowIfCancellationRequested(); // restore the stream position before retrying baseStream.Position = position; await UploadPart(baseStream, client, url, length, ++retryCount); }