diff --git a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs
index e76fa9b67e5bcb..62410b731aa31e 100644
--- a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs
+++ b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs
@@ -159,8 +159,10 @@ internal static partial class WinHttp
public const uint WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL = 133;
public const uint WINHTTP_OPTION_HTTP_PROTOCOL_USED = 134;
public const uint WINHTTP_PROTOCOL_FLAG_HTTP2 = 0x1;
+ public const uint WINHTTP_PROTOCOL_FLAG_HTTP3 = 0x2;
public const uint WINHTTP_HTTP2_PLUS_CLIENT_CERT_FLAG = 0x1;
public const uint WINHTTP_OPTION_DISABLE_STREAM_QUEUE = 139;
+ public const uint WINHTTP_OPTION_HTTP_PROTOCOL_REQUIRED = 145;
public const uint WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET = 114;
public const uint WINHTTP_OPTION_WEB_SOCKET_CLOSE_TIMEOUT = 115;
diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.AcceptAllCerts.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.AcceptAllCerts.cs
index b449f5025276dc..ba0f6cdd16e91b 100644
--- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.AcceptAllCerts.cs
+++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.AcceptAllCerts.cs
@@ -6,6 +6,7 @@
using System.Security.Authentication;
using System.Threading.Tasks;
using Microsoft.DotNet.XUnitExtensions;
+using TestUtilities;
using Xunit;
using Xunit.Abstractions;
@@ -48,13 +49,14 @@ public void SingletonReturnsTrue()
[InlineData(SslProtocols.None, true)]
public async Task SetDelegate_ConnectionSucceeds(SslProtocols acceptedProtocol, bool requestOnlyThisProtocol)
{
+ using TestEventListener listener = new TestEventListener(_output, TestEventListener.NetworkingEvents);
#pragma warning disable SYSLIB0039 // TLS 1.0 and 1.1 are obsolete
// Overriding flag for the same reason we skip tests on Catalina
// On OSX 10.13-10.14 we can override this flag to enable the scenario
requestOnlyThisProtocol |= PlatformDetection.IsOSX && acceptedProtocol == SslProtocols.Tls;
#pragma warning restore SYSLIB0039
- using (HttpClientHandler handler = CreateHttpClientHandler(allowAllCertificates: true))
+ using (HttpClientHandler handler = CreateHttpClientHandler(UseVersion, allowAllCertificates: true))
using (HttpClient client = CreateHttpClient(handler))
{
if (requestOnlyThisProtocol)
@@ -76,13 +78,13 @@ public async Task SetDelegate_ConnectionSucceeds(SslProtocols acceptedProtocol,
#pragma warning restore SYSLIB0039
}
- var options = new LoopbackServer.Options { UseSsl = true, SslProtocols = acceptedProtocol };
- await LoopbackServer.CreateServerAsync(async (server, url) =>
+ var options = new GenericLoopbackOptions { UseSsl = true, SslProtocols = acceptedProtocol };
+ await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
{
await TestHelper.WhenAllCompletedOrAnyFailed(
server.AcceptConnectionSendResponseAndCloseAsync(),
client.GetAsync(url));
- }, options);
+ }, options: options);
}
}
diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs
index c5bed9f4567390..dc628d8abc2646 100644
--- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs
+++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs
@@ -36,10 +36,10 @@ public async Task PostAsync_CancelDuringRequestContentSend_TaskCanceledQuickly(b
return;
}
- if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
+ /*if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
{
return;
- }
+ }*/
if (PlatformDetection.IsBrowser && LoopbackServerFactory.Version < HttpVersion20.Value)
{
@@ -100,10 +100,10 @@ public async Task GetAsync_CancelDuringResponseHeadersReceived_TaskCanceledQuick
return;
}
- if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
+ /*if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
{
return;
- }
+ }*/
using (HttpClient client = CreateHttpClient())
{
@@ -208,10 +208,10 @@ public async Task GetAsync_CancelDuringResponseBodyReceived_Unbuffered_TaskCance
return;
}
- if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
+ /*if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
{
return;
- }
+ }*/
using (HttpClient client = CreateHttpClient())
{
@@ -276,10 +276,10 @@ await ValidateClientCancellationAsync(async () =>
[SkipOnPlatform(TestPlatforms.Browser, "Browser doesn't have blocking synchronous Stream.ReadByte and so it waits for whole body")]
public async Task GetAsync_CancelPendingRequests_DoesntCancelReadAsyncOnResponseStream(CancellationMode mode, bool copyToAsync)
{
- if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
+ /*if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
{
return;
- }
+ }*/
using (HttpClient client = CreateHttpClient())
{
diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs
index bb664f91298560..2b77329eb7af31 100644
--- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs
+++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs
@@ -29,10 +29,10 @@ public HttpClientHandler_Proxy_Test(ITestOutputHelper output) : base(output) { }
[Fact]
public async Task Dispose_HandlerWithProxy_ProxyNotDisposed()
{
- if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
+ /*if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
{
return;
- }
+ }*/
var proxy = new TrackDisposalProxy();
diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs
index 95ba0752a5daa4..d2019c27ad7d99 100644
--- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs
+++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs
@@ -40,10 +40,10 @@ public HttpClientHandler_ServerCertificates_Test(ITestOutputHelper output) : bas
[Fact]
public void Ctor_ExpectedDefaultValues()
{
- if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
+ /*if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
{
return;
- }
+ }*/
using (HttpClientHandler handler = CreateHttpClientHandler())
{
@@ -55,10 +55,10 @@ public void Ctor_ExpectedDefaultValues()
[Fact]
public void ServerCertificateCustomValidationCallback_SetGet_Roundtrips()
{
- if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
+ /*if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
{
return;
- }
+ }*/
using (HttpClientHandler handler = CreateHttpClientHandler())
{
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs
index e0cbf738b019ec..7555a39deb07c8 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs
@@ -903,17 +903,7 @@ private async Task StartRequestAsync(WinHttpRequestState state)
ThrowOnInvalidHandle(connectHandle, nameof(Interop.WinHttp.WinHttpConnect));
connectHandle.SetParentHandle(_sessionHandle);
- // Try to use the requested version if a known/supported version was explicitly requested.
- // Otherwise, we simply use winhttp's default.
- string? httpVersion = null;
- if (state.RequestMessage.Version == HttpVersion.Version10)
- {
- httpVersion = "HTTP/1.0";
- }
- else if (state.RequestMessage.Version == HttpVersion.Version11)
- {
- httpVersion = "HTTP/1.1";
- }
+ string httpVersion = $"HTTP/{state.RequestMessage.Version.Major}.{state.RequestMessage.Version.Minor}";
OpenRequestHandle(state, connectHandle, httpVersion, out WinHttpChunkMode chunkedModeForSend, out SafeWinHttpHandle requestHandle);
state.RequestHandle = requestHandle;
@@ -1271,7 +1261,7 @@ private void SetRequestHandleOptions(WinHttpRequestState state)
SetRequestHandleClientCertificateOptions(state.RequestHandle, state.RequestMessage.RequestUri);
SetRequestHandleCredentialsOptions(state);
SetRequestHandleBufferingOptions(state.RequestHandle);
- SetRequestHandleHttp2Options(state.RequestHandle, state.RequestMessage.Version);
+ SetRequestHandleHttpProtocolOptions(state.RequestHandle, state.RequestMessage.Version);
}
private void SetRequestHandleProxyOptions(WinHttpRequestState state)
@@ -1536,20 +1526,30 @@ private void SetRequestHandleBufferingOptions(SafeWinHttpHandle requestHandle)
SetWinHttpOption(requestHandle, Interop.WinHttp.WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE, ref optionData);
}
- private void SetRequestHandleHttp2Options(SafeWinHttpHandle requestHandle, Version requestVersion)
+ private void SetRequestHandleHttpProtocolOptions(SafeWinHttpHandle requestHandle, Version requestVersion)
{
Debug.Assert(requestHandle != null);
- uint optionData = (requestVersion == HttpVersion20) ? Interop.WinHttp.WINHTTP_PROTOCOL_FLAG_HTTP2 : 0;
+ uint optionData = (requestVersion == HttpVersion30) ? Interop.WinHttp.WINHTTP_PROTOCOL_FLAG_HTTP3 :
+ (requestVersion == HttpVersion20) ? Interop.WinHttp.WINHTTP_PROTOCOL_FLAG_HTTP2 : 0;
if (Interop.WinHttp.WinHttpSetOption(
requestHandle,
Interop.WinHttp.WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL,
ref optionData))
{
- if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"HTTP/2 option supported, setting to {optionData}");
+ if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"HTTP/{requestVersion.Major} option supported, setting to {optionData}");
}
else
{
- if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, "HTTP/2 option not supported");
+ if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"HTTP/{requestVersion.Major} option not supported");
+ }
+
+ uint protocolRequired = 1;
+ if (optionData != 0 && !Interop.WinHttp.WinHttpSetOption(
+ requestHandle,
+ Interop.WinHttp.WINHTTP_OPTION_HTTP_PROTOCOL_REQUIRED,
+ ref protocolRequired))
+ {
+ if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, "HTTP protocol required option not supported");
}
}
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/HttpClientHandlerTestBase.WinHttpHandler.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/HttpClientHandlerTestBase.WinHttpHandler.cs
index 81773638085d93..fa68df5737c2ea 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/HttpClientHandlerTestBase.WinHttpHandler.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/HttpClientHandlerTestBase.WinHttpHandler.cs
@@ -41,6 +41,9 @@ protected static LoopbackServerFactory GetFactoryForVersion(Version useVersion)
{
return useVersion.Major switch
{
+#if !NETFRAMEWORK
+ 3 => Http3LoopbackServerFactory.Singleton,
+#endif
2 => Http2LoopbackServerFactory.Singleton,
_ => Http11LoopbackServerFactory.Singleton
};
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs
index 0d2165eda36e91..76d87751948ed5 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs
@@ -361,4 +361,184 @@ public sealed class PlatformHandler_ResponseStream_Http2_Test : ResponseStreamTe
public PlatformHandler_ResponseStream_Http2_Test(ITestOutputHelper output) : base(output) { }
}
+
+#if NET
+#if !WINHTTPHANDLER_TEST // [ActiveIssue("https://github.com/dotnet/runtime/issues/33930")]
+ [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))]
+ public sealed class PlatformHandlerTest_Cookies_Http3 : HttpClientHandlerTest_Cookies
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandlerTest_Cookies_Http3(ITestOutputHelper output) : base(output) { }
+ }
+#endif
+
+ public sealed class PlatformHandler_HttpClientHandler_Asynchrony_Http3_Test : HttpClientHandler_Asynchrony_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_Asynchrony_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpProtocol_Http3_Tests : HttpProtocolTests
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpProtocol_Http3_Tests(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpProtocolTests_Http3_Dribble : HttpProtocolTests_Dribble
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpProtocolTests_Http3_Dribble(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpClient_SelectedSites_Http3_Test : HttpClient_SelectedSites_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClient_SelectedSites_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpClientEKU_Http3_Test : HttpClientEKUTest
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientEKU_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpClientHandler_Decompression_Http3_Tests : HttpClientHandler_Decompression_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_Decompression_Http3_Tests(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpClientHandler_DangerousAcceptAllCertificatesValidator_Http3_Test : HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_DangerousAcceptAllCertificatesValidator_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpClientHandler_ClientCertificates_Http3_Test : HttpClientHandler_ClientCertificates_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_ClientCertificates_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpClientHandler_DefaultProxyCredentials_Http3_Test : HttpClientHandler_DefaultProxyCredentials_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_DefaultProxyCredentials_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ [SkipOnPlatform(TestPlatforms.Browser, "MaxConnectionsPerServer not supported on Browser")]
+ public sealed class PlatformHandler_HttpClientHandler_MaxConnectionsPerServer_Http3_Test : HttpClientHandler_MaxConnectionsPerServer_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_MaxConnectionsPerServer_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpClientHandler_ServerCertificates_Http3_Test : HttpClientHandler_ServerCertificates_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_ServerCertificates_Http3_Test(ITestOutputHelper output) : base(output)
+ {
+ AllowAllCertificates = false;
+ }
+ }
+
+ public sealed class PlatformHandler_PostScenario_Http3_Test : PostScenarioTest
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_PostScenario_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpClientHandler_SslProtocols_Http3_Test : HttpClientHandler_SslProtocols_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_SslProtocols_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpClientHandler_Proxy_Http3_Test : HttpClientHandler_Proxy_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_Proxy_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))]
+ public sealed class PlatformHandler_HttpClientHandler_Http3_Test : HttpClientHandlerTest
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandlerTest_AutoRedirect_Http3 : HttpClientHandlerTest_AutoRedirect
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandlerTest_AutoRedirect_Http3(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_DefaultCredentials_Http3_Test : DefaultCredentialsTest
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_DefaultCredentials_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_IdnaProtocol_Http3_Tests : IdnaProtocolTests
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_IdnaProtocol_Http3_Tests(ITestOutputHelper output) : base(output) { }
+ // WinHttp on Win7 does not support IDNA
+ protected override bool SupportsIdna => !PlatformDetection.IsWindows7;
+ }
+
+ public sealed class PlatformHandlerTest_Cookies_Http11_Http3 : HttpClientHandlerTest_Cookies_Http11
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandlerTest_Cookies_Http11_Http3(ITestOutputHelper output) : base(output) { }
+ }
+
+ [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))]
+ public sealed class PlatformHandler_HttpClientHandler_MaxResponseHeadersLength_Http3_Test : HttpClientHandler_MaxResponseHeadersLength_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_MaxResponseHeadersLength_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpClientHandler_Cancellation_Http3_Test : HttpClientHandler_Cancellation_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_Cancellation_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+
+ public sealed class PlatformHandler_HttpClientHandler_Authentication_Http3_Test : HttpClientHandler_Authentication_Test
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_HttpClientHandler_Authentication_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+ public sealed class PlatformHandler_ResponseStream_Http3_Test : ResponseStreamTest
+ {
+ protected override Version UseVersion => HttpVersion.Version30;
+
+ public PlatformHandler_ResponseStream_Http3_Test(ITestOutputHelper output) : base(output) { }
+ }
+#endif
}
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj
index c5c7099713aa5f..4a90073d5e8b0e 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj
+++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj
@@ -149,6 +149,12 @@
+
+
+