示例#1
0
        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);
            }));
        }
示例#3
0
        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);
        }