diff --git a/src/Common.CoreLib/Extensions/HttpExtensions.cs b/src/Common.CoreLib/Extensions/HttpExtensions.cs
new file mode 100644
index 000000000..ea28ad20c
--- /dev/null
+++ b/src/Common.CoreLib/Extensions/HttpExtensions.cs
@@ -0,0 +1,87 @@
+using System.Net;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+
+// ReSharper disable once CheckNamespace
+namespace System
+{
+ public static class HttpExtensions
+ {
+ #region UseDefaultSendX 使用此扩展代替 Send,将 DefaultRequestVersion 与 DefaultVersionPolicy 赋值给 HttpRequestMessage
+
+#if NETSTANDARD
+ public static Version DefaultRequestVersion { get; set; } = HttpVersion.Version20;
+#endif
+
+ static void UseDefault(HttpClient httpClient, HttpRequestMessage request)
+ {
+#if NETSTANDARD
+ request.Version = DefaultRequestVersion;
+#else
+ request.Version = httpClient.DefaultRequestVersion;
+ request.VersionPolicy = httpClient.DefaultVersionPolicy;
+#endif
+ }
+
+ ///
+ public static Task UseDefaultSendAsync(this HttpClient httpClient, HttpRequestMessage request)
+ {
+ UseDefault(httpClient, request);
+ return httpClient.SendAsync(request);
+ }
+
+ ///
+ public static Task UseDefaultSendAsync(this HttpClient httpClient, HttpRequestMessage request, HttpCompletionOption completionOption)
+ {
+ UseDefault(httpClient, request);
+ return httpClient.SendAsync(request, completionOption);
+ }
+
+ ///
+ public static Task UseDefaultSendAsync(this HttpClient httpClient, HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
+ {
+ UseDefault(httpClient, request);
+ return httpClient.SendAsync(request, completionOption, cancellationToken);
+ }
+
+ ///
+ public static Task UseDefaultSendAsync(this HttpClient httpClient, HttpRequestMessage request, CancellationToken cancellationToken)
+ {
+ UseDefault(httpClient, request);
+ return httpClient.SendAsync(request, cancellationToken);
+ }
+
+#if NET5_0_OR_GREATER
+ ///
+ public static HttpResponseMessage UseDefaultSend(this HttpClient httpClient, HttpRequestMessage request)
+ {
+ UseDefault(httpClient, request);
+ return httpClient.Send(request);
+ }
+
+ ///
+ public static HttpResponseMessage UseDefaultSend(this HttpClient httpClient, HttpRequestMessage request, HttpCompletionOption completionOption)
+ {
+ UseDefault(httpClient, request);
+ return httpClient.Send(request, completionOption);
+ }
+
+ ///
+ public static HttpResponseMessage UseDefaultSend(this HttpClient httpClient, HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
+ {
+ UseDefault(httpClient, request);
+ return httpClient.Send(request, completionOption, cancellationToken);
+ }
+
+ ///
+ public static HttpResponseMessage UseDefaultSend(this HttpClient httpClient, HttpRequestMessage request, CancellationToken cancellationToken)
+ {
+ UseDefault(httpClient, request);
+ return httpClient.Send(request, cancellationToken);
+ }
+#endif
+
+ #endregion
+ }
+}
diff --git a/src/ST.Client/UI/ViewModels/Pages/DebugPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/DebugPageViewModel.cs
index 4d83f7bbb..ab05d71d1 100644
--- a/src/ST.Client/UI/ViewModels/Pages/DebugPageViewModel.cs
+++ b/src/ST.Client/UI/ViewModels/Pages/DebugPageViewModel.cs
@@ -15,6 +15,8 @@ using System.Globalization;
using System.IO;
using System.IO.Pipes;
using System.Linq;
+using System.Net;
+using System.Net.Http;
using System.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
@@ -74,6 +76,9 @@ namespace System.Application.UI.ViewModels
public void DebugButton_Click()
{
+ TestHttp3Quic();
+ return;
+
//#if DEBUG
// //TestAppUpdate();
// //return;
@@ -94,6 +99,29 @@ namespace System.Application.UI.ViewModels
});
}
+ public async void TestHttp3Quic()
+ {
+ // https://docs.microsoft.com/zh-cn/dotnet/core/extensions/httpclient-http3
+ // https://devblogs.microsoft.com/dotnet/http-3-support-in-dotnet-6
+ using HttpClient httpClient = new()
+ {
+#if NET6_0_OR_GREATER
+ DefaultRequestVersion = HttpVersion.Version30,
+#endif
+ };
+
+ using HttpRequestMessage request = new(HttpMethod.Get, "https://cloudflare-quic.com/");
+ using var response = await httpClient.UseDefaultSendAsync(request);
+
+ var htmlString = await response.Content.ReadAsStringAsync();
+
+ StringBuilder @string = new();
+ @string.AppendFormatLine("request.Version: {0}", request.Version);
+ @string.AppendFormatLine("response.Version: {0}", response.Version);
+ @string.AppendLine(htmlString);
+ DebugString = @string.ToString();
+ }
+
//static async void TestTextBoxWindow(int state)
//{
// string? value = null;
diff --git a/src/ST.Services.CloudService/Services/CloudService/ApiConnection.cs b/src/ST.Services.CloudService/Services/CloudService/ApiConnection.cs
index 48f85f439..157c36ff6 100644
--- a/src/ST.Services.CloudService/Services/CloudService/ApiConnection.cs
+++ b/src/ST.Services.CloudService/Services/CloudService/ApiConnection.cs
@@ -506,7 +506,6 @@ namespace System.Application.Services.CloudService
var request = new HttpRequestMessage(method, requestUri)
{
- Version = HttpVersion.Version20,
Content = GetRequestContent(
isSecurity,
aes,
@@ -555,7 +554,7 @@ namespace System.Application.Services.CloudService
HandleHttpRequest(request);
- var response = await client.SendAsync(request,
+ var response = await client.UseDefaultSendAsync(request,
HttpCompletionOption.ResponseHeadersRead,
cancellationToken)
.ConfigureAwait(false);
@@ -757,10 +756,7 @@ namespace System.Application.Services.CloudService
IApiResponse responseResult;
try
{
- var request = new HttpRequestMessage(method, requestUri)
- {
- Version = HttpVersion.Version20,
- };
+ var request = new HttpRequestMessage(method, requestUri);
JWTEntity? jwt = null;
@@ -773,7 +769,7 @@ namespace System.Application.Services.CloudService
HandleHttpRequest(request);
- var response = await client.SendAsync(request,
+ var response = await client.UseDefaultSendAsync(request,
HttpCompletionOption.ResponseHeadersRead,
cancellationToken)
.ConfigureAwait(false);
diff --git a/src/Startup2.cs b/src/Startup2.cs
index a187e7299..c521c7e21 100644
--- a/src/Startup2.cs
+++ b/src/Startup2.cs
@@ -275,7 +275,7 @@ namespace System.Application
c.DefaultRequestVersion = HttpVersion.Version20;
#endif
#if NET5_0_OR_GREATER
- c.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact;
+ c.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
#endif
}, configureHandler:
#if NETCOREAPP2_1_OR_GREATER
diff --git a/tests/ST.Client.UnitTest/SetupFixture.shared.cs b/tests/ST.Client.UnitTest/SetupFixture.shared.cs
index 1a8024dbf..f1b4722dd 100644
--- a/tests/ST.Client.UnitTest/SetupFixture.shared.cs
+++ b/tests/ST.Client.UnitTest/SetupFixture.shared.cs
@@ -55,7 +55,7 @@ namespace System.Application
public static void OneTimeTearDownCore()
{
#if !Desktop_UnitTest && !__ANDROID__
- HostsFileTest.DeleteAllTempFileName();
+ HostsFileTest.DeleteAllTempFileName();
#endif
}
@@ -102,7 +102,7 @@ namespace System.Application
c.DefaultRequestVersion = HttpVersion.Version20;
#endif
#if NET5_0_OR_GREATER
- c.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact;
+ c.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
#endif
}, configureHandler:
#if NETCOREAPP2_1_OR_GREATER