Skip to content

Instantly share code, notes, and snippets.

@HirbodBehnam
Created December 20, 2019 09:29
Show Gist options
  • Save HirbodBehnam/272aa5e4b82c2fb05583d095f2224861 to your computer and use it in GitHub Desktop.
Save HirbodBehnam/272aa5e4b82c2fb05583d095f2224861 to your computer and use it in GitHub Desktop.
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace TestConsole
{
// From https://stackoverflow.com/a/41392145/4213397
internal class ProgressableStreamContent : HttpContent
{
/// <summary>
/// Lets keep buffer of 20kb
/// </summary>
private const int defaultBufferSize = 5 * 4096;
private HttpContent content;
private int bufferSize;
//private bool contentConsumed;
private Action<long, long> progress;
public ProgressableStreamContent(HttpContent content, Action<long, long> progress) : this(content,
defaultBufferSize, progress)
{
}
public ProgressableStreamContent(HttpContent content, int bufferSize, Action<long, long> progress)
{
if (content == null)
{
throw new ArgumentNullException("content");
}
if (bufferSize <= 0)
{
throw new ArgumentOutOfRangeException("bufferSize");
}
this.content = content;
this.bufferSize = bufferSize;
this.progress = progress;
foreach (var h in content.Headers)
{
this.Headers.Add(h.Key, h.Value);
}
}
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
return Task.Run(async () =>
{
var buffer = new Byte[this.bufferSize];
long size;
TryComputeLength(out size);
var uploaded = 0;
using (var sinput = await content.ReadAsStreamAsync())
{
while (true)
{
var length = sinput.Read(buffer, 0, buffer.Length);
if (length <= 0) break;
//downloader.Uploaded = uploaded += length;
uploaded += length;
progress?.Invoke(uploaded, size);
//System.Diagnostics.Debug.WriteLine($"Bytes sent {uploaded} of {size}");
stream.Write(buffer, 0, length);
stream.Flush();
}
}
stream.Flush();
});
}
protected override bool TryComputeLength(out long length)
{
length = content.Headers.ContentLength.GetValueOrDefault();
return true;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
content.Dispose();
}
base.Dispose(disposing);
}
}
class Program
{
static void Main(string[] args)
{
upload();
Console.ReadKey();
}
static async void upload()
{
using (var client = new HttpClient())
using (var multiForm = new MultipartFormDataContent())
{
client.Timeout = TimeSpan.FromMinutes(5); // You may need this if you are uploading a big file
var file = new ProgressableStreamContent(new StreamContent(File.OpenRead("C://t.txt"))
,(sent,total) => {
Console.SetCursorPosition(1,0); // Remove last line
Console.WriteLine ("\bUploading " + ((float)sent/total)*100f);
});
multiForm.Add(file, "document", "1.txt"); // Add the file
multiForm.Add(new StringContent("value"),"key"); // Add some other fields if you like
var response = await client.PostAsync("https://example.com/upload", multiForm);
Console.WriteLine(response.StatusCode);
if (response.StatusCode == HttpStatusCode.OK)
{
string res = await response.Content.ReadAsStringAsync();
Console.WriteLine(res);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment