From 68fd1af01718a74447d5c3ec6032c4cb40aa2082 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Fri, 21 Feb 2020 14:59:45 +0100 Subject: [PATCH 01/26] ENABLE_HTTP2_PLUS_CLIENT_CERT option is set for HTTP/2 requests --- .../Windows/WinHttp/Interop.winhttp_types.cs | 2 ++ .../src/System/Net/Http/WinHttpHandler.cs | 22 +++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) 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 adf182ec33e774..ab5ff402744863 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 @@ -148,9 +148,11 @@ internal partial class WinHttp public const uint WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS = 111; + public const uint WINHTTP_OPTION_ENABLE_HTTP2_PLUS_CLIENT_CERT = 161; 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_HTTP2_PLUS_CLIENT_CERT_FLAG = 0x1; 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/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs index 6913359c608e59..385af704c25aa3 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 @@ -996,7 +996,7 @@ private void SetRequestHandleOptions(WinHttpRequestState state) SetRequestHandleRedirectionOptions(state.RequestHandle); SetRequestHandleCookieOptions(state.RequestHandle); SetRequestHandleTlsOptions(state.RequestHandle); - SetRequestHandleClientCertificateOptions(state.RequestHandle, state.RequestMessage.RequestUri); + SetRequestHandleClientCertificateOptions(state.RequestHandle, state.RequestMessage.RequestUri, state.RequestMessage.Version); SetRequestHandleCredentialsOptions(state); SetRequestHandleBufferingOptions(state.RequestHandle); SetRequestHandleHttp2Options(state.RequestHandle, state.RequestMessage.Version); @@ -1153,7 +1153,7 @@ private void SetRequestHandleTlsOptions(SafeWinHttpHandle requestHandle) } } - private void SetRequestHandleClientCertificateOptions(SafeWinHttpHandle requestHandle, Uri requestUri) + private void SetRequestHandleClientCertificateOptions(SafeWinHttpHandle requestHandle, Uri requestUri, Version requestVersion) { if (requestUri.Scheme != UriScheme.Https) { @@ -1172,6 +1172,24 @@ private void SetRequestHandleClientCertificateOptions(SafeWinHttpHandle requestH if (clientCertificate != null) { + // Newer versions of WinHTTP fully support HTTP/2 with TLS client certificates. + // But the support must be opted in. + if (requestVersion == HttpVersion20) + { + uint optionData = Interop.WinHttp.WINHTTP_HTTP2_PLUS_CLIENT_CERT_FLAG; + if (Interop.WinHttp.WinHttpSetOption( + requestHandle, + Interop.WinHttp.WINHTTP_OPTION_ENABLE_HTTP2_PLUS_CLIENT_CERT, + ref optionData)) + { + if (NetEventSource.IsEnabled) NetEventSource.Info(this, "HTTP/2 with TLS client cert supported"); + } + else + { + if (NetEventSource.IsEnabled) NetEventSource.Info(this, "HTTP/2 with TLS client cert not supported"); + } + } + SetWinHttpOption( requestHandle, Interop.WinHttp.WINHTTP_OPTION_CLIENT_CERT_CONTEXT, From 2eb56a66d1e9fcd722cc0e297a19d1ac367a8288 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Wed, 26 Feb 2020 14:27:40 +0100 Subject: [PATCH 02/26] UseClientCertOnHttp2_ClientCertValid_Success test --- .../Net/Http/Http2LoopbackConnection.cs | 2 +- .../System/Net/Http/Http2LoopbackServer.cs | 11 +++++- .../FunctionalTests/ServerCertificateTest.cs | 37 +++++++++++++++++-- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index 43be924c03550b..a4940146f89534 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -51,7 +51,7 @@ public Http2LoopbackConnection(Socket socket, Http2Options httpOptions) options.ServerCertificate = cert; - options.ClientCertificateRequired = false; + options.ClientCertificateRequired = httpOptions.ClientCertificateRequired; sslStream.AuthenticateAsServerAsync(options, CancellationToken.None).Wait(); } diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs index f2aea4cfb4f234..024dcedc890f64 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs @@ -181,9 +181,14 @@ public override async Task AcceptConnectionAsync(Func clientFunc, Func serverFunc, int timeout = 60_000) + public static Task CreateClientAndServerAsync(Func clientFunc, Func serverFunc, int timeout = 60_000) { - using (var server = Http2LoopbackServer.CreateServer()) + return CreateClientAndServerAsync(clientFunc, serverFunc, null, timeout); + } + + public static async Task CreateClientAndServerAsync(Func clientFunc, Func serverFunc, Http2Options http2Options, int timeout = 60_000) + { + using (var server = Http2LoopbackServer.CreateServer(http2Options ?? new Http2Options())) { Task clientTask = clientFunc(server.Address); Task serverTask = serverFunc(server); @@ -197,6 +202,8 @@ public class Http2Options : GenericLoopbackOptions { public int ListenBacklog { get; set; } = 1; + public bool ClientCertificateRequired { get; set; } + public Http2Options() { UseSsl = PlatformDetection.SupportsAlpn && !Capability.Http2ForceUnencryptedLoopback(); diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs index 5ad5587abb0c93..9b600747bc1d2f 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs @@ -3,12 +3,12 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.ComponentModel; -using System.Net; -using System.Net.Http; +using System.Diagnostics; using System.Net.Security; using System.Net.Test.Common; -using System.Security.Authentication; +using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; @@ -123,6 +123,37 @@ public async Task UseCallback_CallbackThrowsSpecificException_SpecificExceptionP } } + [Fact] + public async Task UseClientCertOnHttp2_ClientCertValid_Success() + { + //Debugger.Launch(); + await Http2LoopbackServer.CreateClientAndServerAsync( + async address => + { + var handler = new WinHttpHandler(); + handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; + handler.ClientCertificates.Add(Test.Common.Configuration.Certificates.GetClientCertificate()); + handler.ClientCertificateOption = ClientCertificateOption.Manual; + using (var client = new HttpClient(handler)) + using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) {Version = HttpVersion.Version20 })) + { + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.True(_validationCallbackHistory.WasCalled); + + //ConfirmValidCertificate(System.Net.Test.Common.Configuration.Http.Host); + } + }, + async s => + { + using (Http2LoopbackConnection connection = await s.EstablishConnectionAsync().ConfigureAwait(false)) + { + int streamId = await connection.ReadRequestHeaderAsync(); + + await connection.SendDefaultResponseAsync(streamId); + } + }, new Http2Options { ClientCertificateRequired = false }); + } + private void ConfirmValidCertificate(string expectedHostName) { Assert.Equal(SslPolicyErrors.None, _validationCallbackHistory.SslPolicyErrors); From 923f05d70c6d42cfd9fea2caa58fe23cbbebf271 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Wed, 4 Mar 2020 15:06:53 +0100 Subject: [PATCH 03/26] HTTP2_PLUS_CLIENT_CERT option is set before openning a connection --- .../Net/Http/Http2LoopbackConnection.cs | 2 +- .../src/System/Net/Http/WinHttpHandler.cs | 43 ++++--- .../FunctionalTests/BaseCertificateTest.cs | 77 ++++++++++++ .../FunctionalTests/ClientCertificateTest.cs | 117 ++++++++++++++++++ .../FunctionalTests/ServerCertificateTest.cs | 112 ++--------------- ...ttp.WinHttpHandler.Functional.Tests.csproj | 4 + 6 files changed, 233 insertions(+), 122 deletions(-) create mode 100644 src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/BaseCertificateTest.cs create mode 100644 src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index a4940146f89534..cf98b8cd221773 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Net.Http.Functional.Tests; using System.Net.Security; @@ -28,6 +27,7 @@ public class Http2LoopbackConnection : GenericLoopbackConnection private readonly byte[] _prefix; public string PrefixString => Encoding.UTF8.GetString(_prefix, 0, _prefix.Length); public bool IsInvalid => _connectionSocket == null; + public Stream Stream => _connectionStream; public Http2LoopbackConnection(Socket socket, Http2Options httpOptions) { 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 385af704c25aa3..8219a438e72be7 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 @@ -786,6 +786,8 @@ private async Task StartRequestAsync(WinHttpRequestState state) { EnsureSessionHandleExists(state); + SetEnableHttp2PlusClientCertificate(state.RequestMessage.RequestUri, state.RequestMessage.Version); + // Specify an HTTP server. connectHandle = Interop.WinHttp.WinHttpConnect( _sessionHandle, @@ -1172,24 +1174,6 @@ private void SetRequestHandleClientCertificateOptions(SafeWinHttpHandle requestH if (clientCertificate != null) { - // Newer versions of WinHTTP fully support HTTP/2 with TLS client certificates. - // But the support must be opted in. - if (requestVersion == HttpVersion20) - { - uint optionData = Interop.WinHttp.WINHTTP_HTTP2_PLUS_CLIENT_CERT_FLAG; - if (Interop.WinHttp.WinHttpSetOption( - requestHandle, - Interop.WinHttp.WINHTTP_OPTION_ENABLE_HTTP2_PLUS_CLIENT_CERT, - ref optionData)) - { - if (NetEventSource.IsEnabled) NetEventSource.Info(this, "HTTP/2 with TLS client cert supported"); - } - else - { - if (NetEventSource.IsEnabled) NetEventSource.Info(this, "HTTP/2 with TLS client cert not supported"); - } - } - SetWinHttpOption( requestHandle, Interop.WinHttp.WINHTTP_OPTION_CLIENT_CERT_CONTEXT, @@ -1202,6 +1186,29 @@ private void SetRequestHandleClientCertificateOptions(SafeWinHttpHandle requestH } } + private void SetEnableHttp2PlusClientCertificate(Uri requestUri, Version requestVersion) + { + if (requestUri.Scheme != UriScheme.Https || requestVersion != HttpVersion20) + { + return; + } + + // Newer versions of WinHTTP fully support HTTP/2 with TLS client certificates. + // But the support must be opted in. + uint optionData = Interop.WinHttp.WINHTTP_HTTP2_PLUS_CLIENT_CERT_FLAG; + if (Interop.WinHttp.WinHttpSetOption( + _sessionHandle, + Interop.WinHttp.WINHTTP_OPTION_ENABLE_HTTP2_PLUS_CLIENT_CERT, + ref optionData)) + { + if (NetEventSource.IsEnabled) NetEventSource.Info(this, "HTTP/2 with TLS client cert supported"); + } + else + { + if (NetEventSource.IsEnabled) NetEventSource.Info(this, "HTTP/2 with TLS client cert not supported"); + } + } + internal static void SetNoClientCertificate(SafeWinHttpHandle requestHandle) { SetWinHttpOption( diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/BaseCertificateTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/BaseCertificateTest.cs new file mode 100644 index 00000000000000..f1e348db4aa655 --- /dev/null +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/BaseCertificateTest.cs @@ -0,0 +1,77 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using Xunit.Abstractions; + +namespace System.Net.Http.WinHttpHandlerFunctional.Tests +{ + public abstract class BaseCertificateTest + { + protected readonly ValidationCallbackHistory _validationCallbackHistory; + + public BaseCertificateTest() + { + _validationCallbackHistory = new ValidationCallbackHistory(); + } + + public class ValidationCallbackHistory + { + public bool ThrowException; + public bool ReturnFailure; + public bool WasCalled; + public SslPolicyErrors SslPolicyErrors; + public string CertificateSubject; + public X509CertificateCollection CertificateChain; + public X509ChainStatus[] ChainStatus; + + public ValidationCallbackHistory() + { + ThrowException = false; + ReturnFailure = false; + WasCalled = false; + SslPolicyErrors = SslPolicyErrors.None; + CertificateSubject = null; + CertificateChain = new X509CertificateCollection(); + ChainStatus = null; + } + } + + protected bool CustomServerCertificateValidationCallback( + HttpRequestMessage sender, + X509Certificate2 certificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors) + { + _validationCallbackHistory.WasCalled = true; + _validationCallbackHistory.CertificateSubject = certificate.Subject; + foreach (var element in chain.ChainElements) + { + _validationCallbackHistory.CertificateChain.Add(element.Certificate); + } + _validationCallbackHistory.ChainStatus = chain.ChainStatus; + _validationCallbackHistory.SslPolicyErrors = sslPolicyErrors; + + if (_validationCallbackHistory.ThrowException) + { + throw new CustomException(); + } + + if (_validationCallbackHistory.ReturnFailure) + { + return false; + } + + return true; + } + + public class CustomException : Exception + { + public CustomException() + { + } + } + } +} diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs new file mode 100644 index 00000000000000..a6c90bec573f96 --- /dev/null +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Net.Security; +using System.Net.Test.Common; +using System.Security.Cryptography.X509Certificates; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.Http.WinHttpHandlerFunctional.Tests +{ + public class ClientCertificateTest : BaseCertificateTest + { + public static bool DowngradeToHTTP1IfClientCertSet => PlatformDetection.WindowsVersion < 2004; + + [ConditionalFact(typeof(ServerCertificateTest), nameof(DowngradeToHTTP1IfClientCertSet))] + public async Task UseClientCertOnHttp2_DowngradedToHttp1MutualAuth_Success() + { + using X509Certificate2 clientCert = Test.Common.Configuration.Certificates.GetClientCertificate(); + await LoopbackServer.CreateClientAndServerAsync( + async address => + { + var handler = new WinHttpHandler(); + handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; + handler.ClientCertificates.Add(clientCert); + handler.ClientCertificateOption = ClientCertificateOption.Manual; + using (var client = new HttpClient(handler)) + using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion.Version20 })) + { + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.True(_validationCallbackHistory.WasCalled); + Assert.NotEmpty(_validationCallbackHistory.CertificateChain); + Assert.Equal(Test.Common.Configuration.Certificates.GetServerCertificate(), _validationCallbackHistory.CertificateChain[0]); + } + }, + async s => + { + using (LoopbackServer.Connection connection = await s.EstablishConnectionAsync().ConfigureAwait(false)) + { + SslStream sslStream = connection.Stream as SslStream; + Assert.NotNull(sslStream); + Assert.True(sslStream.IsMutuallyAuthenticated); + Assert.Equal(clientCert, sslStream.RemoteCertificate); + await connection.ReadRequestHeaderAndSendResponseAsync(HttpStatusCode.OK); + } + }, new LoopbackServer.Options { UseSsl = true }); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version2004OrGreater))] + public async Task UseClientCertOnHttp2_OSSupportsIt_Success() + { + using X509Certificate2 clientCert = Test.Common.Configuration.Certificates.GetClientCertificate(); + await Http2LoopbackServer.CreateClientAndServerAsync( + async address => + { + var handler = new WinHttpHandler(); + handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; + handler.ClientCertificates.Add(clientCert); + handler.ClientCertificateOption = ClientCertificateOption.Manual; + using (var client = new HttpClient(handler)) + using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion.Version20 })) + { + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.True(_validationCallbackHistory.WasCalled); + Assert.NotEmpty(_validationCallbackHistory.CertificateChain); + Assert.Equal(Test.Common.Configuration.Certificates.GetServerCertificate(), _validationCallbackHistory.CertificateChain[0]); + } + }, + async s => + { + using (Http2LoopbackConnection connection = await s.EstablishConnectionAsync().ConfigureAwait(false)) + { + SslStream sslStream = connection.Stream as SslStream; + Assert.NotNull(sslStream); + Assert.True(sslStream.IsMutuallyAuthenticated); + Assert.Equal(clientCert, sslStream.RemoteCertificate); + + int streamId = await connection.ReadRequestHeaderAsync(); + await connection.SendDefaultResponseAsync(streamId); + } + }, new Http2Options { ClientCertificateRequired = true }); + } + + [Fact] + public async Task UseClientCertOnHttp2_OSSupportsItButCertNotSet_SuccessWithOneWayAuth() + { + await Http2LoopbackServer.CreateClientAndServerAsync( + async address => + { + var handler = new WinHttpHandler(); + handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; + using (var client = new HttpClient(handler)) + using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion.Version20 })) + { + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.True(_validationCallbackHistory.WasCalled); + Assert.NotEmpty(_validationCallbackHistory.CertificateChain); + Assert.Equal(Test.Common.Configuration.Certificates.GetServerCertificate(), _validationCallbackHistory.CertificateChain[0]); + } + }, + async s => + { + using (Http2LoopbackConnection connection = await s.EstablishConnectionAsync().ConfigureAwait(false)) + { + SslStream sslStream = connection.Stream as SslStream; + Assert.NotNull(sslStream); + Assert.False(sslStream.IsMutuallyAuthenticated); + Assert.Null(sslStream.RemoteCertificate); + + int streamId = await connection.ReadRequestHeaderAsync(); + await connection.SendDefaultResponseAsync(streamId); + } + }, new Http2Options { ClientCertificateRequired = true }); + } + } +} diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs index 9b600747bc1d2f..4ac9071fbdad02 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs @@ -2,39 +2,33 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections.Generic; using System.ComponentModel; -using System.Diagnostics; using System.Net.Security; -using System.Net.Test.Common; -using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; - using Xunit; using Xunit.Abstractions; namespace System.Net.Http.WinHttpHandlerFunctional.Tests { - public class ServerCertificateTest + public class ServerCertificateTest : BaseCertificateTest { private readonly ITestOutputHelper _output; - private readonly ValidationCallbackHistory _validationCallbackHistory; public ServerCertificateTest(ITestOutputHelper output) { _output = output; - _validationCallbackHistory = new ValidationCallbackHistory(); } + public static bool DowngradeToHTTP1IfClientCertSet => PlatformDetection.WindowsVersion < 2004; + [OuterLoop] [Fact] public async Task NoCallback_ValidCertificate_CallbackNotCalled() { var handler = new WinHttpHandler(); using (var client = new HttpClient(handler)) - using (HttpResponseMessage response = await client.GetAsync(System.Net.Test.Common.Configuration.Http.SecureRemoteEchoServer)) + using (HttpResponseMessage response = await client.GetAsync(Test.Common.Configuration.Http.SecureRemoteEchoServer)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.False(_validationCallbackHistory.WasCalled); @@ -48,7 +42,7 @@ public async Task UseCallback_NotSecureConnection_CallbackNotCalled() var handler = new WinHttpHandler(); handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; using (var client = new HttpClient(handler)) - using (HttpResponseMessage response = await client.GetAsync(System.Net.Test.Common.Configuration.Http.RemoteEchoServer)) + using (HttpResponseMessage response = await client.GetAsync(Test.Common.Configuration.Http.RemoteEchoServer)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.False(_validationCallbackHistory.WasCalled); @@ -67,7 +61,7 @@ public async Task UseCallback_ValidCertificate_ExpectedValuesDuringCallback() Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.True(_validationCallbackHistory.WasCalled); - ConfirmValidCertificate(System.Net.Test.Common.Configuration.Http.Host); + ConfirmValidCertificate(Test.Common.Configuration.Http.Host); } } @@ -75,7 +69,7 @@ public async Task UseCallback_ValidCertificate_ExpectedValuesDuringCallback() [Fact] public async Task UseCallback_RedirectandValidCertificate_ExpectedValuesDuringCallback() { - Uri uri = System.Net.Test.Common.Configuration.Http.RemoteSecureHttp11Server.RedirectUriForDestinationUri(302, System.Net.Test.Common.Configuration.Http.SecureRemoteEchoServer, 1); + Uri uri = Test.Common.Configuration.Http.RemoteSecureHttp11Server.RedirectUriForDestinationUri(302, System.Net.Test.Common.Configuration.Http.SecureRemoteEchoServer, 1); var handler = new WinHttpHandler(); handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; @@ -85,7 +79,7 @@ public async Task UseCallback_RedirectandValidCertificate_ExpectedValuesDuringCa Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.True(_validationCallbackHistory.WasCalled); - ConfirmValidCertificate(System.Net.Test.Common.Configuration.Http.Host); + ConfirmValidCertificate(Test.Common.Configuration.Http.Host); } } @@ -99,7 +93,7 @@ public async Task UseCallback_CallbackReturnsFailure_ThrowsInnerSecurityFailureE handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; using (var client = new HttpClient(handler)) { - var request = new HttpRequestMessage(HttpMethod.Get, System.Net.Test.Common.Configuration.Http.SecureRemoteEchoServer); + var request = new HttpRequestMessage(HttpMethod.Get, Test.Common.Configuration.Http.SecureRemoteEchoServer); _validationCallbackHistory.ReturnFailure = true; HttpRequestException ex = await Assert.ThrowsAsync(() => client.GetAsync(System.Net.Test.Common.Configuration.Http.SecureRemoteEchoServer)); @@ -123,37 +117,6 @@ public async Task UseCallback_CallbackThrowsSpecificException_SpecificExceptionP } } - [Fact] - public async Task UseClientCertOnHttp2_ClientCertValid_Success() - { - //Debugger.Launch(); - await Http2LoopbackServer.CreateClientAndServerAsync( - async address => - { - var handler = new WinHttpHandler(); - handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; - handler.ClientCertificates.Add(Test.Common.Configuration.Certificates.GetClientCertificate()); - handler.ClientCertificateOption = ClientCertificateOption.Manual; - using (var client = new HttpClient(handler)) - using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) {Version = HttpVersion.Version20 })) - { - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.True(_validationCallbackHistory.WasCalled); - - //ConfirmValidCertificate(System.Net.Test.Common.Configuration.Http.Host); - } - }, - async s => - { - using (Http2LoopbackConnection connection = await s.EstablishConnectionAsync().ConfigureAwait(false)) - { - int streamId = await connection.ReadRequestHeaderAsync(); - - await connection.SendDefaultResponseAsync(streamId); - } - }, new Http2Options { ClientCertificateRequired = false }); - } - private void ConfirmValidCertificate(string expectedHostName) { Assert.Equal(SslPolicyErrors.None, _validationCallbackHistory.SslPolicyErrors); @@ -161,62 +124,5 @@ private void ConfirmValidCertificate(string expectedHostName) _output.WriteLine("Certificate.Subject: {0}", _validationCallbackHistory.CertificateSubject); _output.WriteLine("Expected HostName: {0}", expectedHostName); } - - private bool CustomServerCertificateValidationCallback( - HttpRequestMessage sender, - X509Certificate2 certificate, - X509Chain chain, - SslPolicyErrors sslPolicyErrors) - { - _validationCallbackHistory.WasCalled = true; - _validationCallbackHistory.CertificateSubject = certificate.Subject; - foreach (var element in chain.ChainElements) - { - _validationCallbackHistory.CertificateChain.Add(element.Certificate); - } - _validationCallbackHistory.ChainStatus = chain.ChainStatus; - _validationCallbackHistory.SslPolicyErrors = sslPolicyErrors; - - if (_validationCallbackHistory.ThrowException) - { - throw new CustomException(); - } - - if (_validationCallbackHistory.ReturnFailure) - { - return false; - } - - return true; - } - - public class CustomException : Exception - { - public CustomException() - { - } - } - - public class ValidationCallbackHistory - { - public bool ThrowException; - public bool ReturnFailure; - public bool WasCalled; - public SslPolicyErrors SslPolicyErrors; - public string CertificateSubject; - public X509CertificateCollection CertificateChain; - public X509ChainStatus[] ChainStatus; - - public ValidationCallbackHistory() - { - ThrowException = false; - ReturnFailure = false; - WasCalled = false; - SslPolicyErrors = SslPolicyErrors.None; - CertificateSubject = null; - CertificateChain = new X509CertificateCollection(); - ChainStatus = null; - } - } } } 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 82e2835aa8995b..d29bc5ea2f2d2b 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 @@ -193,6 +193,10 @@ + + + + From 5f3bc1ecc1f3485719a029bad0fc0a22c399ca3c Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Wed, 4 Mar 2020 19:11:18 +0100 Subject: [PATCH 04/26] Fix Windows_NT net472 build --- .../System.Net.Http.WinHttpHandler.Functional.Tests.csproj | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 d29bc5ea2f2d2b..46a57364de4e7e 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 @@ -11,6 +11,7 @@ Common\System\Net\Configuration.Http.cs + @@ -193,9 +194,6 @@ - - - From 72005dc1ac1d6c3fa27b18b114b91a56ace3e0ea Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Fri, 6 Mar 2020 18:47:18 +0100 Subject: [PATCH 05/26] All existing WinHttpHandler tests are enabled for net472 --- .../System/Net/Http/ByteAtATimeContent.cs | 4 ++ .../System/Net/Http/DefaultCredentialsTest.cs | 7 +++- .../System/Net/Http/GenericLoopbackServer.cs | 2 +- .../tests/System/Net/Http/Http2Frames.cs | 9 +++++ .../Net/Http/Http2LoopbackConnection.cs | 40 ++++++++++++++++++- .../System/Net/Http/Http2LoopbackServer.cs | 11 ++++- .../HttpClientHandlerTest.AcceptAllCerts.cs | 6 +++ .../HttpClientHandlerTest.Cancellation.cs | 10 ++--- ...ttpClientHandlerTest.ClientCertificates.cs | 7 ++++ .../Net/Http/HttpClientHandlerTest.Cookies.cs | 7 ++++ .../HttpClientHandlerTest.Decompression.cs | 33 +++++++++++++-- .../HttpClientHandlerTest.SslProtocols.cs | 10 +++++ .../System/Net/Http/HttpClientHandlerTest.cs | 38 ++++++++++++++---- .../Net/Http/HttpClientHandlerTestBase.cs | 20 ++++++++-- .../System/Net/Http/HttpProtocolTests.cs | 15 ++++++- .../System/Net/Http/HttpRetryProtocolTests.cs | 7 +++- .../tests/System/Net/Http/LoopbackServer.cs | 7 +++- .../tests/System/Net/Http/QPackTestDecoder.cs | 36 ++++++++++++++++- .../System/Net/Http/ResponseStreamTest.cs | 6 +++ .../FunctionalTests/ClientCertificateTest.cs | 8 ++-- ...ttpClientHandlerTestBase.WinHttpHandler.cs | 3 +- .../FunctionalTests/PlatformHandlerTest.cs | 8 ++-- ...ttp.WinHttpHandler.Functional.Tests.csproj | 6 +-- 23 files changed, 258 insertions(+), 42 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/ByteAtATimeContent.cs b/src/libraries/Common/tests/System/Net/Http/ByteAtATimeContent.cs index 67a95370cbde11..8abd4e653797e2 100644 --- a/src/libraries/Common/tests/System/Net/Http/ByteAtATimeContent.cs +++ b/src/libraries/Common/tests/System/Net/Http/ByteAtATimeContent.cs @@ -33,7 +33,11 @@ protected override async Task SerializeToStreamAsync(Stream stream, TransportCon for (int i = 0; i < _length; i++) { buffer[0] = (byte)i; +#if !NETFRAMEWORK await stream.WriteAsync(buffer); +#else + await stream.WriteAsync(buffer, 0, buffer.Length); +#endif await stream.FlushAsync(); await Task.Delay(_millisecondDelayBetweenBytes); } diff --git a/src/libraries/Common/tests/System/Net/Http/DefaultCredentialsTest.cs b/src/libraries/Common/tests/System/Net/Http/DefaultCredentialsTest.cs index 40686b97bc519f..3c75f9d48a6ade 100644 --- a/src/libraries/Common/tests/System/Net/Http/DefaultCredentialsTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/DefaultCredentialsTest.cs @@ -335,7 +335,12 @@ private async Task ProcessRequests() // Send a response in the JSON format that the client expects string username = context.User.Identity.Name; - await context.Response.OutputStream.WriteAsync(System.Text.Encoding.UTF8.GetBytes($"{{\"authenticated\": \"true\", \"user\": \"{username}\" }}")); + byte[] bytes = System.Text.Encoding.UTF8.GetBytes($"{{\"authenticated\": \"true\", \"user\": \"{username}\" }}"); +#if !NETFRAMEWORK + await context.Response.OutputStream.WriteAsync(bytes); +#else + await context.Response.OutputStream.WriteAsync(bytes, 0, bytes.Length); +#endif context.Response.Close(); } diff --git a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs index 9e505e37314b63..779055b921e4dc 100644 --- a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs @@ -86,7 +86,7 @@ public class GenericLoopbackOptions public IPAddress Address { get; set; } = IPAddress.Loopback; public bool UseSsl { get; set; } = PlatformDetection.SupportsAlpn && !Capability.Http2ForceUnencryptedLoopback(); public SslProtocols SslProtocols { get; set; } = -#if !NETSTANDARD2_0 +#if !NETSTANDARD2_0 && !NETFRAMEWORK SslProtocols.Tls13 | #endif SslProtocols.Tls12; diff --git a/src/libraries/Common/tests/System/Net/Http/Http2Frames.cs b/src/libraries/Common/tests/System/Net/Http/Http2Frames.cs index 4fe0f5bddd9790..e0ec7580ebbbba 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2Frames.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2Frames.cs @@ -548,10 +548,19 @@ public override void WriteTo(Span buffer) BinaryPrimitives.WriteUInt16BigEndian(buffer, checked((ushort)Origin.Length)); buffer = buffer.Slice(2); +#if !NETFRAMEWORK Encoding.ASCII.GetBytes(Origin, buffer); buffer = buffer.Slice(Origin.Length); Encoding.ASCII.GetBytes(AltSvc, buffer); +#else + var tmpBuffer = Encoding.ASCII.GetBytes(Origin); + tmpBuffer.CopyTo(buffer); + buffer = buffer.Slice(Origin.Length); + + tmpBuffer = Encoding.ASCII.GetBytes(AltSvc); + tmpBuffer.CopyTo(buffer); +#endif } public override string ToString() => $"{base.ToString()}\n{nameof(Origin)}: {Origin}\n{nameof(AltSvc)}: {AltSvc}"; diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index cf98b8cd221773..b230b2ed5c08f1 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net.Http.Functional.Tests; using System.Net.Security; using System.Net.Sockets; @@ -40,6 +41,7 @@ public Http2LoopbackConnection(Socket socket, Http2Options httpOptions) using (var cert = Configuration.Certificates.GetServerCertificate()) { +#if !NETFRAMEWORK SslServerAuthenticationOptions options = new SslServerAuthenticationOptions(); options.EnabledSslProtocols = httpOptions.SslProtocols; @@ -54,6 +56,9 @@ public Http2LoopbackConnection(Socket socket, Http2Options httpOptions) options.ClientCertificateRequired = httpOptions.ClientCertificateRequired; sslStream.AuthenticateAsServerAsync(options, CancellationToken.None).Wait(); +#else + sslStream.AuthenticateAsServerAsync(cert, httpOptions.ClientCertificateRequired, httpOptions.SslProtocols, false).Wait(); +#endif } _connectionStream = sslStream; @@ -90,6 +95,7 @@ public async Task WriteFrameAsync(Frame frame) // Read until the buffer is full // Return false on EOF, throw on partial read +#if !NETFRAMEWORK private async Task FillBufferAsync(Memory buffer, CancellationToken cancellationToken = default(CancellationToken)) { int readBytes = await _connectionStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); @@ -112,11 +118,37 @@ public async Task WriteFrameAsync(Frame frame) return true; } +#else + private async Task FillBufferAsync(byte[] buffer, CancellationToken cancellationToken = default(CancellationToken)) + { + int readBytes = await _connectionStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); + if (readBytes == 0) + { + return false; + } + + buffer = buffer.Skip(readBytes).ToArray(); + while (buffer.Length > 0) + { + readBytes = await _connectionStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); + if (readBytes == 0) + { + throw new Exception("Connection closed when expecting more data."); + } + + buffer = buffer.Skip(readBytes).ToArray(); + } + + return true; + } +#endif public async Task ReadFrameAsync(TimeSpan timeout) { - using CancellationTokenSource timeoutCts = new CancellationTokenSource(timeout); - return await ReadFrameAsync(timeoutCts.Token).ConfigureAwait(false); + using (CancellationTokenSource timeoutCts = new CancellationTokenSource(timeout)) + { + return await ReadFrameAsync(timeoutCts.Token).ConfigureAwait(false); + } } private async Task ReadFrameAsync(CancellationToken cancellationToken) @@ -331,7 +363,11 @@ private static (int bytesConsumed, string value) DecodeString(ReadOnlySpan } else { +#if !NETFRAMEWORK string value = Encoding.ASCII.GetString(headerBlock.Slice(bytesConsumed, stringLength)); +#else + string value = Encoding.ASCII.GetString(headerBlock.Slice(bytesConsumed, stringLength).ToArray()); +#endif return (bytesConsumed + stringLength, value); } } diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs index 024dcedc890f64..b4b38ba3158ef8 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs @@ -244,7 +244,7 @@ public override async Task CreateServerAsync(Func HttpVersion.Version20; + public override Version Version => HttpVersion20.Value; } public enum ProtocolErrors @@ -264,4 +264,13 @@ public enum ProtocolErrors INADEQUATE_SECURITY = 0xc, HTTP_1_1_REQUIRED = 0xd } + + public static class HttpVersion20 + { +#if !NETFRAMEWORK + public static readonly Version Value = HttpVersion.Version20; +#else + public static readonly Version Value = new Version(2, 0); +#endif + } } 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 53d45add78b831..99ef96c4b645bc 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.AcceptAllCerts.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.AcceptAllCerts.cs @@ -39,8 +39,10 @@ public void SingletonReturnsTrue() [InlineData(SslProtocols.Tls, true)] [InlineData(SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls, false)] [InlineData(SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls, true)] +#if !NETFRAMEWORK [InlineData(SslProtocols.Tls13 | SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls, false)] [InlineData(SslProtocols.Tls13 | SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls, true)] +#endif [InlineData(SslProtocols.None, false)] [InlineData(SslProtocols.None, true)] public async Task SetDelegate_ConnectionSucceeds(SslProtocols acceptedProtocol, bool requestOnlyThisProtocol) @@ -64,7 +66,11 @@ public async Task SetDelegate_ConnectionSucceeds(SslProtocols acceptedProtocol, // restrictions on minimum TLS/SSL version // We currently know that some platforms like Debian 10 OpenSSL // will by default block < TLS 1.2 +#if !NETFRAMEWORK handler.SslProtocols = SslProtocols.Tls13 | SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls; +#else + handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls; +#endif } var options = new LoopbackServer.Options { UseSsl = true, SslProtocols = acceptedProtocol }; 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 d7e519fa202ed4..ce0b0b4823e2c7 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs @@ -33,7 +33,7 @@ public HttpClientHandler_Cancellation_Test(ITestOutputHelper output) : base(outp [InlineData(true, CancellationMode.Token)] public async Task PostAsync_CancelDuringRequestContentSend_TaskCanceledQuickly(bool chunkedTransfer, CancellationMode mode) { - if (LoopbackServerFactory.Version >= HttpVersion.Version20 && chunkedTransfer) + if (LoopbackServerFactory.Version >= HttpVersion20.Value && chunkedTransfer) { // There is no chunked encoding in HTTP/2 and later return; @@ -80,7 +80,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [MemberData(nameof(OneBoolAndCancellationMode))] public async Task GetAsync_CancelDuringResponseHeadersReceived_TaskCanceledQuickly(bool connectionClose, CancellationMode mode) { - if (LoopbackServerFactory.Version >= HttpVersion.Version20 && connectionClose) + if (LoopbackServerFactory.Version >= HttpVersion20.Value && connectionClose) { // There is no Connection header in HTTP/2 and later return; @@ -130,7 +130,7 @@ await ValidateClientCancellationAsync(async () => [MemberData(nameof(TwoBoolsAndCancellationMode))] public async Task GetAsync_CancelDuringResponseBodyReceived_Buffered_TaskCanceledQuickly(bool chunkedTransfer, bool connectionClose, CancellationMode mode) { - if (LoopbackServerFactory.Version >= HttpVersion.Version20 && (chunkedTransfer || connectionClose)) + if (LoopbackServerFactory.Version >= HttpVersion20.Value && (chunkedTransfer || connectionClose)) { // There is no chunked encoding or connection header in HTTP/2 and later return; @@ -186,7 +186,7 @@ await ValidateClientCancellationAsync(async () => [MemberData(nameof(ThreeBools))] public async Task GetAsync_CancelDuringResponseBodyReceived_Unbuffered_TaskCanceledQuickly(bool chunkedTransfer, bool connectionClose, bool readOrCopyToAsync) { - if (LoopbackServerFactory.Version >= HttpVersion.Version20 && (chunkedTransfer || connectionClose)) + if (LoopbackServerFactory.Version >= HttpVersion20.Value && (chunkedTransfer || connectionClose)) { // There is no chunked encoding or connection header in HTTP/2 and later return; @@ -312,7 +312,7 @@ await LoopbackServerFactory.CreateServerAsync(async (server, url) => [ConditionalFact] public async Task MaxConnectionsPerServer_WaitingConnectionsAreCancelable() { - if (LoopbackServerFactory.Version >= HttpVersion.Version20) + if (LoopbackServerFactory.Version >= HttpVersion20.Value) { // HTTP/2 does not use connection limits. throw new SkipTestException("Not supported on HTTP/2 and later"); diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ClientCertificates.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ClientCertificates.cs index b75156a6f2556c..1e95c1289ede16 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ClientCertificates.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ClientCertificates.cs @@ -73,6 +73,9 @@ private HttpClient CreateHttpClientWithCert(X509Certificate2 cert) handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates; Assert.NotNull(cert); handler.ClientCertificates.Add(cert); +//#if WINHTTPHANDLER_TEST + handler.ClientCertificateOption = ClientCertificateOption.Manual; +//#endif Assert.True(handler.ClientCertificates.Contains(cert)); return CreateHttpClient(handler); @@ -111,9 +114,13 @@ await TestHelper.WhenAllCompletedOrAnyFailed( SslStream sslStream = Assert.IsType(connection.Stream); if (serverExpectsClientCertificate) { +#if !NETFRAMEWORK _output.WriteLine( "Client cert: {0}", ((X509Certificate2)sslStream.RemoteCertificate).GetNameInfo(X509NameType.SimpleName, false)); +#else + _output.WriteLine("Client cert: {0}", sslStream.RemoteCertificate.Subject); +#endif Assert.Equal(cert, sslStream.RemoteCertificate); } else diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs index 75f440ac1bcdc9..aeadabf1de24e1 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs @@ -182,7 +182,11 @@ await LoopbackServerFactory.CreateClientAndServerAsync( private string GetCookieValue(HttpRequestData request) { +#if !NETFRAMEWORK if (LoopbackServerFactory.Version < HttpVersion.Version20) +#else + if (LoopbackServerFactory.Version < HttpVersion20.Value) +#endif { // HTTP/1.x must have only one value. return request.GetSingleHeaderValue("Cookie"); @@ -334,6 +338,7 @@ await LoopbackServerFactory.CreateServerAsync(async (server, url) => using (HttpClient client = CreateHttpClient(handler)) { + //System.Diagnostics.Debugger.Launch(); Task getResponseTask = client.GetAsync(url); Task serverTask = server.HandleRequestAsync( HttpStatusCode.OK, new HttpHeaderData[] { new HttpHeaderData("Set-Cookie", GetCookieHeaderValue(cookieName, cookieValue)) }, s_simpleContent); @@ -603,7 +608,9 @@ public static IEnumerable CookieNamesValuesAndUseCookies() yield return new object[] { "ABC", "123", useCookies }; yield return new object[] { "Hello", "World", useCookies }; yield return new object[] { "foo", "bar", useCookies }; +#if !WINHTTPHANDLER_TEST yield return new object[] { "Hello World", "value", useCookies }; +#endif yield return new object[] { ".AspNetCore.Session", "RAExEmXpoCbueP_QYM", useCookies }; yield return new object[] diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs index 0fb03c3e612b8c..c0afd4463f12a3 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs @@ -22,6 +22,11 @@ namespace System.Net.Http.Functional.Tests public abstract class HttpClientHandler_Decompression_Test : HttpClientHandlerTestBase { +#if !NETFRAMEWORK + private static readonly DecompressionMethods _all = DecompressionMethods.All; +#else + private static readonly DecompressionMethods _all = DecompressionMethods.Deflate | DecompressionMethods.GZip; +#endif public HttpClientHandler_Decompression_Test(ITestOutputHelper output) : base(output) { } public static IEnumerable RemoteServersAndCompressionUris() @@ -41,20 +46,22 @@ public static IEnumerable DecompressedResponse_MethodSpecified_Decompr { "deflate", new Func(s => new DeflateStream(s, CompressionLevel.Optimal, leaveOpen: true)), - specifyAllMethods ? DecompressionMethods.Deflate : DecompressionMethods.All + specifyAllMethods ? DecompressionMethods.Deflate : _all }; yield return new object[] { "gzip", new Func(s => new GZipStream(s, CompressionLevel.Optimal, leaveOpen: true)), - specifyAllMethods ? DecompressionMethods.GZip : DecompressionMethods.All + specifyAllMethods ? DecompressionMethods.GZip : _all }; +#if !NETFRAMEWORK yield return new object[] { "br", new Func(s => new BrotliStream(s, CompressionLevel.Optimal, leaveOpen: true)), - specifyAllMethods ? DecompressionMethods.Brotli : DecompressionMethods.All + specifyAllMethods ? DecompressionMethods.Brotli : _all }; +#endif } } @@ -88,7 +95,11 @@ await server.AcceptConnectionAsync(async connection => await connection.Writer.WriteAsync($"HTTP/1.1 200 OK\r\nContent-Encoding: {encodingName}\r\n\r\n"); using (Stream compressedStream = compress(connection.Stream)) { +#if !NETFRAMEWORK await compressedStream.WriteAsync(expectedContent); +#else + await compressedStream.WriteAsync(expectedContent, 0, expectedContent.Length); +#endif } }); }); @@ -102,6 +113,7 @@ public static IEnumerable DecompressedResponse_MethodNotSpecified_Orig new Func(s => new DeflateStream(s, CompressionLevel.Optimal, leaveOpen: true)), DecompressionMethods.None }; +#if !NETFRAMEWORK yield return new object[] { "gzip", @@ -114,6 +126,7 @@ public static IEnumerable DecompressedResponse_MethodNotSpecified_Orig new Func(s => new BrotliStream(s, CompressionLevel.Optimal, leaveOpen: true)), DecompressionMethods.Deflate | DecompressionMethods.GZip }; +#endif } [Theory] @@ -127,7 +140,11 @@ public async Task DecompressedResponse_MethodNotSpecified_OriginalContentReturne var compressedContentStream = new MemoryStream(); using (Stream s = compress(compressedContentStream)) { +#if !NETFRAMEWORK await s.WriteAsync(expectedContent); +#else + await s.WriteAsync(expectedContent, 0, expectedContent.Length); +#endif } byte[] compressedContent = compressedContentStream.ToArray(); @@ -144,8 +161,14 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => await server.AcceptConnectionAsync(async connection => { await connection.ReadRequestHeaderAsync(); - await connection.Writer.WriteAsync($"HTTP/1.1 200 OK\r\nContent-Encoding: {encodingName}\r\n\r\n"); + string text = $"HTTP/1.1 200 OK\r\nContent-Encoding: {encodingName}\r\n\r\n"; +#if !NETFRAMEWORK + await connection.Writer.WriteAsync(text); await connection.Stream.WriteAsync(compressedContent); +#else + await connection.Writer.WriteAsync(text.ToCharArray(), 0, text.Length); + await connection.Stream.WriteAsync(compressedContent, 0, compressedContent.Length); +#endif }); }); } @@ -189,10 +212,12 @@ public async Task GetAsync_SetAutomaticDecompression_HeadersRemoved(Configuratio } [Theory] +#if NETCORE [InlineData(DecompressionMethods.Brotli, "br", "")] [InlineData(DecompressionMethods.Brotli, "br", "br")] [InlineData(DecompressionMethods.Brotli, "br", "gzip")] [InlineData(DecompressionMethods.Brotli, "br", "gzip, deflate")] +#endif [InlineData(DecompressionMethods.GZip, "gzip", "")] [InlineData(DecompressionMethods.Deflate, "deflate", "")] [InlineData(DecompressionMethods.GZip | DecompressionMethods.Deflate, "gzip, deflate", "")] diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs index b6bf8b5143c2cf..b264aa6bc6c5d9 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs @@ -43,11 +43,13 @@ public void DefaultProtocols_MatchesExpected() [InlineData(SslProtocols.Tls11 | SslProtocols.Tls12)] [InlineData(SslProtocols.Tls | SslProtocols.Tls12)] [InlineData(SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12)] +#if !NETFRAMEWORK [InlineData(SslProtocols.Tls13)] [InlineData(SslProtocols.Tls11 | SslProtocols.Tls13)] [InlineData(SslProtocols.Tls12 | SslProtocols.Tls13)] [InlineData(SslProtocols.Tls | SslProtocols.Tls13)] [InlineData(SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13)] +#endif public void SetGetProtocols_Roundtrips(SslProtocols protocols) { using (HttpClientHandler handler = CreateHttpClientHandler()) @@ -90,7 +92,9 @@ public static IEnumerable GetAsync_AllowedSSLVersion_Succeeds_MemberDa #pragma warning disable 0618 if (PlatformDetection.SupportsSsl3) { +#if !NETFRAMEWORK yield return new object[] { SslProtocols.Ssl3, true }; +#endif } if (PlatformDetection.IsWindows && !PlatformDetection.IsWindows10Version1607OrGreater) { @@ -100,8 +104,10 @@ public static IEnumerable GetAsync_AllowedSSLVersion_Succeeds_MemberDa // These protocols are new, and might not be enabled everywhere yet if (PlatformDetection.IsUbuntu1810OrHigher) { +#if !NETFRAMEWORK yield return new object[] { SslProtocols.Tls13, false }; yield return new object[] { SslProtocols.Tls13, true }; +#endif } } @@ -124,7 +130,11 @@ public async Task GetAsync_AllowedSSLVersion_Succeeds(SslProtocols acceptedProto // restrictions on minimum TLS/SSL version // We currently know that some platforms like Debian 10 OpenSSL // will by default block < TLS 1.2 +#if !NETFRAMEWORK handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13; +#else + handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12; +#endif } var options = new LoopbackServer.Options { UseSsl = true, SslProtocols = acceptedProtocol }; diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 9902da13afb180..df88979e7fae29 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -479,7 +479,7 @@ public static IEnumerable SecureAndNonSecure_IPBasedUri_MemberData() = [MemberData(nameof(SecureAndNonSecure_IPBasedUri_MemberData))] public async Task GetAsync_SecureAndNonSecureIPBasedUri_CorrectlyFormatted(IPAddress address, bool useSsl) { - if (LoopbackServerFactory.Version >= HttpVersion.Version20) + if (LoopbackServerFactory.Version >= HttpVersion20.Value) { throw new SkipTestException("Host header is not supported on HTTP/2 and later."); } @@ -871,7 +871,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Equal("X-Underscore_Name", requestData.GetSingleHeaderValue("X-Underscore_Name")); Assert.Equal("End", requestData.GetSingleHeaderValue("X-End")); - if (LoopbackServerFactory.Version >= HttpVersion.Version20) + if (LoopbackServerFactory.Version >= HttpVersion20.Value) { // HTTP/2 and later forbids certain headers or values. Assert.Equal("trailers", requestData.GetSingleHeaderValue("TE")); @@ -904,7 +904,7 @@ public static IEnumerable GetAsync_ManyDifferentResponseHeaders_Parsed [MemberData(nameof(GetAsync_ManyDifferentResponseHeaders_ParsedCorrectly_MemberData))] public async Task GetAsync_ManyDifferentResponseHeaders_ParsedCorrectly(string newline, string fold, bool dribble) { - if (LoopbackServerFactory.Version >= HttpVersion.Version20) + if (LoopbackServerFactory.Version >= HttpVersion20.Value) { throw new SkipTestException("Folding is not supported on HTTP/2 and later."); } @@ -1035,7 +1035,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => [ConditionalFact] public async Task GetAsync_NonTraditionalChunkSizes_Accepted() { - if (LoopbackServerFactory.Version >= HttpVersion.Version20) + if (LoopbackServerFactory.Version >= HttpVersion20.Value) { throw new SkipTestException("Chunking is not supported on HTTP/2 and later."); } @@ -1259,7 +1259,7 @@ await connection.ReadRequestHeaderAndSendCustomResponseAsync( [InlineData(null)] public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(bool? chunked) { - if (LoopbackServerFactory.Version >= HttpVersion.Version20 && chunked == true) + if (LoopbackServerFactory.Version >= HttpVersion20.Value && chunked == true) { throw new SkipTestException("Chunking is not supported on HTTP/2 and later."); } @@ -1287,8 +1287,10 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Throws(() => responseStream.Seek(0, SeekOrigin.Begin)); Assert.Throws(() => responseStream.SetLength(0)); Assert.Throws(() => responseStream.Write(new byte[1], 0, 1)); +#if !NETFRAMEWORK Assert.Throws(() => responseStream.Write(new Span(new byte[1]))); Assert.Throws(() => { responseStream.WriteAsync(new Memory(new byte[1])); }); +#endif Assert.Throws(() => { responseStream.WriteAsync(new byte[1], 0, 1); }); Assert.Throws(() => responseStream.WriteByte(1)); @@ -1328,13 +1330,21 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Equal(1, await Task.Factory.FromAsync(responseStream.BeginRead, responseStream.EndRead, buffer, 0, 1, null)); Assert.Equal((byte)'e', buffer[0]); +#if !NETFRAMEWORK Assert.Equal(1, await responseStream.ReadAsync(new Memory(buffer))); +#else + Assert.Equal(1, await responseStream.ReadAsync(buffer, 0, 1)); +#endif Assert.Equal((byte)'l', buffer[0]); Assert.Equal(1, await responseStream.ReadAsync(buffer, 0, 1)); Assert.Equal((byte)'l', buffer[0]); +#if !NETFRAMEWORK Assert.Equal(1, responseStream.Read(new Span(buffer))); +#else + Assert.Equal(1, await responseStream.ReadAsync(buffer, 0, 1)); +#endif Assert.Equal((byte)'o', buffer[0]); Assert.Equal(1, responseStream.Read(buffer, 0, 1)); @@ -1342,9 +1352,13 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => // Doing any of these 0-byte reads causes the connection to fail. Assert.Equal(0, await Task.Factory.FromAsync(responseStream.BeginRead, responseStream.EndRead, Array.Empty(), 0, 0, null)); +#if !NETFRAMEWORK Assert.Equal(0, await responseStream.ReadAsync(Memory.Empty)); +#endif Assert.Equal(0, await responseStream.ReadAsync(Array.Empty(), 0, 0)); +#if !NETFRAMEWORK Assert.Equal(0, responseStream.Read(Span.Empty)); +#endif Assert.Equal(0, responseStream.Read(Array.Empty(), 0, 0)); // And copying @@ -1359,9 +1373,13 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Equal(0, ms.Length); Assert.Equal(-1, responseStream.ReadByte()); Assert.Equal(0, responseStream.Read(buffer, 0, 1)); +#if !NETFRAMEWORK Assert.Equal(0, responseStream.Read(new Span(buffer))); +#endif Assert.Equal(0, await responseStream.ReadAsync(buffer, 0, 1)); +#if !NETFRAMEWORK Assert.Equal(0, await responseStream.ReadAsync(new Memory(buffer))); +#endif Assert.Equal(0, await Task.Factory.FromAsync(responseStream.BeginRead, responseStream.EndRead, buffer, 0, 1, null)); } } @@ -1416,8 +1434,10 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Throws(() => responseStream.Seek(0, SeekOrigin.Begin)); Assert.Throws(() => responseStream.SetLength(0)); Assert.Throws(() => responseStream.Write(new byte[1], 0, 1)); +#if !NETFRAMEWORK Assert.Throws(() => responseStream.Write(new Span(new byte[1]))); await Assert.ThrowsAsync(async () => await responseStream.WriteAsync(new Memory(new byte[1]))); +#endif await Assert.ThrowsAsync(async () => await responseStream.WriteAsync(new byte[1], 0, 1)); Assert.Throws(() => responseStream.WriteByte(1)); @@ -1454,9 +1474,13 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => var buffer = new byte[1]; Assert.Equal(-1, responseStream.ReadByte()); Assert.Equal(0, await Task.Factory.FromAsync(responseStream.BeginRead, responseStream.EndRead, buffer, 0, 1, null)); +#if !NETFRAMEWORK Assert.Equal(0, await responseStream.ReadAsync(new Memory(buffer))); +#endif Assert.Equal(0, await responseStream.ReadAsync(buffer, 0, 1)); +#if !NETFRAMEWORK Assert.Equal(0, responseStream.Read(new Span(buffer))); +#endif Assert.Equal(0, responseStream.Read(buffer, 0, 1)); // Empty copies @@ -2068,7 +2092,7 @@ public async Task SendAsync_101SwitchingProtocolsResponse_Success() return; } - if (LoopbackServerFactory.Version >= HttpVersion.Version20) + if (LoopbackServerFactory.Version >= HttpVersion20.Value) { throw new SkipTestException("Upgrade is not supported on HTTP/2 and later"); } @@ -2238,7 +2262,7 @@ public async Task PostAsync_ReuseRequestContent_Success(Configuration.Http.Remot [InlineData(HttpStatusCode.MethodNotAllowed, "")] public async Task GetAsync_CallMethod_ExpectedStatusLine(HttpStatusCode statusCode, string reasonPhrase) { - if (LoopbackServerFactory.Version >= HttpVersion.Version20) + if (LoopbackServerFactory.Version >= HttpVersion20.Value) { // Custom messages are not supported on HTTP2 and later. return; diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs index 83308747801bf0..003e344d74042a 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs @@ -32,13 +32,21 @@ public HttpClientHandlerTestBase(ITestOutputHelper output) protected virtual HttpClient CreateHttpClient() => CreateHttpClient(CreateHttpClientHandler()); protected HttpClient CreateHttpClient(HttpMessageHandler handler) => - new HttpClient(handler) { DefaultRequestVersion = UseVersion }; + new HttpClient(handler) { +#if !NETFRAMEWORK + DefaultRequestVersion = UseVersion +#endif + }; protected static HttpClient CreateHttpClient(string useVersionString) => CreateHttpClient(CreateHttpClientHandler(useVersionString), useVersionString); protected static HttpClient CreateHttpClient(HttpMessageHandler handler, string useVersionString) => - new HttpClient(handler) { DefaultRequestVersion = Version.Parse(useVersionString) }; + new HttpClient(handler) { +#if !NETFRAMEWORK + DefaultRequestVersion = Version.Parse(useVersionString) +#endif + }; protected HttpClientHandler CreateHttpClientHandler() => CreateHttpClientHandler(UseVersion); @@ -51,7 +59,7 @@ protected static LoopbackServerFactory GetFactoryForVersion(Version useVersion) { return useVersion.Major switch { -#if NETCOREAPP +#if NETCOREAPP || WINHTTPHANDLER_TEST #if HTTP3 3 => Http3LoopbackServerFactory.Singleton, #endif @@ -81,7 +89,11 @@ protected HttpClient CreateHttpClientForRemoteServer(Configuration.Http.RemoteSe wrappedHandler = new VersionCheckerHttpHandler(httpClientHandler, remoteServer.HttpVersion); } - return new HttpClient(wrappedHandler) { DefaultRequestVersion = remoteServer.HttpVersion }; + return new HttpClient(wrappedHandler) { +#if !NETFRAMEWORK + DefaultRequestVersion = remoteServer.HttpVersion +#endif + }; } private sealed class VersionCheckerHttpHandler : DelegatingHandler diff --git a/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs b/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs index 62a46c21b0afc5..6fb1280c8da53b 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs @@ -467,7 +467,11 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => { byte[] buffer = new byte[4096]; int bytesRead; +#if !NETFRAMEWORK while ((bytesRead = await respStream.ReadAsync(buffer)) > 0) +#else + while ((bytesRead = await respStream.ReadAsync(buffer, 0, buffer.Length)) > 0) +#endif { actualData.Write(buffer, 0, bytesRead); } @@ -481,13 +485,22 @@ await server.AcceptConnectionAsync(async connection => { await connection.ReadRequestHeaderAsync(); - await connection.Writer.WriteAsync($"HTTP/1.1 200 OK{lineEnding}Transfer-Encoding: chunked{lineEnding}{lineEnding}"); + string text = $"HTTP/1.1 200 OK{lineEnding}Transfer-Encoding: chunked{lineEnding}{lineEnding}"; +#if !NETFRAMEWORK + await connection.Writer.WriteAsync(text); +#else + await connection.Writer.WriteAsync(text.ToCharArray(), 0, text.Length); +#endif for (int bytesSent = 0; bytesSent < expectedData.Length;) { int bytesRemaining = expectedData.Length - bytesSent; int bytesToSend = rand.Next(1, Math.Min(bytesRemaining, maxChunkSize + 1)); await connection.Writer.WriteAsync(bytesToSend.ToString("X") + lineEnding); +#if !NETFRAMEWORK await connection.Stream.WriteAsync(new Memory(expectedData, bytesSent, bytesToSend)); +#else + await connection.Stream.WriteAsync(expectedData, bytesSent, bytesToSend); +#endif await connection.Writer.WriteAsync(lineEnding); bytesSent += bytesToSend; } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpRetryProtocolTests.cs b/src/libraries/Common/tests/System/Net/Http/HttpRetryProtocolTests.cs index 8f6808e17da10d..31d915e83566c4 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpRetryProtocolTests.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpRetryProtocolTests.cs @@ -130,7 +130,12 @@ protected override async Task SerializeToStreamAsync(Stream stream, TransportCon { _sendingContent.SetResult(true); await _connectionClosed; - await stream.WriteAsync(Encoding.UTF8.GetBytes(_longContent)); + byte[] bytes = Encoding.UTF8.GetBytes(_longContent); +#if !NETFRAMEWORK + await stream.WriteAsync(bytes); +#else + await stream.WriteAsync(bytes, 0, bytes.Length); +#endif } protected override bool TryComputeLength(out long length) diff --git a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs index 6433f539c0dc63..48d75c889b1718 100644 --- a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs @@ -394,7 +394,7 @@ public Options() { UseSsl = false; SslProtocols = -#if !NETSTANDARD2_0 +#if !NETSTANDARD2_0 && !NETFRAMEWORK SslProtocols.Tls13 | #endif SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12; @@ -451,6 +451,11 @@ public async Task ReadAsync(Memory buffer, int offset, int size) } return readLength; +#elif NETFRAMEWORK + var tmpBuffer = new byte[buffer.Length]; + int readBytes = await _stream.ReadAsync(tmpBuffer, offset, size).ConfigureAwait(false); + tmpBuffer.CopyTo(buffer); + return readBytes; #else return await _stream.ReadAsync(buffer.Slice(offset, size)).ConfigureAwait(false); #endif diff --git a/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs b/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs index da276e1ce9d654..c3cbd9c98e89c8 100644 --- a/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs +++ b/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Linq; using System.Numerics; using System.Text; @@ -72,7 +73,12 @@ private static (int bytesConsumed, string value) DecodeString(ReadOnlySpan } (int varIntLength, int stringLength) = DecodeInteger(buffer, prefixMask); - string value = Encoding.ASCII.GetString(buffer.Slice(varIntLength, stringLength)); +#if !NETFRAMEWORK + ReadOnlySpan bytes = buffer.Slice(varIntLength, stringLength); +#else + byte[] bytes = buffer.Slice(varIntLength, stringLength).ToArray(); +#endif + string value = Encoding.ASCII.GetString(bytes); return (varIntLength + stringLength, value); } @@ -203,6 +209,32 @@ public static (int bytesConsumed, int value) DecodeInteger(ReadOnlySpan he new HttpHeaderData("x-frame-options", "deny"), new HttpHeaderData("x-frame-options", "sameorigin"), }; - } +//#if NETFRAMEWORK + private static class BitOperations + { + public static int LeadingZeroCount(byte value) + { + int count = 0; + while ((value & 0b1000_0000) != 0) + { + count++; + value <<= 1; + } + return count; + } + + public static int TrailingZeroCount(int value) + { + int count = 0; + while ((value & 1) != 0) + { + count++; + value >>= 1; + } + return count; + } + } +//#endif + } } diff --git a/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs b/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs index 8df08a7282145c..23325dd0f7752d 100644 --- a/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs @@ -80,7 +80,11 @@ public async Task GetStreamAsync_ReadToEnd_Success(Configuration.Http.RemoteServ case 4: // Individual calls to Read(Span) +#if !NETFRAMEWORK while ((bytesRead = stream.Read(new Span(buffer))) != 0) +#else + while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0) +#endif { ms.Write(buffer, 0, bytesRead); } @@ -173,7 +177,9 @@ public async Task GetStreamAsync_ReadZeroBytes_Success(Configuration.Http.Remote using (Stream stream = await client.GetStreamAsync(remoteServer.EchoUri)) { Assert.Equal(0, stream.Read(new byte[1], 0, 0)); +#if !NETFRAMEWORK Assert.Equal(0, stream.Read(new Span(new byte[1], 0, 0))); +#endif Assert.Equal(0, await stream.ReadAsync(new byte[1], 0, 0)); } } diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs index a6c90bec573f96..a210b7294a0036 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs @@ -26,7 +26,7 @@ await LoopbackServer.CreateClientAndServerAsync( handler.ClientCertificates.Add(clientCert); handler.ClientCertificateOption = ClientCertificateOption.Manual; using (var client = new HttpClient(handler)) - using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion.Version20 })) + using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion20.Value })) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.True(_validationCallbackHistory.WasCalled); @@ -59,7 +59,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync( handler.ClientCertificates.Add(clientCert); handler.ClientCertificateOption = ClientCertificateOption.Manual; using (var client = new HttpClient(handler)) - using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion.Version20 })) + using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion20.Value })) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.True(_validationCallbackHistory.WasCalled); @@ -91,7 +91,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync( var handler = new WinHttpHandler(); handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; using (var client = new HttpClient(handler)) - using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion.Version20 })) + using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion20.Value })) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.True(_validationCallbackHistory.WasCalled); @@ -111,7 +111,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync( int streamId = await connection.ReadRequestHeaderAsync(); await connection.SendDefaultResponseAsync(streamId); } - }, new Http2Options { ClientCertificateRequired = true }); + }, new Http2Options { ClientCertificateRequired = false }); } } } 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 d1798cdf032571..bc70113ebe5b26 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 @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Net.Test.Common; using System.IO; namespace System.Net.Http.Functional.Tests @@ -16,7 +17,7 @@ protected static WinHttpClientHandler CreateHttpClientHandler(Version useVersion WinHttpClientHandler handler = new WinHttpClientHandler(); - if (useVersion >= HttpVersion.Version20) + if (useVersion >= HttpVersion20.Value) { handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates; } 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 a871abc502df40..b18b2620ca0341 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs @@ -194,14 +194,16 @@ public PlatformHandler_HttpClientHandler_Authentication_Test(ITestOutputHelper o // Enable this to run HTTP2 tests on platform handler #if PLATFORM_HANDLER_HTTP2_TESTS - public sealed class PlatformHandlerTest_Http2 : HttpClientHandlerTest_Http2 + /*public sealed class PlatformHandlerTest_Http2 : HttpClientHandlerTest_Http2 { - } + }*/ [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.SupportsAlpn))] public sealed class PlatformHandlerTest_Cookies_Http2 : HttpClientHandlerTest_Cookies { - protected override bool UseHttp2LoopbackServer => true; + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandlerTest_Cookies_Http2(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 46a57364de4e7e..3286c2847532ce 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 @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT true @@ -14,9 +14,7 @@ - - - + Common\System\Net\Http\HttpHandlerDefaults.cs From 1ba5d40a6f7bfd41c540bec68b6bb916d9a7ebb7 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Fri, 6 Mar 2020 18:53:44 +0100 Subject: [PATCH 06/26] Manual_CertificateOnlySentWhenValid_Success works on all frameworks --- .../Net/Http/HttpClientHandlerTest.ClientCertificates.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ClientCertificates.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ClientCertificates.cs index 1e95c1289ede16..2ae15c8065d23c 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ClientCertificates.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ClientCertificates.cs @@ -114,13 +114,9 @@ await TestHelper.WhenAllCompletedOrAnyFailed( SslStream sslStream = Assert.IsType(connection.Stream); if (serverExpectsClientCertificate) { -#if !NETFRAMEWORK _output.WriteLine( "Client cert: {0}", - ((X509Certificate2)sslStream.RemoteCertificate).GetNameInfo(X509NameType.SimpleName, false)); -#else - _output.WriteLine("Client cert: {0}", sslStream.RemoteCertificate.Subject); -#endif + new X509Certificate2(sslStream.RemoteCertificate.Export(X509ContentType.Cert)).GetNameInfo(X509NameType.SimpleName, false)); Assert.Equal(cert, sslStream.RemoteCertificate); } else From 7ca1af2591abcb6e615383fd20e60bc9a4383d7b Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Mon, 9 Mar 2020 13:49:04 +0100 Subject: [PATCH 07/26] Fix build Skip cookie with a space test case on .Net Framework only --- .../Net/Http/HttpClientHandlerTest.ClientCertificates.cs | 3 --- .../tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ClientCertificates.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ClientCertificates.cs index 2ae15c8065d23c..a17334e247f328 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ClientCertificates.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ClientCertificates.cs @@ -73,9 +73,6 @@ private HttpClient CreateHttpClientWithCert(X509Certificate2 cert) handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates; Assert.NotNull(cert); handler.ClientCertificates.Add(cert); -//#if WINHTTPHANDLER_TEST - handler.ClientCertificateOption = ClientCertificateOption.Manual; -//#endif Assert.True(handler.ClientCertificates.Contains(cert)); return CreateHttpClient(handler); diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs index aeadabf1de24e1..63fba8a6214798 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs @@ -608,7 +608,7 @@ public static IEnumerable CookieNamesValuesAndUseCookies() yield return new object[] { "ABC", "123", useCookies }; yield return new object[] { "Hello", "World", useCookies }; yield return new object[] { "foo", "bar", useCookies }; -#if !WINHTTPHANDLER_TEST +#if !NETFRAMEWORK yield return new object[] { "Hello World", "value", useCookies }; #endif yield return new object[] { ".AspNetCore.Session", "RAExEmXpoCbueP_QYM", useCookies }; From 2a01fc661cbe2536be005ee0e31b9a7e4843d691 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Mon, 9 Mar 2020 17:45:18 +0100 Subject: [PATCH 08/26] Fix UseClientCertOnHttp2_OSSupportsItButCertNotSet_SuccessWithOneWayAuth for older Windows and net472 --- .../FunctionalTests/ClientCertificateTest.cs | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs index a210b7294a0036..eb07c9d4cda99a 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs @@ -82,7 +82,39 @@ await Http2LoopbackServer.CreateClientAndServerAsync( }, new Http2Options { ClientCertificateRequired = true }); } - [Fact] +#if NETFRAMEWORK + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))] + public async Task UseClientCertOnHttp2_OSSupportsItButCertNotSet_SuccessWithOneWayAuth() + { + await LoopbackServer.CreateClientAndServerAsync( + async address => + { + var handler = new WinHttpHandler(); + handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; + using (var client = new HttpClient(handler)) + using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion20.Value })) + { + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.True(_validationCallbackHistory.WasCalled); + Assert.NotEmpty(_validationCallbackHistory.CertificateChain); + Assert.Equal(Test.Common.Configuration.Certificates.GetServerCertificate(), _validationCallbackHistory.CertificateChain[0]); + } + }, + async s => + { + using (LoopbackServer.Connection connection = await s.EstablishConnectionAsync().ConfigureAwait(false)) + { + SslStream sslStream = connection.Stream as SslStream; + Assert.NotNull(sslStream); + Assert.False(sslStream.IsMutuallyAuthenticated); + Assert.Null(sslStream.RemoteCertificate); + + await connection.ReadRequestHeaderAndSendResponseAsync(HttpStatusCode.OK); + } + }, new LoopbackServer.Options { UseSsl = true }); + } +#else + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))] public async Task UseClientCertOnHttp2_OSSupportsItButCertNotSet_SuccessWithOneWayAuth() { await Http2LoopbackServer.CreateClientAndServerAsync( @@ -113,5 +145,6 @@ await Http2LoopbackServer.CreateClientAndServerAsync( } }, new Http2Options { ClientCertificateRequired = false }); } +#endif } } From ed354d935749086ff4bd6973fcb6f590bd1fd50e Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Thu, 12 Mar 2020 18:58:52 +0100 Subject: [PATCH 09/26] All HTTP 1.1 tests enabled for WinHttpHandler on all platforms HTTP/2 tests enabled for .Net Core only --- .../Net/Http/Http2LoopbackConnection.cs | 4 + .../FunctionalTests/BaseCertificateTest.cs | 14 +- .../FunctionalTests/ClientCertificateTest.cs | 91 +++------ ...ttpClientHandlerTestBase.WinHttpHandler.cs | 2 +- .../FunctionalTests/PlatformHandlerTest.cs | 184 +++++++++++++++++- .../FunctionalTests/ServerCertificateTest.cs | 16 +- .../FunctionalTests/WinHttpClientHandler.cs | 11 +- 7 files changed, 238 insertions(+), 84 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index b230b2ed5c08f1..7baa4356417334 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -69,6 +69,10 @@ public Http2LoopbackConnection(Socket socket, Http2Options httpOptions) { throw new Exception("Connection stream closed while attempting to read connection preface."); } + else if (Text.Encoding.ASCII.GetString(_prefix).Contains("HTTP/1.1")) + { + throw new Exception("HTTP 1.1 request received."); + } } public async Task SendConnectionPrefaceAsync() diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/BaseCertificateTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/BaseCertificateTest.cs index f1e348db4aa655..58ebefb99dc540 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/BaseCertificateTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/BaseCertificateTest.cs @@ -4,16 +4,20 @@ using System.Net.Security; using System.Security.Cryptography.X509Certificates; +using Xunit; using Xunit.Abstractions; namespace System.Net.Http.WinHttpHandlerFunctional.Tests { public abstract class BaseCertificateTest { + private readonly ITestOutputHelper _output; + protected readonly ValidationCallbackHistory _validationCallbackHistory; - public BaseCertificateTest() + public BaseCertificateTest(ITestOutputHelper output) { + _output = output; _validationCallbackHistory = new ValidationCallbackHistory(); } @@ -67,6 +71,14 @@ protected bool CustomServerCertificateValidationCallback( return true; } + protected void ConfirmValidCertificate(string expectedHostName) + { + Assert.Equal(SslPolicyErrors.None, _validationCallbackHistory.SslPolicyErrors); + Assert.True(_validationCallbackHistory.CertificateChain.Count > 0); + _output.WriteLine("Certificate.Subject: {0}", _validationCallbackHistory.CertificateSubject); + _output.WriteLine("Expected HostName: {0}", expectedHostName); + } + public class CustomException : Exception { public CustomException() diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs index eb07c9d4cda99a..9dfdeefe8a9a9f 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ClientCertificateTest.cs @@ -5,8 +5,11 @@ using System.Net.Security; using System.Net.Test.Common; using System.Security.Cryptography.X509Certificates; +using System.Threading; using System.Threading.Tasks; +using Newtonsoft.Json; using Xunit; +using Xunit.Abstractions; namespace System.Net.Http.WinHttpHandlerFunctional.Tests { @@ -14,6 +17,9 @@ public class ClientCertificateTest : BaseCertificateTest { public static bool DowngradeToHTTP1IfClientCertSet => PlatformDetection.WindowsVersion < 2004; + public ClientCertificateTest(ITestOutputHelper output) : base(output) + { } + [ConditionalFact(typeof(ServerCertificateTest), nameof(DowngradeToHTTP1IfClientCertSet))] public async Task UseClientCertOnHttp2_DowngradedToHttp1MutualAuth_Success() { @@ -47,6 +53,8 @@ await LoopbackServer.CreateClientAndServerAsync( }, new LoopbackServer.Options { UseSsl = true }); } +// Disabling it for full .Net Framework due to a missing ALPN API which leads to a protocol downgrade +#if !NETFRAMEWORK [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version2004OrGreater))] public async Task UseClientCertOnHttp2_OSSupportsIt_Success() { @@ -81,70 +89,31 @@ await Http2LoopbackServer.CreateClientAndServerAsync( } }, new Http2Options { ClientCertificateRequired = true }); } - -#if NETFRAMEWORK - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))] - public async Task UseClientCertOnHttp2_OSSupportsItButCertNotSet_SuccessWithOneWayAuth() - { - await LoopbackServer.CreateClientAndServerAsync( - async address => - { - var handler = new WinHttpHandler(); - handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; - using (var client = new HttpClient(handler)) - using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion20.Value })) - { - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.True(_validationCallbackHistory.WasCalled); - Assert.NotEmpty(_validationCallbackHistory.CertificateChain); - Assert.Equal(Test.Common.Configuration.Certificates.GetServerCertificate(), _validationCallbackHistory.CertificateChain[0]); - } - }, - async s => - { - using (LoopbackServer.Connection connection = await s.EstablishConnectionAsync().ConfigureAwait(false)) - { - SslStream sslStream = connection.Stream as SslStream; - Assert.NotNull(sslStream); - Assert.False(sslStream.IsMutuallyAuthenticated); - Assert.Null(sslStream.RemoteCertificate); - - await connection.ReadRequestHeaderAndSendResponseAsync(HttpStatusCode.OK); - } - }, new LoopbackServer.Options { UseSsl = true }); - } -#else +#endif + [OuterLoop] [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))] public async Task UseClientCertOnHttp2_OSSupportsItButCertNotSet_SuccessWithOneWayAuth() { - await Http2LoopbackServer.CreateClientAndServerAsync( - async address => - { - var handler = new WinHttpHandler(); - handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; - using (var client = new HttpClient(handler)) - using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion20.Value })) - { - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.True(_validationCallbackHistory.WasCalled); - Assert.NotEmpty(_validationCallbackHistory.CertificateChain); - Assert.Equal(Test.Common.Configuration.Certificates.GetServerCertificate(), _validationCallbackHistory.CertificateChain[0]); - } - }, - async s => - { - using (Http2LoopbackConnection connection = await s.EstablishConnectionAsync().ConfigureAwait(false)) - { - SslStream sslStream = connection.Stream as SslStream; - Assert.NotNull(sslStream); - Assert.False(sslStream.IsMutuallyAuthenticated); - Assert.Null(sslStream.RemoteCertificate); - - int streamId = await connection.ReadRequestHeaderAsync(); - await connection.SendDefaultResponseAsync(streamId); - } - }, new Http2Options { ClientCertificateRequired = false }); + WinHttpHandler handler = new WinHttpHandler(); + handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; + string payload = "Mutual Authentication Test"; + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, Test.Common.Configuration.Http.Http2RemoteEchoServer) { Version = HttpVersion20.Value }; + request.Content = new StringContent(payload); + using (var client = new HttpClient(handler)) + using (HttpResponseMessage response = await client.SendAsync(request)) + { + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal(HttpVersion20.Value, response.Version); + string responsePayload = await response.Content.ReadAsStringAsync(); + var responseContent = JsonConvert.DeserializeAnonymousType(responsePayload, new { Method = "_", BodyContent = "_", ClientCertificatePresent = "_", ClientCertificate = "_" }); + Assert.Equal("POST", responseContent.Method); + Assert.Equal(payload, responseContent.BodyContent); + Assert.Equal("false", responseContent.ClientCertificatePresent); + Assert.Null(responseContent.ClientCertificate); + Assert.True(_validationCallbackHistory.WasCalled); + Assert.NotEmpty(_validationCallbackHistory.CertificateChain); + ConfirmValidCertificate("*.azurewebsites.net"); + }; } -#endif } } 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 bc70113ebe5b26..84803b3a36f657 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 @@ -15,7 +15,7 @@ protected static WinHttpClientHandler CreateHttpClientHandler(Version useVersion { useVersion ??= HttpVersion.Version11; - WinHttpClientHandler handler = new WinHttpClientHandler(); + WinHttpClientHandler handler = new WinHttpClientHandler(useVersion); if (useVersion >= HttpVersion20.Value) { 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 b18b2620ca0341..c0f93a3f6fb9fb 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs @@ -192,12 +192,7 @@ public sealed class PlatformHandler_HttpClientHandler_Authentication_Test : Http public PlatformHandler_HttpClientHandler_Authentication_Test(ITestOutputHelper output) : base(output) { } } - // Enable this to run HTTP2 tests on platform handler -#if PLATFORM_HANDLER_HTTP2_TESTS - /*public sealed class PlatformHandlerTest_Http2 : HttpClientHandlerTest_Http2 - { - }*/ - +#if NETCOREAPP [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.SupportsAlpn))] public sealed class PlatformHandlerTest_Cookies_Http2 : HttpClientHandlerTest_Cookies { @@ -205,5 +200,182 @@ public sealed class PlatformHandlerTest_Cookies_Http2 : HttpClientHandlerTest_Co public PlatformHandlerTest_Cookies_Http2(ITestOutputHelper output) : base(output) { } } + + public sealed class PlatformHandler_HttpClientHandler_Asynchrony_Http2_Test : HttpClientHandler_Asynchrony_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_Asynchrony_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpProtocol_Http2_Tests : HttpProtocolTests + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpProtocol_Http2_Tests(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpProtocolTests_Http2_Dribble : HttpProtocolTests_Dribble + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpProtocolTests_Http2_Dribble(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClient_SelectedSites_Http2_Test : HttpClient_SelectedSites_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClient_SelectedSites_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientEKU_Http2_Test : HttpClientEKUTest + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientEKU_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientHandler_Decompression_Http2_Tests : HttpClientHandler_Decompression_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_Decompression_Http2_Tests(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientHandler_DangerousAcceptAllCertificatesValidator_Http2_Test : HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_DangerousAcceptAllCertificatesValidator_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientHandler_ClientCertificates_Http2_Test : HttpClientHandler_ClientCertificates_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_ClientCertificates_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientHandler_DefaultProxyCredentials_Http2_Test : HttpClientHandler_DefaultProxyCredentials_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_DefaultProxyCredentials_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientHandler_MaxConnectionsPerServer_Http2_Test : HttpClientHandler_MaxConnectionsPerServer_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_MaxConnectionsPerServer_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientHandler_ServerCertificates_Http2_Test : HttpClientHandler_ServerCertificates_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_ServerCertificates_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_PostScenario_Http2_Test : PostScenarioTest + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_PostScenario_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_ResponseStream_Http2_Test : ResponseStreamTest + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_ResponseStream_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientHandler_SslProtocols_Http2_Test : HttpClientHandler_SslProtocols_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_SslProtocols_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientHandler_Proxy_Http2_Test : HttpClientHandler_Proxy_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_Proxy_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_SchSendAuxRecordHttp_Http2_Test : SchSendAuxRecordHttpTest + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_SchSendAuxRecordHttp_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientHandler_Http2_Test : HttpClientHandlerTest + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandlerTest_AutoRedirect_Http2 : HttpClientHandlerTest_AutoRedirect + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandlerTest_AutoRedirect_Http2(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_DefaultCredentials_Http2_Test : DefaultCredentialsTest + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_DefaultCredentials_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_IdnaProtocol_Http2_Tests : IdnaProtocolTests + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_IdnaProtocol_Http2_Tests(ITestOutputHelper output) : base(output) { } + // WinHttp on Win7 does not support IDNA + protected override bool SupportsIdna => !PlatformDetection.IsWindows7; + } + + public sealed class PlatformHandler_HttpRetryProtocol_Http2_Tests : HttpRetryProtocolTests + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpRetryProtocol_Http2_Tests(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandlerTest_Cookies_Http11_Http2 : HttpClientHandlerTest_Cookies_Http11 + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandlerTest_Cookies_Http11_Http2(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientHandler_MaxResponseHeadersLength_Http2_Test : HttpClientHandler_MaxResponseHeadersLength_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_MaxResponseHeadersLength_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientHandler_Cancellation_Http2_Test : HttpClientHandler_Cancellation_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_Cancellation_Http2_Test(ITestOutputHelper output) : base(output) { } + } + + public sealed class PlatformHandler_HttpClientHandler_Authentication_Http2_Test : HttpClientHandler_Authentication_Test + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_HttpClientHandler_Authentication_Http2_Test(ITestOutputHelper output) : base(output) { } + } #endif } diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs index 4ac9071fbdad02..f459c2957d2149 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs @@ -13,12 +13,8 @@ namespace System.Net.Http.WinHttpHandlerFunctional.Tests { public class ServerCertificateTest : BaseCertificateTest { - private readonly ITestOutputHelper _output; - - public ServerCertificateTest(ITestOutputHelper output) - { - _output = output; - } + public ServerCertificateTest(ITestOutputHelper output) : base(output) + { } public static bool DowngradeToHTTP1IfClientCertSet => PlatformDetection.WindowsVersion < 2004; @@ -116,13 +112,5 @@ public async Task UseCallback_CallbackThrowsSpecificException_SpecificExceptionP Assert.True(ex.GetBaseException() is CustomException); } } - - private void ConfirmValidCertificate(string expectedHostName) - { - Assert.Equal(SslPolicyErrors.None, _validationCallbackHistory.SslPolicyErrors); - Assert.True(_validationCallbackHistory.CertificateChain.Count > 0); - _output.WriteLine("Certificate.Subject: {0}", _validationCallbackHistory.CertificateSubject); - _output.WriteLine("Expected HostName: {0}", expectedHostName); - } } } diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/WinHttpClientHandler.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/WinHttpClientHandler.cs index 2f8ccd311a3d02..611e6c510a7c4b 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/WinHttpClientHandler.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/WinHttpClientHandler.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Net.Security; +using System.Net.Test.Common; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading; @@ -18,8 +19,9 @@ namespace System.Net.Http public class WinHttpClientHandler : WinHttpHandler { private bool _useProxy; + private readonly Version _requestVersion; - public WinHttpClientHandler() + public WinHttpClientHandler(Version requestVersion) { // Adjust defaults to match current .NET Desktop HttpClientHandler (based on HWR stack). AllowAutoRedirect = true; @@ -41,6 +43,8 @@ public WinHttpClientHandler() ReceiveHeadersTimeout = Timeout.InfiniteTimeSpan; ReceiveDataTimeout = Timeout.InfiniteTimeSpan; SendTimeout = Timeout.InfiniteTimeSpan; + + _requestVersion = requestVersion; } public virtual bool SupportsAutomaticDecompression => true; @@ -178,6 +182,11 @@ protected override Task SendAsync(HttpRequestMessage reques } } + if(_requestVersion >= HttpVersion20.Value) + { + request.Version = _requestVersion; + } + return base.SendAsync(request, cancellationToken); } } From 90051dec1ba12441b020de510a17025a4eeadd60 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Fri, 13 Mar 2020 18:22:58 +0100 Subject: [PATCH 10/26] Tests fixed --- .../HttpClientHandlerTest.Authentication.cs | 6 ++++++ ...HttpClientHandlerTest.ServerCertificates.cs | 18 ++++++++++++++++-- .../System/Net/Http/HttpClientHandlerTest.cs | 8 +++++++- .../tests/System/Net/Http/HttpProtocolTests.cs | 8 +++++++- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs index 3b195350040d97..f7ec7167ded05c 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs @@ -602,6 +602,12 @@ public async Task Credentials_ServerUsesWindowsAuthentication_Success(string ser [InlineData("Negotiate")] public async Task Credentials_ServerChallengesWithWindowsAuth_ClientSendsWindowsAuthHeader(string authScheme) { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion.Version11) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif await LoopbackServerFactory.CreateClientAndServerAsync( async uri => { 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 f4fb04146ea746..4f541c48c5f0d5 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs @@ -13,6 +13,7 @@ using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using Microsoft.DotNet.RemoteExecutor; +using Microsoft.DotNet.XUnitExtensions; using Xunit; using Xunit.Abstractions; @@ -30,9 +31,15 @@ public abstract partial class HttpClientHandler_ServerCertificates_Test : HttpCl public HttpClientHandler_ServerCertificates_Test(ITestOutputHelper output) : base(output) { } - [Fact] + [ConditionalFact] public void Ctor_ExpectedDefaultValues() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion.Version11) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif using (HttpClientHandler handler = CreateHttpClientHandler()) { Assert.Null(handler.ServerCertificateCustomValidationCallback); @@ -40,9 +47,16 @@ public void Ctor_ExpectedDefaultValues() } } - [Fact] + [ConditionalFact] public void ServerCertificateCustomValidationCallback_SetGet_Roundtrips() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion.Version11) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif + using (HttpClientHandler handler = CreateHttpClientHandler()) { Assert.Null(handler.ServerCertificateCustomValidationCallback); diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index df88979e7fae29..a906c4a02eacd5 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -735,9 +735,15 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => server.AcceptConnectionSendCustomResponseAndCloseAsync("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nhe")); } - [Fact] + [ConditionalFact] public async Task PostAsync_ManyDifferentRequestHeaders_SentCorrectly() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion.Version11) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif const string content = "hello world"; // Using examples from https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields diff --git a/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs b/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs index 6fb1280c8da53b..1afb4de5e9fd8f 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs @@ -20,9 +20,15 @@ public abstract class HttpProtocolTests : HttpClientHandlerTestBase public HttpProtocolTests(ITestOutputHelper output) : base(output) { } - [Fact] + [ConditionalFact] public async Task GetAsync_RequestVersion10_Success() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion.Version11) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif await LoopbackServer.CreateServerAsync(async (server, url) => { using (HttpClient client = CreateHttpClient()) From 2f7792f023027140c3c2a3213b37a8d23b2e1b32 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Mon, 16 Mar 2020 13:24:43 +0100 Subject: [PATCH 11/26] Unsuporrted HTTP/2 tests are disabled on Win 7 and 8.1 --- .../tests/FunctionalTests/PlatformHandlerTest.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 c0f93a3f6fb9fb..39fc0894e59922 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs @@ -193,7 +193,7 @@ public PlatformHandler_HttpClientHandler_Authentication_Test(ITestOutputHelper o } #if NETCOREAPP - [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.SupportsAlpn))] + [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))] public sealed class PlatformHandlerTest_Cookies_Http2 : HttpClientHandlerTest_Cookies { protected override Version UseVersion => HttpVersion20.Value; @@ -313,6 +313,7 @@ public sealed class PlatformHandler_SchSendAuxRecordHttp_Http2_Test : SchSendAux public PlatformHandler_SchSendAuxRecordHttp_Http2_Test(ITestOutputHelper output) : base(output) { } } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))] public sealed class PlatformHandler_HttpClientHandler_Http2_Test : HttpClientHandlerTest { protected override Version UseVersion => HttpVersion20.Value; From ba477cdb691acbb2b44fe61ef2632d557eff6386 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Mon, 16 Mar 2020 14:42:07 +0100 Subject: [PATCH 12/26] ConditionalFact replaced with ConditionalClass --- .../tests/FunctionalTests/PlatformHandlerTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 39fc0894e59922..d88f66cc6cb224 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs @@ -313,7 +313,7 @@ public sealed class PlatformHandler_SchSendAuxRecordHttp_Http2_Test : SchSendAux public PlatformHandler_SchSendAuxRecordHttp_Http2_Test(ITestOutputHelper output) : base(output) { } } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))] + [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))] public sealed class PlatformHandler_HttpClientHandler_Http2_Test : HttpClientHandlerTest { protected override Version UseVersion => HttpVersion20.Value; From 03d72f7411c47c6fcc0a8842c51755cc43cf9e3f Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Mon, 16 Mar 2020 17:19:14 +0100 Subject: [PATCH 13/26] More unsupported tests skipped --- .../HttpClientHandlerTest.Cancellation.cs | 33 +++++++++++++- ...entHandlerTest.MaxResponseHeadersLength.cs | 11 +++++ .../Net/Http/HttpClientHandlerTest.Proxy.cs | 10 +++++ .../FunctionalTests/WinHttpHandlerTest.cs | 45 ++++++++++++++++++- 4 files changed, 96 insertions(+), 3 deletions(-) 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 ce0b0b4823e2c7..c650ecce050439 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs @@ -28,7 +28,11 @@ public abstract class HttpClientHandler_Cancellation_Test : HttpClientHandlerTes { public HttpClientHandler_Cancellation_Test(ITestOutputHelper output) : base(output) { } +#if WINHTTPHANDLER_TEST + [ConditionalTheory] +#else [Theory] +#endif [InlineData(false, CancellationMode.Token)] [InlineData(true, CancellationMode.Token)] public async Task PostAsync_CancelDuringRequestContentSend_TaskCanceledQuickly(bool chunkedTransfer, CancellationMode mode) @@ -39,6 +43,13 @@ public async Task PostAsync_CancelDuringRequestContentSend_TaskCanceledQuickly(b return; } +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value && !PlatformDetection.IsWindows10Version1607OrGreater) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif + var serverRelease = new TaskCompletionSource(); await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { @@ -182,7 +193,11 @@ await ValidateClientCancellationAsync(async () => } } +#if WINHTTPHANDLER_TEST + [ConditionalTheory] +#else [Theory] +#endif [MemberData(nameof(ThreeBools))] public async Task GetAsync_CancelDuringResponseBodyReceived_Unbuffered_TaskCanceledQuickly(bool chunkedTransfer, bool connectionClose, bool readOrCopyToAsync) { @@ -192,6 +207,13 @@ public async Task GetAsync_CancelDuringResponseBodyReceived_Unbuffered_TaskCance return; } +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value && !PlatformDetection.IsWindows10Version1607OrGreater) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif + using (HttpClient client = CreateHttpClient()) { client.Timeout = Timeout.InfiniteTimeSpan; @@ -237,14 +259,23 @@ await ValidateClientCancellationAsync(async () => }); } } - +#if WINHTTPHANDLER_TEST + [ConditionalTheory] +#else [Theory] +#endif [InlineData(CancellationMode.CancelPendingRequests, false)] [InlineData(CancellationMode.DisposeHttpClient, false)] [InlineData(CancellationMode.CancelPendingRequests, true)] [InlineData(CancellationMode.DisposeHttpClient, true)] public async Task GetAsync_CancelPendingRequests_DoesntCancelReadAsyncOnResponseStream(CancellationMode mode, bool copyToAsync) { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value && !PlatformDetection.IsWindows10Version1607OrGreater) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif using (HttpClient client = CreateHttpClient()) { client.Timeout = Timeout.InfiniteTimeSpan; diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 7c6db382a06862..80f26d10a85edb 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -7,6 +7,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.DotNet.XUnitExtensions; using Xunit; using Xunit.Abstractions; @@ -46,9 +47,19 @@ public void ValidValue_SetGet_Roundtrips(int validValue) } } +#if WINHTTPHANDLER_TEST + [ConditionalFact] +#else [Fact] +#endif public async Task SetAfterUse_Throws() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value && !PlatformDetection.IsWindows10Version1607OrGreater) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { using HttpClientHandler handler = CreateHttpClientHandler(); 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 7402079d21593a..275670d3951c72 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs @@ -26,9 +26,19 @@ public abstract class HttpClientHandler_Proxy_Test : HttpClientHandlerTestBase { public HttpClientHandler_Proxy_Test(ITestOutputHelper output) : base(output) { } +#if WINHTTPHANDLER_TEST + [ConditionalFact] +#else [Fact] +#endif public async Task Dispose_HandlerWithProxy_ProxyNotDisposed() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value && !PlatformDetection.IsWindows10Version1607OrGreater) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif var proxy = new TrackDisposalProxy(); await LoopbackServerFactory.CreateClientAndServerAsync(async uri => diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/WinHttpHandlerTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/WinHttpHandlerTest.cs index 5c728fced2eeff..0519437ca296e2 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/WinHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/WinHttpHandlerTest.cs @@ -3,9 +3,10 @@ // See the LICENSE file in the project root for more information. using System; -using System.Net; -using System.Net.Http; +using System.Collections.Generic; +using System.Linq; using System.Net.Test.Common; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -131,6 +132,46 @@ public async Task SendAsync_GetUsingChunkedEncoding_ThrowsHttpRequestException() } } + [OuterLoop] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))] + public async Task GetAsync_SetCookieContainerMultipleCookies_CookiesSent() + { + var cookies = new Cookie[] + { + new Cookie("hello", "world"), + new Cookie("foo", "bar"), + new Cookie("ABC", "123") + }; + + WinHttpHandler handler = new WinHttpHandler(); + var cookieContainer = new CookieContainer(); + + foreach (Cookie c in cookies) + { + cookieContainer.Add(Configuration.Http.Http2RemoteEchoServer, c); + } + + handler.CookieContainer = cookieContainer; + handler.CookieUsePolicy = CookieUsePolicy.UseSpecifiedCookieContainer; + handler.ServerCertificateValidationCallback = (m, cert, chain, err) => true; + string payload = "Cookie Test"; + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, Configuration.Http.Http2RemoteEchoServer) { Version = HttpVersion20.Value }; + request.Content = new StringContent(payload); + using (var client = new HttpClient(handler)) + using (HttpResponseMessage response = await client.SendAsync(request)) + { + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal(HttpVersion20.Value, response.Version); + string responsePayload = await response.Content.ReadAsStringAsync(); + var responseContent = Newtonsoft.Json.JsonConvert + .DeserializeAnonymousType(responsePayload, new { Method = "_", BodyContent = "_", Cookies = new Dictionary() }); + Assert.Equal("POST", responseContent.Method); + Assert.Equal(payload, responseContent.BodyContent); + Assert.Equal(cookies.ToDictionary(c => c.Name, c => c.Value), responseContent.Cookies); + + }; + } + public static bool JsonMessageContainsKeyValue(string message, string key, string value) { string pattern = string.Format(@"""{0}"": ""{1}""", key, value); From 27f2817a9b4d8e4373448eb1f478b4f2cb2a58e8 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Mon, 16 Mar 2020 18:02:45 +0100 Subject: [PATCH 14/26] Suggested changes applied --- .../Common/tests/System/Net/Http/Http2LoopbackConnection.cs | 2 +- .../tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index 7baa4356417334..9eb8e520522c76 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -57,7 +57,7 @@ public Http2LoopbackConnection(Socket socket, Http2Options httpOptions) sslStream.AuthenticateAsServerAsync(options, CancellationToken.None).Wait(); #else - sslStream.AuthenticateAsServerAsync(cert, httpOptions.ClientCertificateRequired, httpOptions.SslProtocols, false).Wait(); + sslStream.AuthenticateAsServerAsync(cert, httpOptions.ClientCertificateRequired, httpOptions.SslProtocols, checkCertificateRevocation: false).Wait(); #endif } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs index 63fba8a6214798..3fa53fe5a9be21 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs @@ -338,7 +338,6 @@ await LoopbackServerFactory.CreateServerAsync(async (server, url) => using (HttpClient client = CreateHttpClient(handler)) { - //System.Diagnostics.Debugger.Launch(); Task getResponseTask = client.GetAsync(url); Task serverTask = server.HandleRequestAsync( HttpStatusCode.OK, new HttpHeaderData[] { new HttpHeaderData("Set-Cookie", GetCookieHeaderValue(cookieName, cookieValue)) }, s_simpleContent); From 4d1be6c30a4f4818f4358e3d7bf3da10d679b7fa Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Tue, 17 Mar 2020 11:43:46 +0100 Subject: [PATCH 15/26] Conditional compilation replaced with extension methods --- .../System/Net/Http/ByteAtATimeContent.cs | 4 --- .../System/Net/Http/DefaultCredentialsTest.cs | 4 --- .../HttpClientHandlerTest.Decompression.cs | 13 --------- .../System/Net/Http/HttpProtocolTests.cs | 4 --- .../System/Net/Http/HttpRetryProtocolTests.cs | 4 --- .../tests/System/Net/StreamArrayExtensions.cs | 27 +++++++++++++++++++ ...ttp.WinHttpHandler.Functional.Tests.csproj | 3 +++ 7 files changed, 30 insertions(+), 29 deletions(-) create mode 100644 src/libraries/Common/tests/System/Net/StreamArrayExtensions.cs diff --git a/src/libraries/Common/tests/System/Net/Http/ByteAtATimeContent.cs b/src/libraries/Common/tests/System/Net/Http/ByteAtATimeContent.cs index 8abd4e653797e2..67a95370cbde11 100644 --- a/src/libraries/Common/tests/System/Net/Http/ByteAtATimeContent.cs +++ b/src/libraries/Common/tests/System/Net/Http/ByteAtATimeContent.cs @@ -33,11 +33,7 @@ protected override async Task SerializeToStreamAsync(Stream stream, TransportCon for (int i = 0; i < _length; i++) { buffer[0] = (byte)i; -#if !NETFRAMEWORK await stream.WriteAsync(buffer); -#else - await stream.WriteAsync(buffer, 0, buffer.Length); -#endif await stream.FlushAsync(); await Task.Delay(_millisecondDelayBetweenBytes); } diff --git a/src/libraries/Common/tests/System/Net/Http/DefaultCredentialsTest.cs b/src/libraries/Common/tests/System/Net/Http/DefaultCredentialsTest.cs index 3c75f9d48a6ade..d5b9e4fb940cb4 100644 --- a/src/libraries/Common/tests/System/Net/Http/DefaultCredentialsTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/DefaultCredentialsTest.cs @@ -336,11 +336,7 @@ private async Task ProcessRequests() // Send a response in the JSON format that the client expects string username = context.User.Identity.Name; byte[] bytes = System.Text.Encoding.UTF8.GetBytes($"{{\"authenticated\": \"true\", \"user\": \"{username}\" }}"); -#if !NETFRAMEWORK await context.Response.OutputStream.WriteAsync(bytes); -#else - await context.Response.OutputStream.WriteAsync(bytes, 0, bytes.Length); -#endif context.Response.Close(); } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs index c0afd4463f12a3..4b51908743b2a2 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs @@ -95,11 +95,7 @@ await server.AcceptConnectionAsync(async connection => await connection.Writer.WriteAsync($"HTTP/1.1 200 OK\r\nContent-Encoding: {encodingName}\r\n\r\n"); using (Stream compressedStream = compress(connection.Stream)) { -#if !NETFRAMEWORK await compressedStream.WriteAsync(expectedContent); -#else - await compressedStream.WriteAsync(expectedContent, 0, expectedContent.Length); -#endif } }); }); @@ -140,11 +136,7 @@ public async Task DecompressedResponse_MethodNotSpecified_OriginalContentReturne var compressedContentStream = new MemoryStream(); using (Stream s = compress(compressedContentStream)) { -#if !NETFRAMEWORK await s.WriteAsync(expectedContent); -#else - await s.WriteAsync(expectedContent, 0, expectedContent.Length); -#endif } byte[] compressedContent = compressedContentStream.ToArray(); @@ -162,13 +154,8 @@ await server.AcceptConnectionAsync(async connection => { await connection.ReadRequestHeaderAsync(); string text = $"HTTP/1.1 200 OK\r\nContent-Encoding: {encodingName}\r\n\r\n"; -#if !NETFRAMEWORK await connection.Writer.WriteAsync(text); await connection.Stream.WriteAsync(compressedContent); -#else - await connection.Writer.WriteAsync(text.ToCharArray(), 0, text.Length); - await connection.Stream.WriteAsync(compressedContent, 0, compressedContent.Length); -#endif }); }); } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs b/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs index 1afb4de5e9fd8f..003467ddfa7233 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs @@ -502,11 +502,7 @@ await server.AcceptConnectionAsync(async connection => int bytesRemaining = expectedData.Length - bytesSent; int bytesToSend = rand.Next(1, Math.Min(bytesRemaining, maxChunkSize + 1)); await connection.Writer.WriteAsync(bytesToSend.ToString("X") + lineEnding); -#if !NETFRAMEWORK await connection.Stream.WriteAsync(new Memory(expectedData, bytesSent, bytesToSend)); -#else - await connection.Stream.WriteAsync(expectedData, bytesSent, bytesToSend); -#endif await connection.Writer.WriteAsync(lineEnding); bytesSent += bytesToSend; } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpRetryProtocolTests.cs b/src/libraries/Common/tests/System/Net/Http/HttpRetryProtocolTests.cs index 31d915e83566c4..cb4de58264f024 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpRetryProtocolTests.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpRetryProtocolTests.cs @@ -131,11 +131,7 @@ protected override async Task SerializeToStreamAsync(Stream stream, TransportCon _sendingContent.SetResult(true); await _connectionClosed; byte[] bytes = Encoding.UTF8.GetBytes(_longContent); -#if !NETFRAMEWORK await stream.WriteAsync(bytes); -#else - await stream.WriteAsync(bytes, 0, bytes.Length); -#endif } protected override bool TryComputeLength(out long length) diff --git a/src/libraries/Common/tests/System/Net/StreamArrayExtensions.cs b/src/libraries/Common/tests/System/Net/StreamArrayExtensions.cs new file mode 100644 index 00000000000000..012fefef5257ed --- /dev/null +++ b/src/libraries/Common/tests/System/Net/StreamArrayExtensions.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.IO; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net +{ + public static class StreamArrayExtensions + { + public static ValueTask WriteAsync(this Stream stream, ReadOnlyMemory memory) + { + bool isArray = MemoryMarshal.TryGetArray(memory, out ArraySegment segment); + Assert.True(isArray); + + return new ValueTask(stream.WriteAsync(segment.Array, segment.Offset, segment.Count)); + } + + public static ValueTask WriteAsync(this StreamWriter writer, string text) + { + return new ValueTask(writer.WriteAsync(text.ToCharArray(), 0, text.Length)); + } + } +} 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 3286c2847532ce..fb328de23a9a12 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 @@ -51,6 +51,9 @@ Common\System\Net\TestWebProxies.cs + + Common\System\Net\StreamArrayExtensions.cs + Common\System\Net\Http\ByteAtATimeContent.cs From 8b90785427e20c6d04e547a4a4a36d04ce2af986 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Tue, 17 Mar 2020 13:23:52 +0100 Subject: [PATCH 16/26] Unsupported test disabled on Win7 and Win8.1 --- .../System/Net/Http/HttpClientHandlerTest.Cancellation.cs | 7 +++++++ 1 file changed, 7 insertions(+) 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 c650ecce050439..1010b54438deaf 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs @@ -97,6 +97,13 @@ public async Task GetAsync_CancelDuringResponseHeadersReceived_TaskCanceledQuick return; } +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value && !PlatformDetection.IsWindows10Version1607OrGreater) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif + using (HttpClient client = CreateHttpClient()) { client.Timeout = Timeout.InfiniteTimeSpan; From 4b09bdd47b89ccd2a402f1dfc5c45b00720f238a Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Tue, 17 Mar 2020 16:04:19 +0100 Subject: [PATCH 17/26] Enable PlatformHandler_ResponseStream_Http2_Test for all frameworks --- .../tests/System/Net/Http/ResponseStreamTest.cs | 3 ++- .../tests/FunctionalTests/PlatformHandlerTest.cs | 13 ++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs b/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs index 23325dd0f7752d..67812f9cb73f4f 100644 --- a/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs @@ -227,7 +227,7 @@ await client.GetAsync(remoteServer.EchoUri, HttpCompletionOption.ResponseHeaders } } } - +#if NETCOREAPP [Theory] [InlineData(TransferType.ContentLength, TransferError.ContentLengthTooLarge)] [InlineData(TransferType.Chunked, TransferError.MissingChunkTerminator)] @@ -255,6 +255,7 @@ await StartTransferTypeAndErrorServer(transferType, transferError, async uri => await ReadAsStreamHelper(uri); }); } +#endif public enum TransferType { 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 d88f66cc6cb224..ae87a174901981 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs @@ -285,13 +285,6 @@ public sealed class PlatformHandler_PostScenario_Http2_Test : PostScenarioTest public PlatformHandler_PostScenario_Http2_Test(ITestOutputHelper output) : base(output) { } } - public sealed class PlatformHandler_ResponseStream_Http2_Test : ResponseStreamTest - { - protected override Version UseVersion => HttpVersion20.Value; - - public PlatformHandler_ResponseStream_Http2_Test(ITestOutputHelper output) : base(output) { } - } - public sealed class PlatformHandler_HttpClientHandler_SslProtocols_Http2_Test : HttpClientHandler_SslProtocols_Test { protected override Version UseVersion => HttpVersion20.Value; @@ -379,4 +372,10 @@ public sealed class PlatformHandler_HttpClientHandler_Authentication_Http2_Test public PlatformHandler_HttpClientHandler_Authentication_Http2_Test(ITestOutputHelper output) : base(output) { } } #endif + public sealed class PlatformHandler_ResponseStream_Http2_Test : ResponseStreamTest + { + protected override Version UseVersion => HttpVersion20.Value; + + public PlatformHandler_ResponseStream_Http2_Test(ITestOutputHelper output) : base(output) { } + } } From 6d43f8cb1991fef24ee7d8737a027eff1c3f6ca9 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Tue, 17 Mar 2020 19:30:07 +0100 Subject: [PATCH 18/26] Skipped tests marked as Conditional --- .../tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1010b54438deaf..75d10fac673a5a 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs @@ -87,7 +87,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => }); } - [Theory] + [ConditionalTheory] [MemberData(nameof(OneBoolAndCancellationMode))] public async Task GetAsync_CancelDuringResponseHeadersReceived_TaskCanceledQuickly(bool connectionClose, CancellationMode mode) { From 95bb001d5e6d51cf8b2e39d12b26705f48b063a9 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Tue, 17 Mar 2020 21:47:24 +0100 Subject: [PATCH 19/26] Lang version bumped to 8.0 --- .../Common/tests/System/Net/Http/Http2LoopbackConnection.cs | 6 ++---- .../System.Net.Http.WinHttpHandler.Functional.Tests.csproj | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index 9eb8e520522c76..e9d7cd979cb89d 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -149,10 +149,8 @@ public async Task WriteFrameAsync(Frame frame) public async Task ReadFrameAsync(TimeSpan timeout) { - using (CancellationTokenSource timeoutCts = new CancellationTokenSource(timeout)) - { - return await ReadFrameAsync(timeoutCts.Token).ConfigureAwait(false); - } + using CancellationTokenSource timeoutCts = new CancellationTokenSource(timeout); + return await ReadFrameAsync(timeoutCts.Token).ConfigureAwait(false); } private async Task ReadFrameAsync(CancellationToken cancellationToken) 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 fb328de23a9a12..599da9a519e917 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 @@ -3,6 +3,7 @@ $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT true $(DefineConstants);WINHTTPHANDLER_TEST + 8.0 From ffe648a5150711ede40c21ce54d2cee3c4e947e6 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Wed, 18 Mar 2020 12:57:45 +0100 Subject: [PATCH 20/26] Unsupported outerloop tests disabled --- .../System/Net/Http/HttpClientHandlerTest.Cancellation.cs | 2 ++ .../Common/tests/System/Net/Http/HttpClientHandlerTest.cs | 8 ++++++++ .../tests/System/Net/Http/HttpClientHandlerTestBase.cs | 4 ++-- .../Common/tests/System/Net/Http/PostScenarioTest.cs | 2 ++ .../HttpClientHandlerTestBase.WinHttpHandler.cs | 6 ++++-- .../tests/FunctionalTests/PlatformHandlerTest.cs | 2 ++ 6 files changed, 20 insertions(+), 4 deletions(-) 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 75d10fac673a5a..c602b793a4dc97 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs @@ -528,6 +528,7 @@ public static IEnumerable PostAsync_Cancel_CancellationTokenPassedToCo } } +#if !NETFRAMEWORK [OuterLoop("Uses Task.Delay")] [Theory] [MemberData(nameof(PostAsync_Cancel_CancellationTokenPassedToContent_MemberData))] @@ -556,6 +557,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync( catch (Exception) { } }); } +#endif private async Task ValidateClientCancellationAsync(Func clientBodyAsync) { diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index a906c4a02eacd5..e232d2cc903cac 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -2244,6 +2244,7 @@ public async Task PostAsync_Redirect_LargePayload_Helper(Configuration.Http.Remo } } +#if !NETFRAMEWORK [OuterLoop("Uses external server")] [Theory, MemberData(nameof(RemoteServersMemberData))] public async Task PostAsync_ReuseRequestContent_Success(Configuration.Http.RemoteServer remoteServer) @@ -2262,6 +2263,7 @@ public async Task PostAsync_ReuseRequestContent_Success(Configuration.Http.Remot } } } +#endif [Theory] [InlineData(HttpStatusCode.MethodNotAllowed, "Custom description")] @@ -2415,6 +2417,12 @@ public async Task SendAsync_SendRequestUsingNoBodyMethodToEchoServerWithContent_ [Fact] public async Task SendAsync_RequestVersion10_ServerReceivesVersion10Request() { + // Test is not supported for WinHttpHandler and HTTP/2 + if(IsWinHttpHandler && UseVersion >= HttpVersion20.Value) + { + return; + } + Version receivedRequestVersion = await SendRequestAndGetRequestVersionAsync(new Version(1, 0)); Assert.Equal(new Version(1, 0), receivedRequestVersion); } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs index 003e344d74042a..154eb11a625a43 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs @@ -38,7 +38,7 @@ protected HttpClient CreateHttpClient(HttpMessageHandler handler) => #endif }; - protected static HttpClient CreateHttpClient(string useVersionString) => + protected HttpClient CreateHttpClient(string useVersionString) => CreateHttpClient(CreateHttpClientHandler(useVersionString), useVersionString); protected static HttpClient CreateHttpClient(HttpMessageHandler handler, string useVersionString) => @@ -50,7 +50,7 @@ protected static HttpClient CreateHttpClient(HttpMessageHandler handler, string protected HttpClientHandler CreateHttpClientHandler() => CreateHttpClientHandler(UseVersion); - protected static HttpClientHandler CreateHttpClientHandler(string useVersionString) => + protected HttpClientHandler CreateHttpClientHandler(string useVersionString) => CreateHttpClientHandler(Version.Parse(useVersionString)); protected LoopbackServerFactory LoopbackServerFactory => GetFactoryForVersion(UseVersion); diff --git a/src/libraries/Common/tests/System/Net/Http/PostScenarioTest.cs b/src/libraries/Common/tests/System/Net/Http/PostScenarioTest.cs index 733b29f0c6d6bb..34de8fffac58f2 100644 --- a/src/libraries/Common/tests/System/Net/Http/PostScenarioTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/PostScenarioTest.cs @@ -28,6 +28,7 @@ public abstract class PostScenarioTest : HttpClientHandlerTestBase public PostScenarioTest(ITestOutputHelper output) : base(output) { } +#if !NETFRAMEWORK [OuterLoop("Uses external servers")] [Theory, MemberData(nameof(RemoteServersMemberData))] public async Task PostRewindableStreamContentMultipleTimes_StreamContentFullySent(Configuration.Http.RemoteServer remoteServer) @@ -50,6 +51,7 @@ public async Task PostRewindableStreamContentMultipleTimes_StreamContentFullySen } } } +#endif [OuterLoop("Uses external servers")] [Theory, MemberData(nameof(RemoteServersMemberData))] 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 84803b3a36f657..635febaba5f956 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 @@ -11,13 +11,15 @@ public abstract partial class HttpClientHandlerTestBase : FileCleanupTestBase { protected static bool IsWinHttpHandler => true; - protected static WinHttpClientHandler CreateHttpClientHandler(Version useVersion = null) + protected virtual bool AllowAllCertificates => true; + + protected WinHttpClientHandler CreateHttpClientHandler(Version useVersion = null) { useVersion ??= HttpVersion.Version11; WinHttpClientHandler handler = new WinHttpClientHandler(useVersion); - if (useVersion >= HttpVersion20.Value) + if (useVersion >= HttpVersion20.Value && AllowAllCertificates) { handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates; } 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 ae87a174901981..94c474d607ddff 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs @@ -275,6 +275,8 @@ public sealed class PlatformHandler_HttpClientHandler_ServerCertificates_Http2_T { protected override Version UseVersion => HttpVersion20.Value; + protected override bool AllowAllCertificates => false; + public PlatformHandler_HttpClientHandler_ServerCertificates_Http2_Test(ITestOutputHelper output) : base(output) { } } From 1b306d968136a0b75db8caff2874c1b768de10ab Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Wed, 18 Mar 2020 14:55:59 +0100 Subject: [PATCH 21/26] Tests using RemoteExecutor fixed --- .../HttpClientHandlerTest.Cancellation.cs | 8 ++-- ...entHandlerTest.MaxResponseHeadersLength.cs | 2 +- .../Net/Http/HttpClientHandlerTest.Proxy.cs | 2 +- .../System/Net/Http/HttpClientHandlerTest.cs | 47 +++++++++++++++++-- .../Net/Http/HttpClientHandlerTestBase.cs | 4 +- ...ttpClientHandlerTestBase.WinHttpHandler.cs | 4 +- .../FunctionalTests/PlatformHandlerTest.cs | 6 +-- 7 files changed, 57 insertions(+), 16 deletions(-) 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 c602b793a4dc97..84da77eeddaf27 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs @@ -44,7 +44,7 @@ public async Task PostAsync_CancelDuringRequestContentSend_TaskCanceledQuickly(b } #if WINHTTPHANDLER_TEST - if (UseVersion >= HttpVersion20.Value && !PlatformDetection.IsWindows10Version1607OrGreater) + if (UseVersion >= HttpVersion20.Value) { throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); } @@ -98,7 +98,7 @@ public async Task GetAsync_CancelDuringResponseHeadersReceived_TaskCanceledQuick } #if WINHTTPHANDLER_TEST - if (UseVersion >= HttpVersion20.Value && !PlatformDetection.IsWindows10Version1607OrGreater) + if (UseVersion >= HttpVersion20.Value) { throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); } @@ -215,7 +215,7 @@ public async Task GetAsync_CancelDuringResponseBodyReceived_Unbuffered_TaskCance } #if WINHTTPHANDLER_TEST - if (UseVersion >= HttpVersion20.Value && !PlatformDetection.IsWindows10Version1607OrGreater) + if (UseVersion >= HttpVersion20.Value) { throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); } @@ -278,7 +278,7 @@ await ValidateClientCancellationAsync(async () => public async Task GetAsync_CancelPendingRequests_DoesntCancelReadAsyncOnResponseStream(CancellationMode mode, bool copyToAsync) { #if WINHTTPHANDLER_TEST - if (UseVersion >= HttpVersion20.Value && !PlatformDetection.IsWindows10Version1607OrGreater) + if (UseVersion >= HttpVersion20.Value) { throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 80f26d10a85edb..2089565a0cf9d0 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -55,7 +55,7 @@ public void ValidValue_SetGet_Roundtrips(int validValue) public async Task SetAfterUse_Throws() { #if WINHTTPHANDLER_TEST - if (UseVersion >= HttpVersion20.Value && !PlatformDetection.IsWindows10Version1607OrGreater) + if (UseVersion >= HttpVersion20.Value) { throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); } 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 275670d3951c72..622e227161c3b7 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs @@ -34,7 +34,7 @@ public HttpClientHandler_Proxy_Test(ITestOutputHelper output) : base(output) { } public async Task Dispose_HandlerWithProxy_ProxyNotDisposed() { #if WINHTTPHANDLER_TEST - if (UseVersion >= HttpVersion20.Value && !PlatformDetection.IsWindows10Version1607OrGreater) + if (UseVersion >= HttpVersion20.Value) { throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index e232d2cc903cac..bdc3edd093188e 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -226,6 +226,12 @@ public async Task SendAsync_SimpleGet_Success(Configuration.Http.RemoteServer re [ConditionalFact] public async Task GetAsync_IPv6LinkLocalAddressUri_Success() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif using (HttpClient client = CreateHttpClient()) { var options = new GenericLoopbackOptions { Address = TestHelper.GetIPv6LinkLocalAddress() }; @@ -1265,6 +1271,12 @@ await connection.ReadRequestHeaderAndSendCustomResponseAsync( [InlineData(null)] public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(bool? chunked) { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif if (LoopbackServerFactory.Version >= HttpVersion20.Value && chunked == true) { throw new SkipTestException("Chunking is not supported on HTTP/2 and later."); @@ -1415,9 +1427,19 @@ await server.AcceptConnectionAsync(async connection => }); } +#if WINHTTPHANDLER_TEST + [ConditionalFact] +#else [Fact] +#endif public async Task ReadAsStreamAsync_EmptyResponseBody_HandlerProducesWellBehavedResponseStream() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { using (var client = new HttpMessageInvoker(CreateHttpClientHandler())) @@ -1500,10 +1522,19 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => }, server => server.AcceptConnectionSendResponseAndCloseAsync()); } - +#if WINHTTPHANDLER_TEST + [ConditionalFact] +#else [Fact] +#endif public async Task Dispose_DisposingHandlerCancelsActiveOperationsWithoutResponses() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif await LoopbackServerFactory.CreateServerAsync(async (server1, url1) => { await LoopbackServerFactory.CreateServerAsync(async (server2, url2) => @@ -2551,12 +2582,22 @@ await LoopbackServer.CreateServerAsync(async (server, url) => return receivedRequestVersion; } -#endregion + #endregion -#region Uri wire transmission encoding tests + #region Uri wire transmission encoding tests +#if WINHTTPHANDLER_TEST + [ConditionalFact] +#else [Fact] +#endif public async Task SendRequest_UriPathHasReservedChars_ServerReceivedExpectedPath() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif await LoopbackServerFactory.CreateServerAsync(async (server, rootUrl) => { var uri = new Uri($"{rootUrl.Scheme}://{rootUrl.Host}:{rootUrl.Port}/test[]"); diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs index 154eb11a625a43..003e344d74042a 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs @@ -38,7 +38,7 @@ protected HttpClient CreateHttpClient(HttpMessageHandler handler) => #endif }; - protected HttpClient CreateHttpClient(string useVersionString) => + protected static HttpClient CreateHttpClient(string useVersionString) => CreateHttpClient(CreateHttpClientHandler(useVersionString), useVersionString); protected static HttpClient CreateHttpClient(HttpMessageHandler handler, string useVersionString) => @@ -50,7 +50,7 @@ protected static HttpClient CreateHttpClient(HttpMessageHandler handler, string protected HttpClientHandler CreateHttpClientHandler() => CreateHttpClientHandler(UseVersion); - protected HttpClientHandler CreateHttpClientHandler(string useVersionString) => + protected static HttpClientHandler CreateHttpClientHandler(string useVersionString) => CreateHttpClientHandler(Version.Parse(useVersionString)); protected LoopbackServerFactory LoopbackServerFactory => GetFactoryForVersion(UseVersion); 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 635febaba5f956..516e9f7d3508b8 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 @@ -11,9 +11,9 @@ public abstract partial class HttpClientHandlerTestBase : FileCleanupTestBase { protected static bool IsWinHttpHandler => true; - protected virtual bool AllowAllCertificates => true; + protected static bool AllowAllCertificates { get; set; } = true; - protected WinHttpClientHandler CreateHttpClientHandler(Version useVersion = null) + protected static WinHttpClientHandler CreateHttpClientHandler(Version useVersion = null) { useVersion ??= HttpVersion.Version11; 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 94c474d607ddff..3bd5bc40488ff8 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs @@ -275,9 +275,9 @@ public sealed class PlatformHandler_HttpClientHandler_ServerCertificates_Http2_T { protected override Version UseVersion => HttpVersion20.Value; - protected override bool AllowAllCertificates => false; - - public PlatformHandler_HttpClientHandler_ServerCertificates_Http2_Test(ITestOutputHelper output) : base(output) { } + public PlatformHandler_HttpClientHandler_ServerCertificates_Http2_Test(ITestOutputHelper output) : base(output) { + AllowAllCertificates = false; + } } public sealed class PlatformHandler_PostScenario_Http2_Test : PostScenarioTest From aeca6839d478e5ea406562088e479f96342fe1f8 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Wed, 18 Mar 2020 15:35:01 +0100 Subject: [PATCH 22/26] Unsupported tests disabled --- .../System/Net/Http/HttpClientHandlerTest.cs | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index bdc3edd093188e..1ec0d09d8cca58 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -250,10 +250,20 @@ await TestHelper.WhenAllCompletedOrAnyFailed( } } +#if WINHTTPHANDLER_TEST + [ConditionalTheory] +#else [Theory] +#endif [MemberData(nameof(GetAsync_IPBasedUri_Success_MemberData))] public async Task GetAsync_IPBasedUri_Success(IPAddress address) { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif using (HttpClient client = CreateHttpClient()) { var options = new GenericLoopbackOptions { Address = address }; @@ -562,11 +572,21 @@ public async Task GetAsync_ServerNeedsAuthAndNoCredential_StatusCodeUnauthorized } } +#if WINHTTPHANDLER_TEST + [ConditionalTheory] +#else [Theory] +#endif [InlineData("WWW-Authenticate", "CustomAuth")] [InlineData("", "")] // RFC7235 requires servers to send this header with 401 but some servers don't. public async Task GetAsync_ServerNeedsNonStandardAuthAndSetCredential_StatusCodeUnauthorized(string authHeadrName, string authHeaderValue) { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif await LoopbackServerFactory.CreateServerAsync(async (server, url) => { HttpClientHandler handler = CreateHttpClientHandler(); @@ -1897,9 +1917,19 @@ public async Task PostAsync_ExpectContinue_Success(bool? expectContinue, string } } +#if WINHTTPHANDLER_TEST + [ConditionalFact] +#else [Fact] +#endif public async Task GetAsync_ExpectContinueTrue_NoContent_StillSendsHeader() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif const string ExpectedContent = "Hello, expecting and continuing world."; var clientCompleted = new TaskCompletionSource(); await LoopbackServerFactory.CreateClientAndServerAsync(async uri => @@ -1936,10 +1966,20 @@ public static IEnumerable Interim1xxStatusCode() yield return new object[] { (HttpStatusCode) 199 }; } +#if WINHTTPHANDLER_TEST + [ConditionalTheory] +#else [Theory] +#endif [MemberData(nameof(Interim1xxStatusCode))] public async Task SendAsync_1xxResponsesWithHeaders_InterimResponsesHeadersIgnored(HttpStatusCode responseStatusCode) { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif var clientFinished = new TaskCompletionSource(); const string TestString = "test"; const string CookieHeaderExpected = "yummy_cookie=choco"; @@ -2000,10 +2040,20 @@ await server.AcceptConnectionAsync(async connection => }); } +#if WINHTTPHANDLER_TEST + [ConditionalTheory] +#else [Theory] +#endif [MemberData(nameof(Interim1xxStatusCode))] public async Task SendAsync_Unexpected1xxResponses_DropAllInterimResponses(HttpStatusCode responseStatusCode) { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif var clientFinished = new TaskCompletionSource(); const string TestString = "test"; @@ -2040,9 +2090,19 @@ await server.AcceptConnectionAsync(async connection => }); } +#if WINHTTPHANDLER_TEST + [ConditionalFact] +#else [Fact] +#endif public async Task SendAsync_MultipleExpected100Responses_ReceivesCorrectResponse() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif var clientFinished = new TaskCompletionSource(); const string TestString = "test"; @@ -2079,9 +2139,19 @@ await server.AcceptConnectionAsync(async connection => }); } +#if WINHTTPHANDLER_TEST + [ConditionalFact] +#else [Fact] +#endif public async Task SendAsync_No100ContinueReceived_RequestBodySentEventually() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif var clientFinished = new TaskCompletionSource(); const string RequestString = "request"; const string ResponseString = "response"; @@ -2508,9 +2578,19 @@ public async Task SendAsync_RequestVersion20_ResponseVersion20IfHttp2Supported(U } } +#if WINHTTPHANDLER_TEST + [ConditionalFact] +#else [Fact] +#endif public async Task SendAsync_RequestVersion20_HttpNotHttps_NoUpgradeRequest() { +#if WINHTTPHANDLER_TEST + if (UseVersion >= HttpVersion20.Value) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { using (HttpClient client = CreateHttpClient()) From 35ff8e5ceeead03309a4d242b46f22b40366364b Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Thu, 19 Mar 2020 12:57:13 +0100 Subject: [PATCH 23/26] Comments addressed --- .../tests/System/Net/Http/Http2Frames.cs | 7 ----- .../Net/Http/Http2LoopbackConnection.cs | 29 ------------------- .../System/Net/Http/Http2LoopbackServer.cs | 4 --- .../HttpClientHandlerTest.Decompression.cs | 3 +- .../System/Net/Http/HttpProtocolTests.cs | 9 ++---- .../System/Net/Http/HttpRetryProtocolTests.cs | 3 +- .../tests/System/Net/Http/QPackTestDecoder.cs | 4 +-- .../tests/System/Net/StreamArrayExtensions.cs | 9 ++++++ 8 files changed, 15 insertions(+), 53 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http2Frames.cs b/src/libraries/Common/tests/System/Net/Http/Http2Frames.cs index e0ec7580ebbbba..af0f245b1b8215 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2Frames.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2Frames.cs @@ -548,19 +548,12 @@ public override void WriteTo(Span buffer) BinaryPrimitives.WriteUInt16BigEndian(buffer, checked((ushort)Origin.Length)); buffer = buffer.Slice(2); -#if !NETFRAMEWORK - Encoding.ASCII.GetBytes(Origin, buffer); - buffer = buffer.Slice(Origin.Length); - - Encoding.ASCII.GetBytes(AltSvc, buffer); -#else var tmpBuffer = Encoding.ASCII.GetBytes(Origin); tmpBuffer.CopyTo(buffer); buffer = buffer.Slice(Origin.Length); tmpBuffer = Encoding.ASCII.GetBytes(AltSvc); tmpBuffer.CopyTo(buffer); -#endif } public override string ToString() => $"{base.ToString()}\n{nameof(Origin)}: {Origin}\n{nameof(AltSvc)}: {AltSvc}"; diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index e9d7cd979cb89d..ee774e0f23090c 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -99,7 +99,6 @@ public async Task WriteFrameAsync(Frame frame) // Read until the buffer is full // Return false on EOF, throw on partial read -#if !NETFRAMEWORK private async Task FillBufferAsync(Memory buffer, CancellationToken cancellationToken = default(CancellationToken)) { int readBytes = await _connectionStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); @@ -122,30 +121,6 @@ public async Task WriteFrameAsync(Frame frame) return true; } -#else - private async Task FillBufferAsync(byte[] buffer, CancellationToken cancellationToken = default(CancellationToken)) - { - int readBytes = await _connectionStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); - if (readBytes == 0) - { - return false; - } - - buffer = buffer.Skip(readBytes).ToArray(); - while (buffer.Length > 0) - { - readBytes = await _connectionStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); - if (readBytes == 0) - { - throw new Exception("Connection closed when expecting more data."); - } - - buffer = buffer.Skip(readBytes).ToArray(); - } - - return true; - } -#endif public async Task ReadFrameAsync(TimeSpan timeout) { @@ -365,11 +340,7 @@ private static (int bytesConsumed, string value) DecodeString(ReadOnlySpan } else { -#if !NETFRAMEWORK - string value = Encoding.ASCII.GetString(headerBlock.Slice(bytesConsumed, stringLength)); -#else string value = Encoding.ASCII.GetString(headerBlock.Slice(bytesConsumed, stringLength).ToArray()); -#endif return (bytesConsumed + stringLength, value); } } diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs index b4b38ba3158ef8..4d3486c3a80c74 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs @@ -267,10 +267,6 @@ public enum ProtocolErrors public static class HttpVersion20 { -#if !NETFRAMEWORK - public static readonly Version Value = HttpVersion.Version20; -#else public static readonly Version Value = new Version(2, 0); -#endif } } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs index 4b51908743b2a2..fa0b630594b7f1 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs @@ -153,8 +153,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => await server.AcceptConnectionAsync(async connection => { await connection.ReadRequestHeaderAsync(); - string text = $"HTTP/1.1 200 OK\r\nContent-Encoding: {encodingName}\r\n\r\n"; - await connection.Writer.WriteAsync(text); + await connection.Writer.WriteAsync($"HTTP/1.1 200 OK\r\nContent-Encoding: {encodingName}\r\n\r\n"); await connection.Stream.WriteAsync(compressedContent); }); }); diff --git a/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs b/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs index 003467ddfa7233..96fcbec2eeb7d0 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs @@ -460,7 +460,7 @@ public async Task GetAsync_Chunked_VaryingSizeChunks_ReceivedCorrectly(int maxCh await LoopbackServer.CreateClientAndServerAsync(async uri => { using (HttpMessageInvoker client = new HttpMessageInvoker(CreateHttpClientHandler())) - using (HttpResponseMessage resp = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, uri) { Version = UseVersion }, CancellationToken.None)) + using (HttpResponseMessage resp = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, uri) { Version = base.UseVersion }, CancellationToken.None)) using (Stream respStream = await resp.Content.ReadAsStreamAsync()) { var actualData = new MemoryStream(); @@ -491,12 +491,7 @@ await server.AcceptConnectionAsync(async connection => { await connection.ReadRequestHeaderAsync(); - string text = $"HTTP/1.1 200 OK{lineEnding}Transfer-Encoding: chunked{lineEnding}{lineEnding}"; -#if !NETFRAMEWORK - await connection.Writer.WriteAsync(text); -#else - await connection.Writer.WriteAsync(text.ToCharArray(), 0, text.Length); -#endif + await connection.Writer.WriteAsync($"HTTP/1.1 200 OK{lineEnding}Transfer-Encoding: chunked{lineEnding}{lineEnding}"); for (int bytesSent = 0; bytesSent < expectedData.Length;) { int bytesRemaining = expectedData.Length - bytesSent; diff --git a/src/libraries/Common/tests/System/Net/Http/HttpRetryProtocolTests.cs b/src/libraries/Common/tests/System/Net/Http/HttpRetryProtocolTests.cs index cb4de58264f024..8f6808e17da10d 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpRetryProtocolTests.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpRetryProtocolTests.cs @@ -130,8 +130,7 @@ protected override async Task SerializeToStreamAsync(Stream stream, TransportCon { _sendingContent.SetResult(true); await _connectionClosed; - byte[] bytes = Encoding.UTF8.GetBytes(_longContent); - await stream.WriteAsync(bytes); + await stream.WriteAsync(Encoding.UTF8.GetBytes(_longContent)); } protected override bool TryComputeLength(out long length) diff --git a/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs b/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs index c3cbd9c98e89c8..432b868b3352af 100644 --- a/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs +++ b/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs @@ -210,7 +210,7 @@ public static (int bytesConsumed, int value) DecodeInteger(ReadOnlySpan he new HttpHeaderData("x-frame-options", "sameorigin"), }; -//#if NETFRAMEWORK +#if NETFRAMEWORK private static class BitOperations { public static int LeadingZeroCount(byte value) @@ -235,6 +235,6 @@ public static int TrailingZeroCount(int value) return count; } } -//#endif +#endif } } diff --git a/src/libraries/Common/tests/System/Net/StreamArrayExtensions.cs b/src/libraries/Common/tests/System/Net/StreamArrayExtensions.cs index 012fefef5257ed..0d21fd2cab84c0 100644 --- a/src/libraries/Common/tests/System/Net/StreamArrayExtensions.cs +++ b/src/libraries/Common/tests/System/Net/StreamArrayExtensions.cs @@ -4,6 +4,7 @@ using System.IO; using System.Runtime.InteropServices; +using System.Threading; using System.Threading.Tasks; using Xunit; @@ -23,5 +24,13 @@ public static ValueTask WriteAsync(this StreamWriter writer, string text) { return new ValueTask(writer.WriteAsync(text.ToCharArray(), 0, text.Length)); } + + public static ValueTask ReadAsync(this Stream stream, ReadOnlyMemory buffer, CancellationToken cancellationToken) + { + bool isArray = MemoryMarshal.TryGetArray(buffer, out ArraySegment segment); + Assert.True(isArray); + + return new ValueTask(stream.ReadAsync(segment.Array, segment.Offset, segment.Count, cancellationToken)); + } } } From 378234a9446ed912d32054a651f32b88fcea7152 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Thu, 19 Mar 2020 13:11:40 +0100 Subject: [PATCH 24/26] ConditionalTheory and ConditionalFact are set on skippable tests for all platforms --- .../HttpClientHandlerTest.Cancellation.cs | 12 ----- ...entHandlerTest.MaxResponseHeadersLength.cs | 4 -- .../Net/Http/HttpClientHandlerTest.Proxy.cs | 4 -- .../System/Net/Http/HttpClientHandlerTest.cs | 44 ------------------- 4 files changed, 64 deletions(-) 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 84da77eeddaf27..63ec030feee543 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs @@ -28,11 +28,7 @@ public abstract class HttpClientHandler_Cancellation_Test : HttpClientHandlerTes { public HttpClientHandler_Cancellation_Test(ITestOutputHelper output) : base(output) { } -#if WINHTTPHANDLER_TEST [ConditionalTheory] -#else - [Theory] -#endif [InlineData(false, CancellationMode.Token)] [InlineData(true, CancellationMode.Token)] public async Task PostAsync_CancelDuringRequestContentSend_TaskCanceledQuickly(bool chunkedTransfer, CancellationMode mode) @@ -200,11 +196,7 @@ await ValidateClientCancellationAsync(async () => } } -#if WINHTTPHANDLER_TEST [ConditionalTheory] -#else - [Theory] -#endif [MemberData(nameof(ThreeBools))] public async Task GetAsync_CancelDuringResponseBodyReceived_Unbuffered_TaskCanceledQuickly(bool chunkedTransfer, bool connectionClose, bool readOrCopyToAsync) { @@ -266,11 +258,7 @@ await ValidateClientCancellationAsync(async () => }); } } -#if WINHTTPHANDLER_TEST [ConditionalTheory] -#else - [Theory] -#endif [InlineData(CancellationMode.CancelPendingRequests, false)] [InlineData(CancellationMode.DisposeHttpClient, false)] [InlineData(CancellationMode.CancelPendingRequests, true)] diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 2089565a0cf9d0..dd6daf3e359576 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -47,11 +47,7 @@ public void ValidValue_SetGet_Roundtrips(int validValue) } } -#if WINHTTPHANDLER_TEST [ConditionalFact] -#else - [Fact] -#endif public async Task SetAfterUse_Throws() { #if WINHTTPHANDLER_TEST 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 622e227161c3b7..30e75cda0a1779 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs @@ -26,11 +26,7 @@ public abstract class HttpClientHandler_Proxy_Test : HttpClientHandlerTestBase { public HttpClientHandler_Proxy_Test(ITestOutputHelper output) : base(output) { } -#if WINHTTPHANDLER_TEST [ConditionalFact] -#else - [Fact] -#endif public async Task Dispose_HandlerWithProxy_ProxyNotDisposed() { #if WINHTTPHANDLER_TEST diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 1ec0d09d8cca58..d72a044df75019 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -250,11 +250,7 @@ await TestHelper.WhenAllCompletedOrAnyFailed( } } -#if WINHTTPHANDLER_TEST [ConditionalTheory] -#else - [Theory] -#endif [MemberData(nameof(GetAsync_IPBasedUri_Success_MemberData))] public async Task GetAsync_IPBasedUri_Success(IPAddress address) { @@ -572,11 +568,7 @@ public async Task GetAsync_ServerNeedsAuthAndNoCredential_StatusCodeUnauthorized } } -#if WINHTTPHANDLER_TEST [ConditionalTheory] -#else - [Theory] -#endif [InlineData("WWW-Authenticate", "CustomAuth")] [InlineData("", "")] // RFC7235 requires servers to send this header with 401 but some servers don't. public async Task GetAsync_ServerNeedsNonStandardAuthAndSetCredential_StatusCodeUnauthorized(string authHeadrName, string authHeaderValue) @@ -1447,11 +1439,7 @@ await server.AcceptConnectionAsync(async connection => }); } -#if WINHTTPHANDLER_TEST [ConditionalFact] -#else - [Fact] -#endif public async Task ReadAsStreamAsync_EmptyResponseBody_HandlerProducesWellBehavedResponseStream() { #if WINHTTPHANDLER_TEST @@ -1542,11 +1530,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => }, server => server.AcceptConnectionSendResponseAndCloseAsync()); } -#if WINHTTPHANDLER_TEST [ConditionalFact] -#else - [Fact] -#endif public async Task Dispose_DisposingHandlerCancelsActiveOperationsWithoutResponses() { #if WINHTTPHANDLER_TEST @@ -1917,11 +1901,7 @@ public async Task PostAsync_ExpectContinue_Success(bool? expectContinue, string } } -#if WINHTTPHANDLER_TEST [ConditionalFact] -#else - [Fact] -#endif public async Task GetAsync_ExpectContinueTrue_NoContent_StillSendsHeader() { #if WINHTTPHANDLER_TEST @@ -1966,11 +1946,7 @@ public static IEnumerable Interim1xxStatusCode() yield return new object[] { (HttpStatusCode) 199 }; } -#if WINHTTPHANDLER_TEST [ConditionalTheory] -#else - [Theory] -#endif [MemberData(nameof(Interim1xxStatusCode))] public async Task SendAsync_1xxResponsesWithHeaders_InterimResponsesHeadersIgnored(HttpStatusCode responseStatusCode) { @@ -2040,11 +2016,7 @@ await server.AcceptConnectionAsync(async connection => }); } -#if WINHTTPHANDLER_TEST [ConditionalTheory] -#else - [Theory] -#endif [MemberData(nameof(Interim1xxStatusCode))] public async Task SendAsync_Unexpected1xxResponses_DropAllInterimResponses(HttpStatusCode responseStatusCode) { @@ -2090,11 +2062,7 @@ await server.AcceptConnectionAsync(async connection => }); } -#if WINHTTPHANDLER_TEST [ConditionalFact] -#else - [Fact] -#endif public async Task SendAsync_MultipleExpected100Responses_ReceivesCorrectResponse() { #if WINHTTPHANDLER_TEST @@ -2139,11 +2107,7 @@ await server.AcceptConnectionAsync(async connection => }); } -#if WINHTTPHANDLER_TEST [ConditionalFact] -#else - [Fact] -#endif public async Task SendAsync_No100ContinueReceived_RequestBodySentEventually() { #if WINHTTPHANDLER_TEST @@ -2578,11 +2542,7 @@ public async Task SendAsync_RequestVersion20_ResponseVersion20IfHttp2Supported(U } } -#if WINHTTPHANDLER_TEST [ConditionalFact] -#else - [Fact] -#endif public async Task SendAsync_RequestVersion20_HttpNotHttps_NoUpgradeRequest() { #if WINHTTPHANDLER_TEST @@ -2665,11 +2625,7 @@ await LoopbackServer.CreateServerAsync(async (server, url) => #endregion #region Uri wire transmission encoding tests -#if WINHTTPHANDLER_TEST [ConditionalFact] -#else - [Fact] -#endif public async Task SendRequest_UriPathHasReservedChars_ServerReceivedExpectedPath() { #if WINHTTPHANDLER_TEST From 885b74e4ab8418b43c2f4ceb37a2b4944d2929c5 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Thu, 19 Mar 2020 13:20:43 +0100 Subject: [PATCH 25/26] Protocol version checks fixed --- .../System/Net/Http/HttpClientHandlerTest.Authentication.cs | 2 +- .../System/Net/Http/HttpClientHandlerTest.Cancellation.cs | 6 ++++++ .../Net/Http/HttpClientHandlerTest.ServerCertificates.cs | 4 ++-- .../Common/tests/System/Net/Http/HttpClientHandlerTest.cs | 2 +- .../Common/tests/System/Net/Http/HttpProtocolTests.cs | 2 +- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs index f7ec7167ded05c..9c2c1e2c74e53e 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs @@ -603,7 +603,7 @@ public async Task Credentials_ServerUsesWindowsAuthentication_Success(string ser public async Task Credentials_ServerChallengesWithWindowsAuth_ClientSendsWindowsAuthHeader(string authScheme) { #if WINHTTPHANDLER_TEST - if (UseVersion >= HttpVersion.Version11) + if (UseVersion > HttpVersion.Version11) { throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); } 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 63ec030feee543..0a14a64f5da421 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs @@ -522,6 +522,12 @@ public static IEnumerable PostAsync_Cancel_CancellationTokenPassedToCo [MemberData(nameof(PostAsync_Cancel_CancellationTokenPassedToContent_MemberData))] public async Task PostAsync_Cancel_CancellationTokenPassedToContent(HttpContent content, CancellationTokenSource cancellationTokenSource) { +#if WINHTTPHANDLER_TEST + if (UseVersion > HttpVersion.Version11) + { + throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); + } +#endif await LoopbackServerFactory.CreateClientAndServerAsync( async uri => { 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 4f541c48c5f0d5..36443a3df829fe 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs @@ -35,7 +35,7 @@ public HttpClientHandler_ServerCertificates_Test(ITestOutputHelper output) : bas public void Ctor_ExpectedDefaultValues() { #if WINHTTPHANDLER_TEST - if (UseVersion >= HttpVersion.Version11) + if (UseVersion > HttpVersion.Version11) { throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); } @@ -51,7 +51,7 @@ public void Ctor_ExpectedDefaultValues() public void ServerCertificateCustomValidationCallback_SetGet_Roundtrips() { #if WINHTTPHANDLER_TEST - if (UseVersion >= HttpVersion.Version11) + if (UseVersion > HttpVersion.Version11) { throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index d72a044df75019..8c7a0f7461e724 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -757,7 +757,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => public async Task PostAsync_ManyDifferentRequestHeaders_SentCorrectly() { #if WINHTTPHANDLER_TEST - if (UseVersion >= HttpVersion.Version11) + if (UseVersion > HttpVersion.Version11) { throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs b/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs index 96fcbec2eeb7d0..635cb2bed65c1b 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs @@ -24,7 +24,7 @@ public HttpProtocolTests(ITestOutputHelper output) : base(output) { } public async Task GetAsync_RequestVersion10_Success() { #if WINHTTPHANDLER_TEST - if (UseVersion >= HttpVersion.Version11) + if (UseVersion > HttpVersion.Version11) { throw new SkipTestException($"Test doesn't support {UseVersion} protocol."); } From 1cf8812ddbc0d6ad26d37cc7aacdb36fceeea7c9 Mon Sep 17 00:00:00 2001 From: Alexander Nikolaev Date: Thu, 19 Mar 2020 15:26:43 +0100 Subject: [PATCH 26/26] PostAsync_Cancel_CancellationTokenPassedToContent marked as Condtional --- .../tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0a14a64f5da421..b248f3470bbdda 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs @@ -518,7 +518,7 @@ public static IEnumerable PostAsync_Cancel_CancellationTokenPassedToCo #if !NETFRAMEWORK [OuterLoop("Uses Task.Delay")] - [Theory] + [ConditionalTheory] [MemberData(nameof(PostAsync_Cancel_CancellationTokenPassedToContent_MemberData))] public async Task PostAsync_Cancel_CancellationTokenPassedToContent(HttpContent content, CancellationTokenSource cancellationTokenSource) {