mirror of
https://github.com/2dust/v2rayN.git
synced 2025-05-15 20:58:07 +00:00
186 lines
No EOL
6.4 KiB
C#
186 lines
No EOL
6.4 KiB
C#
using System.Net.Http.Headers;
|
|
using System.Net.Mime;
|
|
using System.Text;
|
|
|
|
namespace ServiceLib.Common
|
|
{
|
|
/// <summary>
|
|
/// </summary>
|
|
public class HttpClientHelper
|
|
{
|
|
private static readonly Lazy<HttpClientHelper> _instance = new(() =>
|
|
{
|
|
SocketsHttpHandler handler = new() { UseCookies = false };
|
|
HttpClientHelper helper = new(new HttpClient(handler));
|
|
return helper;
|
|
});
|
|
|
|
public static HttpClientHelper Instance => _instance.Value;
|
|
private readonly HttpClient httpClient;
|
|
|
|
private HttpClientHelper(HttpClient httpClient) => this.httpClient = httpClient;
|
|
|
|
public async Task<string?> TryGetAsync(string url)
|
|
{
|
|
if (Utils.IsNullOrEmpty(url))
|
|
return null;
|
|
|
|
try
|
|
{
|
|
var response = await httpClient.GetAsync(url);
|
|
return await response.Content.ReadAsStringAsync();
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<string?> GetAsync(string url)
|
|
{
|
|
if (Utils.IsNullOrEmpty(url)) return null;
|
|
return await httpClient.GetStringAsync(url);
|
|
}
|
|
|
|
public async Task<string?> GetAsync(HttpClient client, string url, CancellationToken token = default)
|
|
{
|
|
if (Utils.IsNullOrEmpty(url)) return null;
|
|
return await client.GetStringAsync(url, token);
|
|
}
|
|
|
|
public async Task PutAsync(string url, Dictionary<string, string> headers)
|
|
{
|
|
var jsonContent = JsonUtils.Serialize(headers);
|
|
var content = new StringContent(jsonContent, Encoding.UTF8, MediaTypeNames.Application.Json);
|
|
|
|
var result = await httpClient.PutAsync(url, content);
|
|
}
|
|
|
|
public async Task PatchAsync(string url, Dictionary<string, string> headers)
|
|
{
|
|
var myContent = JsonUtils.Serialize(headers);
|
|
var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
|
|
var byteContent = new ByteArrayContent(buffer);
|
|
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
|
|
|
await httpClient.PatchAsync(url, byteContent);
|
|
}
|
|
|
|
public async Task DeleteAsync(string url)
|
|
{
|
|
await httpClient.DeleteAsync(url);
|
|
}
|
|
|
|
public static async Task DownloadFileAsync(HttpClient client, string url, string fileName, IProgress<double>? progress, CancellationToken token = default)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(url);
|
|
ArgumentNullException.ThrowIfNull(fileName);
|
|
if (File.Exists(fileName)) File.Delete(fileName);
|
|
|
|
using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
|
|
|
|
if (!response.IsSuccessStatusCode) throw new Exception(response.StatusCode.ToString());
|
|
|
|
var total = response.Content.Headers.ContentLength ?? -1L;
|
|
var canReportProgress = total != -1 && progress != null;
|
|
|
|
await using var stream = await response.Content.ReadAsStreamAsync(token);
|
|
await using var file = File.Create(fileName);
|
|
var totalRead = 0L;
|
|
var buffer = new byte[1024 * 1024];
|
|
var progressPercentage = 0;
|
|
|
|
while (true)
|
|
{
|
|
token.ThrowIfCancellationRequested();
|
|
|
|
var read = await stream.ReadAsync(buffer, token);
|
|
totalRead += read;
|
|
|
|
if (read == 0) break;
|
|
await file.WriteAsync(buffer.AsMemory(0, read), token);
|
|
|
|
if (canReportProgress)
|
|
{
|
|
var percent = (int)(100.0 * totalRead / total);
|
|
//if (progressPercentage != percent && percent % 10 == 0)
|
|
{
|
|
progressPercentage = percent;
|
|
progress?.Report(percent);
|
|
}
|
|
}
|
|
}
|
|
if (canReportProgress)
|
|
{
|
|
progress?.Report(101);
|
|
}
|
|
}
|
|
|
|
public async Task DownloadDataAsync4Speed(HttpClient client, string url, IProgress<string> progress, CancellationToken token = default)
|
|
{
|
|
if (Utils.IsNullOrEmpty(url))
|
|
{
|
|
throw new ArgumentNullException(nameof(url));
|
|
}
|
|
|
|
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
throw new Exception(response.StatusCode.ToString());
|
|
}
|
|
|
|
//var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L;
|
|
//var canReportProgress = total != -1 && progress != null;
|
|
|
|
await using var stream = await response.Content.ReadAsStreamAsync(token);
|
|
var totalRead = 0L;
|
|
var buffer = new byte[1024 * 64];
|
|
var isMoreToRead = true;
|
|
var progressSpeed = string.Empty;
|
|
var totalDatetime = DateTime.Now;
|
|
var totalSecond = 0;
|
|
|
|
do
|
|
{
|
|
if (token.IsCancellationRequested)
|
|
{
|
|
if (totalRead > 0)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
token.ThrowIfCancellationRequested();
|
|
}
|
|
}
|
|
|
|
var read = await stream.ReadAsync(buffer, token);
|
|
|
|
if (read == 0)
|
|
{
|
|
isMoreToRead = false;
|
|
}
|
|
else
|
|
{
|
|
var data = new byte[read];
|
|
buffer.ToList().CopyTo(0, data, 0, read);
|
|
|
|
totalRead += read;
|
|
|
|
var 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)
|
|
{
|
|
progressSpeed = speed;
|
|
progress.Report(speed);
|
|
}
|
|
}
|
|
}
|
|
} while (isMoreToRead);
|
|
}
|
|
}
|
|
} |