v2rayN/v2rayN/ServiceLib/Common/DownloaderHelper.cs

185 lines
6.3 KiB
C#
Raw Normal View History

2023-02-08 11:20:44 +00:00
using System.Net;
2025-01-30 09:10:05 +00:00
using Downloader;
2023-02-08 11:20:44 +00:00
2024-08-19 10:15:54 +00:00
namespace ServiceLib.Common
2023-02-08 11:20:44 +00:00
{
2024-08-19 10:15:54 +00:00
public class DownloaderHelper
2023-02-08 11:20:44 +00:00
{
2023-02-17 07:17:01 +00:00
private static readonly Lazy<DownloaderHelper> _instance = new(() => new());
2023-02-08 11:20:44 +00:00
public static DownloaderHelper Instance => _instance.Value;
2023-02-20 10:16:30 +00:00
public async Task<string?> DownloadStringAsync(IWebProxy? webProxy, string url, string? userAgent, int timeout)
2023-02-09 06:54:54 +00:00
{
2024-03-26 06:26:03 +00:00
if (Utils.IsNullOrEmpty(url))
2023-02-09 06:54:54 +00:00
{
return null;
}
2023-02-17 06:36:28 +00:00
Uri uri = new(url);
2023-02-09 06:54:54 +00:00
//Authorization Header
var headers = new WebHeaderCollection();
2024-09-17 08:52:41 +00:00
if (Utils.IsNotEmpty(uri.UserInfo))
2023-02-09 06:54:54 +00:00
{
2024-03-26 06:26:03 +00:00
headers.Add(HttpRequestHeader.Authorization, "Basic " + Utils.Base64Encode(uri.UserInfo));
2023-02-09 06:54:54 +00:00
}
var downloadOpt = new DownloadConfiguration()
{
Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2,
RequestConfiguration =
{
Headers = headers,
UserAgent = userAgent,
Timeout = timeout * 1000,
Proxy = webProxy
}
};
2024-10-14 02:57:40 +00:00
await using var downloader = new Downloader.DownloadService(downloadOpt);
2023-02-17 06:36:28 +00:00
downloader.DownloadFileCompleted += (sender, value) =>
2023-02-09 06:54:54 +00:00
{
2023-02-17 06:36:28 +00:00
if (value.Error != null)
2023-02-09 06:54:54 +00:00
{
2023-02-20 10:16:30 +00:00
throw value.Error;
2023-02-09 06:54:54 +00:00
}
2023-02-17 06:36:28 +00:00
};
2023-04-24 14:02:50 +00:00
using var cts = new CancellationTokenSource();
2024-10-14 02:57:40 +00:00
await using var stream = await downloader.DownloadFileTaskAsync(address: url, cts.Token).WaitAsync(TimeSpan.FromSeconds(timeout), cts.Token);
2023-02-17 06:36:28 +00:00
using StreamReader reader = new(stream);
2023-02-09 06:54:54 +00:00
downloadOpt = null;
2024-10-14 02:57:40 +00:00
return await reader.ReadToEndAsync(cts.Token);
2023-02-09 06:54:54 +00:00
}
2023-02-08 11:20:44 +00:00
public async Task DownloadDataAsync4Speed(IWebProxy webProxy, string url, IProgress<string> progress, int timeout)
{
2024-03-26 06:26:03 +00:00
if (Utils.IsNullOrEmpty(url))
2023-02-08 11:20:44 +00:00
{
2023-02-17 06:36:28 +00:00
throw new ArgumentNullException(nameof(url));
2023-02-08 11:20:44 +00:00
}
var downloadOpt = new DownloadConfiguration()
{
Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2,
RequestConfiguration =
{
Timeout= timeout * 1000,
Proxy = webProxy
}
};
2024-10-14 02:57:40 +00:00
var totalDatetime = DateTime.Now;
var totalSecond = 0;
2023-02-08 11:20:44 +00:00
var hasValue = false;
double maxSpeed = 0;
2024-10-14 02:57:40 +00:00
await using var downloader = new Downloader.DownloadService(downloadOpt);
2023-02-17 06:36:28 +00:00
//downloader.DownloadStarted += (sender, value) =>
//{
// if (progress != null)
// {
// progress.Report("Start download data...");
// }
//};
downloader.DownloadProgressChanged += (sender, value) =>
2023-02-08 11:20:44 +00:00
{
2024-10-14 02:57:40 +00:00
var ts = (DateTime.Now - totalDatetime);
2023-02-17 06:36:28 +00:00
if (progress != null && ts.Seconds > totalSecond)
2023-02-08 11:20:44 +00:00
{
2023-02-17 06:36:28 +00:00
hasValue = true;
totalSecond = ts.Seconds;
if (value.BytesPerSecondSpeed > maxSpeed)
2023-02-08 11:20:44 +00:00
{
2023-02-17 06:36:28 +00:00
maxSpeed = value.BytesPerSecondSpeed;
var speed = (maxSpeed / 1000 / 1000).ToString("#0.0");
progress.Report(speed);
2023-02-08 11:20:44 +00:00
}
2023-02-17 06:36:28 +00:00
}
};
downloader.DownloadFileCompleted += (sender, value) =>
{
if (progress != null)
2023-02-08 11:20:44 +00:00
{
2023-02-17 06:36:28 +00:00
if (!hasValue && value.Error != null)
2023-02-08 11:20:44 +00:00
{
2023-02-17 06:36:28 +00:00
progress.Report(value.Error?.Message);
2023-02-08 11:20:44 +00:00
}
2023-02-17 06:36:28 +00:00
}
};
2023-03-17 02:32:56 +00:00
//progress.Report("......");
2023-04-24 14:02:50 +00:00
using var cts = new CancellationTokenSource();
2023-04-27 06:17:27 +00:00
cts.CancelAfter(timeout * 1000);
2024-10-14 02:57:40 +00:00
await using var stream = await downloader.DownloadFileTaskAsync(address: url, cts.Token);
2023-02-11 11:34:15 +00:00
2023-02-08 11:20:44 +00:00
downloadOpt = null;
}
2023-02-09 02:54:31 +00:00
2023-02-20 10:16:30 +00:00
public async Task DownloadFileAsync(IWebProxy? webProxy, string url, string fileName, IProgress<double> progress, int timeout)
2023-02-09 02:54:31 +00:00
{
2024-03-26 06:26:03 +00:00
if (Utils.IsNullOrEmpty(url))
2023-02-09 02:54:31 +00:00
{
2023-02-17 07:17:01 +00:00
throw new ArgumentNullException(nameof(url));
2023-02-09 02:54:31 +00:00
}
2024-03-26 06:26:03 +00:00
if (Utils.IsNullOrEmpty(fileName))
2023-02-09 02:54:31 +00:00
{
2023-02-17 07:17:01 +00:00
throw new ArgumentNullException(nameof(fileName));
2023-02-09 02:54:31 +00:00
}
if (File.Exists(fileName))
{
File.Delete(fileName);
}
var downloadOpt = new DownloadConfiguration()
{
Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2,
RequestConfiguration =
{
Timeout= timeout * 1000,
Proxy = webProxy
}
};
var progressPercentage = 0;
var hasValue = false;
2024-10-14 02:57:40 +00:00
await using var downloader = new Downloader.DownloadService(downloadOpt);
2023-02-17 06:36:28 +00:00
downloader.DownloadStarted += (sender, value) =>
2023-02-09 02:54:31 +00:00
{
2023-02-17 06:36:28 +00:00
progress?.Report(0);
};
downloader.DownloadProgressChanged += (sender, value) =>
{
hasValue = true;
var percent = (int)value.ProgressPercentage;// Convert.ToInt32((totalRead * 1d) / (total * 1d) * 100);
if (progressPercentage != percent && percent % 10 == 0)
2023-02-09 02:54:31 +00:00
{
2023-02-17 06:36:28 +00:00
progressPercentage = percent;
progress.Report(percent);
}
};
downloader.DownloadFileCompleted += (sender, value) =>
{
if (progress != null)
2023-02-09 02:54:31 +00:00
{
2023-02-17 06:36:28 +00:00
if (hasValue && value.Error == null)
2023-02-09 02:54:31 +00:00
{
2023-02-17 06:36:28 +00:00
progress.Report(101);
2023-02-09 02:54:31 +00:00
}
2024-09-01 08:39:45 +00:00
else if (value.Error != null)
{
throw value.Error;
}
2023-02-17 06:36:28 +00:00
}
};
2023-02-09 02:54:31 +00:00
2023-04-24 14:02:50 +00:00
using var cts = new CancellationTokenSource();
2024-09-04 07:47:17 +00:00
await downloader.DownloadFileTaskAsync(url, fileName, cts.Token);
2023-02-09 02:54:31 +00:00
downloadOpt = null;
}
2023-02-08 11:20:44 +00:00
}
2025-01-30 09:10:05 +00:00
}