private static extern unsafe int http_websockets_write_bytes( NativeSafeHandle pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK *pDataChunks, int nChunks, PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback, IntPtr pvCompletionContext, out bool fCompletionExpected);
internal static unsafe bool HttpSupportTrailer(NativeSafeHandle pInProcessHandler) { bool supportsTrailers; Validate(http_has_response4(pInProcessHandler, out supportsTrailers)); return(supportsTrailers); }
protected override void ResetOperation() { base.ResetOperation(); _requestHandler = default; _engine.ReturnOperation(this); }
private static NativeMethods.REQUEST_NOTIFICATION_STATUS HandleRequest(IntPtr pInProcessHandler, IntPtr pvRequestContext) { IISHttpServer?server = null; try { // Unwrap the server so we can create an http context and process the request server = (IISHttpServer?)GCHandle.FromIntPtr(pvRequestContext).Target; // server can be null if ungraceful shutdown. if (server == null) { return(NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_FINISH_REQUEST); } var safehandle = new NativeSafeHandle(pInProcessHandler); Debug.Assert(server._iisContextFactory != null, "StartAsync must be called first."); var context = server._iisContextFactory.CreateHttpContext(safehandle); ThreadPool.UnsafeQueueUserWorkItem(context, preferLocal: false); 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_FINISH_REQUEST); } }
private static extern unsafe int http_websockets_read_bytes( NativeSafeHandle pInProcessHandler, byte *pvBuffer, int cbBuffer, PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback, IntPtr pvCompletionContext, out int dwBytesReceived, out bool fCompletionExpected);
private static extern int register_callbacks(NativeSafeHandle pInProcessApplication, PFN_REQUEST_HANDLER requestCallback, PFN_SHUTDOWN_HANDLER shutdownCallback, PFN_DISCONNECT_HANDLER disconnectCallback, PFN_ASYNC_COMPLETION asyncCallback, PFN_REQUESTS_DRAINED_HANDLER requestsDrainedHandler, IntPtr pvRequestContext, IntPtr pvShutdownContext);
protected override void ResetOperation() { base.ResetOperation(); _requestHandler = default; _buffer = default; _handles.AsSpan().Clear(); }
internal static unsafe int HttpWebsocketsWriteBytes( NativeSafeHandle 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 unsafe int HttpWebsocketsReadBytes( NativeSafeHandle 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 void HttpRegisterCallbacks(NativeSafeHandle pInProcessApplication, PFN_REQUEST_HANDLER requestCallback, PFN_SHUTDOWN_HANDLER shutdownCallback, PFN_DISCONNECT_HANDLER disconnectCallback, PFN_ASYNC_COMPLETION asyncCallback, PFN_REQUESTS_DRAINED_HANDLER requestsDrainedHandler, IntPtr pvRequestContext, IntPtr pvShutdownContext) { Validate(register_callbacks(pInProcessApplication, requestCallback, shutdownCallback, disconnectCallback, asyncCallback, requestsDrainedHandler, pvRequestContext, pvShutdownContext)); }
protected override void ResetOperation() { base.ResetOperation(); _memory = default; _inputHandle.Dispose(); _inputHandle = default; _requestHandler = default; _engine.ReturnOperation(this); }
private unsafe int WriteSequence(NativeSafeHandle requestHandler, int nChunks, ReadOnlySequence <byte> buffer, HttpApiTypes.HTTP_DATA_CHUNK *pDataChunks, out bool fCompletionExpected) { var currentChunk = 0; if (_handles == null || _handles.Length < nChunks) { _handles = new MemoryHandle[nChunks]; } foreach (var readOnlyMemory in buffer) { ref var handle = ref _handles[currentChunk]; ref var chunk = ref pDataChunks[currentChunk];
public static bool HttpTryCancelIO(NativeSafeHandle pInProcessHandler) { var hr = http_cancel_io(pInProcessHandler); // ERROR_NOT_FOUND is expected if async operation finished // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363792(v=vs.85).aspx // ERROR_INVALID_PARAMETER is expected for "fake" requests like applicationInitialization ones if (hr == ERROR_NOT_FOUND || hr == ERROR_INVALID_PARAMETER) { return(false); } Validate(hr); return(true); }
// TODO: Remove pInProcessHandler argument public bool IsWebSocketAvailable(NativeSafeHandle pInProcessHandler) { // Check if the Http upgrade feature is available in IIS. // To check this, we can look at the server variable WEBSOCKET_VERSION // And see if there is a version. Same check that Katana did: // https://github.com/aspnet/AspNetKatana/blob/9f6e09af6bf203744feb5347121fe25f6eec06d8/src/Microsoft.Owin.Host.SystemWeb/OwinAppContext.cs#L125 // Actively not locking here as acquiring a lock on every request will hurt perf more than checking the // server variables a few extra times if a bunch of requests hit the server at the same time. if (!_websocketAvailable.HasValue) { _websocketAvailable = NativeMethods.HttpTryGetServerVariable(pInProcessHandler, WebSocketVersionString, out var webSocketsSupported) && !string.IsNullOrEmpty(webSocketsSupported); } return(_websocketAvailable.Value); }
public void Initialize(NativeSafeHandle requestHandler, Memory <byte> memory) { _requestHandler = requestHandler; _memory = memory; }
private static extern int http_set_response_status_code(NativeSafeHandle pInProcessHandler, ushort statusCode, string pszReason);
private static extern unsafe int http_read_request_bytes(NativeSafeHandle pInProcessHandler, byte *pvBuffer, int cbBuffer, out int dwBytesReceived, out bool fCompletionExpected);
private static extern int http_stop_incoming_requests(NativeSafeHandle pInProcessApplication);
private static extern int http_disable_buffering(NativeSafeHandle pInProcessHandler);
private static extern int http_stop_calls_into_managed(NativeSafeHandle pInProcessApplication);
internal static unsafe void HttpResetStream(NativeSafeHandle pInProcessHandler, ulong errorCode) { Validate(http_reset_stream(pInProcessHandler, errorCode)); }
private static extern int http_post_completion(NativeSafeHandle pInProcessHandler, int cbBytes);
public IISNativeApplication(NativeSafeHandle nativeApplication) { _nativeApplication = nativeApplication; }
private static extern void http_indicate_completion(NativeSafeHandle pInProcessHandler, REQUEST_NOTIFICATION_STATUS notificationStatus);
public AsyncIOEngine(IISHttpContext context, NativeSafeHandle handler) { _context = context; _handler = handler; }
private static extern int http_flush_response_bytes(NativeSafeHandle pInProcessHandler, bool fMoreData, out bool fCompletionExpected);
private static extern int http_set_completion_status(NativeSafeHandle pInProcessHandler, REQUEST_NOTIFICATION_STATUS rquestNotificationStatus);
private static extern unsafe HttpApiTypes.HTTP_REQUEST_V2 *http_get_raw_request(NativeSafeHandle pInProcessHandler);
private static extern unsafe int register_callbacks(NativeSafeHandle pInProcessApplication,
private static extern unsafe int http_write_response_bytes(NativeSafeHandle pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK *pDataChunks, int nChunks, out bool fCompletionExpected);