SPT-AKI-Installer/SPTInstaller/Helpers/HttpClientProgressExtensions.cs

54 lines
2.5 KiB
C#
Raw Normal View History

using System.Net.Http;
2022-06-07 20:34:09 +01:00
using System.Threading;
using System.Threading.Tasks;
namespace SPTInstaller.Helpers;
public static class HttpClientProgressExtensions
2022-06-07 20:34:09 +01:00
{
public static async Task DownloadDataAsync(this HttpClient client, string requestUrl, Stream destination, IProgress<double> progress = null, CancellationToken cancellationToken = default(CancellationToken))
2022-07-09 13:14:03 -04:00
{
using (var response = await client.GetAsync(requestUrl, HttpCompletionOption.ResponseHeadersRead))
2022-07-09 13:14:03 -04:00
{
var contentLength = response.Content.Headers.ContentLength;
using (var download = await response.Content.ReadAsStreamAsync())
2022-07-09 13:14:03 -04:00
{
// no progress... no contentLength... very sad
if (progress is null || !contentLength.HasValue)
2022-07-09 13:14:03 -04:00
{
await download.CopyToAsync(destination);
return;
2022-07-09 13:14:03 -04:00
}
// Such progress and contentLength much reporting Wow!
var progressWrapper = new Progress<long>(totalBytes => progress.Report(GetProgressPercentage(totalBytes, contentLength.Value)));
await download.CopyToAsync(destination, 81920, progressWrapper, cancellationToken);
2022-07-09 13:14:03 -04:00
}
}
2022-06-07 20:34:09 +01:00
float GetProgressPercentage(float totalBytes, float currentBytes) => (totalBytes / currentBytes) * 100f;
}
2022-06-07 20:34:09 +01:00
static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<long> progress = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (bufferSize < 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize));
if (source is null)
throw new ArgumentNullException(nameof(source));
if (!source.CanRead)
throw new InvalidOperationException($"'{nameof(source)}' is not readable.");
if (destination == null)
throw new ArgumentNullException(nameof(destination));
if (!destination.CanWrite)
throw new InvalidOperationException($"'{nameof(destination)}' is not writable.");
var buffer = new byte[bufferSize];
long totalBytesRead = 0;
int bytesRead;
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0)
{
await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
totalBytesRead += bytesRead;
progress?.Report(totalBytesRead);
2022-07-09 13:14:03 -04:00
}
}
2022-06-07 20:34:09 +01:00
}