From: Geoff Kizer Date: Fri, 5 Jul 2019 03:32:31 +0000 (-0700) Subject: ensure remote server HTTP2 tests are actually using HTTP2 and modify some remote... X-Git-Tag: submit/tizen/20210909.063632~11031^2~907^2~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e89fbd6b5e94fcbfc6bc59d4acb5cb824d2868ff;p=platform%2Fupstream%2Fdotnet%2Fruntime.git ensure remote server HTTP2 tests are actually using HTTP2 and modify some remote server tests to run over HTTP2 as well as HTTP/1.1 Commit migrated from https://github.com/dotnet/corefx/commit/f013baadc511567f012d6132f9e710fb3acafb66 --- diff --git a/src/libraries/Common/tests/System/Net/Configuration.Http.cs b/src/libraries/Common/tests/System/Net/Configuration.Http.cs index 90db9a9..2d38bdb 100644 --- a/src/libraries/Common/tests/System/Net/Configuration.Http.cs +++ b/src/libraries/Common/tests/System/Net/Configuration.Http.cs @@ -2,6 +2,8 @@ // 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.Collections; +using System.Collections.Generic; using System.Linq; namespace System.Net.Test.Common @@ -44,9 +46,6 @@ namespace System.Net.Test.Common public static string EchoClientCertificateRemoteServer => GetValue("COREFX_HTTPHOST_ECHOCLIENTCERT", "https://corefx-net-tls.azurewebsites.net/EchoClientCertificate.ashx"); public static string Http2ForceUnencryptedLoopback => GetValue("COREFX_HTTP2_FORCEUNENCRYPTEDLOOPBACK"); - private const string HttpScheme = "http"; - private const string HttpsScheme = "https"; - private const string EchoHandler = "Echo.ashx"; private const string EmptyContentHandler = "EmptyContent.ashx"; private const string RedirectHandler = "Redirect.ashx"; @@ -77,67 +76,68 @@ namespace System.Net.Test.Common public static readonly object[][] Http2Servers = { new object[] { new Uri("https://" + Http2Host) } }; public static readonly object[][] Http2NoPushServers = { new object[] { new Uri("https://" + Http2NoPushHost) } }; - public static Uri NegotiateAuthUriForDefaultCreds(bool secure) - { - return new Uri( - string.Format( - "{0}://{1}/{2}?auth=negotiate", - secure ? HttpsScheme : HttpScheme, - Host, - EchoHandler)); - } + public static readonly RemoteServer RemoteHttp11Server = new RemoteServer(new Uri("http://" + Host + "/"), HttpVersion.Version11); + public static readonly RemoteServer RemoteSecureHttp11Server = new RemoteServer(new Uri("https://" + SecureHost + "/"), HttpVersion.Version11); + public static readonly RemoteServer RemoteHttp2Server = new RemoteServer(new Uri("https://" + Http2Host + "/"), HttpVersion.Version20); - public static Uri BasicAuthUriForCreds(bool secure, string userName, string password) - { - return new Uri( - string.Format( - "{0}://{1}/{2}?auth=basic&user={3}&password={4}", - secure ? HttpsScheme : HttpScheme, - Host, - EchoHandler, - userName, - password)); - } + public static readonly IEnumerable RemoteServers = new RemoteServer[] { RemoteHttp11Server, RemoteSecureHttp11Server, RemoteHttp2Server }; - public static Uri RedirectUriForDestinationUri(bool secure, int statusCode, Uri destinationUri, int hops, bool relative = false) - { - string uriString; - string destination = Uri.EscapeDataString(relative ? destinationUri.PathAndQuery : destinationUri.AbsoluteUri); + public static readonly IEnumerable RemoteServersMemberData = RemoteServers.Select(s => new object[] { s }); - if (hops > 1) + public sealed class RemoteServer + { + public RemoteServer(Uri baseUri, Version httpVersion) { - uriString = string.Format("{0}://{1}/{2}?statuscode={3}&uri={4}&hops={5}", - secure ? HttpsScheme : HttpScheme, - Host, - RedirectHandler, - statusCode, - destination, - hops); + BaseUri = baseUri; + HttpVersion = httpVersion; } - else - { - uriString = string.Format("{0}://{1}/{2}?statuscode={3}&uri={4}", - secure ? HttpsScheme : HttpScheme, - Host, - RedirectHandler, - statusCode, - destination); + + public Uri BaseUri { get; } + + public Version HttpVersion { get; } + + public bool IsSecure => BaseUri.Scheme == Uri.UriSchemeHttps; + + public Uri EchoUri => new Uri(BaseUri, $"/{EchoHandler}"); + + public Uri VerifyUploadUri => new Uri(BaseUri, $"/{VerifyUploadHandler}"); + + public Uri GZipUri => new Uri(BaseUri, $"/{GZipHandler}"); + + public Uri DeflateUri => new Uri(BaseUri, $"/{DeflateHandler}"); + + public Uri NegotiateAuthUriForDefaultCreds => + new Uri(BaseUri, $"/{EchoHandler}?auth=negotiate"); + + public Uri BasicAuthUriForCreds(string userName, string password) => + new Uri(BaseUri, $"/{EchoHandler}?auth=basic&user={userName}&password={password}"); + + public Uri RedirectUriForDestinationUri(int statusCode, Uri destinationUri, int hops, bool relative = false) + { + string destination = Uri.EscapeDataString(relative ? destinationUri.PathAndQuery : destinationUri.AbsoluteUri); + + if (hops > 1) + { + return new Uri(BaseUri, $"/{RedirectHandler}?statuscode={statusCode}&uri={destination}&hops={hops}"); + } + else + { + return new Uri(BaseUri, $"/{RedirectHandler}?statuscode={statusCode}&uri={destination}"); + } } - return new Uri(uriString); - } + public Uri RedirectUriForCreds(int statusCode, string userName, string password) + { + Uri destinationUri = BasicAuthUriForCreds(userName, password); + string destination = Uri.EscapeDataString(destinationUri.AbsoluteUri); - public static Uri RedirectUriForCreds(bool secure, int statusCode, string userName, string password) - { - Uri destinationUri = BasicAuthUriForCreds(secure, userName, password); - string destination = Uri.EscapeDataString(destinationUri.AbsoluteUri); - - return new Uri(string.Format("{0}://{1}/{2}?statuscode={3}&uri={4}", - secure ? HttpsScheme : HttpScheme, - Host, - RedirectHandler, - statusCode, - destination)); + return new Uri(BaseUri, $"/{RedirectHandler}?statuscode={statusCode}&uri={destination}"); + } + + public override string ToString() + { + return $"(BaseUri: {BaseUri}, HttpVersion: {HttpVersion})"; + } } } } 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 0aad931..a64bf39 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/ServerCertificateTest.cs @@ -76,7 +76,7 @@ namespace System.Net.Http.WinHttpHandlerFunctional.Tests [Fact] public async Task UseCallback_RedirectandValidCertificate_ExpectedValuesDuringCallback() { - Uri uri = System.Net.Test.Common.Configuration.Http.RedirectUriForDestinationUri(true, 302, System.Net.Test.Common.Configuration.Http.SecureRemoteEchoServer, 1); + Uri uri = System.Net.Test.Common.Configuration.Http.RemoteSecureHttp11Server.RedirectUriForDestinationUri(302, System.Net.Test.Common.Configuration.Http.SecureRemoteEchoServer, 1); var handler = new WinHttpHandler(); handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback; 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 cf5812a..5e7ba34 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/WinHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/WinHttpHandlerTest.cs @@ -57,7 +57,7 @@ namespace System.Net.Http.WinHttpHandlerFunctional.Tests string cookieName, string cookieValue) { - Uri uri = System.Net.Test.Common.Configuration.Http.RedirectUriForDestinationUri(false, 302, System.Net.Test.Common.Configuration.Http.RemoteEchoServer, 1); + Uri uri = System.Net.Test.Common.Configuration.Http.RemoteHttp11Server.RedirectUriForDestinationUri(302, System.Net.Test.Common.Configuration.Http.RemoteEchoServer, 1); var handler = new WinHttpHandler(); handler.WindowsProxyUsePolicy = WindowsProxyUsePolicy.UseWinInetProxy; handler.CookieUsePolicy = cookieUsePolicy; diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AutoRedirect.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AutoRedirect.cs index 67ee77e..7050020 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AutoRedirect.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AutoRedirect.cs @@ -23,16 +23,18 @@ namespace System.Net.Http.Functional.Tests private readonly NetworkCredential _credential = new NetworkCredential(Username, Password); - public static readonly object[][] EchoServers = Configuration.Http.EchoServers; - - public static readonly object[][] RedirectStatusCodes = { - new object[] { 300 }, - new object[] { 301 }, - new object[] { 302 }, - new object[] { 303 }, - new object[] { 307 }, - new object[] { 308 } - }; + public static IEnumerable RemoteServersAndRedirectStatusCodes() + { + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) + { + yield return new object[] { remoteServer, 300 }; + yield return new object[] { remoteServer, 301 }; + yield return new object[] { remoteServer, 302 }; + yield return new object[] { remoteServer, 303 }; + yield return new object[] { remoteServer, 307 }; + yield return new object[] { remoteServer, 308 }; + } + } public static readonly object[][] RedirectStatusCodesOldMethodsNewMethods = { new object[] { 300, "GET", "GET" }, @@ -63,8 +65,8 @@ namespace System.Net.Http.Functional.Tests public HttpClientHandlerTest_AutoRedirect(ITestOutputHelper output) : base(output) { } [OuterLoop("Uses external server")] - [Theory, MemberData(nameof(RedirectStatusCodes))] - public async Task GetAsync_AllowAutoRedirectFalse_RedirectFromHttpToHttp_StatusCodeRedirect(int statusCode) + [Theory, MemberData(nameof(RemoteServersAndRedirectStatusCodes))] + public async Task GetAsync_AllowAutoRedirectFalse_RedirectFromHttpToHttp_StatusCodeRedirect(Configuration.Http.RemoteServer remoteServer, int statusCode) { if (statusCode == 308 && (IsWinHttpHandler && PlatformDetection.WindowsVersion < 10)) { @@ -74,12 +76,11 @@ namespace System.Net.Http.Functional.Tests HttpClientHandler handler = CreateHttpClientHandler(); handler.AllowAutoRedirect = false; - using (HttpClient client = CreateHttpClient(handler)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { - Uri uri = Configuration.Http.RedirectUriForDestinationUri( - secure: false, + Uri uri = remoteServer.RedirectUriForDestinationUri( statusCode: statusCode, - destinationUri: Configuration.Http.RemoteEchoServer, + destinationUri: remoteServer.EchoUri, hops: 1); _output.WriteLine("Uri: {0}", uri); using (HttpResponseMessage response = await client.GetAsync(uri)) @@ -223,8 +224,8 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Theory, MemberData(nameof(RedirectStatusCodes))] - public async Task GetAsync_AllowAutoRedirectTrue_RedirectFromHttpToHttp_StatusCodeOK(int statusCode) + [Theory, MemberData(nameof(RemoteServersAndRedirectStatusCodes))] + public async Task GetAsync_AllowAutoRedirectTrue_RedirectFromHttpToHttp_StatusCodeOK(Configuration.Http.RemoteServer remoteServer, int statusCode) { if (statusCode == 308 && (IsWinHttpHandler && PlatformDetection.WindowsVersion < 10)) { @@ -234,18 +235,17 @@ namespace System.Net.Http.Functional.Tests HttpClientHandler handler = CreateHttpClientHandler(); handler.AllowAutoRedirect = true; - using (HttpClient client = CreateHttpClient(handler)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { - Uri uri = Configuration.Http.RedirectUriForDestinationUri( - secure: false, + Uri uri = remoteServer.RedirectUriForDestinationUri( statusCode: statusCode, - destinationUri: Configuration.Http.RemoteEchoServer, + destinationUri: remoteServer.EchoUri, hops: 1); _output.WriteLine("Uri: {0}", uri); using (HttpResponseMessage response = await client.GetAsync(uri)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.Equal(Configuration.Http.RemoteEchoServer, response.RequestMessage.RequestUri); + Assert.Equal(remoteServer.EchoUri, response.RequestMessage.RequestUri); } } } @@ -258,10 +258,9 @@ namespace System.Net.Http.Functional.Tests handler.AllowAutoRedirect = true; using (HttpClient client = CreateHttpClient(handler)) { - Uri uri = Configuration.Http.RedirectUriForDestinationUri( - secure: false, + Uri uri = Configuration.Http.RemoteHttp11Server.RedirectUriForDestinationUri( statusCode: 302, - destinationUri: Configuration.Http.SecureRemoteEchoServer, + destinationUri: Configuration.Http.RemoteSecureHttp11Server.EchoUri, hops: 1); _output.WriteLine("Uri: {0}", uri); using (HttpResponseMessage response = await client.GetAsync(uri)) @@ -280,10 +279,9 @@ namespace System.Net.Http.Functional.Tests handler.AllowAutoRedirect = true; using (HttpClient client = CreateHttpClient(handler)) { - Uri uri = Configuration.Http.RedirectUriForDestinationUri( - secure: true, + Uri uri = Configuration.Http.RemoteSecureHttp11Server.RedirectUriForDestinationUri( statusCode: 302, - destinationUri: Configuration.Http.RemoteEchoServer, + destinationUri: Configuration.Http.RemoteHttp11Server.EchoUri, hops: 1); _output.WriteLine("Uri: {0}", uri); @@ -324,16 +322,15 @@ namespace System.Net.Http.Functional.Tests [ActiveIssue(32647, TargetFrameworkMonikers.Uap)] [OuterLoop("Uses external server")] - [Fact] - public async Task GetAsync_AllowAutoRedirectTrue_RedirectToUriWithParams_RequestMsgUriSet() + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task GetAsync_AllowAutoRedirectTrue_RedirectToUriWithParams_RequestMsgUriSet(Configuration.Http.RemoteServer remoteServer) { HttpClientHandler handler = CreateHttpClientHandler(); handler.AllowAutoRedirect = true; - Uri targetUri = Configuration.Http.BasicAuthUriForCreds(secure: false, userName: Username, password: Password); - using (HttpClient client = CreateHttpClient(handler)) + Uri targetUri = remoteServer.BasicAuthUriForCreds(userName: Username, password: Password); + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { - Uri uri = Configuration.Http.RedirectUriForDestinationUri( - secure: false, + Uri uri = remoteServer.RedirectUriForDestinationUri( statusCode: 302, destinationUri: targetUri, hops: 1); @@ -365,10 +362,9 @@ namespace System.Net.Http.Functional.Tests handler.MaxAutomaticRedirections = maxHops; using (HttpClient client = CreateHttpClient(handler)) { - Task t = client.GetAsync(Configuration.Http.RedirectUriForDestinationUri( - secure: false, + Task t = client.GetAsync(Configuration.Http.RemoteHttp11Server.RedirectUriForDestinationUri( statusCode: 302, - destinationUri: Configuration.Http.RemoteEchoServer, + destinationUri: Configuration.Http.RemoteHttp11Server.EchoUri, hops: hops)); if (hops <= maxHops) @@ -397,17 +393,16 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Fact] - public async Task GetAsync_AllowAutoRedirectTrue_RedirectWithRelativeLocation() + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task GetAsync_AllowAutoRedirectTrue_RedirectWithRelativeLocation(Configuration.Http.RemoteServer remoteServer) { HttpClientHandler handler = CreateHttpClientHandler(); handler.AllowAutoRedirect = true; - using (HttpClient client = CreateHttpClient(handler)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { - Uri uri = Configuration.Http.RedirectUriForDestinationUri( - secure: false, + Uri uri = remoteServer.RedirectUriForDestinationUri( statusCode: 302, - destinationUri: Configuration.Http.RemoteEchoServer, + destinationUri: remoteServer.EchoUri, hops: 1, relative: true); _output.WriteLine("Uri: {0}", uri); @@ -415,7 +410,7 @@ namespace System.Net.Http.Functional.Tests using (HttpResponseMessage response = await client.GetAsync(uri)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.Equal(Configuration.Http.RemoteEchoServer, response.RequestMessage.RequestUri); + Assert.Equal(remoteServer.EchoUri, response.RequestMessage.RequestUri); } } } @@ -524,16 +519,15 @@ namespace System.Net.Http.Functional.Tests } [ActiveIssue(32647, TargetFrameworkMonikers.Uap)] - [Fact] + [Theory, MemberData(nameof(RemoteServersMemberData))] [OuterLoop("Uses external server")] - public async Task GetAsync_CredentialIsNetworkCredentialUriRedirect_StatusCodeUnauthorized() + public async Task GetAsync_CredentialIsNetworkCredentialUriRedirect_StatusCodeUnauthorized(Configuration.Http.RemoteServer remoteServer) { HttpClientHandler handler = CreateHttpClientHandler(); handler.Credentials = _credential; - using (HttpClient client = CreateHttpClient(handler)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { - Uri redirectUri = Configuration.Http.RedirectUriForCreds( - secure: false, + Uri redirectUri = remoteServer.RedirectUriForCreds( statusCode: 302, userName: Username, password: Password); @@ -545,16 +539,15 @@ namespace System.Net.Http.Functional.Tests } [ActiveIssue(32647, TargetFrameworkMonikers.Uap)] - [Fact] + [Theory, MemberData(nameof(RemoteServersMemberData))] [OuterLoop("Uses external server")] - public async Task HttpClientHandler_CredentialIsNotCredentialCacheAfterRedirect_StatusCodeOK() + public async Task HttpClientHandler_CredentialIsNotCredentialCacheAfterRedirect_StatusCodeOK(Configuration.Http.RemoteServer remoteServer) { HttpClientHandler handler = CreateHttpClientHandler(); handler.Credentials = _credential; - using (HttpClient client = CreateHttpClient(handler)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { - Uri redirectUri = Configuration.Http.RedirectUriForCreds( - secure: false, + Uri redirectUri = remoteServer.RedirectUriForCreds( statusCode: 302, userName: Username, password: Password); @@ -564,7 +557,7 @@ namespace System.Net.Http.Functional.Tests } // Use the same handler to perform get request, authentication should succeed after redirect. - Uri uri = Configuration.Http.BasicAuthUriForCreds(secure: true, userName: Username, password: Password); + Uri uri = remoteServer.BasicAuthUriForCreds(userName: Username, password: Password); using (HttpResponseMessage authResponse = await client.GetAsync(uri)) { Assert.Equal(HttpStatusCode.OK, authResponse.StatusCode); @@ -573,8 +566,8 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Theory, MemberData(nameof(RedirectStatusCodes))] - public async Task GetAsync_CredentialIsCredentialCacheUriRedirect_StatusCodeOK(int statusCode) + [Theory, MemberData(nameof(RemoteServersAndRedirectStatusCodes))] + public async Task GetAsync_CredentialIsCredentialCacheUriRedirect_StatusCodeOK(Configuration.Http.RemoteServer remoteServer, int statusCode) { if (statusCode == 308 && (IsWinHttpHandler && PlatformDetection.WindowsVersion < 10)) { @@ -582,9 +575,8 @@ namespace System.Net.Http.Functional.Tests return; } - Uri uri = Configuration.Http.BasicAuthUriForCreds(secure: false, userName: Username, password: Password); - Uri redirectUri = Configuration.Http.RedirectUriForCreds( - secure: false, + Uri uri = remoteServer.BasicAuthUriForCreds(userName: Username, password: Password); + Uri redirectUri = remoteServer.RedirectUriForCreds( statusCode: statusCode, userName: Username, password: Password); @@ -602,7 +594,7 @@ namespace System.Net.Http.Functional.Tests else { handler.Credentials = credentialCache; - using (HttpClient client = CreateHttpClient(handler)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { using (HttpResponseMessage response = await client.GetAsync(redirectUri)) { @@ -615,8 +607,8 @@ namespace System.Net.Http.Functional.Tests [ActiveIssue(29802, TargetFrameworkMonikers.Uap)] [OuterLoop("Uses external server")] - [Theory, MemberData(nameof(RedirectStatusCodes))] - public async Task DefaultHeaders_SetCredentials_ClearedOnRedirect(int statusCode) + [Theory, MemberData(nameof(RemoteServersAndRedirectStatusCodes))] + public async Task DefaultHeaders_SetCredentials_ClearedOnRedirect(Configuration.Http.RemoteServer remoteServer, int statusCode) { if (statusCode == 308 && (IsWinHttpHandler && PlatformDetection.WindowsVersion < 10)) { @@ -625,14 +617,13 @@ namespace System.Net.Http.Functional.Tests } HttpClientHandler handler = CreateHttpClientHandler(); - using (HttpClient client = CreateHttpClient(handler)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { string credentialString = _credential.UserName + ":" + _credential.Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentialString); - Uri uri = Configuration.Http.RedirectUriForDestinationUri( - secure: false, + Uri uri = remoteServer.RedirectUriForDestinationUri( statusCode: statusCode, - destinationUri: Configuration.Http.RemoteEchoServer, + destinationUri: remoteServer.EchoUri, hops: 1); _output.WriteLine("Uri: {0}", uri); using (HttpResponseMessage response = await client.GetAsync(uri)) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Decompression.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Decompression.cs index 47c69af..cfe6f8a 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Decompression.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Decompression.cs @@ -14,12 +14,21 @@ using Xunit.Abstractions; namespace System.Net.Http.Functional.Tests { + using Configuration = System.Net.Test.Common.Configuration; + public abstract class HttpClientHandler_Decompression_Test : HttpClientHandlerTestBase { - public static readonly object[][] CompressedServers = System.Net.Test.Common.Configuration.Http.CompressedServers; - public HttpClientHandler_Decompression_Test(ITestOutputHelper output) : base(output) { } + public static IEnumerable RemoteServersAndCompressionUris() + { + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) + { + yield return new object[] { remoteServer, remoteServer.GZipUri }; + yield return new object[] { remoteServer, remoteServer.DeflateUri }; + } + } + public static IEnumerable DecompressedResponse_MethodSpecified_DecompressedContentReturned_MemberData() { foreach (bool specifyAllMethods in new[] { false, true }) @@ -145,14 +154,14 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(CompressedServers))] - public async Task GetAsync_SetAutomaticDecompression_ContentDecompressed(Uri server) + [Theory, MemberData(nameof(RemoteServersAndCompressionUris))] + public async Task GetAsync_SetAutomaticDecompression_ContentDecompressed(Configuration.Http.RemoteServer remoteServer, Uri uri) { HttpClientHandler handler = CreateHttpClientHandler(); handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; - using (HttpClient client = CreateHttpClient(handler)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { - using (HttpResponseMessage response = await client.GetAsync(server)) + using (HttpResponseMessage response = await client.GetAsync(uri)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); string responseContent = await response.Content.ReadAsStringAsync(); @@ -167,13 +176,13 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Theory, MemberData(nameof(CompressedServers))] - public async Task GetAsync_SetAutomaticDecompression_HeadersRemoved(Uri server) + [Theory, MemberData(nameof(RemoteServersAndCompressionUris))] + public async Task GetAsync_SetAutomaticDecompression_HeadersRemoved(Configuration.Http.RemoteServer remoteServer, Uri uri) { HttpClientHandler handler = CreateHttpClientHandler(); handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; - using (HttpClient client = CreateHttpClient(handler)) - using (HttpResponseMessage response = await client.GetAsync(server, HttpCompletionOption.ResponseHeadersRead)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) + using (HttpResponseMessage response = await client.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.ServerCertificates.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.ServerCertificates.cs index 58b126d..cc1b33b 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.ServerCertificates.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.ServerCertificates.cs @@ -190,23 +190,32 @@ namespace System.Net.Http.Functional.Tests public static IEnumerable UseCallback_ValidCertificate_ExpectedValuesDuringCallback_Urls() { - foreach (bool checkRevocation in new[] { true, false }) + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) { - yield return new object[] { Configuration.Http.SecureRemoteEchoServer, checkRevocation }; - yield return new object[] { - Configuration.Http.RedirectUriForDestinationUri( - secure:true, - statusCode:302, - destinationUri:Configuration.Http.SecureRemoteEchoServer, - hops:1), - checkRevocation }; + if (remoteServer.IsSecure) + { + foreach (bool checkRevocation in new[] { true, false }) + { + yield return new object[] { + remoteServer, + remoteServer.EchoUri, + checkRevocation }; + yield return new object[] { + remoteServer, + remoteServer.RedirectUriForDestinationUri( + statusCode:302, + remoteServer.EchoUri, + hops:1), + checkRevocation }; + } + } } } [OuterLoop("Uses external server")] [Theory] [MemberData(nameof(UseCallback_ValidCertificate_ExpectedValuesDuringCallback_Urls))] - public async Task UseCallback_ValidCertificate_ExpectedValuesDuringCallback(Uri url, bool checkRevocation) + public async Task UseCallback_ValidCertificate_ExpectedValuesDuringCallback(Configuration.Http.RemoteServer remoteServer, Uri url, bool checkRevocation) { if (!BackendSupportsCustomCertificateHandling) { @@ -215,7 +224,7 @@ namespace System.Net.Http.Functional.Tests } HttpClientHandler handler = CreateHttpClientHandler(); - using (HttpClient client = CreateHttpClient(handler)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { bool callbackCalled = false; handler.CheckCertificateRevocationList = checkRevocation; diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs index dec04a4..b14ad1d 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs @@ -12,9 +12,7 @@ using System.Net.Test.Common; using System.Runtime.InteropServices; using System.Security.Authentication; using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using System.Text; -using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Microsoft.DotNet.XUnitExtensions; @@ -37,8 +35,6 @@ namespace System.Net.Http.Functional.Tests private readonly NetworkCredential _credential = new NetworkCredential(Username, Password); - public static readonly object[][] EchoServers = Configuration.Http.EchoServers; - public static readonly object[][] VerifyUploadServers = Configuration.Http.VerifyUploadServers; public static readonly object[][] Http2Servers = Configuration.Http.Http2Servers; public static readonly object[][] Http2NoPushServers = Configuration.Http.Http2NoPushServers; @@ -187,7 +183,7 @@ namespace System.Net.Http.Functional.Tests handler.UseDefaultCredentials = false; using (HttpClient client = CreateHttpClient(handler)) { - Uri uri = Configuration.Http.NegotiateAuthUriForDefaultCreds(secure: false); + Uri uri = Configuration.Http.RemoteHttp11Server.NegotiateAuthUriForDefaultCreds; _output.WriteLine("Uri: {0}", uri); using (HttpResponseMessage response = await client.GetAsync(uri)) { @@ -224,11 +220,11 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(EchoServers))] - public async Task SendAsync_SimpleGet_Success(Uri remoteServer) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task SendAsync_SimpleGet_Success(Configuration.Http.RemoteServer remoteServer) { - using (HttpClient client = CreateHttpClient()) - using (HttpResponseMessage response = await client.GetAsync(remoteServer)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) + using (HttpResponseMessage response = await client.GetAsync(remoteServer.EchoUri)) { string responseContent = await response.Content.ReadAsStringAsync(); _output.WriteLine(responseContent); @@ -531,14 +527,14 @@ namespace System.Net.Http.Functional.Tests [ActiveIssue(32647, TargetFrameworkMonikers.Uap)] [OuterLoop("Uses external server")] - [Fact] - public async Task GetAsync_ServerNeedsBasicAuthAndSetDefaultCredentials_StatusCodeUnauthorized() + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task GetAsync_ServerNeedsBasicAuthAndSetDefaultCredentials_StatusCodeUnauthorized(Configuration.Http.RemoteServer remoteServer) { HttpClientHandler handler = CreateHttpClientHandler(); handler.Credentials = CredentialCache.DefaultCredentials; - using (HttpClient client = CreateHttpClient(handler)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { - Uri uri = Configuration.Http.BasicAuthUriForCreds(secure: false, userName: Username, password: Password); + Uri uri = remoteServer.BasicAuthUriForCreds(userName: Username, password: Password); using (HttpResponseMessage response = await client.GetAsync(uri)) { Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); @@ -547,14 +543,14 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Fact] - public async Task GetAsync_ServerNeedsAuthAndSetCredential_StatusCodeOK() + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task GetAsync_ServerNeedsAuthAndSetCredential_StatusCodeOK(Configuration.Http.RemoteServer remoteServer) { HttpClientHandler handler = CreateHttpClientHandler(); handler.Credentials = _credential; - using (HttpClient client = CreateHttpClient(handler)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { - Uri uri = Configuration.Http.BasicAuthUriForCreds(secure: false, userName: Username, password: Password); + Uri uri = remoteServer.BasicAuthUriForCreds(userName: Username, password: Password); using (HttpResponseMessage response = await client.GetAsync(uri)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); @@ -573,7 +569,7 @@ namespace System.Net.Http.Functional.Tests { using (HttpClient client = CreateHttpClient(useSocketsHttpHandlerString, useHttp2String)) { - Uri uri = Configuration.Http.BasicAuthUriForCreds(secure: false, userName: Username, password: Password); + Uri uri = Configuration.Http.RemoteHttp11Server.BasicAuthUriForCreds(userName: Username, password: Password); using (HttpResponseMessage response = await client.GetAsync(uri)) { Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); @@ -610,8 +606,8 @@ namespace System.Net.Http.Functional.Tests [OuterLoop("Uses external server")] [SkipOnTargetFramework(TargetFrameworkMonikers.Uap)] [Theory] - [MemberData(nameof(HeaderEchoUrisMemberData))] - public async Task GetAsync_RequestHeadersAddCustomHeaders_HeaderAndEmptyValueSent(Uri uri) + [MemberData(nameof(RemoteServersAndHeaderEchoUrisMemberData))] + public async Task GetAsync_RequestHeadersAddCustomHeaders_HeaderAndEmptyValueSent(Configuration.Http.RemoteServer remoteServer, Uri uri) { if (IsWinHttpHandler && !PlatformDetection.IsWindows10Version1709OrGreater) { @@ -620,7 +616,7 @@ namespace System.Net.Http.Functional.Tests string name = "X-Cust-Header-NoValue"; string value = ""; - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) { _output.WriteLine($"name={name}, value={value}"); client.DefaultRequestHeaders.Add(name, value); @@ -635,10 +631,10 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Theory, MemberData(nameof(HeaderValueAndUris))] - public async Task GetAsync_RequestHeadersAddCustomHeaders_HeaderAndValueSent(string name, string value, Uri uri) + [Theory, MemberData(nameof(RemoteServersHeaderValuesAndUris))] + public async Task GetAsync_RequestHeadersAddCustomHeaders_HeaderAndValueSent(Configuration.Http.RemoteServer remoteServer, string name, string value, Uri uri) { - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) { _output.WriteLine($"name={name}, value={value}"); client.DefaultRequestHeaders.Add(name, value); @@ -653,8 +649,8 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Theory, MemberData(nameof(HeaderEchoUrisMemberData))] - public async Task GetAsync_LargeRequestHeader_HeadersAndValuesSent(Uri uri) + [Theory, MemberData(nameof(RemoteServersAndHeaderEchoUrisMemberData))] + public async Task GetAsync_LargeRequestHeader_HeadersAndValuesSent(Configuration.Http.RemoteServer remoteServer, Uri uri) { // Unfortunately, our remote servers seem to have pretty strict limits (around 16K?) // on the total size of the request header. @@ -664,7 +660,7 @@ namespace System.Net.Http.Functional.Tests string headerValue = new string('a', 2048); const int headerCount = 6; - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) { for (int i = 0; i < headerCount; i++) { @@ -684,12 +680,12 @@ namespace System.Net.Http.Functional.Tests } } - public static IEnumerable HeaderValueAndUris() + public static IEnumerable RemoteServersHeaderValuesAndUris() { - foreach (Uri uri in HeaderEchoUris()) + foreach ((Configuration.Http.RemoteServer remoteServer, Uri uri) in RemoteServersAndHeaderEchoUris()) { - yield return new object[] { "X-CustomHeader", "x-value", uri }; - yield return new object[] { "MyHeader", "1, 2, 3", uri }; + yield return new object[] { remoteServer, "X-CustomHeader", "x-value", uri }; + yield return new object[] { remoteServer, "MyHeader", "1, 2, 3", uri }; // Construct a header value with every valid character (except space) string allchars = ""; @@ -701,24 +697,23 @@ namespace System.Net.Http.Functional.Tests // Put a space in the middle so it's not interpreted as insignificant leading/trailing whitespace allchars = allchars + " " + allchars; - yield return new object[] { "All-Valid-Chars-Header", allchars, uri }; + yield return new object[] { remoteServer, "All-Valid-Chars-Header", allchars, uri }; } } - public static IEnumerable HeaderEchoUris() + public static IEnumerable<(Configuration.Http.RemoteServer remoteServer, Uri uri)> RemoteServersAndHeaderEchoUris() { - foreach (Uri uri in Configuration.Http.EchoServerList) + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) { - yield return uri; - yield return Configuration.Http.RedirectUriForDestinationUri( - secure: false, + yield return (remoteServer, remoteServer.EchoUri); + yield return (remoteServer, remoteServer.RedirectUriForDestinationUri( statusCode: 302, - destinationUri: uri, - hops: 1); + destinationUri: remoteServer.EchoUri, + hops: 1)); } } - public static IEnumerable HeaderEchoUrisMemberData() => HeaderEchoUris().Select(uri => new object[] { uri }); + public static IEnumerable RemoteServersAndHeaderEchoUrisMemberData() => RemoteServersAndHeaderEchoUris().Select(x => new object[] { x.remoteServer, x.uri }); [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "UAP HTTP ignores invalid headers")] [Theory] @@ -1656,16 +1651,16 @@ namespace System.Net.Http.Functional.Tests #region Post Methods Tests [OuterLoop("Uses external server")] - [Theory, MemberData(nameof(VerifyUploadServers))] - public async Task PostAsync_CallMethodTwice_StringContent(Uri remoteServer) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostAsync_CallMethodTwice_StringContent(Configuration.Http.RemoteServer remoteServer) { - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) { string data = "Test String"; var content = new StringContent(data, Encoding.UTF8); content.Headers.ContentMD5 = TestHelper.ComputeMD5Hash(data); HttpResponseMessage response; - using (response = await client.PostAsync(remoteServer, content)) + using (response = await client.PostAsync(remoteServer.VerifyUploadUri, content)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); } @@ -1673,7 +1668,7 @@ namespace System.Net.Http.Functional.Tests // Repeat call. content = new StringContent(data, Encoding.UTF8); content.Headers.ContentMD5 = TestHelper.ComputeMD5Hash(data); - using (response = await client.PostAsync(remoteServer, content)) + using (response = await client.PostAsync(remoteServer.VerifyUploadUri, content)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); } @@ -1681,16 +1676,16 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Theory, MemberData(nameof(VerifyUploadServers))] - public async Task PostAsync_CallMethod_UnicodeStringContent(Uri remoteServer) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostAsync_CallMethod_UnicodeStringContent(Configuration.Http.RemoteServer remoteServer) { - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) { string data = "\ub4f1\uffc7\u4e82\u67ab4\uc6d4\ud1a0\uc694\uc77c\uffda3\u3155\uc218\uffdb"; var content = new StringContent(data, Encoding.UTF8); content.Headers.ContentMD5 = TestHelper.ComputeMD5Hash(data); - using (HttpResponseMessage response = await client.PostAsync(remoteServer, content)) + using (HttpResponseMessage response = await client.PostAsync(remoteServer.VerifyUploadUri, content)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); } @@ -1699,13 +1694,13 @@ namespace System.Net.Http.Functional.Tests [OuterLoop("Uses external server")] [Theory, MemberData(nameof(VerifyUploadServersStreamsAndExpectedData))] - public async Task PostAsync_CallMethod_StreamContent(Uri remoteServer, HttpContent content, byte[] expectedData) + public async Task PostAsync_CallMethod_StreamContent(Configuration.Http.RemoteServer remoteServer, HttpContent content, byte[] expectedData) { - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) { content.Headers.ContentMD5 = TestHelper.ComputeMD5Hash(expectedData); - using (HttpResponseMessage response = await client.PostAsync(remoteServer, content)) + using (HttpResponseMessage response = await client.PostAsync(remoteServer.VerifyUploadUri, content)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); } @@ -1746,18 +1741,16 @@ namespace System.Net.Http.Functional.Tests { get { - foreach (object[] serverArr in VerifyUploadServers) // target server + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) // target server foreach (bool syncCopy in new[] { true, false }) // force the content copy to happen via Read/Write or ReadAsync/WriteAsync { - Uri server = (Uri)serverArr[0]; - byte[] data = new byte[1234]; new Random(42).NextBytes(data); // A MemoryStream { var memStream = new MemoryStream(data, writable: false); - yield return new object[] { server, new StreamContentWithSyncAsyncCopy(memStream, syncCopy: syncCopy), data }; + yield return new object[] { remoteServer, new StreamContentWithSyncAsyncCopy(memStream, syncCopy: syncCopy), data }; } // A multipart content that provides its own stream from CreateContentReadStreamAsync @@ -1766,7 +1759,7 @@ namespace System.Net.Http.Functional.Tests mc.Add(new ByteArrayContent(data)); var memStream = new MemoryStream(); mc.CopyToAsync(memStream).GetAwaiter().GetResult(); - yield return new object[] { server, mc, memStream.ToArray() }; + yield return new object[] { remoteServer, mc, memStream.ToArray() }; } // A stream that provides the data synchronously and has a known length @@ -1780,7 +1773,7 @@ namespace System.Net.Http.Functional.Tests positionSetFunc: p => wrappedMemStream.Position = p, readFunc: (buffer, offset, count) => wrappedMemStream.Read(buffer, offset, count), readAsyncFunc: (buffer, offset, count, token) => wrappedMemStream.ReadAsync(buffer, offset, count, token)); - yield return new object[] { server, new StreamContentWithSyncAsyncCopy(syncKnownLengthStream, syncCopy: syncCopy), data }; + yield return new object[] { remoteServer, new StreamContentWithSyncAsyncCopy(syncKnownLengthStream, syncCopy: syncCopy), data }; } // A stream that provides the data synchronously and has an unknown length @@ -1801,7 +1794,7 @@ namespace System.Net.Http.Functional.Tests canSeekFunc: () => false, readFunc: readFunc, readAsyncFunc: (buffer, offset, count, token) => Task.FromResult(readFunc(buffer, offset, count))); - yield return new object[] { server, new StreamContentWithSyncAsyncCopy(syncUnknownLengthStream, syncCopy: syncCopy), data }; + yield return new object[] { remoteServer, new StreamContentWithSyncAsyncCopy(syncUnknownLengthStream, syncCopy: syncCopy), data }; } // A stream that provides the data asynchronously @@ -1826,25 +1819,25 @@ namespace System.Net.Http.Functional.Tests await Task.Delay(1).ConfigureAwait(false); return readFunc(buffer, offset, count); }); - yield return new object[] { server, new StreamContentWithSyncAsyncCopy(asyncStream, syncCopy: syncCopy), data }; + yield return new object[] { remoteServer, new StreamContentWithSyncAsyncCopy(asyncStream, syncCopy: syncCopy), data }; } // Providing data from a FormUrlEncodedContent's stream { var formContent = new FormUrlEncodedContent(new[] { new KeyValuePair("key", "val") }); - yield return new object[] { server, formContent, Encoding.GetEncoding("iso-8859-1").GetBytes("key=val") }; + yield return new object[] { remoteServer, formContent, Encoding.GetEncoding("iso-8859-1").GetBytes("key=val") }; } } } } [OuterLoop("Uses external server")] - [Theory, MemberData(nameof(EchoServers))] - public async Task PostAsync_CallMethod_NullContent(Uri remoteServer) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostAsync_CallMethod_NullContent(Configuration.Http.RemoteServer remoteServer) { - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) { - using (HttpResponseMessage response = await client.PostAsync(remoteServer, null)) + using (HttpResponseMessage response = await client.PostAsync(remoteServer.EchoUri, null)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); @@ -1860,13 +1853,13 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Theory, MemberData(nameof(EchoServers))] - public async Task PostAsync_CallMethod_EmptyContent(Uri remoteServer) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostAsync_CallMethod_EmptyContent(Configuration.Http.RemoteServer remoteServer) { - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) { var content = new StringContent(string.Empty); - using (HttpResponseMessage response = await client.PostAsync(remoteServer, content)) + using (HttpResponseMessage response = await client.PostAsync(remoteServer.EchoUri, content)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); @@ -2215,20 +2208,17 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Theory] - [InlineData(false)] - [InlineData(true)] - public async Task PostAsync_Redirect_ResultingGetFormattedCorrectly(bool secure) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostAsync_Redirect_ResultingGetFormattedCorrectly(Configuration.Http.RemoteServer remoteServer) { const string ContentString = "This is the content string."; var content = new StringContent(ContentString); - Uri redirectUri = Configuration.Http.RedirectUriForDestinationUri( - secure, + Uri redirectUri = remoteServer.RedirectUriForDestinationUri( 302, - secure ? Configuration.Http.SecureRemoteEchoServer : Configuration.Http.RemoteEchoServer, + remoteServer.EchoUri, 1); - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) using (HttpResponseMessage response = await client.PostAsync(redirectUri, content)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); @@ -2240,20 +2230,20 @@ namespace System.Net.Http.Functional.Tests [ActiveIssue(22191, TargetFrameworkMonikers.Uap)] [OuterLoop("Takes several seconds")] - [Fact] - public async Task PostAsync_RedirectWith307_LargePayload() + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostAsync_RedirectWith307_LargePayload(Configuration.Http.RemoteServer remoteServer) { - await PostAsync_Redirect_LargePayload_Helper(307, true); + await PostAsync_Redirect_LargePayload_Helper(remoteServer, 307, true); } [OuterLoop("Takes several seconds")] - [Fact] - public async Task PostAsync_RedirectWith302_LargePayload() + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostAsync_RedirectWith302_LargePayload(Configuration.Http.RemoteServer remoteServer) { - await PostAsync_Redirect_LargePayload_Helper(302, false); + await PostAsync_Redirect_LargePayload_Helper(remoteServer, 302, false); } - public async Task PostAsync_Redirect_LargePayload_Helper(int statusCode, bool expectRedirectToPost) + public async Task PostAsync_Redirect_LargePayload_Helper(Configuration.Http.RemoteServer remoteServer, int statusCode, bool expectRedirectToPost) { using (var fs = new FileStream( Path.Combine(Path.GetTempPath(), Path.GetTempFileName()), @@ -2269,17 +2259,16 @@ namespace System.Net.Http.Functional.Tests fs.Flush(flushToDisk: true); fs.Position = 0; - Uri redirectUri = Configuration.Http.RedirectUriForDestinationUri( - secure: false, + Uri redirectUri = remoteServer.RedirectUriForDestinationUri( statusCode: statusCode, - destinationUri: Configuration.Http.SecureRemoteVerifyUploadServer, + destinationUri: remoteServer.VerifyUploadUri, hops: 1); var content = new StreamContent(fs); // Compute MD5 of request body data. This will be verified by the server when it receives the request. content.Headers.ContentMD5 = TestHelper.ComputeMD5Hash(contentBytes); - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) using (HttpResponseMessage response = await client.PostAsync(redirectUri, content)) { try @@ -2302,17 +2291,17 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Theory, MemberData(nameof(EchoServers))] + [Theory, MemberData(nameof(RemoteServersMemberData))] [ActiveIssue(31104, TestPlatforms.AnyUnix)] - public async Task PostAsync_ReuseRequestContent_Success(Uri remoteServer) + public async Task PostAsync_ReuseRequestContent_Success(Configuration.Http.RemoteServer remoteServer) { const string ContentString = "This is the content string."; - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) { var content = new StringContent(ContentString); for (int i = 0; i < 2; i++) { - using (HttpResponseMessage response = await client.PostAsync(remoteServer, content)) + using (HttpResponseMessage response = await client.PostAsync(remoteServer.EchoUri, content)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Contains(ContentString, await response.Content.ReadAsStringAsync()); @@ -2644,7 +2633,7 @@ namespace System.Net.Http.Functional.Tests } }); } - #endregion +#endregion [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsSubsystemForLinux))] // [ActiveIssue(11057)] public async Task GetAsync_InvalidUrl_ExpectedExceptionThrown() diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.cs index 0219973..1ccef58 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.cs @@ -2,17 +2,19 @@ // 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.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Reflection; using System.Net.Test.Common; - +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; using Xunit.Abstractions; -using System.Collections.Generic; -using System.Text; namespace System.Net.Http.Functional.Tests { + using Configuration = System.Net.Test.Common.Configuration; + public abstract class HttpClientHandlerTestBase : FileCleanupTestBase { public readonly ITestOutputHelper _output; @@ -39,7 +41,13 @@ namespace System.Net.Http.Functional.Tests protected HttpClient CreateHttpClient(HttpMessageHandler handler) { var client = new HttpClient(handler); - SetDefaultRequestVersion(client, VersionFromUseHttp2); + + // Always set the default request version to HTTP/2. + // The actual version used will be determined by the server (either loopback server or remote server). + // Note that if you create the HttpRequestMessage explicitly, you will need to set its Version explicitly + // because it defaults to 1.1. + + SetDefaultRequestVersion(client, HttpVersion.Version20); return client; } @@ -107,5 +115,54 @@ namespace System.Net.Http.Functional.Tests (LoopbackServerFactory)Http2LoopbackServerFactory.Singleton : #endif Http11LoopbackServerFactory.Singleton; + + // For use by remote server tests + + public static readonly IEnumerable RemoteServersMemberData = Configuration.Http.RemoteServersMemberData; + + protected HttpClient CreateHttpClientForRemoteServer(Configuration.Http.RemoteServer remoteServer) + { + return CreateHttpClientForRemoteServer(remoteServer, CreateHttpClientHandler()); + } + + protected HttpClient CreateHttpClientForRemoteServer(Configuration.Http.RemoteServer remoteServer, HttpClientHandler httpClientHandler) + { + // ActiveIssue #39293: WinHttpHandler will downgrade to 1.1 if you set Transfer-Encoding: chunked. + // So, skip this verification if we're not using SocketsHttpHandler. + HttpMessageHandler wrappedHandler = + IsSocketsHttpHandler(httpClientHandler) ? new VersionCheckerHttpHandler(httpClientHandler, remoteServer.HttpVersion) : (HttpMessageHandler)httpClientHandler; + + var client = new HttpClient(wrappedHandler); + SetDefaultRequestVersion(client, remoteServer.HttpVersion); + return client; + } + + private sealed class VersionCheckerHttpHandler : DelegatingHandler + { + private readonly Version _expectedVersion; + + public VersionCheckerHttpHandler(HttpMessageHandler innerHandler, Version expectedVersion) + : base(innerHandler) + { + _expectedVersion = expectedVersion; + } + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + if (request.Version != _expectedVersion) + { + throw new Exception($"Unexpected request version: expected {_expectedVersion}, saw {request.Version}"); + } + + HttpResponseMessage response = await base.SendAsync(request, cancellationToken); + + if (response.Version != _expectedVersion) + { + throw new Exception($"Unexpected response version: expected {_expectedVersion}, saw {response.Version}"); + } + + return response; + } + } } } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/PostScenarioTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/PostScenarioTest.cs index 1fa75a6..b6d5e9d 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/PostScenarioTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/PostScenarioTest.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; using System.Threading.Tasks; using Xunit; @@ -20,27 +21,13 @@ namespace System.Net.Http.Functional.Tests private const string ExpectedContent = "Test contest"; private const string UserName = "user1"; private const string Password = "password1"; - private static readonly Uri BasicAuthServerUri = - Configuration.Http.BasicAuthUriForCreds(false, UserName, Password); - private static readonly Uri SecureBasicAuthServerUri = - Configuration.Http.BasicAuthUriForCreds(true, UserName, Password); - - public static readonly object[][] EchoServers = Configuration.Http.EchoServers; - public static readonly object[][] VerifyUploadServers = Configuration.Http.VerifyUploadServers; - - public static readonly object[][] BasicAuthEchoServers = - new object[][] - { - new object[] { BasicAuthServerUri }, - new object[] { SecureBasicAuthServerUri } - }; public PostScenarioTest(ITestOutputHelper output) : base(output) { } [ActiveIssue(30057, TargetFrameworkMonikers.Uap)] [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(EchoServers))] - public async Task PostRewindableStreamContentMultipleTimes_StreamContentFullySent(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostRewindableStreamContentMultipleTimes_StreamContentFullySent(Configuration.Http.RemoteServer remoteServer) { if (IsCurlHandler) { @@ -50,14 +37,14 @@ namespace System.Net.Http.Functional.Tests const string requestBody = "ABC"; - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(requestBody))) { var content = new StreamContent(ms); for (int i = 1; i <= 3; i++) { - HttpResponseMessage response = await client.PostAsync(serverUri, content); + HttpResponseMessage response = await client.PostAsync(remoteServer.EchoUri, content); Assert.Equal(requestBody.Length, ms.Position); // Stream left at end after send. string responseBody = await response.Content.ReadAsStringAsync(); @@ -68,100 +55,100 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(VerifyUploadServers))] - public async Task PostNoContentUsingContentLengthSemantics_Success(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostNoContentUsingContentLengthSemantics_Success(Configuration.Http.RemoteServer remoteServer) { - await PostHelper(serverUri, string.Empty, null, + await PostHelper(remoteServer, string.Empty, null, useContentLengthUpload: true, useChunkedEncodingUpload: false); } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(VerifyUploadServers))] - public async Task PostEmptyContentUsingContentLengthSemantics_Success(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostEmptyContentUsingContentLengthSemantics_Success(Configuration.Http.RemoteServer remoteServer) { - await PostHelper(serverUri, string.Empty, new StringContent(string.Empty), + await PostHelper(remoteServer, string.Empty, new StringContent(string.Empty), useContentLengthUpload: true, useChunkedEncodingUpload: false); } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(VerifyUploadServers))] - public async Task PostEmptyContentUsingChunkedEncoding_Success(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostEmptyContentUsingChunkedEncoding_Success(Configuration.Http.RemoteServer remoteServer) { - await PostHelper(serverUri, string.Empty, new StringContent(string.Empty), + await PostHelper(remoteServer, string.Empty, new StringContent(string.Empty), useContentLengthUpload: false, useChunkedEncodingUpload: true); } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(VerifyUploadServers))] - public async Task PostEmptyContentUsingConflictingSemantics_Success(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostEmptyContentUsingConflictingSemantics_Success(Configuration.Http.RemoteServer remoteServer) { - await PostHelper(serverUri, string.Empty, new StringContent(string.Empty), + await PostHelper(remoteServer, string.Empty, new StringContent(string.Empty), useContentLengthUpload: true, useChunkedEncodingUpload: true); } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(VerifyUploadServers))] - public async Task PostUsingContentLengthSemantics_Success(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostUsingContentLengthSemantics_Success(Configuration.Http.RemoteServer remoteServer) { - await PostHelper(serverUri, ExpectedContent, new StringContent(ExpectedContent), + await PostHelper(remoteServer, ExpectedContent, new StringContent(ExpectedContent), useContentLengthUpload: true, useChunkedEncodingUpload: false); } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(VerifyUploadServers))] - public async Task PostUsingChunkedEncoding_Success(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostUsingChunkedEncoding_Success(Configuration.Http.RemoteServer remoteServer) { - await PostHelper(serverUri, ExpectedContent, new StringContent(ExpectedContent), + await PostHelper(remoteServer, ExpectedContent, new StringContent(ExpectedContent), useContentLengthUpload: false, useChunkedEncodingUpload: true); } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(VerifyUploadServers))] - public async Task PostSyncBlockingContentUsingChunkedEncoding_Success(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostSyncBlockingContentUsingChunkedEncoding_Success(Configuration.Http.RemoteServer remoteServer) { - await PostHelper(serverUri, ExpectedContent, new SyncBlockingContent(ExpectedContent), + await PostHelper(remoteServer, ExpectedContent, new SyncBlockingContent(ExpectedContent), useContentLengthUpload: false, useChunkedEncodingUpload: true); } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(VerifyUploadServers))] - public async Task PostRepeatedFlushContentUsingChunkedEncoding_Success(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostRepeatedFlushContentUsingChunkedEncoding_Success(Configuration.Http.RemoteServer remoteServer) { - await PostHelper(serverUri, ExpectedContent, new RepeatedFlushContent(ExpectedContent), + await PostHelper(remoteServer, ExpectedContent, new RepeatedFlushContent(ExpectedContent), useContentLengthUpload: false, useChunkedEncodingUpload: true); } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(VerifyUploadServers))] - public async Task PostUsingUsingConflictingSemantics_UsesChunkedSemantics(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostUsingUsingConflictingSemantics_UsesChunkedSemantics(Configuration.Http.RemoteServer remoteServer) { - await PostHelper(serverUri, ExpectedContent, new StringContent(ExpectedContent), + await PostHelper(remoteServer, ExpectedContent, new StringContent(ExpectedContent), useContentLengthUpload: true, useChunkedEncodingUpload: true); } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(VerifyUploadServers))] + [Theory, MemberData(nameof(RemoteServersMemberData))] [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "WinRT behaves differently and will use 'Content-Length' semantics")] - public async Task PostUsingNoSpecifiedSemantics_UsesChunkedSemantics(Uri serverUri) + public async Task PostUsingNoSpecifiedSemantics_UsesChunkedSemantics(Configuration.Http.RemoteServer remoteServer) { - await PostHelper(serverUri, ExpectedContent, new StringContent(ExpectedContent), + await PostHelper(remoteServer, ExpectedContent, new StringContent(ExpectedContent), useContentLengthUpload: false, useChunkedEncodingUpload: false); } - public static IEnumerable VerifyUploadServersAndLargeContentSizes() + public static IEnumerable RemoteServersAndLargeContentSizes() { - foreach (Uri uri in Configuration.Http.VerifyUploadServerList) + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) { - yield return new object[] { uri, 5 * 1024 }; - yield return new object[] { uri, 63 * 1024 }; - yield return new object[] { uri, 129 * 1024 }; + yield return new object[] { remoteServer, 5 * 1024 }; + yield return new object[] { remoteServer, 63 * 1024 }; + yield return new object[] { remoteServer, 129 * 1024 }; } } [OuterLoop("Uses external server")] [Theory] - [MemberData(nameof(VerifyUploadServersAndLargeContentSizes))] - public async Task PostLargeContentUsingContentLengthSemantics_Success(Uri serverUri, int contentLength) + [MemberData(nameof(RemoteServersAndLargeContentSizes))] + public async Task PostLargeContentUsingContentLengthSemantics_Success(Configuration.Http.RemoteServer remoteServer, int contentLength) { var rand = new Random(42); var sb = new StringBuilder(contentLength); @@ -171,35 +158,35 @@ namespace System.Net.Http.Functional.Tests } string content = sb.ToString(); - await PostHelper(serverUri, content, new StringContent(content), + await PostHelper(remoteServer, content, new StringContent(content), useContentLengthUpload: true, useChunkedEncodingUpload: false); } [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "WinRT based handler has PreAuthenticate always true")] [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(BasicAuthEchoServers))] - public async Task PostRewindableContentUsingAuth_NoPreAuthenticate_Success(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostRewindableContentUsingAuth_NoPreAuthenticate_Success(Configuration.Http.RemoteServer remoteServer) { HttpContent content = new StreamContent(new CustomContent.CustomStream(Encoding.UTF8.GetBytes(ExpectedContent), true)); var credential = new NetworkCredential(UserName, Password); - await PostUsingAuthHelper(serverUri, ExpectedContent, content, credential, false); + await PostUsingAuthHelper(remoteServer, ExpectedContent, content, credential, false); } [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "WinRT based handler has PreAuthenticate always true")] [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(BasicAuthEchoServers))] - public async Task PostNonRewindableContentUsingAuth_NoPreAuthenticate_ThrowsHttpRequestException(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostNonRewindableContentUsingAuth_NoPreAuthenticate_ThrowsHttpRequestException(Configuration.Http.RemoteServer remoteServer) { HttpContent content = new StreamContent(new CustomContent.CustomStream(Encoding.UTF8.GetBytes(ExpectedContent), false)); var credential = new NetworkCredential(UserName, Password); await Assert.ThrowsAsync(() => - PostUsingAuthHelper(serverUri, ExpectedContent, content, credential, preAuthenticate: false)); + PostUsingAuthHelper(remoteServer, ExpectedContent, content, credential, preAuthenticate: false)); } [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "WinRT based handler has PreAuthenticate always true")] [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(BasicAuthEchoServers))] - public async Task PostNonRewindableContentUsingAuth_PreAuthenticate_Success(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostNonRewindableContentUsingAuth_PreAuthenticate_Success(Configuration.Http.RemoteServer remoteServer) { if (IsWinHttpHandler) { @@ -209,15 +196,15 @@ namespace System.Net.Http.Functional.Tests HttpContent content = new StreamContent(new CustomContent.CustomStream(Encoding.UTF8.GetBytes(ExpectedContent), false)); var credential = new NetworkCredential(UserName, Password); - await PostUsingAuthHelper(serverUri, ExpectedContent, content, credential, preAuthenticate: true); + await PostUsingAuthHelper(remoteServer, ExpectedContent, content, credential, preAuthenticate: true); } [OuterLoop("Uses external servers")] - [Theory, MemberData(nameof(EchoServers))] - public async Task PostAsync_EmptyContent_ContentTypeHeaderNotSent(Uri serverUri) + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task PostAsync_EmptyContent_ContentTypeHeaderNotSent(Configuration.Http.RemoteServer remoteServer) { - using (HttpClient client = CreateHttpClient()) - using (HttpResponseMessage response = await client.PostAsync(serverUri, null)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) + using (HttpResponseMessage response = await client.PostAsync(remoteServer.EchoUri, null)) { string responseContent = await response.Content.ReadAsStringAsync(); bool sentContentType = TestHelper.JsonMessageContainsKey(responseContent, "Content-Type"); @@ -227,13 +214,13 @@ namespace System.Net.Http.Functional.Tests } private async Task PostHelper( - Uri serverUri, + Configuration.Http.RemoteServer remoteServer, string requestBody, HttpContent requestContent, bool useContentLengthUpload, bool useChunkedEncodingUpload) { - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) { if (requestContent != null) { @@ -257,7 +244,7 @@ namespace System.Net.Http.Functional.Tests client.DefaultRequestHeaders.TransferEncodingChunked = true; } - using (HttpResponseMessage response = await client.PostAsync(serverUri, requestContent)) + using (HttpResponseMessage response = await client.PostAsync(remoteServer.VerifyUploadUri, requestContent)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); } @@ -265,27 +252,29 @@ namespace System.Net.Http.Functional.Tests } private async Task PostUsingAuthHelper( - Uri serverUri, + Configuration.Http.RemoteServer remoteServer, string requestBody, HttpContent requestContent, NetworkCredential credential, bool preAuthenticate) { + Uri serverUri = remoteServer.BasicAuthUriForCreds(UserName, Password); + HttpClientHandler handler = CreateHttpClientHandler(); handler.PreAuthenticate = preAuthenticate; handler.Credentials = credential; - using (HttpClient client = CreateHttpClient(handler)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler)) { // Send HEAD request to help bypass the 401 auth challenge for the latter POST assuming // that the authentication will be cached and re-used later when PreAuthenticate is true. - var request = new HttpRequestMessage(HttpMethod.Head, serverUri) { Version = VersionFromUseHttp2 }; + var request = new HttpRequestMessage(HttpMethod.Head, serverUri) { Version = remoteServer.HttpVersion }; using (HttpResponseMessage response = await client.SendAsync(request)) { Assert.Equal(HttpStatusCode.OK, response.StatusCode); } // Now send POST request. - request = new HttpRequestMessage(HttpMethod.Post, serverUri) { Version = VersionFromUseHttp2 }; + request = new HttpRequestMessage(HttpMethod.Post, serverUri) { Version = remoteServer.HttpVersion }; request.Content = requestContent; requestContent.Headers.ContentLength = null; request.Headers.TransferEncodingChunked = true; diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/ResponseStreamTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/ResponseStreamTest.cs index b665177..cc2d97a 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/ResponseStreamTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/ResponseStreamTest.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.Collections.Generic; using System.IO; using System.Net.Test.Common; using System.Text; @@ -19,24 +20,27 @@ namespace System.Net.Http.Functional.Tests { public ResponseStreamTest(ITestOutputHelper output) : base(output) { } + public static IEnumerable RemoteServersAndReadModes() + { + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) + { + for (int i = 0; i < 8; i++) + { + yield return new object[] { remoteServer, i }; + } + } + + } [OuterLoop("Uses external server")] - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(2)] - [InlineData(3)] - [InlineData(4)] - [InlineData(5)] - [InlineData(6)] - [InlineData(7)] - public async Task GetStreamAsync_ReadToEnd_Success(int readMode) + [Theory, MemberData(nameof(RemoteServersAndReadModes))] + public async Task GetStreamAsync_ReadToEnd_Success(Configuration.Http.RemoteServer remoteServer, int readMode) { - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) { string customHeaderValue = Guid.NewGuid().ToString("N"); client.DefaultRequestHeaders.Add("X-ResponseStreamTest", customHeaderValue); - using (Stream stream = await client.GetStreamAsync(Configuration.Http.RemoteEchoServer)) + using (Stream stream = await client.GetStreamAsync(remoteServer.EchoUri)) { var ms = new MemoryStream(); int bytesRead; @@ -119,11 +123,11 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Fact] - public async Task GetAsync_UseResponseHeadersReadAndCallLoadIntoBuffer_Success() + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task GetAsync_UseResponseHeadersReadAndCallLoadIntoBuffer_Success(Configuration.Http.RemoteServer remoteServer) { - using (HttpClient client = CreateHttpClient()) - using (HttpResponseMessage response = await client.GetAsync(Configuration.Http.RemoteEchoServer, HttpCompletionOption.ResponseHeadersRead)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) + using (HttpResponseMessage response = await client.GetAsync(remoteServer.EchoUri, HttpCompletionOption.ResponseHeadersRead)) { await response.Content.LoadIntoBufferAsync(); @@ -138,11 +142,11 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Fact] - public async Task GetAsync_UseResponseHeadersReadAndCopyToMemoryStream_Success() + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task GetAsync_UseResponseHeadersReadAndCopyToMemoryStream_Success(Configuration.Http.RemoteServer remoteServer) { - using (HttpClient client = CreateHttpClient()) - using (HttpResponseMessage response = await client.GetAsync(Configuration.Http.RemoteEchoServer, HttpCompletionOption.ResponseHeadersRead)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) + using (HttpResponseMessage response = await client.GetAsync(remoteServer.EchoUri, HttpCompletionOption.ResponseHeadersRead)) { var memoryStream = new MemoryStream(); await response.Content.CopyToAsync(memoryStream); @@ -162,11 +166,11 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Fact] - public async Task GetStreamAsync_ReadZeroBytes_Success() + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task GetStreamAsync_ReadZeroBytes_Success(Configuration.Http.RemoteServer remoteServer) { - using (HttpClient client = CreateHttpClient()) - using (Stream stream = await client.GetStreamAsync(Configuration.Http.RemoteEchoServer)) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) + using (Stream stream = await client.GetStreamAsync(remoteServer.EchoUri)) { Assert.Equal(0, stream.Read(new byte[1], 0, 0)); Assert.Equal(0, stream.Read(new Span(new byte[1], 0, 0))); @@ -175,14 +179,14 @@ namespace System.Net.Http.Functional.Tests } [OuterLoop("Uses external server")] - [Fact] - public async Task ReadAsStreamAsync_Cancel_TaskIsCanceled() + [Theory, MemberData(nameof(RemoteServersMemberData))] + public async Task ReadAsStreamAsync_Cancel_TaskIsCanceled(Configuration.Http.RemoteServer remoteServer) { var cts = new CancellationTokenSource(); - using (HttpClient client = CreateHttpClient()) + using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) using (HttpResponseMessage response = - await client.GetAsync(Configuration.Http.RemoteEchoServer, HttpCompletionOption.ResponseHeadersRead)) + await client.GetAsync(remoteServer.EchoUri, HttpCompletionOption.ResponseHeadersRead)) using (Stream stream = await response.Content.ReadAsStreamAsync()) { var buffer = new byte[2048];