PR feedback from #11412 (#11474)

- Remove ExpectedMiddlewareCount since everything is middleware now
- Renamed everything adapter to middleware
- Added a regression test for an https scenario
- Don't send client certs for tests that don't expect it
This commit is contained in:
David Fowler 2019-06-23 21:08:10 -07:00 committed by GitHub
parent 2420d8f0ac
commit 5ca92305c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 140 additions and 136 deletions

View File

@ -2,15 +2,19 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.AspNetCore.Testing; using Microsoft.AspNetCore.Testing;
using Microsoft.AspNetCore.Testing.xunit; using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Xunit; using Xunit;
@ -149,5 +153,39 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
Assert.True(ipV6Attempt, "Should have attempted to bind to IPAddress.IPv6Any"); Assert.True(ipV6Attempt, "Should have attempted to bind to IPAddress.IPv6Any");
Assert.Contains(logger.Messages, f => f.Equals(CoreStrings.FormatFallbackToIPv4Any(80))); Assert.Contains(logger.Messages, f => f.Equals(CoreStrings.FormatFallbackToIPv4Any(80)));
} }
[Fact]
public async Task DefaultAddressBinderWithoutDevCertButHttpsConfiguredBindsToHttpsPorts()
{
var x509Certificate2 = TestResources.GetTestCertificate();
var logger = new MockLogger();
var addresses = new ServerAddressesFeature();
var services = new ServiceCollection();
services.AddLogging();
var options = new KestrelServerOptions()
{
// This stops the dev cert from being loaded
IsDevCertLoaded = true,
ApplicationServices = services.BuildServiceProvider()
};
options.ConfigureEndpointDefaults(e =>
{
if (e.IPEndPoint.Port == 5001)
{
e.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = x509Certificate2 });
}
});
var endpoints = new List<ListenOptions>();
await AddressBinder.BindAsync(addresses, options, logger, listenOptions =>
{
endpoints.Add(listenOptions);
return Task.CompletedTask;
});
Assert.Contains(endpoints, e => e.IPEndPoint.Port == 5000 && !e.IsTls);
Assert.Contains(endpoints, e => e.IPEndPoint.Port == 5001 && e.IsTls);
}
} }
} }

View File

@ -76,8 +76,6 @@ namespace Microsoft.AspNetCore.Testing
public Func<MemoryPool<byte>> MemoryPoolFactory { get; set; } = System.Buffers.SlabMemoryPoolFactory.Create; public Func<MemoryPool<byte>> MemoryPoolFactory { get; set; } = System.Buffers.SlabMemoryPoolFactory.Create;
public int ExpectedConnectionMiddlewareCount { get; set; }
public string DateHeaderValue => DateHeaderValueManager.GetDateHeaderValues().String; public string DateHeaderValue => DateHeaderValueManager.GetDateHeaderValues().String;
} }
} }

View File

@ -89,11 +89,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
c.Configure(context.ServerOptions); c.Configure(context.ServerOptions);
} }
// Prevent ListenOptions reuse. This is easily done accidentally when trying to debug a test by running it
// in a loop, but will cause problems because only the app func from the first loop will ever be invoked.
Assert.All(context.ServerOptions.ListenOptions, lo =>
Assert.Equal(context.ExpectedConnectionMiddlewareCount, lo._middleware.Count));
return new KestrelServer(sp.GetRequiredService<IConnectionListenerFactory>(), context); return new KestrelServer(sp.GetRequiredService<IConnectionListenerFactory>(), context);
}); });
configureServices(services); configureServices(services);

View File

@ -12,15 +12,15 @@ using Xunit;
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
{ {
public class ConnectionAdapterTests : LoggedTest public class ConnectionMiddlewareTests : LoggedTest
{ {
[Fact] [Fact]
public async Task ThrowingSynchronousConnectionAdapterDoesNotCrashServer() public async Task ThrowingSynchronousConnectionMiddlewareDoesNotCrashServer()
{ {
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)); var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
listenOptions.Use(next => context => throw new Exception()); listenOptions.Use(next => context => throw new Exception());
var serviceContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }; var serviceContext = new TestServiceContext(LoggerFactory);
using (var server = new TestServer(TestApp.EchoApp, serviceContext, listenOptions)) using (var server = new TestServer(TestApp.EchoApp, serviceContext, listenOptions))
{ {

View File

@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2
var ex = Assert.Throws<NotSupportedException>(() => new TestServer(context => var ex = Assert.Throws<NotSupportedException>(() => new TestServer(context =>
{ {
throw new NotImplementedException(); throw new NotImplementedException();
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, }, new TestServiceContext(LoggerFactory),
kestrelOptions => kestrelOptions =>
{ {
kestrelOptions.Listen(IPAddress.Loopback, 0, listenOptions => kestrelOptions.Listen(IPAddress.Loopback, 0, listenOptions =>
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2
"ALPN: " + tlsFeature.ApplicationProtocol.Length); "ALPN: " + tlsFeature.ApplicationProtocol.Length);
return context.Response.WriteAsync("hello world " + context.Request.Protocol); return context.Response.WriteAsync("hello world " + context.Request.Protocol);
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, }, new TestServiceContext(LoggerFactory),
kestrelOptions => kestrelOptions =>
{ {
kestrelOptions.Listen(IPAddress.Loopback, 0, listenOptions => kestrelOptions.Listen(IPAddress.Loopback, 0, listenOptions =>
@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2
"ALPN: " + tlsFeature.ApplicationProtocol.Length); "ALPN: " + tlsFeature.ApplicationProtocol.Length);
return context.Response.WriteAsync("hello world " + context.Request.Protocol); return context.Response.WriteAsync("hello world " + context.Request.Protocol);
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, }, new TestServiceContext(LoggerFactory),
kestrelOptions => kestrelOptions =>
{ {
kestrelOptions.Listen(IPAddress.Loopback, 0, listenOptions => kestrelOptions.Listen(IPAddress.Loopback, 0, listenOptions =>

View File

@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2
.Setup(m => m.Http2ConnectionClosing(It.IsAny<string>())) .Setup(m => m.Http2ConnectionClosing(It.IsAny<string>()))
.Callback(() => requestStopping.SetResult(null)); .Callback(() => requestStopping.SetResult(null));
var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object) { ExpectedConnectionMiddlewareCount = 1 }; var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object);
testContext.InitializeHeartbeat(); testContext.InitializeHeartbeat();
@ -112,8 +112,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2
var testContext = new TestServiceContext(LoggerFactory) var testContext = new TestServiceContext(LoggerFactory)
{ {
MemoryPoolFactory = memoryPoolFactory.Create, MemoryPoolFactory = memoryPoolFactory.Create
ExpectedConnectionMiddlewareCount = 1
}; };
TestApplicationErrorLogger.ThrowOnUngracefulShutdown = false; TestApplicationErrorLogger.ThrowOnUngracefulShutdown = false;

View File

@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
private const int _connectionResetEventId = 19; private const int _connectionResetEventId = 19;
private static readonly int _semaphoreWaitTimeout = Debugger.IsAttached ? 10000 : 2500; private static readonly int _semaphoreWaitTimeout = Debugger.IsAttached ? 10000 : 2500;
public static TheoryData<ListenOptions> ConnectionAdapterData => new TheoryData<ListenOptions> public static TheoryData<ListenOptions> ConnectionMiddlewareData => new TheoryData<ListenOptions>
{ {
new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)), new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)),
new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)).UsePassThrough() new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)).UsePassThrough()
@ -503,10 +503,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
} }
[Theory] [Theory]
[MemberData(nameof(ConnectionAdapterData))] [MemberData(nameof(ConnectionMiddlewareData))]
public async Task ConnectionClosedTokenFiresOnClientFIN(ListenOptions listenOptions) public async Task ConnectionClosedTokenFiresOnClientFIN(ListenOptions listenOptions)
{ {
var testContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = listenOptions._middleware.Count }; var testContext = new TestServiceContext(LoggerFactory);
var appStartedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); var appStartedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
var connectionClosedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); var connectionClosedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
@ -540,10 +540,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
[Theory] [Theory]
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2181", FlakyOn.Helix.All)] [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2181", FlakyOn.Helix.All)]
[MemberData(nameof(ConnectionAdapterData))] [MemberData(nameof(ConnectionMiddlewareData))]
public async Task ConnectionClosedTokenFiresOnServerFIN(ListenOptions listenOptions) public async Task ConnectionClosedTokenFiresOnServerFIN(ListenOptions listenOptions)
{ {
var testContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = listenOptions._middleware.Count }; var testContext = new TestServiceContext(LoggerFactory);
var connectionClosedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); var connectionClosedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
using (var server = new TestServer(context => using (var server = new TestServer(context =>
@ -577,10 +577,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
} }
[Theory] [Theory]
[MemberData(nameof(ConnectionAdapterData))] [MemberData(nameof(ConnectionMiddlewareData))]
public async Task ConnectionClosedTokenFiresOnServerAbort(ListenOptions listenOptions) public async Task ConnectionClosedTokenFiresOnServerAbort(ListenOptions listenOptions)
{ {
var testContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = listenOptions._middleware.Count }; var testContext = new TestServiceContext(LoggerFactory);
var connectionClosedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); var connectionClosedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
using (var server = new TestServer(context => using (var server = new TestServer(context =>
@ -619,13 +619,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
} }
[Theory] [Theory]
[MemberData(nameof(ConnectionAdapterData))] [MemberData(nameof(ConnectionMiddlewareData))]
public async Task RequestsCanBeAbortedMidRead(ListenOptions listenOptions) public async Task RequestsCanBeAbortedMidRead(ListenOptions listenOptions)
{ {
// This needs a timeout. // This needs a timeout.
const int applicationAbortedConnectionId = 34; const int applicationAbortedConnectionId = 34;
var testContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = listenOptions._middleware.Count }; var testContext = new TestServiceContext(LoggerFactory);
var readTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); var readTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
var registrationTcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); var registrationTcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
@ -710,7 +710,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
} }
[Theory] [Theory]
[MemberData(nameof(ConnectionAdapterData))] [MemberData(nameof(ConnectionMiddlewareData))]
public async Task ServerCanAbortConnectionAfterUnobservedClose(ListenOptions listenOptions) public async Task ServerCanAbortConnectionAfterUnobservedClose(ListenOptions listenOptions)
{ {
const int connectionPausedEventId = 4; const int connectionPausedEventId = 4;
@ -743,7 +743,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
var mockKestrelTrace = new Mock<IKestrelTrace>(); var mockKestrelTrace = new Mock<IKestrelTrace>();
var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object) var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object)
{ {
ExpectedConnectionMiddlewareCount = listenOptions._middleware.Count,
ServerOptions = ServerOptions =
{ {
Limits = Limits =
@ -796,14 +795,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
#if LIBUV #if LIBUV
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/1971", FlakyOn.Helix.All)] [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/1971", FlakyOn.Helix.All)]
#endif #endif
[MemberData(nameof(ConnectionAdapterData))] [MemberData(nameof(ConnectionMiddlewareData))]
public async Task AppCanHandleClientAbortingConnectionMidRequest(ListenOptions listenOptions) public async Task AppCanHandleClientAbortingConnectionMidRequest(ListenOptions listenOptions)
{ {
var readTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); var readTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
var appStartedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); var appStartedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
var mockKestrelTrace = new Mock<IKestrelTrace>(); var mockKestrelTrace = new Mock<IKestrelTrace>();
var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object) { ExpectedConnectionMiddlewareCount = listenOptions._middleware.Count }; var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object);
var scratchBuffer = new byte[4096]; var scratchBuffer = new byte[4096];

View File

@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
{ {
public class ResponseTests : TestApplicationErrorLoggerLoggedTest public class ResponseTests : TestApplicationErrorLoggerLoggedTest
{ {
public static TheoryData<ListenOptions> ConnectionAdapterData => new TheoryData<ListenOptions> public static TheoryData<ListenOptions> ConnectionMiddlewareData => new TheoryData<ListenOptions>
{ {
new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)), new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)),
new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)).UsePassThrough() new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)).UsePassThrough()
@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
} }
[Theory] [Theory]
[MemberData(nameof(ConnectionAdapterData))] [MemberData(nameof(ConnectionMiddlewareData))]
public async Task WriteAfterConnectionCloseNoops(ListenOptions listenOptions) public async Task WriteAfterConnectionCloseNoops(ListenOptions listenOptions)
{ {
var connectionClosed = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); var connectionClosed = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
@ -157,7 +157,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
{ {
appCompleted.TrySetException(ex); appCompleted.TrySetException(ex);
} }
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = listenOptions._middleware.Count }, listenOptions)) }, new TestServiceContext(LoggerFactory), listenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
@ -180,7 +180,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
} }
[Theory] [Theory]
[MemberData(nameof(ConnectionAdapterData))] [MemberData(nameof(ConnectionMiddlewareData))]
public async Task ThrowsOnWriteWithRequestAbortedTokenAfterRequestIsAborted(ListenOptions listenOptions) public async Task ThrowsOnWriteWithRequestAbortedTokenAfterRequestIsAborted(ListenOptions listenOptions)
{ {
// This should match _maxBytesPreCompleted in SocketOutput // This should match _maxBytesPreCompleted in SocketOutput
@ -219,7 +219,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
} }
writeTcs.SetException(new Exception("This shouldn't be reached.")); writeTcs.SetException(new Exception("This shouldn't be reached."));
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = listenOptions._middleware.Count }, listenOptions)) }, new TestServiceContext(LoggerFactory), listenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
@ -244,7 +244,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
} }
[Theory] [Theory]
[MemberData(nameof(ConnectionAdapterData))] [MemberData(nameof(ConnectionMiddlewareData))]
public async Task WritingToConnectionAfterUnobservedCloseTriggersRequestAbortedToken(ListenOptions listenOptions) public async Task WritingToConnectionAfterUnobservedCloseTriggersRequestAbortedToken(ListenOptions listenOptions)
{ {
const int connectionPausedEventId = 4; const int connectionPausedEventId = 4;
@ -273,7 +273,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object) var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object)
{ {
ExpectedConnectionMiddlewareCount = listenOptions._middleware.Count,
ServerOptions = ServerOptions =
{ {
Limits = Limits =
@ -341,7 +340,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
[Theory] [Theory]
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/1972", FlakyOn.All)] [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/1972", FlakyOn.All)]
[MemberData(nameof(ConnectionAdapterData))] [MemberData(nameof(ConnectionMiddlewareData))]
public async Task AppCanHandleClientAbortingConnectionMidResponse(ListenOptions listenOptions) public async Task AppCanHandleClientAbortingConnectionMidResponse(ListenOptions listenOptions)
{ {
const int connectionResetEventId = 19; const int connectionResetEventId = 19;
@ -368,7 +367,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
await requestAborted.Task.DefaultTimeout(); await requestAborted.Task.DefaultTimeout();
appCompletedTcs.SetResult(null); appCompletedTcs.SetResult(null);
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = listenOptions._middleware.Count }, listenOptions)) }, new TestServiceContext(LoggerFactory), listenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
@ -414,7 +413,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
} }
[Theory] [Theory]
[MemberData(nameof(ConnectionAdapterData))] [MemberData(nameof(ConnectionMiddlewareData))]
public async Task ClientAbortingConnectionImmediatelyIsNotLoggedHigherThanDebug(ListenOptions listenOptions) public async Task ClientAbortingConnectionImmediatelyIsNotLoggedHigherThanDebug(ListenOptions listenOptions)
{ {
// Attempt multiple connections to be extra sure the resets are consistently logged appropriately. // Attempt multiple connections to be extra sure the resets are consistently logged appropriately.
@ -422,7 +421,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
// There's not guarantee that the app even gets invoked in this test. The connection reset can be observed // There's not guarantee that the app even gets invoked in this test. The connection reset can be observed
// as early as accept. // as early as accept.
var testServiceContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = listenOptions._middleware.Count }; var testServiceContext = new TestServiceContext(LoggerFactory);
using (var server = new TestServer(context => Task.CompletedTask, testServiceContext, listenOptions)) using (var server = new TestServer(context => Task.CompletedTask, testServiceContext, listenOptions))
{ {
for (var i = 0; i < numConnections; i++) for (var i = 0; i < numConnections; i++)
@ -582,8 +581,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
{ {
MinResponseDataRate = new MinDataRate(bytesPerSecond: 1024 * 1024, gracePeriod: TimeSpan.FromSeconds(2)) MinResponseDataRate = new MinDataRate(bytesPerSecond: 1024 * 1024, gracePeriod: TimeSpan.FromSeconds(2))
} }
}, }
ExpectedConnectionMiddlewareCount = 1
}; };
testContext.InitializeHeartbeat(); testContext.InitializeHeartbeat();

View File

@ -207,10 +207,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
private TestServer CreateServerWithMaxConnections(RequestDelegate app, ResourceCounter concurrentConnectionCounter) private TestServer CreateServerWithMaxConnections(RequestDelegate app, ResourceCounter concurrentConnectionCounter)
{ {
var serviceContext = new TestServiceContext(LoggerFactory) var serviceContext = new TestServiceContext(LoggerFactory);
{
ExpectedConnectionMiddlewareCount = 1
};
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)); var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
listenOptions.Use(next => listenOptions.Use(next =>

View File

@ -18,7 +18,7 @@ using Xunit;
namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
public class ConnectionAdapterTests : TestApplicationErrorLoggerLoggedTest public class ConnectionMiddlewareTests : TestApplicationErrorLoggerLoggedTest
{ {
public static TheoryData<RequestDelegate> EchoAppRequestDelegates => public static TheoryData<RequestDelegate> EchoAppRequestDelegates =>
new TheoryData<RequestDelegate> new TheoryData<RequestDelegate>
@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
return middleware.OnConnectionAsync; return middleware.OnConnectionAsync;
}); });
var serviceContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }; var serviceContext = new TestServiceContext(LoggerFactory);
var sendString = "POST / HTTP/1.0\r\nContent-Length: 12\r\n\r\nHello World?"; var sendString = "POST / HTTP/1.0\r\nContent-Length: 12\r\n\r\nHello World?";
@ -64,12 +64,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
[Theory] [Theory]
[MemberData(nameof(EchoAppRequestDelegates))] [MemberData(nameof(EchoAppRequestDelegates))]
public async Task CanReadAndWriteWithAsyncConnectionAdapter(RequestDelegate requestDelegate) public async Task CanReadAndWriteWithAsyncConnectionMiddleware(RequestDelegate requestDelegate)
{ {
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)); var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
listenOptions.Use(next => new AsyncConnectionMiddleware(next).OnConnectionAsync); listenOptions.Use(next => new AsyncConnectionMiddleware(next).OnConnectionAsync);
var serviceContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }; var serviceContext = new TestServiceContext(LoggerFactory);
await using (var server = new TestServer(requestDelegate, serviceContext, listenOptions)) await using (var server = new TestServer(requestDelegate, serviceContext, listenOptions))
{ {
@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)); var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
listenOptions.Use(next => new AsyncConnectionMiddleware(next).OnConnectionAsync); listenOptions.Use(next => new AsyncConnectionMiddleware(next).OnConnectionAsync);
var serviceContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }; var serviceContext = new TestServiceContext(LoggerFactory);
await using (var server = new TestServer(requestDelegate, serviceContext, listenOptions)) await using (var server = new TestServer(requestDelegate, serviceContext, listenOptions))
{ {
@ -117,7 +117,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)); var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
listenOptions.Use(next => context => throw new InvalidOperationException()); listenOptions.Use(next => context => throw new InvalidOperationException());
var serviceContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }; var serviceContext = new TestServiceContext(LoggerFactory);
await using (var server = new TestServer(requestDelegate, serviceContext, listenOptions)) await using (var server = new TestServer(requestDelegate, serviceContext, listenOptions))
{ {
@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)); var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
listenOptions.Use(next => new AsyncConnectionMiddleware(next).OnConnectionAsync); listenOptions.Use(next => new AsyncConnectionMiddleware(next).OnConnectionAsync);
var serviceContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }; var serviceContext = new TestServiceContext(LoggerFactory);
TestApplicationErrorLogger.ThrowOnUngracefulShutdown = false; TestApplicationErrorLogger.ThrowOnUngracefulShutdown = false;
@ -172,7 +172,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
}; };
}); });
var serviceContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }; var serviceContext = new TestServiceContext(LoggerFactory);
await using (var server = new TestServer(TestApp.EchoApp, serviceContext, listenOptions)) await using (var server = new TestServer(TestApp.EchoApp, serviceContext, listenOptions))
{ {
@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
[Theory] [Theory]
[MemberData(nameof(EchoAppRequestDelegates))] [MemberData(nameof(EchoAppRequestDelegates))]
public async Task ThrowingSynchronousConnectionAdapterDoesNotCrashServer(RequestDelegate requestDelegate) public async Task ThrowingSynchronousConnectionMiddlewareDoesNotCrashServer(RequestDelegate requestDelegate)
{ {
var connectionId = ""; var connectionId = "";
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)); var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
@ -201,7 +201,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
throw new InvalidOperationException(); throw new InvalidOperationException();
}); });
var serviceContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }; var serviceContext = new TestServiceContext(LoggerFactory);
await using (var server = new TestServer(requestDelegate, serviceContext, listenOptions)) await using (var server = new TestServer(requestDelegate, serviceContext, listenOptions))
{ {
@ -220,12 +220,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
} }
[Fact] [Fact]
public async Task CanFlushAsyncWithConnectionAdapter() public async Task CanFlushAsyncWithConnectionMiddleware()
{ {
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)) var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
.UsePassThrough(); .UsePassThrough();
var serviceContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }; var serviceContext = new TestServiceContext(LoggerFactory);
await using (var server = new TestServer(async context => await using (var server = new TestServer(async context =>
{ {
@ -251,12 +251,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
} }
[Fact] [Fact]
public async Task CanFlushAsyncWithConnectionAdapterPipeWriter() public async Task CanFlushAsyncWithConnectionMiddlewarePipeWriter()
{ {
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)) var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
.UsePassThrough(); .UsePassThrough();
var serviceContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }; var serviceContext = new TestServiceContext(LoggerFactory);
await using (var server = new TestServer(async context => await using (var server = new TestServer(async context =>
{ {

View File

@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.Http2
return context.Response.WriteAsync("hello world " + context.Request.Protocol); return context.Response.WriteAsync("hello world " + context.Request.Protocol);
}, },
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1}, new TestServiceContext(LoggerFactory),
listenOptions => listenOptions =>
{ {
listenOptions.Protocols = HttpProtocols.Http2; listenOptions.Protocols = HttpProtocols.Http2;

View File

@ -17,8 +17,8 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Https.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Https; using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.AspNetCore.Server.Kestrel.Https.Internal;
using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport; using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport;
using Microsoft.AspNetCore.Testing; using Microsoft.AspNetCore.Testing;
using Microsoft.AspNetCore.Testing.xunit; using Microsoft.AspNetCore.Testing.xunit;
@ -27,20 +27,20 @@ using Xunit;
namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
public class HttpsConnectionAdapterTests : LoggedTest public class HttpsConnectionMiddlewareTests : LoggedTest
{ {
private static X509Certificate2 _x509Certificate2 = TestResources.GetTestCertificate(); private static X509Certificate2 _x509Certificate2 = TestResources.GetTestCertificate();
private static X509Certificate2 _x509Certificate2NoExt = TestResources.GetTestCertificate("no_extensions.pfx"); private static X509Certificate2 _x509Certificate2NoExt = TestResources.GetTestCertificate("no_extensions.pfx");
[Fact] [Fact]
public async Task CanReadAndWriteWithHttpsConnectionAdapter() public async Task CanReadAndWriteWithHttpsConnectionMiddleware()
{ {
void ConfigureListenOptions(ListenOptions listenOptions) void ConfigureListenOptions(ListenOptions listenOptions)
{ {
listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 }); listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 });
}; };
await using (var server = new TestServer(App, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(App, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
var result = await server.HttpClientSlim.PostAsync($"https://localhost:{server.Port}/", var result = await server.HttpClientSlim.PostAsync($"https://localhost:{server.Port}/",
new FormUrlEncodedContent(new[] { new FormUrlEncodedContent(new[] {
@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
Assert.True(tlsFeature.KeyExchangeStrength >= 0, "KeyExchangeStrength"); // May be 0 on mac Assert.True(tlsFeature.KeyExchangeStrength >= 0, "KeyExchangeStrength"); // May be 0 on mac
return context.Response.WriteAsync("hello world"); return context.Response.WriteAsync("hello world");
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) }, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
var result = await server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/", validateCertificate: false); var result = await server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/", validateCertificate: false);
Assert.Equal("hello world", result); Assert.Equal("hello world", result);
@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
ClientCertificateMode = ClientCertificateMode.RequireCertificate ClientCertificateMode = ClientCertificateMode.RequireCertificate
}); });
await using (var server = new TestServer(App, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, listenOptions)) await using (var server = new TestServer(App, new TestServiceContext(LoggerFactory), listenOptions))
{ {
await Assert.ThrowsAnyAsync<Exception>( await Assert.ThrowsAnyAsync<Exception>(
() => server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/")); () => server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/"));
@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
Assert.NotNull(tlsFeature); Assert.NotNull(tlsFeature);
Assert.Null(tlsFeature.ClientCertificate); Assert.Null(tlsFeature.ClientCertificate);
return context.Response.WriteAsync("hello world"); return context.Response.WriteAsync("hello world");
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) }, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
var result = await server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/", validateCertificate: false); var result = await server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/", validateCertificate: false);
Assert.Equal("hello world", result); Assert.Equal("hello world", result);
@ -138,13 +138,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 }); listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 });
}; };
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
// 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.
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStream(connection.Stream);
await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false);
Assert.True(stream.RemoteCertificate.Equals(_x509Certificate2)); Assert.True(stream.RemoteCertificate.Equals(_x509Certificate2));
@ -171,13 +168,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
}); });
} }
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
// 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.
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStream(connection.Stream);
await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false);
Assert.True(stream.RemoteCertificate.Equals(_x509Certificate2)); Assert.True(stream.RemoteCertificate.Equals(_x509Certificate2));
@ -209,13 +203,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
}); });
} }
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
// 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.
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStream(connection.Stream);
await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false);
Assert.True(stream.RemoteCertificate.Equals(_x509Certificate2)); Assert.True(stream.RemoteCertificate.Equals(_x509Certificate2));
@ -223,9 +214,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
} }
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
// 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.
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStream(connection.Stream);
await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false);
Assert.True(stream.RemoteCertificate.Equals(_x509Certificate2NoExt)); Assert.True(stream.RemoteCertificate.Equals(_x509Certificate2NoExt));
@ -250,13 +238,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
}); });
} }
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
// 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.
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStream(connection.Stream);
await Assert.ThrowsAsync<IOException>(() => await Assert.ThrowsAsync<IOException>(() =>
stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false)); stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false));
@ -285,13 +270,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
}); });
} }
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
// 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.
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStream(connection.Stream);
await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false);
Assert.True(stream.RemoteCertificate.Equals(_x509Certificate2)); Assert.True(stream.RemoteCertificate.Equals(_x509Certificate2));
@ -316,13 +298,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
}); });
} }
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
// 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.
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStream(connection.Stream);
await Assert.ThrowsAsync<IOException>(() => await Assert.ThrowsAsync<IOException>(() =>
stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false)); stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false));
@ -354,14 +333,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
Assert.NotNull(tlsFeature.ClientCertificate); Assert.NotNull(tlsFeature.ClientCertificate);
Assert.NotNull(context.Connection.ClientCertificate); Assert.NotNull(context.Connection.ClientCertificate);
return context.Response.WriteAsync("hello world"); return context.Response.WriteAsync("hello world");
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) }, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
// 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 = OpenSslStream(connection.Stream); var stream = OpenSslStreamWithCert(connection.Stream);
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);
} }
@ -376,7 +355,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 }); listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 });
} }
await using (var server = new TestServer(context => context.Response.WriteAsync(context.Request.Scheme), new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(context => context.Response.WriteAsync(context.Request.Scheme), new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
var result = await server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/", validateCertificate: false); var result = await server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/", validateCertificate: false);
Assert.Equal("https", result); Assert.Equal("https", result);
@ -397,14 +376,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
} }
await using (var server = new TestServer(context => context.Response.WriteAsync("hello world"), new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(context => context.Response.WriteAsync("hello world"), new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
// 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.
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStreamWithCert(connection.Stream);
var ex = await Assert.ThrowsAsync<IOException>( var ex = await Assert.ThrowsAsync<IOException>(
async () => await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls, false)); async () => await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls, false));
} }
@ -434,11 +413,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
}); });
} }
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStreamWithCert(connection.Stream);
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);
@ -462,11 +441,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
}); });
} }
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStreamWithCert(connection.Stream);
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, false); await AssertConnectionResult(stream, false);
} }
@ -487,11 +466,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
}); });
} }
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStreamWithCert(connection.Stream);
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, false); await AssertConnectionResult(stream, false);
} }
@ -512,11 +491,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
}); });
} }
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
using (var connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStreamWithCert(connection.Stream);
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);
} }
@ -546,14 +525,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
return context.Response.WriteAsync("hello world"); return context.Response.WriteAsync("hello world");
}; };
await using (var server = new TestServer(app, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) await using (var server = new TestServer(app, new TestServiceContext(LoggerFactory), ConfigureListenOptions))
{ {
// 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 connection = server.CreateConnection()) using (var connection = server.CreateConnection())
{ {
var stream = OpenSslStream(connection.Stream); var stream = OpenSslStreamWithCert(connection.Stream);
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);
} }
@ -630,7 +606,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
} }
} }
private static SslStream OpenSslStream(Stream rawStream, X509Certificate2 clientCertificate = null) private static SslStream OpenSslStream(Stream rawStream)
{
return new SslStream(rawStream, false, (sender, certificate, chain, errors) => true);
}
/// <summary>
/// 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.
/// </summary>
private static SslStream OpenSslStreamWithCert(Stream rawStream, X509Certificate2 clientCertificate = null)
{ {
return new SslStream(rawStream, false, (sender, certificate, chain, errors) => true, return new SslStream(rawStream, false, (sender, certificate, chain, errors) => true,
(sender, host, certificates, certificate, issuers) => clientCertificate ?? _x509Certificate2); (sender, host, certificates, certificate, issuers) => clientCertificate ?? _x509Certificate2);

View File

@ -122,7 +122,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
LoggerFactory.AddProvider(loggerProvider); LoggerFactory.AddProvider(loggerProvider);
await using (var server = new TestServer(context => Task.CompletedTask, await using (var server = new TestServer(context => Task.CompletedTask,
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, new TestServiceContext(LoggerFactory),
listenOptions => listenOptions =>
{ {
listenOptions.UseHttps(TestResources.GetTestCertificate()); listenOptions.UseHttps(TestResources.GetTestCertificate());
@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
LoggerFactory.AddProvider(loggerProvider); LoggerFactory.AddProvider(loggerProvider);
await using (var server = new TestServer(context => Task.CompletedTask, await using (var server = new TestServer(context => Task.CompletedTask,
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, new TestServiceContext(LoggerFactory),
listenOptions => listenOptions =>
{ {
listenOptions.UseHttps(TestResources.GetTestCertificate()); listenOptions.UseHttps(TestResources.GetTestCertificate());
@ -193,7 +193,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
} }
} }
}, },
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, new TestServiceContext(LoggerFactory),
listenOptions => listenOptions =>
{ {
listenOptions.UseHttps(TestResources.GetTestCertificate()); listenOptions.UseHttps(TestResources.GetTestCertificate());
@ -237,7 +237,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
tcs.SetException(ex); tcs.SetException(ex);
} }
}, },
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, new TestServiceContext(LoggerFactory),
listenOptions => listenOptions =>
{ {
listenOptions.UseHttps(TestResources.GetTestCertificate()); listenOptions.UseHttps(TestResources.GetTestCertificate());
@ -268,7 +268,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
LoggerFactory.AddProvider(loggerProvider); LoggerFactory.AddProvider(loggerProvider);
await using (var server = new TestServer(context => Task.CompletedTask, await using (var server = new TestServer(context => Task.CompletedTask,
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, new TestServiceContext(LoggerFactory),
listenOptions => listenOptions =>
{ {
listenOptions.UseHttps(TestResources.GetTestCertificate()); listenOptions.UseHttps(TestResources.GetTestCertificate());
@ -294,7 +294,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
LoggerFactory.AddProvider(loggerProvider); LoggerFactory.AddProvider(loggerProvider);
await using (var server = new TestServer(context => Task.CompletedTask, await using (var server = new TestServer(context => Task.CompletedTask,
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, new TestServiceContext(LoggerFactory),
listenOptions => listenOptions =>
{ {
listenOptions.UseHttps(TestResources.GetTestCertificate()); listenOptions.UseHttps(TestResources.GetTestCertificate());
@ -313,7 +313,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
var loggerProvider = new HandshakeErrorLoggerProvider(); var loggerProvider = new HandshakeErrorLoggerProvider();
LoggerFactory.AddProvider(loggerProvider); LoggerFactory.AddProvider(loggerProvider);
var testContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }; var testContext = new TestServiceContext(LoggerFactory);
var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager); var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);
var handshakeStartedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); var handshakeStartedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
@ -361,7 +361,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
LoggerFactory.AddProvider(loggerProvider); LoggerFactory.AddProvider(loggerProvider);
await using (var server = new TestServer(context => Task.CompletedTask, await using (var server = new TestServer(context => Task.CompletedTask,
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, new TestServiceContext(LoggerFactory),
listenOptions => listenOptions =>
{ {
listenOptions.UseHttps(TestResources.GetTestCertificate()); listenOptions.UseHttps(TestResources.GetTestCertificate());
@ -393,7 +393,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
var onAuthenticateCalled = false; var onAuthenticateCalled = false;
await using (var server = new TestServer(context => Task.CompletedTask, await using (var server = new TestServer(context => Task.CompletedTask,
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, new TestServiceContext(LoggerFactory),
listenOptions => listenOptions =>
{ {
listenOptions.UseHttps(httpsOptions => listenOptions.UseHttps(httpsOptions =>
@ -429,7 +429,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
var onAuthenticateCalled = false; var onAuthenticateCalled = false;
await using (var server = new TestServer(context => Task.CompletedTask, await using (var server = new TestServer(context => Task.CompletedTask,
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, new TestServiceContext(LoggerFactory),
listenOptions => listenOptions =>
{ {
listenOptions.UseHttps(httpsOptions => listenOptions.UseHttps(httpsOptions =>

View File

@ -12,18 +12,18 @@ using Xunit;
namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
public class LoggingConnectionAdapterTests : LoggedTest public class LoggingConnectionMiddlewareTests : LoggedTest
{ {
[Fact] [Fact]
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2276", FlakyOn.Helix.All)] [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2276", FlakyOn.Helix.All)]
public async Task LoggingConnectionAdapterCanBeAddedBeforeAndAfterHttpsAdapter() public async Task LoggingConnectionMiddlewareCanBeAddedBeforeAndAfterHttps()
{ {
await using (var server = new TestServer(context => await using (var server = new TestServer(context =>
{ {
context.Response.ContentLength = 12; context.Response.ContentLength = 12;
return context.Response.WriteAsync("Hello World!"); return context.Response.WriteAsync("Hello World!");
}, },
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 3 }, new TestServiceContext(LoggerFactory),
listenOptions => listenOptions =>
{ {
listenOptions.UseConnectionLogging(); listenOptions.UseConnectionLogging();

View File

@ -15,17 +15,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
{ {
public class ResponseDrainingTests : TestApplicationErrorLoggerLoggedTest public class ResponseDrainingTests : TestApplicationErrorLoggerLoggedTest
{ {
public static TheoryData<ListenOptions> ConnectionAdapterData => new TheoryData<ListenOptions> public static TheoryData<ListenOptions> ConnectionMiddlewareData => new TheoryData<ListenOptions>
{ {
new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)), new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)),
new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)).UsePassThrough() new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)).UsePassThrough()
}; };
[Theory] [Theory]
[MemberData(nameof(ConnectionAdapterData))] [MemberData(nameof(ConnectionMiddlewareData))]
public async Task ConnectionClosedWhenResponseNotDrainedAtMinimumDataRate(ListenOptions listenOptions) public async Task ConnectionClosedWhenResponseNotDrainedAtMinimumDataRate(ListenOptions listenOptions)
{ {
var testContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = listenOptions._middleware.Count }; var testContext = new TestServiceContext(LoggerFactory);
var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager); var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);
var minRate = new MinDataRate(16384, TimeSpan.FromSeconds(2)); var minRate = new MinDataRate(16384, TimeSpan.FromSeconds(2));

View File

@ -80,12 +80,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTrans
{ {
context.ServerOptions.ApplicationServices = sp; context.ServerOptions.ApplicationServices = sp;
configureKestrel(context.ServerOptions); configureKestrel(context.ServerOptions);
// Prevent ListenOptions reuse. This is easily done accidentally when trying to debug a test by running it
// in a loop, but will cause problems because only the app func from the first loop will ever be invoked.
Assert.All(context.ServerOptions.ListenOptions, lo =>
Assert.Equal(context.ExpectedConnectionMiddlewareCount, lo._middleware.Count));
return new KestrelServer(_transportFactory, context); return new KestrelServer(_transportFactory, context);
}); });
}); });