Don't crash the server if a connection filter throws synchronously.

This commit is contained in:
Cesar Blum Silveira 2015-11-18 16:32:22 -08:00
parent efec0feda2
commit 307e020703
2 changed files with 64 additions and 18 deletions

View File

@ -78,6 +78,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
Address = ServerAddress Address = ServerAddress
}; };
try
{
ConnectionFilter.OnConnection(_filterContext).ContinueWith((task, state) => ConnectionFilter.OnConnection(_filterContext).ContinueWith((task, state) =>
{ {
var connection = (Connection)state; var connection = (Connection)state;
@ -98,6 +100,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
} }
}, this); }, this);
} }
catch (Exception ex)
{
Log.LogError("ConnectionFilter.OnConnection", ex);
ConnectionControl.End(ProduceEndType.SocketDisconnect);
}
}
} }
public void Abort() public void Abort()

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// 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.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
@ -82,6 +83,35 @@ namespace Microsoft.AspNet.Server.KestrelTests
} }
} }
[ConditionalFact]
[FrameworkSkipCondition(RuntimeFrameworks.Mono, SkipReason = "Test hangs after execution on Mono.")]
public async Task ThrowingSynchronousConnectionFilterDoesNotCrashServer()
{
var serviceContext = new TestServiceContext()
{
ConnectionFilter = new ThrowingConnectionFilter()
};
using (var server = new TestServer(App, serviceContext))
{
using (var connection = new TestConnection())
{
try
{
await connection.SendEnd(
"POST / HTTP/1.0",
"",
"Hello World?");
}
catch (IOException)
{
// Will throw because the exception in the connection filter will close the connection.
Assert.True(true);
}
}
}
}
private class RewritingConnectionFilter : IConnectionFilter private class RewritingConnectionFilter : IConnectionFilter
{ {
private static Task _empty = Task.FromResult<object>(null); private static Task _empty = Task.FromResult<object>(null);
@ -112,6 +142,14 @@ namespace Microsoft.AspNet.Server.KestrelTests
} }
} }
private class ThrowingConnectionFilter : IConnectionFilter
{
public Task OnConnection(ConnectionFilterContext context)
{
throw new Exception();
}
}
private class RewritingStream : Stream private class RewritingStream : Stream
{ {
private readonly Stream _innerStream; private readonly Stream _innerStream;