Skip to content

Commit

Permalink
WinHttpHandler tests are back (dotnet#1676)
Browse files Browse the repository at this point in the history
The tests used by PlatformHandlerTest moved to Common/tests in order to share them between System.Net.Http and System.Net.Http.WinHttpHandler.
The added conditions correspond to the state before WinHttpHandler removal. They're just based on IsWinHttpHandler instead of UseSocketHandler.
Some of the code must be conditionally compiled since there is no usable common base class for HttpClientHandler and WinHttpHandler. Other issues solved by introducing WinHttpClientHandler for testing purposes. It corresponds to HttpClientHandler.Windows.cs code from before its removal.
  • Loading branch information
ManickaP committed Jan 21, 2020
1 parent a6738ed commit 26298bc
Show file tree
Hide file tree
Showing 39 changed files with 873 additions and 317 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ namespace System.Net.Http.Functional.Tests
{
using Configuration = System.Net.Test.Common.Configuration;

#if WINHTTPHANDLER_TEST
using HttpClientHandler = System.Net.Http.WinHttpClientHandler;
#endif

[PlatformSpecific(TestPlatforms.Windows)]
public abstract class DefaultCredentialsTest : HttpClientHandlerTestBase
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ namespace System.Net.Http.Functional.Tests
{
using Configuration = System.Net.Test.Common.Configuration;

#if WINHTTPHANDLER_TEST
using HttpClientHandler = System.Net.Http.WinHttpClientHandler;
#endif

public abstract class HttpClientEKUTest : HttpClientHandlerTestBase
{
private static bool CanTestCertificates =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,27 @@ namespace System.Net.Http.Functional.Tests
{
using Configuration = System.Net.Test.Common.Configuration;

#if WINHTTPHANDLER_TEST
using HttpClientHandler = System.Net.Http.WinHttpClientHandler;
#endif

public abstract class HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test : HttpClientHandlerTestBase
{
private static bool ClientSupportsDHECipherSuites => (!PlatformDetection.IsWindows || PlatformDetection.IsWindows10Version1607OrGreater);

public HttpClientHandler_DangerousAcceptAllCertificatesValidator_Test(ITestOutputHelper output) : base(output) { }

#if !WINHTTPHANDLER_TEST
[Fact]
public void SingletonReturnsTrue()
{
Assert.NotNull(HttpClientHandler.DangerousAcceptAnyServerCertificateValidator);
Assert.Same(HttpClientHandler.DangerousAcceptAnyServerCertificateValidator, HttpClientHandler.DangerousAcceptAnyServerCertificateValidator);
Assert.True(HttpClientHandler.DangerousAcceptAnyServerCertificateValidator(null, null, null, SslPolicyErrors.None));
}
#endif

[ConditionalTheory]
[Theory]
[InlineData(SslProtocols.Tls, false)] // try various protocols to ensure we correctly set versions even when accepting all certs
[InlineData(SslProtocols.Tls, true)]
[InlineData(SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls, false)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ namespace System.Net.Http.Functional.Tests
{
using Configuration = System.Net.Test.Common.Configuration;

#if WINHTTPHANDLER_TEST
using HttpClientHandler = System.Net.Http.WinHttpClientHandler;
#endif

public abstract class HttpClientHandler_Authentication_Test : HttpClientHandlerTestBase
{
private const string Username = "testusername";
Expand Down Expand Up @@ -70,6 +74,12 @@ await TestHelper.WhenAllCompletedOrAnyFailedWithTimeout(TestHelper.PassingTestTi
[InlineData("WWW-Authenticate: Digest realm=\"hello1\", nonce=\"hello\", algorithm=MD5\r\nWWW-Authenticate: Digest realm=\"hello\", nonce=\"hello\", algorithm=MD5\r\n")]
public async Task HttpClientHandler_MultipleAuthenticateHeaders_WithSameAuth_Succeeds(string authenticateHeader)
{
if (IsWinHttpHandler)
{
// TODO: https://github.com/dotnet/corefx/issues/28065: Fix failing authentication test cases on different httpclienthandlers.
return;
}

await HttpClientHandler_MultipleAuthenticateHeaders_Succeeds(authenticateHeader);
}

Expand Down Expand Up @@ -413,6 +423,12 @@ await LoopbackServer.CreateClientAndServerAsync(async uri =>
[Fact]
public async Task PreAuthenticate_SuccessfulBasic_ThenDigestChallenged()
{
if (IsWinHttpHandler)
{
// WinHttpHandler fails with Unauthorized after the basic preauth fails.
return;
}

await LoopbackServer.CreateClientAndServerAsync(async uri =>
{
using (HttpClientHandler handler = CreateHttpClientHandler())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ namespace System.Net.Http.Functional.Tests
{
using Configuration = System.Net.Test.Common.Configuration;

#if WINHTTPHANDLER_TEST
using HttpClientHandler = System.Net.Http.WinHttpClientHandler;
#endif

public abstract class HttpClientHandlerTest_AutoRedirect : HttpClientHandlerTestBase
{
private const string ExpectedContent = "Test content";
Expand Down Expand Up @@ -68,6 +72,12 @@ public HttpClientHandlerTest_AutoRedirect(ITestOutputHelper output) : base(outpu
[Theory, MemberData(nameof(RemoteServersAndRedirectStatusCodes))]
public async Task GetAsync_AllowAutoRedirectFalse_RedirectFromHttpToHttp_StatusCodeRedirect(Configuration.Http.RemoteServer remoteServer, int statusCode)
{
if (statusCode == 308 && (IsWinHttpHandler && PlatformDetection.WindowsVersion < 10))
{
// 308 redirects are not supported on old versions of WinHttp, or on .NET Framework.
return;
}

HttpClientHandler handler = CreateHttpClientHandler();
handler.AllowAutoRedirect = false;
using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler))
Expand All @@ -89,6 +99,12 @@ public async Task GetAsync_AllowAutoRedirectFalse_RedirectFromHttpToHttp_StatusC
public async Task AllowAutoRedirect_True_ValidateNewMethodUsedOnRedirection(
int statusCode, string oldMethod, string newMethod)
{
if (statusCode == 308 && (IsWinHttpHandler && PlatformDetection.WindowsVersion < 10))
{
// 308 redirects are not supported on old versions of WinHttp, or on .NET Framework.
return;
}

HttpClientHandler handler = CreateHttpClientHandler();
using (HttpClient client = CreateHttpClient(handler))
{
Expand Down Expand Up @@ -191,6 +207,12 @@ await LoopbackServer.CreateServerAsync(async (redirServer, redirUrl) =>
[Theory, MemberData(nameof(RemoteServersAndRedirectStatusCodes))]
public async Task GetAsync_AllowAutoRedirectTrue_RedirectFromHttpToHttp_StatusCodeOK(Configuration.Http.RemoteServer remoteServer, int statusCode)
{
if (statusCode == 308 && (IsWinHttpHandler && PlatformDetection.WindowsVersion < 10))
{
// 308 redirects are not supported on old versions of WinHttp, or on .NET Framework.
return;
}

HttpClientHandler handler = CreateHttpClientHandler();
handler.AllowAutoRedirect = true;
using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler))
Expand Down Expand Up @@ -254,6 +276,12 @@ public async Task GetAsync_AllowAutoRedirectTrue_RedirectFromHttpsToHttp_StatusC
[Fact]
public async Task GetAsync_AllowAutoRedirectTrue_RedirectWithoutLocation_ReturnsOriginalResponse()
{
// [ActiveIssue("https://github.com/dotnet/corefx/issues/24819", TestPlatforms.Windows)]
if (IsWinHttpHandler)
{
return;
}

HttpClientHandler handler = CreateHttpClientHandler();
handler.AllowAutoRedirect = true;
using (HttpClient client = CreateHttpClient(handler))
Expand Down Expand Up @@ -301,6 +329,13 @@ public async Task GetAsync_AllowAutoRedirectTrue_RedirectToUriWithParams_Request
[InlineData(3, 4)]
public async Task GetAsync_MaxAutomaticRedirectionsNServerHops_ThrowsIfTooMany(int maxHops, int hops)
{
if (IsWinHttpHandler && !PlatformDetection.IsWindows10Version1703OrGreater)
{
// Skip this test if using WinHttpHandler but on a release prior to Windows 10 Creators Update.
_output.WriteLine("Skipping test due to Windows 10 version prior to Version 1703.");
return;
}

HttpClientHandler handler = CreateHttpClientHandler();
handler.MaxAutomaticRedirections = maxHops;
using (HttpClient client = CreateHttpClient(handler))
Expand All @@ -320,9 +355,16 @@ public async Task GetAsync_MaxAutomaticRedirectionsNServerHops_ThrowsIfTooMany(i
}
else
{
using (HttpResponseMessage response = await t)
if (!IsWinHttpHandler)
{
using (HttpResponseMessage response = await t)
{
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
}
}
else
{
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
await Assert.ThrowsAsync<HttpRequestException>(() => t);
}
}
}
Expand Down Expand Up @@ -394,6 +436,20 @@ await TestHelper.WhenAllCompletedOrAnyFailed(
public async Task GetAsync_AllowAutoRedirectTrue_RetainsOriginalFragmentIfAppropriate(
string origFragment, string redirFragment, string expectedFragment, bool useRelativeRedirect)
{
if (IsWinHttpHandler)
{
// According to https://tools.ietf.org/html/rfc7231#section-7.1.2,
// "If the Location value provided in a 3xx (Redirection) response does
// not have a fragment component, a user agent MUST process the
// redirection as if the value inherits the fragment component of the
// URI reference used to generate the request target(i.e., the
// redirection inherits the original reference's fragment, if any)."
// WINHTTP is not doing this, and thus neither is WinHttpHandler.
// It also sometimes doesn't include the fragments for redirects
// even in other cases.
return;
}

HttpClientHandler handler = CreateHttpClientHandler();
handler.AllowAutoRedirect = true;
using (HttpClient client = CreateHttpClient(handler))
Expand Down Expand Up @@ -482,6 +538,12 @@ public async Task HttpClientHandler_CredentialIsNotCredentialCacheAfterRedirect_
[Theory, MemberData(nameof(RemoteServersAndRedirectStatusCodes))]
public async Task GetAsync_CredentialIsCredentialCacheUriRedirect_StatusCodeOK(Configuration.Http.RemoteServer remoteServer, int statusCode)
{
if (statusCode == 308 && (IsWinHttpHandler && PlatformDetection.WindowsVersion < 10))
{
// 308 redirects are not supported on old versions of WinHttp, or on .NET Framework.
return;
}

Uri uri = remoteServer.BasicAuthUriForCreds(userName: Username, password: Password);
Uri redirectUri = remoteServer.RedirectUriForCreds(
statusCode: statusCode,
Expand All @@ -508,6 +570,12 @@ public async Task GetAsync_CredentialIsCredentialCacheUriRedirect_StatusCodeOK(C
[Theory, MemberData(nameof(RemoteServersAndRedirectStatusCodes))]
public async Task DefaultHeaders_SetCredentials_ClearedOnRedirect(Configuration.Http.RemoteServer remoteServer, int statusCode)
{
if (statusCode == 308 && (IsWinHttpHandler && PlatformDetection.WindowsVersion < 10))
{
// 308 redirects are not supported on old versions of WinHttp, or on .NET Framework.
return;
}

HttpClientHandler handler = CreateHttpClientHandler();
using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

namespace System.Net.Http.Functional.Tests
{
#if WINHTTPHANDLER_TEST
using HttpClientHandler = System.Net.Http.WinHttpClientHandler;
#endif

public abstract class HttpClientHandler_Cancellation_Test : HttpClientHandlerTestBase
{
public HttpClientHandler_Cancellation_Test(ITestOutputHelper output) : base(output) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ namespace System.Net.Http.Functional.Tests
{
using Configuration = System.Net.Test.Common.Configuration;

#if WINHTTPHANDLER_TEST
using HttpClientHandler = System.Net.Http.WinHttpClientHandler;
#endif

public abstract class HttpClientHandler_ClientCertificates_Test : HttpClientHandlerTestBase
{
public HttpClientHandler_ClientCertificates_Test(ITestOutputHelper output) : base(output) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@

namespace System.Net.Http.Functional.Tests
{
#if WINHTTPHANDLER_TEST
using HttpClientHandler = System.Net.Http.WinHttpClientHandler;
#endif

public abstract class HttpClientHandlerTest_Cookies : HttpClientHandlerTestBase
{
private const string s_cookieName = "ABC";
Expand Down Expand Up @@ -526,6 +530,13 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async url =>
[Fact]
public async Task GetAsyncWithBasicAuth_ReceiveSetCookie_CookieSent()
{
if (IsWinHttpHandler)
{
// Issue https://github.com/dotnet/corefx/issues/26986
// WinHttpHandler does not process the cookie.
return;
}

await LoopbackServerFactory.CreateClientAndServerAsync(async url =>
{
HttpClientHandler handler = CreateHttpClientHandler();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ namespace System.Net.Http.Functional.Tests
{
using Configuration = System.Net.Test.Common.Configuration;

#if WINHTTPHANDLER_TEST
using HttpClientHandler = System.Net.Http.WinHttpClientHandler;
#endif

public abstract class HttpClientHandler_Decompression_Test : HttpClientHandlerTestBase
{
public HttpClientHandler_Decompression_Test(ITestOutputHelper output) : base(output) { }
Expand Down Expand Up @@ -59,6 +63,12 @@ public static IEnumerable<object[]> DecompressedResponse_MethodSpecified_Decompr
public async Task DecompressedResponse_MethodSpecified_DecompressedContentReturned(
string encodingName, Func<Stream, Stream> compress, DecompressionMethods methods)
{
// Brotli only supported on SocketsHttpHandler.
if (IsWinHttpHandler && encodingName == "br")
{
return;
}

var expectedContent = new byte[12345];
new Random(42).NextBytes(expectedContent);

Expand Down Expand Up @@ -179,12 +189,10 @@ public async Task GetAsync_SetAutomaticDecompression_HeadersRemoved(Configuratio
}

[Theory]
#if NETCOREAPP
[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", "")]
Expand All @@ -200,6 +208,12 @@ public async Task GetAsync_SetAutomaticDecompression_AcceptEncodingHeaderSentWit
string encodings,
string manualAcceptEncodingHeaderValues)
{
// Brotli only supported on SocketsHttpHandler.
if (IsWinHttpHandler && (encodings.Contains("br") || manualAcceptEncodingHeaderValues.Contains("br")))
{
return;
}

await LoopbackServer.CreateServerAsync(async (server, url) =>
{
HttpClientHandler handler = CreateHttpClientHandler();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ namespace System.Net.Http.Functional.Tests
{
using Configuration = System.Net.Test.Common.Configuration;

#if WINHTTPHANDLER_TEST
using HttpClientHandler = System.Net.Http.WinHttpClientHandler;
#endif

public abstract class HttpClientHandler_DefaultProxyCredentials_Test : HttpClientHandlerTestBase
{
public HttpClientHandler_DefaultProxyCredentials_Test(ITestOutputHelper output) : base(output) { }
Expand Down Expand Up @@ -76,6 +80,7 @@ await server.AcceptConnectionSendResponseAndCloseAsync(
});
}

#if !WINHTTPHANDLER_TEST
[ActiveIssue("https://github.com/dotnet/corefx/issues/42323")]
[OuterLoop("Uses external server")]
[PlatformSpecific(TestPlatforms.AnyUnix)] // The default proxy is resolved via WinINet on Windows.
Expand Down Expand Up @@ -122,6 +127,7 @@ await LoopbackServer.CreateServerAsync(async (proxyServer, proxyUri) =>
}
}, options);
}
#endif

// The purpose of this test is mainly to validate the .NET Framework OOB System.Net.Http implementation
// since it has an underlying dependency to WebRequest. While .NET Core implementations of System.Net.Http
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ namespace System.Net.Http.Functional.Tests
{
using Configuration = System.Net.Test.Common.Configuration;

#if WINHTTPHANDLER_TEST
using HttpClientHandler = System.Net.Http.WinHttpClientHandler;
#endif

public abstract class HttpClientHandler_MaxConnectionsPerServer_Test : HttpClientHandlerTestBase
{
public HttpClientHandler_MaxConnectionsPerServer_Test(ITestOutputHelper output) : base(output) { }
Expand Down
Loading

0 comments on commit 26298bc

Please sign in to comment.