public Task <RequestContext> GetContextAsync() { 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) { // someother bad error, possible(?) return values are: // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED asyncResult.Dispose(); throw new WebListenerException((int)statusCode); } } catch (Exception exception) { LogHelper.LogException(_logger, "GetContextAsync", exception); throw; } return(asyncResult.Task); }
internal NativeRequestContext(AsyncAcceptContext result) { _acceptResult = result; UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST *requestBlob = Allocate(0); if (requestBlob == null) { GC.SuppressFinalize(this); } else { _memoryBlob = requestBlob; } }
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 WebListenerException((int)errorCode)); complete = true; } else { WebListener 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. bool stoleBlob = false; try { if (server.ValidateRequest(asyncResult._nativeRequestContext) && server.ValidateAuth(asyncResult._nativeRequestContext)) { stoleBlob = true; RequestContext requestContext = new RequestContext(server, asyncResult._nativeRequestContext); asyncResult.Tcs.TrySetResult(requestContext); complete = true; } } finally { if (stoleBlob) { // The request has been handed to the user, which means this code can't reuse the blob. Reset it here. asyncResult._nativeRequestContext = complete ? null : new NativeRequestContext(asyncResult); } else { asyncResult._nativeRequestContext.Reset(0, 0); } } } else { asyncResult._nativeRequestContext.Reset(asyncResult._nativeRequestContext.RequestBlob->RequestId, numBytes); } // 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 WebListenerException((int)statusCode)); complete = true; } } if (!complete) { return; } } if (complete) { asyncResult.Dispose(); } } catch (Exception exception) { // Logged by caller asyncResult.Tcs.TrySetException(exception); asyncResult.Dispose(); } }