/// <summary> /// Accept a request from the incoming request queue. /// </summary> public Task <RequestContext> AcceptAsync() { AsyncAcceptContext asyncResult = null; try { CheckDisposed(); Debug.Assert(_state != State.Stopped, "Listener has been stopped."); // prepare the ListenerAsyncResult object (this will have it's own // event that the user can wait on for IO completion - which means we // need to signal it when IO completes) asyncResult = new AsyncAcceptContext(this); uint statusCode = asyncResult.QueueBeginGetContext(); if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING) { // some other bad error, possible(?) return values are: // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED asyncResult.Dispose(); throw new HttpSysException((int)statusCode); } } catch (Exception exception) { LogHelper.LogException(Logger, "GetContextAsync", exception); throw; } return(asyncResult.Task); }
private static void IOCompleted(AsyncAcceptContext asyncResult, uint errorCode, uint numBytes) { bool complete = false; try { if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA) { asyncResult.Tcs.TrySetException(new HttpSysException((int)errorCode)); complete = true; } else { HttpSysListener server = asyncResult.Server; if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { // at this point we have received an unmanaged HTTP_REQUEST and memoryBlob // points to it we need to hook up our authentication handling code here. try { if (server.ValidateRequest(asyncResult._nativeRequestContext) && server.ValidateAuth(asyncResult._nativeRequestContext)) { RequestContext requestContext = new RequestContext(server, asyncResult._nativeRequestContext); asyncResult.Tcs.TrySetResult(requestContext); complete = true; } } catch (Exception) { server.SendError(asyncResult._nativeRequestContext.RequestId, StatusCodes.Status400BadRequest); throw; } finally { // The request has been handed to the user, which means this code can't reuse the blob. Reset it here. if (complete) { asyncResult._nativeRequestContext = null; } else { asyncResult.AllocateNativeRequest(size: asyncResult._nativeRequestContext.Size); } } } else { // (uint)backingBuffer.Length - AlignmentPadding asyncResult.AllocateNativeRequest(numBytes, asyncResult._nativeRequestContext.RequestId); } // We need to issue a new request, either because auth failed, or because our buffer was too small the first time. if (!complete) { uint statusCode = asyncResult.QueueBeginGetContext(); if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING) { // someother bad error, possible(?) return values are: // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED asyncResult.Tcs.TrySetException(new HttpSysException((int)statusCode)); complete = true; } } if (!complete) { return; } } if (complete) { asyncResult.Dispose(); } } catch (Exception exception) { // Logged by caller asyncResult.Tcs.TrySetException(exception); asyncResult.Dispose(); } }