/// <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 = false;
client.KeepAlive = true;
client.ServicePoint.Expect100Continue = false;
client.ServicePoint.SetTcpKeepAlive(true, 100, 100);
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);
}