v2rayN/v2rayN/v2rayN/Common/HttpClientHelper.cs

156 lines
5.4 KiB
C#
Raw Normal View History

2023-01-01 11:42:01 +00:00
using System.IO;
2022-04-11 07:26:32 +00:00
using System.Net.Http;
2023-02-20 10:16:30 +00:00
using System.Net.Mime;
using System.Text;
2022-04-11 07:26:32 +00:00
2024-01-10 08:32:26 +00:00
namespace v2rayN
2022-04-11 07:26:32 +00:00
{
/// <summary>
/// </summary>
public class HttpClientHelper
{
2023-04-14 12:49:36 +00:00
private static readonly Lazy<HttpClientHelper> _instance = new(() =>
2022-04-11 07:26:32 +00:00
{
2023-02-20 10:16:30 +00:00
HttpClientHandler handler = new() { UseCookies = false };
HttpClientHelper helper = new(new HttpClient(handler));
return helper;
});
2023-04-14 12:49:36 +00:00
2023-02-20 10:16:30 +00:00
public static HttpClientHelper Instance => _instance.Value;
private readonly HttpClient httpClient;
private HttpClientHelper(HttpClient httpClient) => this.httpClient = httpClient;
2022-04-11 07:26:32 +00:00
2023-02-17 06:36:28 +00:00
public async Task<string?> GetAsync(string url)
2022-04-11 07:26:32 +00:00
{
2024-03-23 10:26:04 +00:00
if (Utile.IsNullOrEmpty(url)) return null;
2023-02-20 10:16:30 +00:00
return await httpClient.GetStringAsync(url);
2022-04-11 07:26:32 +00:00
}
2023-02-24 03:13:13 +00:00
2023-02-20 10:16:30 +00:00
public async Task<string?> GetAsync(HttpClient client, string url, CancellationToken token = default)
2022-04-11 07:26:32 +00:00
{
2024-03-23 10:26:04 +00:00
if (Utile.IsNullOrEmpty(url)) return null;
2023-02-20 10:16:30 +00:00
return await client.GetStringAsync(url, token);
2022-04-11 07:26:32 +00:00
}
public async Task PutAsync(string url, Dictionary<string, string> headers)
{
2024-02-19 09:43:36 +00:00
var jsonContent = JsonUtile.Serialize(headers);
2023-02-20 10:16:30 +00:00
var content = new StringContent(jsonContent, Encoding.UTF8, MediaTypeNames.Application.Json);
2022-04-11 07:26:32 +00:00
2023-02-20 10:16:30 +00:00
var result = await httpClient.PutAsync(url, content);
2022-04-11 07:26:32 +00:00
}
2023-02-20 10:16:30 +00:00
public static async Task DownloadFileAsync(HttpClient client, string url, string fileName, IProgress<double>? progress, CancellationToken token = default)
2022-04-11 07:26:32 +00:00
{
2023-02-20 10:16:30 +00:00
ArgumentNullException.ThrowIfNull(url);
ArgumentNullException.ThrowIfNull(fileName);
if (File.Exists(fileName)) File.Delete(fileName);
2022-04-11 07:26:32 +00:00
2023-02-20 10:16:30 +00:00
using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
2022-04-11 07:26:32 +00:00
2023-02-20 10:16:30 +00:00
if (!response.IsSuccessStatusCode) throw new Exception(response.StatusCode.ToString());
2022-04-11 07:26:32 +00:00
2023-02-19 05:34:22 +00:00
var total = response.Content.Headers.ContentLength ?? -1L;
2022-04-11 07:26:32 +00:00
var canReportProgress = total != -1 && progress != null;
2023-02-19 05:34:22 +00:00
using var stream = await response.Content.ReadAsStreamAsync(token);
2023-02-17 06:36:28 +00:00
using var file = File.Create(fileName);
var totalRead = 0L;
var buffer = new byte[1024 * 1024];
var progressPercentage = 0;
2023-02-20 10:16:30 +00:00
while (true)
2022-04-11 07:26:32 +00:00
{
2023-02-17 06:36:28 +00:00
token.ThrowIfCancellationRequested();
2023-02-19 05:34:22 +00:00
var read = await stream.ReadAsync(buffer, token);
2023-02-20 10:16:30 +00:00
totalRead += read;
2023-02-17 06:36:28 +00:00
2023-02-20 10:16:30 +00:00
if (read == 0) break;
file.Write(buffer, 0, read);
2022-04-11 07:26:32 +00:00
2023-02-20 10:16:30 +00:00
if (canReportProgress)
{
var percent = (int)(100.0 * totalRead / total);
//if (progressPercentage != percent && percent % 10 == 0)
2022-04-11 07:26:32 +00:00
{
2023-02-20 10:16:30 +00:00
progressPercentage = percent;
2024-03-13 08:38:37 +00:00
progress?.Report(percent);
2022-04-11 07:26:32 +00:00
}
}
2023-02-20 10:16:30 +00:00
}
2023-02-17 06:36:28 +00:00
if (canReportProgress)
{
2024-03-13 08:38:37 +00:00
progress?.Report(101);
2022-04-11 07:26:32 +00:00
}
}
2023-02-20 10:16:30 +00:00
public async Task DownloadDataAsync4Speed(HttpClient client, string url, IProgress<string> progress, CancellationToken token = default)
2022-04-11 07:26:32 +00:00
{
2024-03-23 10:26:04 +00:00
if (Utile.IsNullOrEmpty(url))
2022-04-11 07:26:32 +00:00
{
2023-02-17 06:36:28 +00:00
throw new ArgumentNullException(nameof(url));
2022-04-11 07:26:32 +00:00
}
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
if (!response.IsSuccessStatusCode)
{
2023-02-20 10:16:30 +00:00
throw new Exception(response.StatusCode.ToString());
2022-04-11 07:26:32 +00:00
}
2022-04-25 11:07:09 +00:00
//var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L;
//var canReportProgress = total != -1 && progress != null;
2022-04-11 07:26:32 +00:00
2023-02-17 06:36:28 +00:00
using var stream = await response.Content.ReadAsStreamAsync(token);
var totalRead = 0L;
var buffer = new byte[1024 * 64];
var isMoreToRead = true;
string progressSpeed = string.Empty;
DateTime totalDatetime = DateTime.Now;
int totalSecond = 0;
do
2022-04-11 07:26:32 +00:00
{
2023-02-17 06:36:28 +00:00
if (token.IsCancellationRequested)
2022-04-11 07:26:32 +00:00
{
2023-02-17 06:36:28 +00:00
if (totalRead > 0)
2022-04-12 05:38:42 +00:00
{
2023-02-17 06:36:28 +00:00
return;
2022-04-11 07:26:32 +00:00
}
else
{
2023-02-17 06:36:28 +00:00
token.ThrowIfCancellationRequested();
}
}
2023-02-19 05:34:22 +00:00
var read = await stream.ReadAsync(buffer, token);
2022-04-11 07:26:32 +00:00
2023-02-17 06:36:28 +00:00
if (read == 0)
{
isMoreToRead = false;
}
else
{
var data = new byte[read];
buffer.ToList().CopyTo(0, data, 0, read);
2022-04-11 07:26:32 +00:00
2023-02-17 06:36:28 +00:00
totalRead += read;
TimeSpan ts = (DateTime.Now - totalDatetime);
if (progress != null && ts.Seconds > totalSecond)
{
totalSecond = ts.Seconds;
var speed = (totalRead * 1d / ts.TotalMilliseconds / 1000).ToString("#0.0");
if (progressSpeed != speed)
2022-04-25 05:24:10 +00:00
{
2023-02-17 06:36:28 +00:00
progressSpeed = speed;
progress.Report(speed);
2022-04-25 05:24:10 +00:00
}
2022-04-11 07:26:32 +00:00
}
2023-02-17 06:36:28 +00:00
}
} while (isMoreToRead);
2022-04-11 07:26:32 +00:00
}
}
2023-04-14 12:49:36 +00:00
}