/// <summary>
        /// Uploads file
        /// </summary>
        /// <typeparam name="TResult">Result type</typeparam>
        /// <param name="method">HTTP method</param>
        /// <param name="url">URL for request</param>
        /// <param name="fileInfo">File upload parameters. Input stream must support Length</param>
        /// <returns>Async result object</returns>
        public async Task <TResult> SendFile <TResult>(HttpMethod method, string url, SendFileInfo fileInfo)
        {
            var result = default(TResult);
            await Retry.Do(
                RetryTimes,
                RetryDelay,
                async() =>
            {
                var client = await GetHttpClient(url);
                try
                {
                    client.Method = method.ToString();
                    client.AllowWriteStreamBuffering = false;

                    var boundry        = Guid.NewGuid().ToString();
                    client.ContentType = $"multipart/form-data; boundary={fileInfo.MultipartBoundary.Boundary}";
                    client.SendChunked = false;

                    using (var input = fileInfo.StreamOpener())
                    {
                        var preFix  = fileInfo.MultipartBoundary.GetPrefix(input);
                        var postFix = fileInfo.MultipartBoundary.Postfix;

                        client.ContentLength = preFix.Length + input.Length + postFix.Length;

                        fileInfo.CancellationToken.ThrowIfCancellationRequested();

                        using (var output = await client.GetRequestStreamAsync())
                        {
                            var state = new CopyStreamState();

                            await CopyStreams(preFix, output, fileInfo, null);
                            await CopyStreams(input, output, fileInfo, state);

                            await CopyStreams(postFix, output, fileInfo, null);
                        }
                    }
                    using (var response = (HttpWebResponse)await client.GetResponseAsync())
                    {
                        if (!response.IsSuccessStatusCode())
                        {
                            return(await LogBadResponse(response));
                        }

                        result = await response.ReadAsAsync <TResult>();
                    }
                    return(true);
                }
                catch (Exception)
                {
                    client.Abort();
                    throw;
                }
            },
                FileSendExceptionProcessor);

            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// Uploads file
        /// </summary>
        /// <typeparam name="R">Result type</typeparam>
        /// <param name="method">HTTP method</param>
        /// <param name="url">URL for request</param>
        /// <param name="file">File upload parameters. Input stream must support Length</param>
        /// <returns>Async result object</returns>
        public async Task <R> SendFile <R>(HttpMethod method, string url, SendFileInfo file)
        {
            R result = default(R);
            await Retry.Do(
                RetryTimes,
                RetryDelay,
                async() =>
            {
                var client = await GetHttpClient(url).ConfigureAwait(false);
                try
                {
                    client.Method = method.ToString();
                    client.AllowWriteStreamBuffering = false;

                    var boundry        = Guid.NewGuid().ToString();
                    client.ContentType = $"multipart/form-data; boundary={boundry}";
                    client.SendChunked = true;

                    using (var input = file.StreamOpener())
                    {
                        var pre              = GetMultipartFormPre(file, input.Length, boundry);
                        var post             = GetMultipartFormPost(boundry);
                        client.ContentLength = pre.Length + input.Length + post.Length;
                        using (var output = await client.GetRequestStreamAsync().ConfigureAwait(false))
                        {
                            var state = new CopyStreamState();
                            await CopyStreams(pre, output, file, state).ConfigureAwait(false);
                            await CopyStreams(input, output, file, state).ConfigureAwait(false);
                            await CopyStreams(post, output, file, state).ConfigureAwait(false);
                        }
                    }
                    using (var response = (HttpWebResponse)await client.GetResponseAsync().ConfigureAwait(false))
                    {
                        if (!response.IsSuccessStatusCode())
                        {
                            return(await LogBadResponse(response).ConfigureAwait(false));
                        }

                        result = await response.ReadAsAsync <R>().ConfigureAwait(false);
                    }
                    return(true);
                }
                catch (Exception)
                {
                    client.Abort();
                    throw;
                }
            },
                GeneralExceptionProcessor).ConfigureAwait(false);

            return(result);
        }
Esempio n. 3
0
        private static async Task CopyStreams(Stream source, Stream destination, SendFileInfo info, CopyStreamState state)
        {
            var buffer = new byte[info.BufferSize];
            int bytesRead;

            while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
            {
                if (info.CancellationToken != null && info.CancellationToken.Value.IsCancellationRequested)
                {
                    throw new TaskCanceledException();
                }

                await destination.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false);

                state.Pos += bytesRead;
                if (info.Progress != null && state.Pos >= state.NextPos)
                {
                    state.NextPos = info.Progress.Invoke(state.Pos);
                }
            }
        }
Esempio n. 4
0
        private static async Task CopyStreams(Stream source, Stream destination, SendFileInfo info, CopyStreamState state)
        {
            var buffer = new byte[info.BufferSize];
            int bytesRead;
            var lastProgessCalled = false;

            while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, info.CancellationToken)) > 0)
            {
                await destination.WriteAsync(buffer, 0, bytesRead, info.CancellationToken);

                lastProgessCalled = false;
                if (state != null)
                {
                    state.Pos += bytesRead;
                    if (info.Progress != null && (state.Pos >= state.NextPos))
                    {
                        state.NextPos = await info.Progress.Invoke(state.Pos);

                        lastProgessCalled = true;
                    }
                }
            }

            if (state != null && info.Progress != null && !lastProgessCalled)
            {
                await info.Progress.Invoke(state.Pos);
            }
        }