/// <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="file">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 file) { 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={boundry}"; client.SendChunked = false; using (var input = file.StreamOpener()) { var pre = GetMultipartFormPre(file, input.Length, boundry); var post = GetMultipartFormPost(boundry); var clientContentLength = pre.Length + input.Length + post.Length; client.ContentLength = clientContentLength; file.CancellationToken.ThrowIfCancellationRequested(); using (var output = await client.GetRequestStreamAsync()) { var state = new CopyStreamState(); await CopyStreams(pre, output, file, null); await CopyStreams(input, output, file, state); await CopyStreams(post, output, file, 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); }
/// <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; string 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)) { if (file.CancellationToken != null) { var token = (CancellationToken)file.CancellationToken; await pre.CopyToAsync(output, 81920).ConfigureAwait(false); //await input.CopyToAsync(output, 81920).ConfigureAwait(false); await CopyToStreamAsync(input, output, 81920, token, file.Progress).ConfigureAwait(false); if (token.IsCancellationRequested) { client.Abort(); throw new OperationCanceledException(token); } await post.CopyToAsync(output, 81920).ConfigureAwait(false); } else { await pre.CopyToAsync(output).ConfigureAwait(false); await input.CopyToAsync(output).ConfigureAwait(false); await post.CopyToAsync(output).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); }