// 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
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";
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<RemoteServer> 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<object[]> 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})";
+ }
}
}
}
[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;
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;
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<object[]> 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" },
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))
{
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))
}
[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))
{
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);
}
}
}
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))
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);
[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);
handler.MaxAutomaticRedirections = maxHops;
using (HttpClient client = CreateHttpClient(handler))
{
- Task<HttpResponseMessage> t = client.GetAsync(Configuration.Http.RedirectUriForDestinationUri(
- secure: false,
+ Task<HttpResponseMessage> t = client.GetAsync(Configuration.Http.RemoteHttp11Server.RedirectUriForDestinationUri(
statusCode: 302,
- destinationUri: Configuration.Http.RemoteEchoServer,
+ destinationUri: Configuration.Http.RemoteHttp11Server.EchoUri,
hops: hops));
if (hops <= maxHops)
}
[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);
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);
}
}
}
}
[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);
}
[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);
}
// 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);
}
[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))
{
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);
else
{
handler.Credentials = credentialCache;
- using (HttpClient client = CreateHttpClient(handler))
+ using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler))
{
using (HttpResponseMessage response = await client.GetAsync(redirectUri))
{
[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))
{
}
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))
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<object[]> 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<object[]> DecompressedResponse_MethodSpecified_DecompressedContentReturned_MemberData()
{
foreach (bool specifyAllMethods in new[] { false, true })
}
[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();
}
[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);
public static IEnumerable<object[]> 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)
{
}
HttpClientHandler handler = CreateHttpClientHandler();
- using (HttpClient client = CreateHttpClient(handler))
+ using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer, handler))
{
bool callbackCalled = false;
handler.CheckCertificateRevocationList = checkRevocation;
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;
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;
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))
{
}
[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);
[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);
}
[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);
{
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);
[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)
{
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);
}
[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);
}
[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.
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++)
{
}
}
- public static IEnumerable<object[]> HeaderValueAndUris()
+ public static IEnumerable<object[]> 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 = "";
// 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<Uri> 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<object[]> HeaderEchoUrisMemberData() => HeaderEchoUris().Select(uri => new object[] { uri });
+ public static IEnumerable<object[]> RemoteServersAndHeaderEchoUrisMemberData() => RemoteServersAndHeaderEchoUris().Select(x => new object[] { x.remoteServer, x.uri });
[SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "UAP HTTP ignores invalid headers")]
[Theory]
#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);
}
// 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);
}
}
[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);
}
[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);
}
{
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
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
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
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
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<string, string>("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);
}
[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);
}
[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);
[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()),
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
}
[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());
}
});
}
- #endregion
+#endregion
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsSubsystemForLinux))] // [ActiveIssue(11057)]
public async Task GetAsync_InvalidUrl_ExpectedExceptionThrown()
// 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;
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;
}
(LoopbackServerFactory)Http2LoopbackServerFactory.Singleton :
#endif
Http11LoopbackServerFactory.Singleton;
+
+ // For use by remote server tests
+
+ public static readonly IEnumerable<object[]> 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<HttpResponseMessage> 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;
+ }
+ }
}
}
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
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)
{
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();
}
[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<object[]> VerifyUploadServersAndLargeContentSizes()
+ public static IEnumerable<object[]> 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);
}
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<HttpRequestException>(() =>
- 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)
{
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");
}
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)
{
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);
}
}
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;
// 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;
{
public ResponseStreamTest(ITestOutputHelper output) : base(output) { }
+ public static IEnumerable<object[]> 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;
}
[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();
}
[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);
}
[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<byte>(new byte[1], 0, 0)));
}
[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];