Quick fix for SslStream ODEs in HttpsAdaptedConnection.PrepareRequest (#1786)

This commit is contained in:
Stephen Halter 2017-04-27 16:56:07 -07:00 committed by GitHub
parent 1a26dc0238
commit 79ea2bb9b3
2 changed files with 42 additions and 4 deletions

View File

@ -164,7 +164,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
{ {
Log.LogError(0, ex, $"Uncaught exception from the {nameof(IConnectionAdapter.OnConnectionAsync)} method of an {nameof(IConnectionAdapter)}."); Log.LogError(0, ex, $"Uncaught exception from the {nameof(IConnectionAdapter.OnConnectionAsync)} method of an {nameof(IConnectionAdapter)}.");
_frameStartedTcs.SetResult(false); _frameStartedTcs.SetResult(false);
CloseRawPipes(); _ = CloseRawPipesAsync();
} }
} }
@ -181,15 +181,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
} }
finally finally
{ {
CloseRawPipes(); // Don't allow _adaptedPipelineTask to be held up by StopAsync() or else StopAsync() will never complete.
_ = CloseRawPipesAsync();
} }
} }
private void CloseRawPipes() private async Task CloseRawPipesAsync()
{ {
_filteredStream?.Dispose();
_context.OutputProducer.Dispose(); _context.OutputProducer.Dispose();
_context.Input.Reader.Complete(); _context.Input.Reader.Complete();
// Wait until request processing is complete before disposing the Stream.
await StopAsync();
_filteredStream?.Dispose();
} }
private void StartFrame() private void StartFrame()

View File

@ -196,6 +196,39 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
await tcs.Task.TimeoutAfter(TimeSpan.FromSeconds(10)); await tcs.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
} }
// Regression test for https://github.com/aspnet/KestrelHttpServer/issues/1693
[Fact]
public async Task DoesNotThrowObjectDisposedExceptionOnEmptyConnection()
{
var loggerFactory = new HandshakeErrorLoggerFactory();
var hostBuilder = new WebHostBuilder()
.UseKestrel(options =>
{
options.Listen(new IPEndPoint(IPAddress.Loopback, 0), listenOptions =>
{
listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword");
});
})
.UseLoggerFactory(loggerFactory)
.Configure(app => app.Run(httpContext => Task.CompletedTask));
using (var host = hostBuilder.Build())
{
host.Start();
using (var socket = await HttpClientSlim.GetSocket(new Uri($"https://127.0.0.1:{host.GetPort()}/")))
using (var stream = new NetworkStream(socket, ownsSocket: false))
using (var sslStream = new SslStream(stream, true, (sender, certificate, chain, errors) => true))
{
await sslStream.AuthenticateAsClientAsync("127.0.0.1", clientCertificates: null,
enabledSslProtocols: SslProtocols.Tls11 | SslProtocols.Tls12,
checkCertificateRevocation: false);
}
}
Assert.False(loggerFactory.ErrorLogger.ObjectDisposedExceptionLogged);
}
// Regression test for https://github.com/aspnet/KestrelHttpServer/pull/1197 // Regression test for https://github.com/aspnet/KestrelHttpServer/pull/1197
[Fact] [Fact]
public void ConnectionFilterDoesNotLeakBlock() public void ConnectionFilterDoesNotLeakBlock()