Check native HRESULTs (#742)

This commit is contained in:
Pavel Krymets 2018-03-30 15:07:08 -07:00 committed by GitHub
parent 3f40f042bc
commit 8ea2de1dc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 230 additions and 95 deletions

View File

@ -7,24 +7,28 @@ using Microsoft.AspNetCore.HttpSys.Internal;
namespace Microsoft.AspNetCore.Server.IISIntegration namespace Microsoft.AspNetCore.Server.IISIntegration
{ {
internal class NativeMethods internal static class NativeMethods
{ {
#if DOTNET5_4 private const int HR_NOT_FOUND = unchecked((int)0x80070490);
private const string api_ms_win_core_handle_LIB = "api-ms-win-core-handle-l1-1-0.dll"; private const int HR_OK = 0;
#else
private const string KERNEL32 = "kernel32.dll"; private const string KERNEL32 = "kernel32.dll";
#endif
#if DOTNET5_4
[DllImport(api_ms_win_core_handle_LIB, ExactSpelling = true, SetLastError = true)]
#else
[DllImport(KERNEL32, ExactSpelling = true, SetLastError = true)]
#endif
internal static extern bool CloseHandle(IntPtr handle);
public const int S_OK = 0;
private const string AspNetCoreModuleDll = "aspnetcorerh.dll"; private const string AspNetCoreModuleDll = "aspnetcorerh.dll";
[DllImport(KERNEL32, ExactSpelling = true, SetLastError = true)]
public static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);
public static bool IsAspNetCoreModuleLoaded()
{
return GetModuleHandle(AspNetCoreModuleDll) != IntPtr.Zero;
}
public enum REQUEST_NOTIFICATION_STATUS public enum REQUEST_NOTIFICATION_STATUS
{ {
RQ_NOTIFICATION_CONTINUE, RQ_NOTIFICATION_CONTINUE,
@ -37,85 +41,232 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
public delegate REQUEST_NOTIFICATION_STATUS PFN_ASYNC_COMPLETION(IntPtr pvManagedHttpContext, int hr, int bytes); public delegate REQUEST_NOTIFICATION_STATUS PFN_ASYNC_COMPLETION(IntPtr pvManagedHttpContext, int hr, int bytes);
public delegate REQUEST_NOTIFICATION_STATUS PFN_WEBSOCKET_ASYNC_COMPLETION(IntPtr pInProcessHandler, IntPtr completionInfo, IntPtr pvCompletionContext); public delegate REQUEST_NOTIFICATION_STATUS PFN_WEBSOCKET_ASYNC_COMPLETION(IntPtr pInProcessHandler, IntPtr completionInfo, IntPtr pvCompletionContext);
// TODO make this all internal
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public static extern int http_post_completion(IntPtr pInProcessHandler, int cbBytes); private static extern int http_post_completion(IntPtr pInProcessHandler, int cbBytes);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public static extern int http_set_completion_status(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS rquestNotificationStatus); private static extern int http_set_completion_status(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS rquestNotificationStatus);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public 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)]
public 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 void register_callbacks(PFN_REQUEST_HANDLER request_callback, PFN_SHUTDOWN_HANDLER shutdown_callback, PFN_ASYNC_COMPLETION managed_context_handler, IntPtr pvRequestContext, IntPtr pvShutdownContext);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
internal unsafe static extern 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);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public unsafe static extern int http_flush_response_bytes(IntPtr pInProcessHandler, out bool fCompletionExpected); private static extern int http_flush_response_bytes(IntPtr pInProcessHandler, out bool fCompletionExpected);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
internal unsafe static extern 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)]
internal unsafe static extern void http_stop_calls_into_managed(); private static extern void http_stop_calls_into_managed();
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
internal unsafe static extern void http_stop_incoming_requests(); private static extern void http_stop_incoming_requests();
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
internal unsafe static extern HttpApiTypes.HTTP_RESPONSE_V2* http_get_raw_response(IntPtr pInProcessHandler); private static extern unsafe HttpApiTypes.HTTP_RESPONSE_V2* http_get_raw_response(IntPtr pInProcessHandler);
[DllImport(AspNetCoreModuleDll, CharSet = CharSet.Ansi)] [DllImport(AspNetCoreModuleDll, CharSet = CharSet.Ansi)]
public unsafe static extern int http_set_response_status_code(IntPtr pInProcessHandler, ushort statusCode, string pszReason); private static extern int http_set_response_status_code(IntPtr pInProcessHandler, ushort statusCode, string pszReason);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public unsafe static extern int http_read_request_bytes(IntPtr pInProcessHandler, byte* pvBuffer, int cbBuffer, out int dwBytesReceived, out bool fCompletionExpected); private static extern unsafe int http_read_request_bytes(IntPtr pInProcessHandler, byte* pvBuffer, int cbBuffer, out int dwBytesReceived, out bool fCompletionExpected);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public unsafe static extern bool http_get_completion_info(IntPtr pCompletionInfo, out int cbBytes, out int hr); private static extern void http_get_completion_info(IntPtr pCompletionInfo, out int cbBytes, out int hr);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public unsafe static extern bool http_set_managed_context(IntPtr pInProcessHandler, IntPtr pvManagedContext); private static extern int http_set_managed_context(IntPtr pInProcessHandler, IntPtr pvManagedContext);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public unsafe static extern int http_get_application_properties(ref IISConfigurationData iiConfigData); private static extern int http_get_application_properties(ref IISConfigurationData iiConfigData);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public static extern int http_get_server_variable(IntPtr pInProcessHandler, [MarshalAs(UnmanagedType.AnsiBStr)] string variableName, [MarshalAs(UnmanagedType.BStr)] out string value); private static extern int http_get_server_variable(
IntPtr pInProcessHandler,
[MarshalAs(UnmanagedType.AnsiBStr)] string variableName,
[MarshalAs(UnmanagedType.BStr)] out string value);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public unsafe static extern bool http_shutdown(); private static extern unsafe int http_websockets_read_bytes(
IntPtr pInProcessHandler,
byte* pvBuffer,
int cbBuffer,
PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback,
IntPtr pvCompletionContext,
out int dwBytesReceived,
out bool fCompletionExpected);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public unsafe static extern int http_websockets_read_bytes(IntPtr pInProcessHandler, byte* pvBuffer, int cbBuffer, PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback, IntPtr pvCompletionContext, out int dwBytesReceived, out bool fCompletionExpected); private static extern unsafe int http_websockets_write_bytes(
IntPtr pInProcessHandler,
HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks,
int nChunks,
PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback,
IntPtr pvCompletionContext,
out bool fCompletionExpected);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
internal unsafe static extern int http_websockets_write_bytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback, IntPtr pvCompletionContext, out bool fCompletionExpected); private static extern int http_enable_websockets(IntPtr pInProcessHandler);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public unsafe static extern int http_enable_websockets(IntPtr pInProcessHandler); private static extern int http_cancel_io(IntPtr pInProcessHandler);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public unsafe static extern int http_cancel_io(IntPtr pInProcessHandler); private static extern unsafe int http_response_set_unknown_header(IntPtr pInProcessHandler, byte* pszHeaderName, byte* pszHeaderValue, ushort usHeaderValueLength, bool fReplace);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
public unsafe static extern int http_response_set_unknown_header(IntPtr pInProcessHandler, byte* pszHeaderName, byte* pszHeaderValue, ushort usHeaderValueLength, bool fReplace); private static extern unsafe int http_response_set_known_header(IntPtr pInProcessHandler, int headerId, byte* pHeaderValue, ushort length, bool fReplace);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
internal unsafe static extern int http_response_set_known_header(IntPtr pInProcessHandler, int headerId, byte* pHeaderValue, ushort length, bool fReplace); private static extern int http_get_authentication_information(IntPtr pInProcessHandler, [MarshalAs(UnmanagedType.BStr)] out string authType, out IntPtr token);
[DllImport(AspNetCoreModuleDll)] public static void HttpPostCompletion(IntPtr pInProcessHandler, int cbBytes)
public unsafe static extern int http_get_authentication_information(IntPtr pInProcessHandler, [MarshalAs(UnmanagedType.BStr)] out string authType, out IntPtr token);
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string lpModuleName);
public static bool IsAspNetCoreModuleLoaded()
{ {
return GetModuleHandle(AspNetCoreModuleDll) != IntPtr.Zero; Validate(http_post_completion(pInProcessHandler, cbBytes));
}
public static void HttpSetCompletionStatus(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS rquestNotificationStatus)
{
Validate(http_set_completion_status(pInProcessHandler, rquestNotificationStatus));
}
public static void HttpIndicateCompletion(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS 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)
{
register_callbacks(request_callback, shutdown_callback, managed_context_handler, pvRequestContext, pvShutdownContext);
}
public static unsafe int HttpWriteResponseBytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected)
{
return http_write_response_bytes(pInProcessHandler, pDataChunks, nChunks, out fCompletionExpected);
}
public static int HttpFlushResponseBytes(IntPtr pInProcessHandler, out bool fCompletionExpected)
{
return http_flush_response_bytes(pInProcessHandler, out fCompletionExpected);
}
public static unsafe HttpApiTypes.HTTP_REQUEST_V2* HttpGetRawRequest(IntPtr pInProcessHandler)
{
return http_get_raw_request(pInProcessHandler);
}
public static void HttpStopCallsIntoManaged()
{
http_stop_calls_into_managed();
}
public static void HttpStopIncomingRequests()
{
http_stop_incoming_requests();
}
public static unsafe HttpApiTypes.HTTP_RESPONSE_V2* HttpGetRawResponse(IntPtr pInProcessHandler)
{
return http_get_raw_response(pInProcessHandler);
}
public static void HttpSetResponseStatusCode(IntPtr pInProcessHandler, ushort statusCode, string pszReason)
{
Validate(http_set_response_status_code(pInProcessHandler, statusCode, pszReason));
}
public static unsafe int HttpReadRequestBytes(IntPtr pInProcessHandler, byte* pvBuffer, int cbBuffer, out int dwBytesReceived, out bool fCompletionExpected)
{
return http_read_request_bytes(pInProcessHandler, pvBuffer, cbBuffer, out dwBytesReceived, out fCompletionExpected);
}
public static void HttpGetCompletionInfo(IntPtr pCompletionInfo, out int cbBytes, out int hr)
{
http_get_completion_info(pCompletionInfo, out cbBytes, out hr);
}
public static void HttpSetManagedContext(IntPtr pInProcessHandler, IntPtr pvManagedContext)
{
Validate(http_set_managed_context(pInProcessHandler, pvManagedContext));
}
public static IISConfigurationData HttpGetApplicationProperties()
{
var iisConfigurationData = new IISConfigurationData();
Validate(http_get_application_properties(ref iisConfigurationData));
return iisConfigurationData;
}
public static bool HttpTryGetServerVariable(IntPtr pInProcessHandler, string variableName, out string value)
{
return http_get_server_variable(pInProcessHandler, variableName, out value) == 0;
}
public static unsafe int HttpWebsocketsReadBytes(
IntPtr pInProcessHandler,
byte* pvBuffer,
int cbBuffer,
PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback,
IntPtr pvCompletionContext, out int dwBytesReceived,
out bool fCompletionExpected)
{
return http_websockets_read_bytes(pInProcessHandler, pvBuffer, cbBuffer, pfnCompletionCallback, pvCompletionContext, out dwBytesReceived, out fCompletionExpected);
}
public static unsafe int HttpWebsocketsWriteBytes(
IntPtr pInProcessHandler,
HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks,
int nChunks,
PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback,
IntPtr pvCompletionContext,
out bool fCompletionExpected)
{
return http_websockets_write_bytes(pInProcessHandler, pDataChunks, nChunks, pfnCompletionCallback, pvCompletionContext, out fCompletionExpected);
}
public static void HttpEnableWebsockets(IntPtr pInProcessHandler)
{
Validate(http_enable_websockets(pInProcessHandler));
}
public static bool HttpTryCancelIO(IntPtr pInProcessHandler)
{
var hr = http_cancel_io(pInProcessHandler);
// Async operation finished
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363792(v=vs.85).aspx
if (hr == HR_NOT_FOUND)
{
return false;
}
Validate(hr);
return true;
}
public static unsafe void HttpResponseSetUnknownHeader(IntPtr pInProcessHandler, byte* pszHeaderName, byte* pszHeaderValue, ushort usHeaderValueLength, bool fReplace)
{
Validate(http_response_set_unknown_header(pInProcessHandler, pszHeaderName, pszHeaderValue, usHeaderValueLength, fReplace));
}
public static unsafe void HttpResponseSetKnownHeader(IntPtr pInProcessHandler, int headerId, byte* pHeaderValue, ushort length, bool fReplace)
{
Validate(http_response_set_known_header(pInProcessHandler, headerId, pHeaderValue, length, fReplace));
}
public static void HttpGetAuthenticationInformation(IntPtr pInProcessHandler, out string authType, out IntPtr token)
{
Validate(http_get_authentication_information(pInProcessHandler, out authType, out token));
}
private static void Validate(int hr)
{
if (hr != HR_OK)
{
throw Marshal.GetExceptionForHR(hr);
}
} }
} }
} }

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{ {
var context = (IISHttpContext)GCHandle.FromIntPtr(pvCompletionContext).Target; var context = (IISHttpContext)GCHandle.FromIntPtr(pvCompletionContext).Target;
NativeMethods.http_get_completion_info(pCompletionInfo, out int cbBytes, out int hr); NativeMethods.HttpGetCompletionInfo(pCompletionInfo, out int cbBytes, out int hr);
context.CompleteReadWebSockets(hr, cbBytes); context.CompleteReadWebSockets(hr, cbBytes);
@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{ {
var context = (IISHttpContext)GCHandle.FromIntPtr(pvCompletionContext).Target; var context = (IISHttpContext)GCHandle.FromIntPtr(pvCompletionContext).Target;
NativeMethods.http_get_completion_info(pCompletionInfo, out int cbBytes, out int hr); NativeMethods.HttpGetCompletionInfo(pCompletionInfo, out int cbBytes, out int hr);
context.CompleteWriteWebSockets(hr, cbBytes); context.CompleteWriteWebSockets(hr, cbBytes);

View File

@ -243,8 +243,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
return null; return null;
} }
int hr = NativeMethods.http_get_server_variable(_pInProcessHandler, variableName, out var value); return NativeMethods.HttpTryGetServerVariable(_pInProcessHandler, variableName, out var value) ? value : null;
return hr == 0 ? value : null;
} }
} }
@ -296,7 +295,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
ReasonPhrase = ReasonPhrases.GetReasonPhrase(StatusCodes.Status101SwitchingProtocols); ReasonPhrase = ReasonPhrases.GetReasonPhrase(StatusCodes.Status101SwitchingProtocols);
_readWebSocketsOperation = new IISAwaitable(); _readWebSocketsOperation = new IISAwaitable();
_writeWebSocketsOperation = new IISAwaitable(); _writeWebSocketsOperation = new IISAwaitable();
NativeMethods.http_enable_websockets(_pInProcessHandler); NativeMethods.HttpEnableWebsockets(_pInProcessHandler);
// Upgrade async will cause the stream processing to go into duplex mode // Upgrade async will cause the stream processing to go into duplex mode
await UpgradeAsync(); await UpgradeAsync();

View File

@ -169,7 +169,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
} }
else else
{ {
var hr = NativeMethods.http_read_request_bytes( var hr = NativeMethods.HttpReadRequestBytes(
_pInProcessHandler, _pInProcessHandler,
(byte*)_inputHandle.Pointer, (byte*)_inputHandle.Pointer,
length, length,
@ -225,7 +225,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
chunk.DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; chunk.DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
chunk.fromMemory.pBuffer = (IntPtr)pBuffer; chunk.fromMemory.pBuffer = (IntPtr)pBuffer;
chunk.fromMemory.BufferLength = (uint)buffer.Length; chunk.fromMemory.BufferLength = (uint)buffer.Length;
hr = NativeMethods.http_write_response_bytes(_pInProcessHandler, pDataChunks, nChunks, out fCompletionExpected); hr = NativeMethods.HttpWriteResponseBytes(_pInProcessHandler, pDataChunks, nChunks, out fCompletionExpected);
} }
} }
else if (nChunks < HttpDataChunkStackLimit) else if (nChunks < HttpDataChunkStackLimit)
@ -274,7 +274,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
currentChunk++; currentChunk++;
} }
hr = NativeMethods.http_write_response_bytes(_pInProcessHandler, pDataChunks, nChunks, out fCompletionExpected); hr = NativeMethods.HttpWriteResponseBytes(_pInProcessHandler, pDataChunks, nChunks, out fCompletionExpected);
// Free the handles // Free the handles
foreach (var handle in handles) foreach (var handle in handles)
@ -289,7 +289,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{ {
// Calls flush // Calls flush
var hr = 0; var hr = 0;
hr = NativeMethods.http_flush_response_bytes(_pInProcessHandler, out var fCompletionExpected); hr = NativeMethods.HttpFlushResponseBytes(_pInProcessHandler, out var fCompletionExpected);
if (!fCompletionExpected) if (!fCompletionExpected)
{ {
_operation.Complete(hr, 0); _operation.Complete(hr, 0);
@ -468,7 +468,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{ {
_reading = false; _reading = false;
// Calls IHttpContext->CancelIo(), which will cause the OnAsyncCompletion handler to fire. // Calls IHttpContext->CancelIo(), which will cause the OnAsyncCompletion handler to fire.
NativeMethods.http_cancel_io(_pInProcessHandler); NativeMethods.HttpTryCancelIO(_pInProcessHandler);
} }
} }
} }

View File

@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
bool fCompletionExpected; bool fCompletionExpected;
// For websocket calls, we can directly provide a callback function to be called once the websocket operation completes. // For websocket calls, we can directly provide a callback function to be called once the websocket operation completes.
hr = NativeMethods.http_websockets_read_bytes( hr = NativeMethods.HttpWebsocketsReadBytes(
_pInProcessHandler, _pInProcessHandler,
(byte*)_inputHandle.Pointer, (byte*)_inputHandle.Pointer,
length, length,
@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
chunk.DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; chunk.DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
chunk.fromMemory.pBuffer = (IntPtr)pBuffer; chunk.fromMemory.pBuffer = (IntPtr)pBuffer;
chunk.fromMemory.BufferLength = (uint)buffer.Length; chunk.fromMemory.BufferLength = (uint)buffer.Length;
hr = NativeMethods.http_websockets_write_bytes(_pInProcessHandler, pDataChunks, nChunks, IISAwaitable.WriteCallback, (IntPtr)_thisHandle, out fCompletionExpected); hr = NativeMethods.HttpWebsocketsWriteBytes(_pInProcessHandler, pDataChunks, nChunks, IISAwaitable.WriteCallback, (IntPtr)_thisHandle, out fCompletionExpected);
} }
} }
else else
@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
currentChunk++; currentChunk++;
} }
hr = NativeMethods.http_websockets_write_bytes(_pInProcessHandler, pDataChunks, nChunks, IISAwaitable.WriteCallback, (IntPtr)_thisHandle, out fCompletionExpected); hr = NativeMethods.HttpWebsocketsWriteBytes(_pInProcessHandler, pDataChunks, nChunks, IISAwaitable.WriteCallback, (IntPtr)_thisHandle, out fCompletionExpected);
foreach (var handle in handles) foreach (var handle in handles)
{ {

View File

@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
private const string WebSocketVersionString = "WEBSOCKET_VERSION"; private const string WebSocketVersionString = "WEBSOCKET_VERSION";
internal unsafe IISHttpContext(MemoryPool<byte> memoryPool, IntPtr pInProcessHandler, IISOptions options, IISHttpServer server) internal unsafe IISHttpContext(MemoryPool<byte> memoryPool, IntPtr pInProcessHandler, IISOptions options, IISHttpServer server)
: base((HttpApiTypes.HTTP_REQUEST*)NativeMethods.http_get_raw_request(pInProcessHandler)) : base((HttpApiTypes.HTTP_REQUEST*)NativeMethods.HttpGetRawRequest(pInProcessHandler))
{ {
_thisHandle = GCHandle.Alloc(this); _thisHandle = GCHandle.Alloc(this);
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
_pInProcessHandler = pInProcessHandler; _pInProcessHandler = pInProcessHandler;
_server = server; _server = server;
NativeMethods.http_set_managed_context(pInProcessHandler, (IntPtr)_thisHandle); NativeMethods.HttpSetManagedContext(pInProcessHandler, (IntPtr)_thisHandle);
unsafe unsafe
{ {
Method = GetVerb(); Method = GetVerb();
@ -145,8 +145,9 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
// server variables a few extra times if a bunch of requests hit the server at the same time. // server variables a few extra times if a bunch of requests hit the server at the same time.
if (_websocketAvailability == WebsocketAvailabilityStatus.Uninitialized) if (_websocketAvailability == WebsocketAvailabilityStatus.Uninitialized)
{ {
NativeMethods.http_get_server_variable(pInProcessHandler, WebSocketVersionString, out var webSocketsSupported); var webSocketsAvailable = NativeMethods.HttpTryGetServerVariable(pInProcessHandler, WebSocketVersionString, out var webSocketsSupported)
var webSocketsAvailable = !string.IsNullOrEmpty(webSocketsSupported); && !string.IsNullOrEmpty(webSocketsSupported);
_websocketAvailability = webSocketsAvailable ? _websocketAvailability = webSocketsAvailable ?
WebsocketAvailabilityStatus.Available : WebsocketAvailabilityStatus.Available :
WebsocketAvailabilityStatus.NotAvailable; WebsocketAvailabilityStatus.NotAvailable;
@ -335,7 +336,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
var reasonPhrase = string.IsNullOrEmpty(ReasonPhrase) ? ReasonPhrases.GetReasonPhrase(StatusCode) : ReasonPhrase; var reasonPhrase = string.IsNullOrEmpty(ReasonPhrase) ? ReasonPhrases.GetReasonPhrase(StatusCode) : ReasonPhrase;
// This copies data into the underlying buffer // This copies data into the underlying buffer
NativeMethods.http_set_response_status_code(_pInProcessHandler, (ushort)StatusCode, reasonPhrase); NativeMethods.HttpSetResponseStatusCode(_pInProcessHandler, (ushort)StatusCode, reasonPhrase);
HttpResponseHeaders.IsReadOnly = true; HttpResponseHeaders.IsReadOnly = true;
foreach (var headerPair in HttpResponseHeaders) foreach (var headerPair in HttpResponseHeaders)
@ -352,7 +353,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{ {
fixed (byte* pHeaderValue = headerValueBytes) fixed (byte* pHeaderValue = headerValueBytes)
{ {
NativeMethods.http_response_set_unknown_header(_pInProcessHandler, pHeaderName, pHeaderValue, (ushort)headerValueBytes.Length, fReplace: false); NativeMethods.HttpResponseSetUnknownHeader(_pInProcessHandler, pHeaderName, pHeaderValue, (ushort)headerValueBytes.Length, fReplace: false);
} }
} }
} }
@ -364,7 +365,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
var headerValueBytes = Encoding.UTF8.GetBytes(headerValues[i]); var headerValueBytes = Encoding.UTF8.GetBytes(headerValues[i]);
fixed (byte* pHeaderValue = headerValueBytes) fixed (byte* pHeaderValue = headerValueBytes)
{ {
NativeMethods.http_response_set_known_header(_pInProcessHandler, knownHeaderIndex, pHeaderValue, (ushort)headerValueBytes.Length, fReplace: false); NativeMethods.HttpResponseSetKnownHeader(_pInProcessHandler, knownHeaderIndex, pHeaderValue, (ushort)headerValueBytes.Length, fReplace: false);
} }
} }
} }
@ -475,22 +476,13 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{ {
Debug.Assert(!_operation.HasContinuation, "Pending async operation!"); Debug.Assert(!_operation.HasContinuation, "Pending async operation!");
var hr = NativeMethods.http_set_completion_status(_pInProcessHandler, requestNotificationStatus); NativeMethods.HttpSetCompletionStatus(_pInProcessHandler, requestNotificationStatus);
if (hr != NativeMethods.S_OK) NativeMethods.HttpPostCompletion(_pInProcessHandler, 0);
{
throw Marshal.GetExceptionForHR(hr);
}
hr = NativeMethods.http_post_completion(_pInProcessHandler, 0);
if (hr != NativeMethods.S_OK)
{
throw Marshal.GetExceptionForHR(hr);
}
} }
public void IndicateCompletion(NativeMethods.REQUEST_NOTIFICATION_STATUS notificationStatus) public void IndicateCompletion(NativeMethods.REQUEST_NOTIFICATION_STATUS notificationStatus)
{ {
NativeMethods.http_indicate_completion(_pInProcessHandler, notificationStatus); NativeMethods.HttpIndicateCompletion(_pInProcessHandler, notificationStatus);
} }
internal void OnAsyncCompletion(int hr, int cbBytes) internal void OnAsyncCompletion(int hr, int cbBytes)
@ -540,9 +532,9 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
private WindowsPrincipal GetWindowsPrincipal() private WindowsPrincipal GetWindowsPrincipal()
{ {
var hr = NativeMethods.http_get_authentication_information(_pInProcessHandler, out var authenticationType, out var token); NativeMethods.HttpGetAuthenticationInformation(_pInProcessHandler, out var authenticationType, out var token);
if (hr == 0 && token != IntPtr.Zero && authenticationType != null) if (token != IntPtr.Zero && authenticationType != null)
{ {
if ((authenticationType.Equals(NtlmString, StringComparison.OrdinalIgnoreCase) if ((authenticationType.Equals(NtlmString, StringComparison.OrdinalIgnoreCase)
|| authenticationType.Equals(NegotiateString, StringComparison.OrdinalIgnoreCase) || authenticationType.Equals(NegotiateString, StringComparison.OrdinalIgnoreCase)

View File

@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
_iisContextFactory = new IISContextFactory<TContext>(_memoryPool, application, _options, this); _iisContextFactory = new IISContextFactory<TContext>(_memoryPool, application, _options, this);
// Start the server by registering the callback // Start the server by registering the callback
NativeMethods.register_callbacks(_requestHandler, _shutdownHandler, _onAsyncCompletion, (IntPtr)_httpServerHandle, (IntPtr)_httpServerHandle); NativeMethods.HttpRegisterCallbacks(_requestHandler, _shutdownHandler, _onAsyncCompletion, (IntPtr)_httpServerHandle, (IntPtr)_httpServerHandle);
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{ {
cancellationToken.Register(() => cancellationToken.Register(() =>
{ {
NativeMethods.http_stop_calls_into_managed(); NativeMethods.HttpStopCallsIntoManaged();
_shutdownSignal.TrySetResult(null); _shutdownSignal.TrySetResult(null);
}); });
} }
@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
} }
// 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.http_stop_incoming_requests(); NativeMethods.HttpStopIncomingRequests();
try try
{ {
@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
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.http_stop_calls_into_managed(); NativeMethods.HttpStopCallsIntoManaged();
_shutdownSignal.TrySetResult(null); _shutdownSignal.TrySetResult(null);
} }
} }
@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
_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.http_stop_calls_into_managed(); NativeMethods.HttpStopCallsIntoManaged();
_shutdownSignal.TrySetResult(null); _shutdownSignal.TrySetResult(null);
if (_httpServerHandle.IsAllocated) if (_httpServerHandle.IsAllocated)
@ -153,7 +153,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
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.http_stop_calls_into_managed(); NativeMethods.HttpStopCallsIntoManaged();
context.Server._shutdownSignal.TrySetResult(null); context.Server._shutdownSignal.TrySetResult(null);
} }
@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
~IISHttpServer() ~IISHttpServer()
{ {
// If this finalize is invoked, try our best to block all calls into managed. // If this finalize is invoked, try our best to block all calls into managed.
NativeMethods.http_stop_calls_into_managed(); NativeMethods.HttpStopCallsIntoManaged();
} }
} }

View File

@ -43,6 +43,7 @@ namespace Microsoft.AspNetCore.Hosting
// Check if in process // Check if in process
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && NativeMethods.IsAspNetCoreModuleLoaded()) if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && NativeMethods.IsAspNetCoreModuleLoaded())
{ {
return SetupInProcessServer(hostBuilder); return SetupInProcessServer(hostBuilder);
} }
@ -112,15 +113,7 @@ namespace Microsoft.AspNetCore.Hosting
hostBuilder.UseSetting(nameof(UseIISIntegration), "true"); hostBuilder.UseSetting(nameof(UseIISIntegration), "true");
hostBuilder.CaptureStartupErrors(true); hostBuilder.CaptureStartupErrors(true);
var iisConfigData = new IISConfigurationData(); var iisConfigData = NativeMethods.HttpGetApplicationProperties();
var hResult = NativeMethods.http_get_application_properties(ref iisConfigData);
var exception = Marshal.GetExceptionForHR(hResult);
if (exception != null)
{
throw exception;
}
hostBuilder.UseContentRoot(iisConfigData.pwzFullApplicationPath); hostBuilder.UseContentRoot(iisConfigData.pwzFullApplicationPath);
return hostBuilder.ConfigureServices( return hostBuilder.ConfigureServices(
services => { services => {