Reduce usage of static inprocess application (#962)
This commit is contained in:
parent
d3d257b90e
commit
bc345bc8e7
|
|
@ -9,8 +9,9 @@
|
||||||
// Initialization export
|
// Initialization export
|
||||||
//
|
//
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
VOID
|
HRESULT
|
||||||
register_callbacks(
|
register_callbacks(
|
||||||
|
_In_ IN_PROCESS_APPLICATION* pInProcessApplication,
|
||||||
_In_ PFN_REQUEST_HANDLER request_handler,
|
_In_ PFN_REQUEST_HANDLER request_handler,
|
||||||
_In_ PFN_SHUTDOWN_HANDLER shutdown_handler,
|
_In_ PFN_SHUTDOWN_HANDLER shutdown_handler,
|
||||||
_In_ PFN_MANAGED_CONTEXT_HANDLER async_completion_handler,
|
_In_ PFN_MANAGED_CONTEXT_HANDLER async_completion_handler,
|
||||||
|
|
@ -18,13 +19,20 @@ register_callbacks(
|
||||||
_In_ VOID* pvShutdownHandlerContext
|
_In_ VOID* pvShutdownHandlerContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IN_PROCESS_APPLICATION::GetInstance()->SetCallbackHandles(
|
if (pInProcessApplication == NULL)
|
||||||
|
{
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
pInProcessApplication->SetCallbackHandles(
|
||||||
request_handler,
|
request_handler,
|
||||||
shutdown_handler,
|
shutdown_handler,
|
||||||
async_completion_handler,
|
async_completion_handler,
|
||||||
pvRequstHandlerContext,
|
pvRequstHandlerContext,
|
||||||
pvShutdownHandlerContext
|
pvShutdownHandlerContext
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
|
|
@ -150,12 +158,12 @@ http_get_completion_info(
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// todo: we should not rely on IN_PROCESS_APPLICATION::GetInstance()
|
|
||||||
// the signature should be changed. application's based address should be passed in
|
// the signature should be changed. application's based address should be passed in
|
||||||
//
|
//
|
||||||
|
|
||||||
struct IISConfigurationData
|
struct IISConfigurationData
|
||||||
{
|
{
|
||||||
|
IN_PROCESS_APPLICATION* pInProcessApplication;
|
||||||
BSTR pwzFullApplicationPath;
|
BSTR pwzFullApplicationPath;
|
||||||
BSTR pwzVirtualApplicationPath;
|
BSTR pwzVirtualApplicationPath;
|
||||||
BOOL fWindowsAuthEnabled;
|
BOOL fWindowsAuthEnabled;
|
||||||
|
|
@ -169,16 +177,15 @@ http_get_application_properties(
|
||||||
_In_ IISConfigurationData* pIISCofigurationData
|
_In_ IISConfigurationData* pIISCofigurationData
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
REQUESTHANDLER_CONFIG* pConfiguration = NULL;
|
auto pInProcessApplication = IN_PROCESS_APPLICATION::GetInstance();
|
||||||
IN_PROCESS_APPLICATION* pApplication = IN_PROCESS_APPLICATION::GetInstance();
|
if (pInProcessApplication == NULL)
|
||||||
|
|
||||||
if (pApplication == NULL)
|
|
||||||
{
|
{
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pConfiguration = pApplication->QueryConfig();
|
auto pConfiguration = pInProcessApplication->QueryConfig();
|
||||||
|
|
||||||
|
pIISCofigurationData->pInProcessApplication = pInProcessApplication;
|
||||||
pIISCofigurationData->pwzFullApplicationPath = SysAllocString(pConfiguration->QueryApplicationPhysicalPath()->QueryStr());
|
pIISCofigurationData->pwzFullApplicationPath = SysAllocString(pConfiguration->QueryApplicationPhysicalPath()->QueryStr());
|
||||||
pIISCofigurationData->pwzVirtualApplicationPath = SysAllocString(pConfiguration->QueryApplicationVirtualPath()->QueryStr());
|
pIISCofigurationData->pwzVirtualApplicationPath = SysAllocString(pConfiguration->QueryApplicationVirtualPath()->QueryStr());
|
||||||
pIISCofigurationData->fWindowsAuthEnabled = pConfiguration->QueryWindowsAuthEnabled();
|
pIISCofigurationData->fWindowsAuthEnabled = pConfiguration->QueryWindowsAuthEnabled();
|
||||||
|
|
@ -433,17 +440,29 @@ http_get_authentication_information(
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
VOID
|
HRESULT
|
||||||
http_stop_calls_into_managed()
|
http_stop_calls_into_managed(_In_ IN_PROCESS_APPLICATION* pInProcessApplication)
|
||||||
{
|
{
|
||||||
IN_PROCESS_APPLICATION::GetInstance()->StopCallsIntoManaged();
|
if (pInProcessApplication == NULL)
|
||||||
|
{
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
pInProcessApplication->StopCallsIntoManaged();
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
VOID
|
HRESULT
|
||||||
http_stop_incoming_requests()
|
http_stop_incoming_requests(_In_ IN_PROCESS_APPLICATION* pInProcessApplication)
|
||||||
{
|
{
|
||||||
IN_PROCESS_APPLICATION::GetInstance()->StopIncomingRequests();
|
if (pInProcessApplication == NULL)
|
||||||
|
{
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
pInProcessApplication->StopIncomingRequests();
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
// 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.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.IIS.Core
|
namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
internal unsafe struct IISConfigurationData
|
internal struct IISConfigurationData
|
||||||
{
|
{
|
||||||
|
public IntPtr pNativeApplication;
|
||||||
[MarshalAs(UnmanagedType.BStr)]
|
[MarshalAs(UnmanagedType.BStr)]
|
||||||
public string pwzFullApplicationPath;
|
public string pwzFullApplicationPath;
|
||||||
[MarshalAs(UnmanagedType.BStr)]
|
[MarshalAs(UnmanagedType.BStr)]
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting.Server;
|
using Microsoft.AspNetCore.Hosting.Server;
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.IIS.Core
|
namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
|
|
@ -27,8 +28,9 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
private readonly MemoryPool<byte> _memoryPool = new SlabMemoryPool();
|
private readonly MemoryPool<byte> _memoryPool = new SlabMemoryPool();
|
||||||
private GCHandle _httpServerHandle;
|
private GCHandle _httpServerHandle;
|
||||||
private readonly IApplicationLifetime _applicationLifetime;
|
private readonly IApplicationLifetime _applicationLifetime;
|
||||||
private readonly IAuthenticationSchemeProvider _authentication;
|
private readonly ILogger<IISHttpServer> _logger;
|
||||||
private readonly IISServerOptions _options;
|
private readonly IISServerOptions _options;
|
||||||
|
private readonly IISNativeApplication _nativeApplication;
|
||||||
|
|
||||||
private volatile int _stopping;
|
private volatile int _stopping;
|
||||||
private bool Stopping => _stopping == 1;
|
private bool Stopping => _stopping == 1;
|
||||||
|
|
@ -56,10 +58,17 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
return _websocketAvailable.Value;
|
return _websocketAvailable.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IISHttpServer(IApplicationLifetime applicationLifetime, IAuthenticationSchemeProvider authentication, IOptions<IISServerOptions> options)
|
public IISHttpServer(
|
||||||
|
IISNativeApplication nativeApplication,
|
||||||
|
IApplicationLifetime applicationLifetime,
|
||||||
|
IAuthenticationSchemeProvider authentication,
|
||||||
|
IOptions<IISServerOptions> options,
|
||||||
|
ILogger<IISHttpServer> logger
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
_nativeApplication = nativeApplication;
|
||||||
_applicationLifetime = applicationLifetime;
|
_applicationLifetime = applicationLifetime;
|
||||||
_authentication = authentication;
|
_logger = logger;
|
||||||
_options = options.Value;
|
_options = options.Value;
|
||||||
|
|
||||||
if (_options.ForwardWindowsAuthentication)
|
if (_options.ForwardWindowsAuthentication)
|
||||||
|
|
@ -73,10 +82,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
_httpServerHandle = GCHandle.Alloc(this);
|
_httpServerHandle = GCHandle.Alloc(this);
|
||||||
|
|
||||||
_iisContextFactory = new IISContextFactory<TContext>(_memoryPool, application, _options, this);
|
_iisContextFactory = new IISContextFactory<TContext>(_memoryPool, application, _options, this);
|
||||||
|
_nativeApplication.RegisterCallbacks(_requestHandler, _shutdownHandler, _onAsyncCompletion, (IntPtr)_httpServerHandle, (IntPtr)_httpServerHandle);
|
||||||
// Start the server by registering the callback
|
|
||||||
NativeMethods.HttpRegisterCallbacks(_requestHandler, _shutdownHandler, _onAsyncCompletion, (IntPtr)_httpServerHandle, (IntPtr)_httpServerHandle);
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,7 +92,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
{
|
{
|
||||||
cancellationToken.Register(() =>
|
cancellationToken.Register(() =>
|
||||||
{
|
{
|
||||||
NativeMethods.HttpStopCallsIntoManaged();
|
_nativeApplication.StopCallsIntoManaged();
|
||||||
_shutdownSignal.TrySetResult(null);
|
_shutdownSignal.TrySetResult(null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +104,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
// First call back into native saying "DON'T SEND ME ANY MORE REQUESTS"
|
// First call back into native saying "DON'T SEND ME ANY MORE REQUESTS"
|
||||||
NativeMethods.HttpStopIncomingRequests();
|
_nativeApplication.StopIncomingRequests();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -110,7 +116,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We have drained all requests. Block any callbacks into managed at this point.
|
// We have drained all requests. Block any callbacks into managed at this point.
|
||||||
NativeMethods.HttpStopCallsIntoManaged();
|
_nativeApplication.StopCallsIntoManaged();
|
||||||
_shutdownSignal.TrySetResult(null);
|
_shutdownSignal.TrySetResult(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +133,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
_stopping = 1;
|
_stopping = 1;
|
||||||
|
|
||||||
// Block any more calls into managed from native as we are unloading.
|
// Block any more calls into managed from native as we are unloading.
|
||||||
NativeMethods.HttpStopCallsIntoManaged();
|
_nativeApplication.StopCallsIntoManaged();
|
||||||
_shutdownSignal.TrySetResult(null);
|
_shutdownSignal.TrySetResult(null);
|
||||||
|
|
||||||
if (_httpServerHandle.IsAllocated)
|
if (_httpServerHandle.IsAllocated)
|
||||||
|
|
@ -136,8 +142,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
_memoryPool.Dispose();
|
_memoryPool.Dispose();
|
||||||
|
_nativeApplication.Dispose();
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NativeMethods.REQUEST_NOTIFICATION_STATUS HandleRequest(IntPtr pInProcessHandler, IntPtr pvRequestContext)
|
private static NativeMethods.REQUEST_NOTIFICATION_STATUS HandleRequest(IntPtr pInProcessHandler, IntPtr pvRequestContext)
|
||||||
|
|
@ -155,8 +160,19 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
|
|
||||||
private static async Task HandleRequest(IISHttpContext context)
|
private static async Task HandleRequest(IISHttpContext context)
|
||||||
{
|
{
|
||||||
var result = await context.ProcessRequestAsync();
|
bool successfulRequest = false;
|
||||||
CompleteRequest(context, result);
|
try
|
||||||
|
{
|
||||||
|
successfulRequest = await context.ProcessRequestAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
context.Server._logger.LogError("Exception in ProcessRequestAsync", ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
CompleteRequest(context, successfulRequest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool HandleShutdown(IntPtr pvRequestContext)
|
private static bool HandleShutdown(IntPtr pvRequestContext)
|
||||||
|
|
@ -181,7 +197,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
if (Interlocked.Decrement(ref context.Server._outstandingRequests) == 0 && context.Server.Stopping)
|
if (Interlocked.Decrement(ref context.Server._outstandingRequests) == 0 && context.Server.Stopping)
|
||||||
{
|
{
|
||||||
// All requests have been drained.
|
// All requests have been drained.
|
||||||
NativeMethods.HttpStopCallsIntoManaged();
|
context.Server._nativeApplication.StopCallsIntoManaged();
|
||||||
context.Server._shutdownSignal.TrySetResult(null);
|
context.Server._shutdownSignal.TrySetResult(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,12 +231,6 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
return new IISHttpContextOfT<T>(_memoryPool, _application, pInProcessHandler, _options, _server);
|
return new IISHttpContextOfT<T>(_memoryPool, _application, pInProcessHandler, _options, _server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~IISHttpServer()
|
|
||||||
{
|
|
||||||
// If this finalize is invoked, try our best to block all calls into managed.
|
|
||||||
NativeMethods.HttpStopCallsIntoManaged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Over engineering to avoid allocations...
|
// Over engineering to avoid allocations...
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
|
{
|
||||||
|
internal class IISNativeApplication
|
||||||
|
{
|
||||||
|
private readonly IntPtr _nativeApplication;
|
||||||
|
|
||||||
|
public IISNativeApplication(IntPtr nativeApplication)
|
||||||
|
{
|
||||||
|
_nativeApplication = nativeApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopIncomingRequests()
|
||||||
|
{
|
||||||
|
NativeMethods.HttpStopIncomingRequests(_nativeApplication);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopCallsIntoManaged()
|
||||||
|
{
|
||||||
|
NativeMethods.HttpStopCallsIntoManaged(_nativeApplication);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterCallbacks(
|
||||||
|
NativeMethods.PFN_REQUEST_HANDLER requestHandler,
|
||||||
|
NativeMethods.PFN_SHUTDOWN_HANDLER shutdownHandler,
|
||||||
|
NativeMethods.PFN_ASYNC_COMPLETION onAsyncCompletion,
|
||||||
|
IntPtr requestContext,
|
||||||
|
IntPtr shutdownContext)
|
||||||
|
{
|
||||||
|
NativeMethods.HttpRegisterCallbacks(_nativeApplication, requestHandler, shutdownHandler, onAsyncCompletion, requestContext, shutdownContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~IISNativeApplication()
|
||||||
|
{
|
||||||
|
// If this finalize is invoked, try our best to block all calls into managed.
|
||||||
|
StopCallsIntoManaged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Server.IIS
|
||||||
private static extern void http_indicate_completion(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS notificationStatus);
|
private static extern void http_indicate_completion(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS notificationStatus);
|
||||||
|
|
||||||
[DllImport(AspNetCoreModuleDll)]
|
[DllImport(AspNetCoreModuleDll)]
|
||||||
private static extern void register_callbacks(PFN_REQUEST_HANDLER request_callback, PFN_SHUTDOWN_HANDLER shutdown_callback, PFN_ASYNC_COMPLETION managed_context_handler, IntPtr pvRequestContext, IntPtr pvShutdownContext);
|
private static extern int register_callbacks(IntPtr pInProcessApplication, PFN_REQUEST_HANDLER requestCallback, PFN_SHUTDOWN_HANDLER shutdownCallback, PFN_ASYNC_COMPLETION asyncCallback, IntPtr pvRequestContext, IntPtr pvShutdownContext);
|
||||||
|
|
||||||
[DllImport(AspNetCoreModuleDll)]
|
[DllImport(AspNetCoreModuleDll)]
|
||||||
private static extern unsafe int http_write_response_bytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected);
|
private static extern unsafe int http_write_response_bytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected);
|
||||||
|
|
@ -65,10 +65,10 @@ namespace Microsoft.AspNetCore.Server.IIS
|
||||||
private static extern unsafe HttpApiTypes.HTTP_REQUEST_V2* http_get_raw_request(IntPtr pInProcessHandler);
|
private static extern unsafe HttpApiTypes.HTTP_REQUEST_V2* http_get_raw_request(IntPtr pInProcessHandler);
|
||||||
|
|
||||||
[DllImport(AspNetCoreModuleDll)]
|
[DllImport(AspNetCoreModuleDll)]
|
||||||
private static extern void http_stop_calls_into_managed();
|
private static extern int http_stop_calls_into_managed(IntPtr pInProcessApplication);
|
||||||
|
|
||||||
[DllImport(AspNetCoreModuleDll)]
|
[DllImport(AspNetCoreModuleDll)]
|
||||||
private static extern void http_stop_incoming_requests();
|
private static extern int http_stop_incoming_requests(IntPtr pInProcessApplication);
|
||||||
|
|
||||||
[DllImport(AspNetCoreModuleDll)]
|
[DllImport(AspNetCoreModuleDll)]
|
||||||
private static extern unsafe HttpApiTypes.HTTP_RESPONSE_V2* http_get_raw_response(IntPtr pInProcessHandler);
|
private static extern unsafe HttpApiTypes.HTTP_RESPONSE_V2* http_get_raw_response(IntPtr pInProcessHandler);
|
||||||
|
|
@ -142,9 +142,9 @@ namespace Microsoft.AspNetCore.Server.IIS
|
||||||
{
|
{
|
||||||
http_indicate_completion(pInProcessHandler, notificationStatus);
|
http_indicate_completion(pInProcessHandler, notificationStatus);
|
||||||
}
|
}
|
||||||
public static void HttpRegisterCallbacks(PFN_REQUEST_HANDLER request_callback, PFN_SHUTDOWN_HANDLER shutdown_callback, PFN_ASYNC_COMPLETION managed_context_handler, IntPtr pvRequestContext, IntPtr pvShutdownContext)
|
public static void HttpRegisterCallbacks(IntPtr pInProcessApplication, PFN_REQUEST_HANDLER requestCallback, PFN_SHUTDOWN_HANDLER shutdownCallback, PFN_ASYNC_COMPLETION asyncCallback, IntPtr pvRequestContext, IntPtr pvShutdownContext)
|
||||||
{
|
{
|
||||||
register_callbacks(request_callback, shutdown_callback, managed_context_handler, pvRequestContext, pvShutdownContext);
|
Validate(register_callbacks(pInProcessApplication, requestCallback, shutdownCallback, asyncCallback, pvRequestContext, pvShutdownContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe int HttpWriteResponseBytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected)
|
public static unsafe int HttpWriteResponseBytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected)
|
||||||
|
|
@ -161,14 +161,14 @@ namespace Microsoft.AspNetCore.Server.IIS
|
||||||
return http_get_raw_request(pInProcessHandler);
|
return http_get_raw_request(pInProcessHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void HttpStopCallsIntoManaged()
|
public static void HttpStopCallsIntoManaged(IntPtr pInProcessApplication)
|
||||||
{
|
{
|
||||||
http_stop_calls_into_managed();
|
Validate(http_stop_calls_into_managed(pInProcessApplication));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void HttpStopIncomingRequests()
|
public static void HttpStopIncomingRequests(IntPtr pInProcessApplication)
|
||||||
{
|
{
|
||||||
http_stop_incoming_requests();
|
Validate(http_stop_incoming_requests(pInProcessApplication));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe HttpApiTypes.HTTP_RESPONSE_V2* HttpGetRawResponse(IntPtr pInProcessHandler)
|
public static unsafe HttpApiTypes.HTTP_RESPONSE_V2* HttpGetRawResponse(IntPtr pInProcessHandler)
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ namespace Microsoft.AspNetCore.Hosting
|
||||||
hostBuilder.UseContentRoot(iisConfigData.pwzFullApplicationPath);
|
hostBuilder.UseContentRoot(iisConfigData.pwzFullApplicationPath);
|
||||||
return hostBuilder.ConfigureServices(
|
return hostBuilder.ConfigureServices(
|
||||||
services => {
|
services => {
|
||||||
|
services.AddSingleton(new IISNativeApplication(iisConfigData.pNativeApplication));
|
||||||
services.AddSingleton<IServer, IISHttpServer>();
|
services.AddSingleton<IServer, IISHttpServer>();
|
||||||
services.AddSingleton<IStartupFilter>(new IISServerSetupFilter(iisConfigData.pwzVirtualApplicationPath));
|
services.AddSingleton<IStartupFilter>(new IISServerSetupFilter(iisConfigData.pwzVirtualApplicationPath));
|
||||||
services.AddAuthenticationCore();
|
services.AddAuthenticationCore();
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ namespace IISIntegration.FunctionalTests.Inprocess
|
||||||
|
|
||||||
var hostShutdownToken = deploymentResult.DeploymentResult.HostShutdownToken;
|
var hostShutdownToken = deploymentResult.DeploymentResult.HostShutdownToken;
|
||||||
|
|
||||||
Assert.True(hostShutdownToken.WaitHandle.WaitOne(millisecondsTimeout: 1000));
|
Assert.True(hostShutdownToken.WaitHandle.WaitOne(Helpers.DefaultTimeout));
|
||||||
Assert.True(hostShutdownToken.IsCancellationRequested);
|
Assert.True(hostShutdownToken.IsCancellationRequested);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using IISIntegration.FunctionalTests.Utilities;
|
||||||
|
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||||
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
|
using Xunit;
|
||||||
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
|
{
|
||||||
|
[SkipIfIISExpressSchemaMissingInProcess]
|
||||||
|
public class ShutdownTests : IISFunctionalTestBase
|
||||||
|
{
|
||||||
|
|
||||||
|
public ShutdownTests(ITestOutputHelper output) : base(output)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
public async Task ServerShutsDownWhenMainExits()
|
||||||
|
{
|
||||||
|
var parameters = Helpers.GetBaseDeploymentParameters();
|
||||||
|
var result = await DeployAsync(parameters);
|
||||||
|
|
||||||
|
var response = await result.RetryingHttpClient.GetAsync("/Shutdown");
|
||||||
|
Assert.True(result.DeploymentResult.HostShutdownToken.WaitHandle.WaitOne(Helpers.DefaultTimeout));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
@ -11,6 +12,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
{
|
{
|
||||||
public class Helpers
|
public class Helpers
|
||||||
{
|
{
|
||||||
|
public static TimeSpan DefaultTimeout = TimeSpan.FromSeconds(3);
|
||||||
|
|
||||||
public static string GetTestWebSitePath(string name)
|
public static string GetTestWebSitePath(string name)
|
||||||
{
|
{
|
||||||
return Path.Combine(TestPathUtilities.GetSolutionRootDirectory("IISIntegration"),"test", "WebSites", name);
|
return Path.Combine(TestPathUtilities.GetSolutionRootDirectory("IISIntegration"),"test", "WebSites", name);
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,12 @@ using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
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.IISIntegration.FunctionalTests;
|
using Microsoft.AspNetCore.IISIntegration.FunctionalTests;
|
||||||
using Microsoft.AspNetCore.Server.IIS;
|
using Microsoft.AspNetCore.Server.IIS;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -725,5 +727,14 @@ namespace IISTestSite
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Shutdown(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.Run(async ctx =>
|
||||||
|
{
|
||||||
|
await ctx.Response.WriteAsync("Shutting down");
|
||||||
|
ctx.RequestServices.GetService<IApplicationLifetime>().StopApplication();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue