Catch all exception in native callbacks (#1369)

This commit is contained in:
Pavel Krymets 2018-09-05 16:48:10 -07:00 committed by GitHub
parent 613fbcc349
commit 18a718d1f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 42 additions and 15 deletions

View File

@ -20,9 +20,9 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
{ {
private const string WebSocketVersionString = "WEBSOCKET_VERSION"; private const string WebSocketVersionString = "WEBSOCKET_VERSION";
private static NativeMethods.PFN_REQUEST_HANDLER _requestHandler = HandleRequest; private static readonly NativeMethods.PFN_REQUEST_HANDLER _requestHandler = HandleRequest;
private static NativeMethods.PFN_SHUTDOWN_HANDLER _shutdownHandler = HandleShutdown; private static readonly NativeMethods.PFN_SHUTDOWN_HANDLER _shutdownHandler = HandleShutdown;
private static NativeMethods.PFN_ASYNC_COMPLETION _onAsyncCompletion = OnAsyncCompletion; private static readonly NativeMethods.PFN_ASYNC_COMPLETION _onAsyncCompletion = OnAsyncCompletion;
private IISContextFactory _iisContextFactory; private IISContextFactory _iisContextFactory;
private readonly MemoryPool<byte> _memoryPool = new SlabMemoryPool(); private readonly MemoryPool<byte> _memoryPool = new SlabMemoryPool();
@ -147,15 +147,24 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
private static NativeMethods.REQUEST_NOTIFICATION_STATUS HandleRequest(IntPtr pInProcessHandler, IntPtr pvRequestContext) private static NativeMethods.REQUEST_NOTIFICATION_STATUS HandleRequest(IntPtr pInProcessHandler, IntPtr pvRequestContext)
{ {
// Unwrap the server so we can create an http context and process the request IISHttpServer server = null;
var server = (IISHttpServer)GCHandle.FromIntPtr(pvRequestContext).Target; try
Interlocked.Increment(ref server._outstandingRequests); {
// Unwrap the server so we can create an http context and process the request
server = (IISHttpServer)GCHandle.FromIntPtr(pvRequestContext).Target;
Interlocked.Increment(ref server._outstandingRequests);
var context = server._iisContextFactory.CreateHttpContext(pInProcessHandler); var context = server._iisContextFactory.CreateHttpContext(pInProcessHandler);
ThreadPool.QueueUserWorkItem(state => _ = HandleRequest((IISHttpContext)state), context); ThreadPool.QueueUserWorkItem(state => _ = HandleRequest((IISHttpContext)state), context);
return NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_PENDING;
}
catch (Exception ex)
{
server?._logger.LogError(0, ex, $"Unexpected exception in static {nameof(IISHttpServer)}.{nameof(HandleRequest)}.");
return NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_PENDING; return NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_FINISH_REQUEST;
}
} }
private static async Task HandleRequest(IISHttpContext context) private static async Task HandleRequest(IISHttpContext context)
@ -167,7 +176,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
} }
catch (Exception ex) catch (Exception ex)
{ {
context.Server._logger.LogError("Exception in ProcessRequestAsync", ex); context.Server._logger.LogError(0, ex, $"Unexpected exception in {nameof(IISHttpServer)}.{nameof(HandleRequest)}.");
} }
finally finally
{ {
@ -177,16 +186,34 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
private static bool HandleShutdown(IntPtr pvRequestContext) private static bool HandleShutdown(IntPtr pvRequestContext)
{ {
var server = (IISHttpServer)GCHandle.FromIntPtr(pvRequestContext).Target; IISHttpServer server = null;
server._applicationLifetime.StopApplication(); try
{
server = (IISHttpServer)GCHandle.FromIntPtr(pvRequestContext).Target;
server._applicationLifetime.StopApplication();
}
catch (Exception ex)
{
server?._logger.LogError(0, ex, $"Unexpected exception in {nameof(IISHttpServer)}.{nameof(HandleShutdown)}.");
}
return true; return true;
} }
private static NativeMethods.REQUEST_NOTIFICATION_STATUS OnAsyncCompletion(IntPtr pvManagedHttpContext, int hr, int bytes) private static NativeMethods.REQUEST_NOTIFICATION_STATUS OnAsyncCompletion(IntPtr pvManagedHttpContext, int hr, int bytes)
{ {
var context = (IISHttpContext)GCHandle.FromIntPtr(pvManagedHttpContext).Target; IISHttpContext context = null;
context.OnAsyncCompletion(hr, bytes); try
return NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_PENDING; {
context = (IISHttpContext)GCHandle.FromIntPtr(pvManagedHttpContext).Target;
context.OnAsyncCompletion(hr, bytes);
return NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_PENDING;
}
catch (Exception ex)
{
context?.Server._logger.LogError(0, ex, $"Unexpected exception in {nameof(IISHttpServer)}.{nameof(OnAsyncCompletion)}.");
return NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_FINISH_REQUEST;
}
} }
private static void CompleteRequest(IISHttpContext context, bool result) private static void CompleteRequest(IISHttpContext context, bool result)