diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs index a43938b61c..4f8c2ce10e 100644 --- a/src/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs +++ b/src/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs @@ -7,24 +7,28 @@ using Microsoft.AspNetCore.HttpSys.Internal; namespace Microsoft.AspNetCore.Server.IISIntegration { - internal class NativeMethods + internal static class NativeMethods { -#if DOTNET5_4 - private const string api_ms_win_core_handle_LIB = "api-ms-win-core-handle-l1-1-0.dll"; -#else + private const int HR_NOT_FOUND = unchecked((int)0x80070490); + private const int HR_OK = 0; + 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"; + [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 { 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_WEBSOCKET_ASYNC_COMPLETION(IntPtr pInProcessHandler, IntPtr completionInfo, IntPtr pvCompletionContext); - // TODO make this all internal [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)] - 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)] - 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)] - 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)] - 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)] - 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)] - 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)] - internal unsafe static extern void http_stop_calls_into_managed(); + private static extern void http_stop_calls_into_managed(); [DllImport(AspNetCoreModuleDll)] - internal unsafe static extern void http_stop_incoming_requests(); + private static extern void http_stop_incoming_requests(); [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)] - 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)] - 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)] - 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)] - 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)] - 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)] - 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)] - 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)] - 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)] - 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)] - public unsafe static extern int http_enable_websockets(IntPtr pInProcessHandler); + private static extern int http_cancel_io(IntPtr pInProcessHandler); [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)] - 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)] - 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 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() + public static void HttpPostCompletion(IntPtr pInProcessHandler, int cbBytes) { - 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); + } } } } diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISAwaitable.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISAwaitable.cs index 28cc3672d5..a24586b137 100644 --- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISAwaitable.cs +++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISAwaitable.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration { 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); @@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration { 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); diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.FeatureCollection.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.FeatureCollection.cs index 4a1ecd5f27..f43c88a319 100644 --- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.FeatureCollection.cs +++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.FeatureCollection.cs @@ -243,8 +243,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration return null; } - int hr = NativeMethods.http_get_server_variable(_pInProcessHandler, variableName, out var value); - return hr == 0 ? value : null; + return NativeMethods.HttpTryGetServerVariable(_pInProcessHandler, variableName, out var value) ? value : null; } } @@ -296,7 +295,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration ReasonPhrase = ReasonPhrases.GetReasonPhrase(StatusCodes.Status101SwitchingProtocols); _readWebSocketsOperation = 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 await UpgradeAsync(); diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.ReadWrite.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.ReadWrite.cs index 699081e659..7b5f18efce 100644 --- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.ReadWrite.cs +++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.ReadWrite.cs @@ -169,7 +169,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration } else { - var hr = NativeMethods.http_read_request_bytes( + var hr = NativeMethods.HttpReadRequestBytes( _pInProcessHandler, (byte*)_inputHandle.Pointer, length, @@ -225,7 +225,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration chunk.DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; chunk.fromMemory.pBuffer = (IntPtr)pBuffer; 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) @@ -274,7 +274,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration currentChunk++; } - hr = NativeMethods.http_write_response_bytes(_pInProcessHandler, pDataChunks, nChunks, out fCompletionExpected); + hr = NativeMethods.HttpWriteResponseBytes(_pInProcessHandler, pDataChunks, nChunks, out fCompletionExpected); // Free the handles foreach (var handle in handles) @@ -289,7 +289,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration { // Calls flush var hr = 0; - hr = NativeMethods.http_flush_response_bytes(_pInProcessHandler, out var fCompletionExpected); + hr = NativeMethods.HttpFlushResponseBytes(_pInProcessHandler, out var fCompletionExpected); if (!fCompletionExpected) { _operation.Complete(hr, 0); @@ -468,7 +468,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration { _reading = false; // Calls IHttpContext->CancelIo(), which will cause the OnAsyncCompletion handler to fire. - NativeMethods.http_cancel_io(_pInProcessHandler); + NativeMethods.HttpTryCancelIO(_pInProcessHandler); } } } diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.Websockets.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.Websockets.cs index fa84c3ce11..6ddbdef865 100644 --- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.Websockets.cs +++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.Websockets.cs @@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration bool fCompletionExpected; // 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, (byte*)_inputHandle.Pointer, length, @@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration chunk.DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; chunk.fromMemory.pBuffer = (IntPtr)pBuffer; 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 @@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration 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) { diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.cs index 32afb07033..8ca003ed7f 100644 --- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.cs +++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.cs @@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration private const string WebSocketVersionString = "WEBSOCKET_VERSION"; internal unsafe IISHttpContext(MemoryPool 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); @@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration _pInProcessHandler = pInProcessHandler; _server = server; - NativeMethods.http_set_managed_context(pInProcessHandler, (IntPtr)_thisHandle); + NativeMethods.HttpSetManagedContext(pInProcessHandler, (IntPtr)_thisHandle); unsafe { 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. if (_websocketAvailability == WebsocketAvailabilityStatus.Uninitialized) { - NativeMethods.http_get_server_variable(pInProcessHandler, WebSocketVersionString, out var webSocketsSupported); - var webSocketsAvailable = !string.IsNullOrEmpty(webSocketsSupported); + var webSocketsAvailable = NativeMethods.HttpTryGetServerVariable(pInProcessHandler, WebSocketVersionString, out var webSocketsSupported) + && !string.IsNullOrEmpty(webSocketsSupported); + _websocketAvailability = webSocketsAvailable ? WebsocketAvailabilityStatus.Available : WebsocketAvailabilityStatus.NotAvailable; @@ -335,7 +336,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration var reasonPhrase = string.IsNullOrEmpty(ReasonPhrase) ? ReasonPhrases.GetReasonPhrase(StatusCode) : ReasonPhrase; // 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; foreach (var headerPair in HttpResponseHeaders) @@ -352,7 +353,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration { 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]); 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!"); - var hr = NativeMethods.http_set_completion_status(_pInProcessHandler, requestNotificationStatus); - if (hr != NativeMethods.S_OK) - { - throw Marshal.GetExceptionForHR(hr); - } - - hr = NativeMethods.http_post_completion(_pInProcessHandler, 0); - if (hr != NativeMethods.S_OK) - { - throw Marshal.GetExceptionForHR(hr); - } + NativeMethods.HttpSetCompletionStatus(_pInProcessHandler, requestNotificationStatus); + NativeMethods.HttpPostCompletion(_pInProcessHandler, 0); } 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) @@ -540,9 +532,9 @@ namespace Microsoft.AspNetCore.Server.IISIntegration 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) || authenticationType.Equals(NegotiateString, StringComparison.OrdinalIgnoreCase) diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpServer.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpServer.cs index 110b38e729..046d8b9c4f 100644 --- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpServer.cs +++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpServer.cs @@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration _iisContextFactory = new IISContextFactory(_memoryPool, application, _options, this); // 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; } @@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration { cancellationToken.Register(() => { - NativeMethods.http_stop_calls_into_managed(); + NativeMethods.HttpStopCallsIntoManaged(); _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" - NativeMethods.http_stop_incoming_requests(); + NativeMethods.HttpStopIncomingRequests(); try { @@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration else { // We have drained all requests. Block any callbacks into managed at this point. - NativeMethods.http_stop_calls_into_managed(); + NativeMethods.HttpStopCallsIntoManaged(); _shutdownSignal.TrySetResult(null); } } @@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration _stopping = 1; // Block any more calls into managed from native as we are unloading. - NativeMethods.http_stop_calls_into_managed(); + NativeMethods.HttpStopCallsIntoManaged(); _shutdownSignal.TrySetResult(null); if (_httpServerHandle.IsAllocated) @@ -153,7 +153,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration if (Interlocked.Decrement(ref context.Server._outstandingRequests) == 0 && context.Server.Stopping) { // All requests have been drained. - NativeMethods.http_stop_calls_into_managed(); + NativeMethods.HttpStopCallsIntoManaged(); context.Server._shutdownSignal.TrySetResult(null); } @@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration ~IISHttpServer() { // If this finalize is invoked, try our best to block all calls into managed. - NativeMethods.http_stop_calls_into_managed(); + NativeMethods.HttpStopCallsIntoManaged(); } } diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs index fbf081f725..c236c7eac4 100644 --- a/src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs +++ b/src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs @@ -43,6 +43,7 @@ namespace Microsoft.AspNetCore.Hosting // Check if in process if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && NativeMethods.IsAspNetCoreModuleLoaded()) { + return SetupInProcessServer(hostBuilder); } @@ -112,15 +113,7 @@ namespace Microsoft.AspNetCore.Hosting hostBuilder.UseSetting(nameof(UseIISIntegration), "true"); hostBuilder.CaptureStartupErrors(true); - var iisConfigData = new IISConfigurationData(); - var hResult = NativeMethods.http_get_application_properties(ref iisConfigData); - - var exception = Marshal.GetExceptionForHR(hResult); - if (exception != null) - { - throw exception; - } - + var iisConfigData = NativeMethods.HttpGetApplicationProperties(); hostBuilder.UseContentRoot(iisConfigData.pwzFullApplicationPath); return hostBuilder.ConfigureServices( services => {