Fix merge formatting issues and cross plat tests

This commit is contained in:
Pavel Krymets 2016-05-26 10:34:25 -07:00
parent 71ecf5612f
commit ef8b0a90d8
1 changed files with 141 additions and 137 deletions

View File

@ -21,15 +21,13 @@ using Xunit;
namespace Microsoft.AspNetCore.Server.KestrelTests namespace Microsoft.AspNetCore.Server.KestrelTests
{ {
public class HttpsConnectionFilterTests: IDisposable public class HttpsConnectionFilterTests : IDisposable
{ {
private static string _serverAddress = "https://127.0.0.1:0/"; private static string _serverAddress = "https://127.0.0.1:0/";
private static RemoteCertificateValidationCallback _alwaysValidCallback = private static RemoteCertificateValidationCallback _alwaysValidCallback =
(sender, cert, chain, sslPolicyErrors) => true; (sender, cert, chain, sslPolicyErrors) => true;
private static X509Certificate2 _x509Certificate2 = new X509Certificate2(@"TestResources/testCert.pfx", "testPassword"); private static X509Certificate2 _x509Certificate2 = new X509Certificate2(@"TestResources/testCert.pfx", "testPassword");
private HttpMessageHandler _handler;
#if NET451 #if NET451
static HttpsConnectionFilterTests() static HttpsConnectionFilterTests()
{ {
@ -43,21 +41,16 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
public HttpsConnectionFilterTests() public HttpsConnectionFilterTests()
{ {
#if NET451 #if NET451
_handler = new HttpClientHandler();
ServicePointManager.ServerCertificateValidationCallback += _alwaysValidCallback; ServicePointManager.ServerCertificateValidationCallback += _alwaysValidCallback;
#else
var handler = new WinHttpHandler();
handler.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
_handler = handler;
#endif #endif
} }
public void Dispose() public void Dispose()
{ {
#if NET451 #if NET451
ServicePointManager.ServerCertificateValidationCallback -= _alwaysValidCallback; ServicePointManager.ServerCertificateValidationCallback -= _alwaysValidCallback;
#endif #endif
} }
// https://github.com/aspnet/KestrelHttpServer/issues/240 // https://github.com/aspnet/KestrelHttpServer/issues/240
// This test currently fails on mono because of an issue with SslStream. // This test currently fails on mono because of an issue with SslStream.
@ -66,88 +59,88 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "WinHttpHandler not available on non-Windows.")] [OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "WinHttpHandler not available on non-Windows.")]
public async Task CanReadAndWriteWithHttpsConnectionFilter() public async Task CanReadAndWriteWithHttpsConnectionFilter()
{ {
var serviceContext = new TestServiceContext(new HttpsConnectionFilter( var serviceContext = new TestServiceContext(new HttpsConnectionFilter(
new HttpsConnectionFilterOptions new HttpsConnectionFilterOptions
{ ServerCertificate = _x509Certificate2 }, { ServerCertificate = _x509Certificate2 },
new NoOpConnectionFilter()) new NoOpConnectionFilter())
); );
using (var server = new TestServer(App, serviceContext, _serverAddress)) using (var server = new TestServer(App, serviceContext, _serverAddress))
{
using (var client = new HttpClient(GetHandler()))
{ {
using (var client = new HttpClient(_handler)) var result = await client.PostAsync($"https://localhost:{server.Port}/", new FormUrlEncodedContent(new[] {
{
var result = await client.PostAsync($"https://localhost:{server.Port}/", new FormUrlEncodedContent(new[] {
new KeyValuePair<string, string>("content", "Hello World?") new KeyValuePair<string, string>("content", "Hello World?")
})); }));
Assert.Equal("content=Hello+World%3F", await result.Content.ReadAsStringAsync()); Assert.Equal("content=Hello+World%3F", await result.Content.ReadAsStringAsync());
}
} }
} }
}
[ConditionalFact] [ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux, SkipReason = "WinHttpHandler not available on non-Windows.")] [OSSkipCondition(OperatingSystems.Linux, SkipReason = "WinHttpHandler not available on non-Windows.")]
[OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "WinHttpHandler not available on non-Windows.")] [OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "WinHttpHandler not available on non-Windows.")]
public async Task RequireCertificateFailsWhenNoCertificate() public async Task RequireCertificateFailsWhenNoCertificate()
{ {
var serviceContext = new TestServiceContext(new HttpsConnectionFilter( var serviceContext = new TestServiceContext(new HttpsConnectionFilter(
new HttpsConnectionFilterOptions new HttpsConnectionFilterOptions
{ {
ServerCertificate = _x509Certificate2, ServerCertificate = _x509Certificate2,
ClientCertificateMode = ClientCertificateMode.RequireCertificate ClientCertificateMode = ClientCertificateMode.RequireCertificate
}, },
new NoOpConnectionFilter()) new NoOpConnectionFilter())
); );
using (var server = new TestServer(App, serviceContext, _serverAddress)) using (var server = new TestServer(App, serviceContext, _serverAddress))
{
using (var client = new HttpClient(GetHandler()))
{ {
using (var client = new HttpClient(_handler)) await Assert.ThrowsAnyAsync<Exception>(
{ () => client.GetAsync($"https://localhost:{server.Port}/"));
await Assert.ThrowsAnyAsync<Exception>(
() => client.GetAsync($"https://localhost:{server.Port}/"));
}
} }
} }
}
[ConditionalFact] [ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux, SkipReason = "WinHttpHandler not available on non-Windows.")] [OSSkipCondition(OperatingSystems.Linux, SkipReason = "WinHttpHandler not available on non-Windows.")]
[OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "WinHttpHandler not available on non-Windows.")] [OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "WinHttpHandler not available on non-Windows.")]
public async Task AllowCertificateContinuesWhenNoCertificate() public async Task AllowCertificateContinuesWhenNoCertificate()
{ {
var serviceContext = new TestServiceContext(new HttpsConnectionFilter( var serviceContext = new TestServiceContext(new HttpsConnectionFilter(
new HttpsConnectionFilterOptions new HttpsConnectionFilterOptions
{
ServerCertificate = _x509Certificate2,
ClientCertificateMode = ClientCertificateMode.AllowCertificate
},
new NoOpConnectionFilter())
);
RequestDelegate app = context =>
{ {
Assert.Equal(context.Features.Get<ITlsConnectionFeature>(), null); ServerCertificate = _x509Certificate2,
return context.Response.WriteAsync("hello world"); ClientCertificateMode = ClientCertificateMode.AllowCertificate
}; },
new NoOpConnectionFilter())
);
RequestDelegate app = context =>
{
Assert.Equal(context.Features.Get<ITlsConnectionFeature>(), null);
return context.Response.WriteAsync("hello world");
};
using (var server = new TestServer(app, serviceContext, _serverAddress)) using (var server = new TestServer(app, serviceContext, _serverAddress))
{
using (var client = new HttpClient(GetHandler()))
{ {
using (var client = new HttpClient(_handler)) var result = await client.GetAsync($"https://localhost:{server.Port}/");
{
var result = await client.GetAsync($"https://localhost:{server.Port}/");
Assert.Equal("hello world", await result.Content.ReadAsStringAsync()); Assert.Equal("hello world", await result.Content.ReadAsStringAsync());
}
} }
} }
}
[Fact] [Fact]
public void ThrowsWhenNoServerCertificateIsProvided() public void ThrowsWhenNoServerCertificateIsProvided()
{ {
Assert.Throws<ArgumentException>(() => new HttpsConnectionFilter( Assert.Throws<ArgumentException>(() => new HttpsConnectionFilter(
new HttpsConnectionFilterOptions(), new HttpsConnectionFilterOptions(),
new NoOpConnectionFilter()) new NoOpConnectionFilter())
); );
} }
[Fact] [Fact]
public async Task UsesProvidedServerCertificate() public async Task UsesProvidedServerCertificate()
@ -179,103 +172,103 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[Fact] [Fact]
public async Task CertificatePassedToHttpContext() public async Task CertificatePassedToHttpContext()
{ {
var serviceContext = new TestServiceContext(new HttpsConnectionFilter( var serviceContext = new TestServiceContext(new HttpsConnectionFilter(
new HttpsConnectionFilterOptions new HttpsConnectionFilterOptions
{
ServerCertificate = _x509Certificate2,
ClientCertificateMode = ClientCertificateMode.RequireCertificate,
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true
},
new NoOpConnectionFilter())
);
RequestDelegate app = context =>
{ {
var tlsFeature = context.Features.Get<ITlsConnectionFeature>(); ServerCertificate = _x509Certificate2,
Assert.NotNull(tlsFeature); ClientCertificateMode = ClientCertificateMode.RequireCertificate,
Assert.NotNull(tlsFeature.ClientCertificate); ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true
Assert.NotNull(context.Connection.ClientCertificate); },
return context.Response.WriteAsync("hello world"); new NoOpConnectionFilter())
}; );
RequestDelegate app = context =>
{
var tlsFeature = context.Features.Get<ITlsConnectionFeature>();
Assert.NotNull(tlsFeature);
Assert.NotNull(tlsFeature.ClientCertificate);
Assert.NotNull(context.Connection.ClientCertificate);
return context.Response.WriteAsync("hello world");
};
using (var server = new TestServer(app, serviceContext, _serverAddress)) using (var server = new TestServer(app, serviceContext, _serverAddress))
{ {
using (var client = new TcpClient()) using (var client = new TcpClient())
{ {
// SslStream is used to ensure the certificate is actually passed to the server // SslStream is used to ensure the certificate is actually passed to the server
// HttpClient might not send the certificate because it is invalid or it doesn't match any // HttpClient might not send the certificate because it is invalid or it doesn't match any
// of the certificate authorities sent by the server in the SSL handshake. // of the certificate authorities sent by the server in the SSL handshake.
var stream = await OpenSslStream(client, server); var stream = await OpenSslStream(client, server);
await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false);
await AssertConnectionResult(stream, true); await AssertConnectionResult(stream, true);
}
} }
} }
}
[ConditionalFact] [ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux, SkipReason = "WinHttpHandler not available on non-Windows.")] [OSSkipCondition(OperatingSystems.Linux, SkipReason = "WinHttpHandler not available on non-Windows.")]
[OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "WinHttpHandler not available on non-Windows.")] [OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "WinHttpHandler not available on non-Windows.")]
public async Task HttpsSchemePassedToRequestFeature() public async Task HttpsSchemePassedToRequestFeature()
{ {
var serviceContext = new TestServiceContext( var serviceContext = new TestServiceContext(
new HttpsConnectionFilter( new HttpsConnectionFilter(
new HttpsConnectionFilterOptions new HttpsConnectionFilterOptions
{ {
ServerCertificate = _x509Certificate2 ServerCertificate = _x509Certificate2
}, },
new NoOpConnectionFilter()) new NoOpConnectionFilter())
); );
RequestDelegate app = context => context.Response.WriteAsync(context.Request.Scheme); RequestDelegate app = context => context.Response.WriteAsync(context.Request.Scheme);
using (var server = new TestServer(app, serviceContext, _serverAddress)) using (var server = new TestServer(app, serviceContext, _serverAddress))
{
using (var client = new HttpClient(GetHandler()))
{ {
using (var client = new HttpClient(_handler)) var result = await client.GetAsync($"https://localhost:{server.Port}/");
{
var result = await client.GetAsync($"https://localhost:{server.Port}/");
Assert.Equal("https", await result.Content.ReadAsStringAsync()); Assert.Equal("https", await result.Content.ReadAsStringAsync());
}
} }
} }
}
[Fact] [Fact]
public async Task DoesNotSupportTls10() public async Task DoesNotSupportTls10()
{ {
var serviceContext = new TestServiceContext(new HttpsConnectionFilter( var serviceContext = new TestServiceContext(new HttpsConnectionFilter(
new HttpsConnectionFilterOptions new HttpsConnectionFilterOptions
{
ServerCertificate = _x509Certificate2,
ClientCertificateMode = ClientCertificateMode.RequireCertificate,
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true
},
new NoOpConnectionFilter())
);
RequestDelegate app = context =>
{ {
return context.Response.WriteAsync("hello world"); ServerCertificate = _x509Certificate2,
}; ClientCertificateMode = ClientCertificateMode.RequireCertificate,
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true
},
new NoOpConnectionFilter())
);
RequestDelegate app = context =>
{
return context.Response.WriteAsync("hello world");
};
using (var server = new TestServer(app, serviceContext, _serverAddress)) using (var server = new TestServer(app, serviceContext, _serverAddress))
{
// SslStream is used to ensure the certificate is actually passed to the server
// HttpClient might not send the certificate because it is invalid or it doesn't match any
// of the certificate authorities sent by the server in the SSL handshake.
using (var client = new TcpClient())
{ {
// SslStream is used to ensure the certificate is actually passed to the server
// HttpClient might not send the certificate because it is invalid or it doesn't match any
// of the certificate authorities sent by the server in the SSL handshake.
using (var client = new TcpClient())
{
var stream = await OpenSslStream(client, server); var stream = await OpenSslStream(client, server);
var ex = await Assert.ThrowsAsync(typeof(IOException), async () => var ex = await Assert.ThrowsAsync(typeof(IOException),
await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls, false)); async () => await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls, false));
}
} }
} }
}
[Theory] [Theory]
[InlineData(ClientCertificateMode.AllowCertificate)] [InlineData(ClientCertificateMode.AllowCertificate)]
[InlineData(ClientCertificateMode.RequireCertificate)] [InlineData(ClientCertificateMode.RequireCertificate)]
public async Task ClientCertificateValidationGetsCalledWithNotNullParameters(ClientCertificateMode mode) public async Task ClientCertificateValidationGetsCalledWithNotNullParameters(ClientCertificateMode mode)
{ {
var clientCertificateValidationCalled = false; var clientCertificateValidationCalled = false;
var serviceContext = new TestServiceContext(new HttpsConnectionFilter( var serviceContext = new TestServiceContext(new HttpsConnectionFilter(
new HttpsConnectionFilterOptions new HttpsConnectionFilterOptions
@ -288,7 +281,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
Assert.NotNull(certificate); Assert.NotNull(certificate);
Assert.NotNull(chain); Assert.NotNull(chain);
return true; return true;
} }
}, },
new NoOpConnectionFilter()) new NoOpConnectionFilter())
); );
@ -303,7 +296,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false);
await AssertConnectionResult(stream, true); await AssertConnectionResult(stream, true);
Assert.True(clientCertificateValidationCalled); Assert.True(clientCertificateValidationCalled);
} }
} }
} }
@ -340,9 +333,9 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
[InlineData(ClientCertificateMode.RequireCertificate)] [InlineData(ClientCertificateMode.RequireCertificate)]
public async Task RejectsConnectionOnSslPolicyErrorsWhenNoValidation(ClientCertificateMode mode) public async Task RejectsConnectionOnSslPolicyErrorsWhenNoValidation(ClientCertificateMode mode)
{ {
var serviceContext = new TestServiceContext(new HttpsConnectionFilter( var serviceContext = new TestServiceContext(new HttpsConnectionFilter(
new HttpsConnectionFilterOptions new HttpsConnectionFilterOptions
{ {
ServerCertificate = _x509Certificate2, ServerCertificate = _x509Certificate2,
ClientCertificateMode = mode, ClientCertificateMode = mode,
}, },
@ -369,29 +362,29 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
new HttpsConnectionFilterOptions new HttpsConnectionFilterOptions
{ {
ServerCertificate = _x509Certificate2, ServerCertificate = _x509Certificate2,
ClientCertificateMode = ClientCertificateMode.RequireCertificate, ClientCertificateMode = ClientCertificateMode.RequireCertificate,
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true
}, },
new NoOpConnectionFilter()) new NoOpConnectionFilter())
); );
RequestDelegate app = context => RequestDelegate app = context =>
{ {
var tlsFeature = context.Features.Get<ITlsConnectionFeature>(); var tlsFeature = context.Features.Get<ITlsConnectionFeature>();
Assert.NotNull(tlsFeature); Assert.NotNull(tlsFeature);
Assert.NotNull(tlsFeature.ClientCertificate); Assert.NotNull(tlsFeature.ClientCertificate);
Assert.NotNull(context.Connection.ClientCertificate); Assert.NotNull(context.Connection.ClientCertificate);
Assert.NotNull(context.Connection.ClientCertificate.PublicKey); Assert.NotNull(context.Connection.ClientCertificate.PublicKey);
return context.Response.WriteAsync("hello world"); return context.Response.WriteAsync("hello world");
}; };
using (var server = new TestServer(app, serviceContext, _serverAddress)) using (var server = new TestServer(app, serviceContext, _serverAddress))
{
// SslStream is used to ensure the certificate is actually passed to the server
// HttpClient might not send the certificate because it is invalid or it doesn't match any
// of the certificate authorities sent by the server in the SSL handshake.
using (var client = new TcpClient())
{ {
// SslStream is used to ensure the certificate is actually passed to the server
// HttpClient might not send the certificate because it is invalid or it doesn't match any
// of the certificate authorities sent by the server in the SSL handshake.
using (var client = new TcpClient())
{
var stream = await OpenSslStream(client, server); var stream = await OpenSslStream(client, server);
await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false);
await AssertConnectionResult(stream, true); await AssertConnectionResult(stream, true);
@ -418,8 +411,8 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
private static async Task<SslStream> OpenSslStream(TcpClient client, TestServer server, X509Certificate2 clientCertificate = null) private static async Task<SslStream> OpenSslStream(TcpClient client, TestServer server, X509Certificate2 clientCertificate = null)
{ {
await client.ConnectAsync("127.0.0.1", server.Port); await client.ConnectAsync("127.0.0.1", server.Port);
var stream = new SslStream(client.GetStream(), false, (sender, certificate, chain, errors) => true, var stream = new SslStream(client.GetStream(), false, (sender, certificate, chain, errors) => true,
(sender, host, certificates, certificate, issuers) => clientCertificate ?? _x509Certificate2); (sender, host, certificates, certificate, issuers) => clientCertificate ?? _x509Certificate2);
return stream; return stream;
@ -427,15 +420,15 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
private static async Task AssertConnectionResult(SslStream stream, bool success) private static async Task AssertConnectionResult(SslStream stream, bool success)
{ {
var request = Encoding.UTF8.GetBytes("GET / HTTP/1.0\r\n\r\n"); var request = Encoding.UTF8.GetBytes("GET / HTTP/1.0\r\n\r\n");
await stream.WriteAsync(request, 0, request.Length); await stream.WriteAsync(request, 0, request.Length);
var reader = new StreamReader(stream); var reader = new StreamReader(stream);
string line = null; string line = null;
if (success) if (success)
{ {
line = await reader.ReadLineAsync(); line = await reader.ReadLineAsync();
Assert.Equal("HTTP/1.1 200 OK", line); Assert.Equal("HTTP/1.1 200 OK", line);
} }
else else
{ {
try try
@ -445,6 +438,17 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
catch (IOException) { } catch (IOException) { }
Assert.Null(line); Assert.Null(line);
} }
} }
private HttpMessageHandler GetHandler()
{
#if NET451
return new HttpClientHandler();
#else
var handler = new WinHttpHandler();
handler.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
return handler;
#endif
} }
} }
}