fix: Unable to obtain subscription normally when dns has multiple records

This commit is contained in:
SoHugePenguin 2025-10-08 19:35:35 +08:00
parent a559586e71
commit 1d2dfabf06

View file

@ -15,7 +15,8 @@ public class DownloadService
private static readonly string _tag = "DownloadService"; private static readonly string _tag = "DownloadService";
public async Task<int> DownloadDataAsync(string url, WebProxy webProxy, int downloadTimeout, Func<bool, string, Task> updateFunc) public async Task<int> DownloadDataAsync(string url, WebProxy webProxy, int downloadTimeout,
Func<bool, string, Task> updateFunc)
{ {
try try
{ {
@ -37,6 +38,7 @@ public class DownloadService
await updateFunc?.Invoke(false, ex.InnerException.Message); await updateFunc?.Invoke(false, ex.InnerException.Message);
} }
} }
return 0; return 0;
} }
@ -48,7 +50,8 @@ public class DownloadService
UpdateCompleted?.Invoke(this, new RetResult(false, $"{ResUI.Downloading} {url}")); UpdateCompleted?.Invoke(this, new RetResult(false, $"{ResUI.Downloading} {url}"));
var progress = new Progress<double>(); var progress = new Progress<double>();
progress.ProgressChanged += (sender, value) => UpdateCompleted?.Invoke(this, new RetResult(value > 100, $"...{value}%")); progress.ProgressChanged += (sender, value) =>
UpdateCompleted?.Invoke(this, new RetResult(value > 100, $"...{value}%"));
var webProxy = await GetWebProxy(blProxy); var webProxy = await GetWebProxy(blProxy);
await DownloaderHelper.Instance.DownloadFileAsync(webProxy, await DownloaderHelper.Instance.DownloadFileAsync(webProxy,
@ -74,8 +77,7 @@ public class DownloadService
SetSecurityProtocol(AppManager.Instance.Config.GuiItem.EnableSecurityProtocolTls13); SetSecurityProtocol(AppManager.Instance.Config.GuiItem.EnableSecurityProtocolTls13);
var webRequestHandler = new SocketsHttpHandler var webRequestHandler = new SocketsHttpHandler
{ {
AllowAutoRedirect = false, AllowAutoRedirect = false, Proxy = await GetWebProxy(blProxy)
Proxy = await GetWebProxy(blProxy)
}; };
HttpClient client = new(webRequestHandler); HttpClient client = new(webRequestHandler);
@ -96,7 +98,7 @@ public class DownloadService
{ {
try try
{ {
var result1 = await DownloadStringAsync(url, blProxy, userAgent, 15); var result1 = await DownloadStringAsync(url, blProxy, userAgent, 5);
if (result1.IsNotEmpty()) if (result1.IsNotEmpty())
{ {
return result1; return result1;
@ -141,30 +143,90 @@ public class DownloadService
{ {
try try
{ {
Uri uri = new(url);
SetSecurityProtocol(AppManager.Instance.Config.GuiItem.EnableSecurityProtocolTls13); SetSecurityProtocol(AppManager.Instance.Config.GuiItem.EnableSecurityProtocolTls13);
var webProxy = await GetWebProxy(blProxy); var webProxy = await GetWebProxy(blProxy);
var client = new HttpClient(new SocketsHttpHandler() using var cts = new CancellationTokenSource();
{
Proxy = webProxy,
UseProxy = webProxy != null
});
if (userAgent.IsNullOrEmpty()) if (userAgent.IsNullOrEmpty())
{ {
userAgent = Utils.GetVersion(false); userAgent = Utils.GetVersion(false);
} }
try
{
// 轮询解析 DNS
var addresses = await Dns.GetHostAddressesAsync(uri.Host);
foreach (var addr in addresses)
{
NoticeManager.Instance.SendMessage($"{uri.Host} find Resolved: {addr}");
}
NoticeManager.Instance.SendMessage($"Start download [{uri.Host}] sub...");
Exception? lastEx = null;
foreach (var addr in addresses)
{
NoticeManager.Instance.SendMessage($"Download sub domain Resolved: {addr}");
try
{
using var handler = new SocketsHttpHandler
{
Proxy = webProxy,
UseProxy = webProxy != null,
ConnectCallback = async (context, cancellationToken) =>
{
var socket = new Socket(
addr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
cts.CancelAfter(TimeSpan.FromSeconds(5));
await socket.ConnectAsync(addr, uri.Port, cts.Token).AsTask();
return new NetworkStream(socket, ownsSocket: true);
}
};
var client = new HttpClient(handler);
client.DefaultRequestHeaders.UserAgent.TryParseAdd(userAgent); client.DefaultRequestHeaders.UserAgent.TryParseAdd(userAgent);
Uri uri = new(url);
//Authorization Header //Authorization Header
if (uri.UserInfo.IsNotEmpty()) if (uri.UserInfo.IsNotEmpty())
{ {
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Utils.Base64Encode(uri.UserInfo)); client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", Utils.Base64Encode(uri.UserInfo));
} }
using var cts = new CancellationTokenSource(); // 这里仍然使用原始 URLHost 保留
var result = await HttpClientHelper.Instance.GetAsync(client, url, cts.Token).WaitAsync(TimeSpan.FromSeconds(timeout), cts.Token); var response = await client.GetAsync(uri, cts.Token)
return result; .WaitAsync(TimeSpan.FromSeconds(timeout), cts.Token);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync(cts.Token);
NoticeManager.Instance.SendMessage($"Request succeeded via {addr}");
return content;
}
catch (Exception ex)
{
lastEx = ex;
NoticeManager.Instance.SendMessage($"Request via {addr} failed: {ex.Message}");
}
}
NoticeManager.Instance.SendMessage("[HttpClientHelper] All IP attempts failed");
if (lastEx != null) throw lastEx;
return null;
}
catch (Exception ex)
{
NoticeManager.Instance.SendMessage($"[HttpClientHelper] {ex.GetType().Name}: {ex.Message}");
return null;
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -175,6 +237,7 @@ public class DownloadService
Error?.Invoke(this, new ErrorEventArgs(ex.InnerException)); Error?.Invoke(this, new ErrorEventArgs(ex.InnerException));
} }
} }
return null; return null;
} }
@ -194,6 +257,7 @@ public class DownloadService
{ {
userAgent = Utils.GetVersion(false); userAgent = Utils.GetVersion(false);
} }
var result = await DownloaderHelper.Instance.DownloadStringAsync(webProxy, url, userAgent, timeout); var result = await DownloaderHelper.Instance.DownloadStringAsync(webProxy, url, userAgent, timeout);
return result; return result;
} }
@ -206,6 +270,7 @@ public class DownloadService
Error?.Invoke(this, new ErrorEventArgs(ex.InnerException)); Error?.Invoke(this, new ErrorEventArgs(ex.InnerException));
} }
} }
return null; return null;
} }
@ -215,6 +280,7 @@ public class DownloadService
{ {
return null; return null;
} }
var port = AppManager.Instance.GetLocalPort(EInboundProtocol.socks); var port = AppManager.Instance.GetLocalPort(EInboundProtocol.socks);
if (await SocketCheck(Global.Loopback, port) == false) if (await SocketCheck(Global.Loopback, port) == false)
{ {
@ -249,6 +315,7 @@ public class DownloadService
{ {
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12; ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
} }
ServicePointManager.DefaultConnectionLimit = 256; ServicePointManager.DefaultConnectionLimit = 256;
} }
} }