/// <summary> /// Begins an ansynchronous receive operation. /// </summary> /// <param name="callback">The callback method.</param> /// <param name="state">The user state.</param> /// <returns>The result of the asynchronous operation.</returns> public IAsyncResult BeginReceive(AsyncCallback callback, object state) { ListenerAsyncResult result = new ListenerAsyncResult() { Buffer = new byte[65535], EndPoint = this.endPoint, Callback = callback, State = state }; result.AsyncResult = this.socket.BeginReceiveFrom(result.Buffer, 0, 65535, SocketFlags.None, ref result.EndPoint, OnSocketCallback, result); return result; }
public HttpListenerContext GetContext() { if (_state == State.Stopped) { throw new InvalidOperationException(SR.Format(SR.net_listener_mustcall, "Start()")); } if (_prefixes.Count == 0) { throw new InvalidOperationException(SR.Format(SR.net_listener_mustcall, "AddPrefix()")); } ListenerAsyncResult ares = (ListenerAsyncResult)BeginGetContext(null, null); ares._inGet = true; return(EndGetContext(ares)); }
private static void InvokeCallback(object o) { ListenerAsyncResult ares = (ListenerAsyncResult)o; if (ares._forward != null) { InvokeCallback(ares._forward); return; } try { ares._cb(ares); } catch { } }
public HttpListenerContext EndGetContext(IAsyncResult asyncResult) { CheckDisposed(); if (asyncResult == null) { throw new ArgumentNullException(nameof(asyncResult)); } ListenerAsyncResult ares = asyncResult as ListenerAsyncResult; if (ares == null) { throw new ArgumentException(SR.net_io_invalidasyncresult, nameof(asyncResult)); } if (ares._endCalled) { throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, nameof(EndGetContext))); } ares._endCalled = true; if (!ares.IsCompleted) { ares.AsyncWaitHandle.WaitOne(); } lock ((_asyncWaitQueue as ICollection).SyncRoot) { int idx = _asyncWaitQueue.IndexOf(ares); if (idx >= 0) { _asyncWaitQueue.RemoveAt(idx); } } HttpListenerContext context = ares.GetContext(); context.ParseAuthentication(SelectAuthenticationScheme(context)); return(context); }
public HttpListenerContext EndGetContext(IAsyncResult asyncResult) { CheckDisposed(); if (asyncResult == null) { throw new ArgumentNullException("asyncResult"); } ListenerAsyncResult ares = asyncResult as ListenerAsyncResult; if (ares == null) { throw new ArgumentException("Wrong IAsyncResult.", "asyncResult"); } if (ares.EndCalled) { throw new ArgumentException("Cannot reuse this IAsyncResult"); } ares.EndCalled = true; if (!ares.IsCompleted) { ares.AsyncWaitHandle.WaitOne(); } lock (wait_queue) { int idx = wait_queue.IndexOf(ares); if (idx >= 0) { wait_queue.RemoveAt(idx); } } HttpListenerContext context = ares.GetContext(); context.ParseAuthentication(SelectAuthenticationScheme(context)); return(context); // This will throw on error. }
internal void RegisterContext(HttpListenerContext context) { lock (_registry) _registry[context] = context; ListenerAsyncResult ares = null; lock (_waitQueue) { if (_waitQueue.Count == 0) { lock (_ctxQueue) _ctxQueue.Add(context); } else { ares = (ListenerAsyncResult)_waitQueue[0]; _waitQueue.RemoveAt(0); } } ares?.Complete(context); }
internal void RegisterContext(HttpListenerContext context) { try { Monitor.Enter(registry); registry [context] = context; Monitor.Enter(wait_queue); Monitor.Enter(ctx_queue); if (wait_queue.Count == 0) { ctx_queue.Add(context); } else { ListenerAsyncResult ares = (ListenerAsyncResult)wait_queue [0]; wait_queue.RemoveAt(0); ares.Complete(context); } } finally { Monitor.Exit(ctx_queue); Monitor.Exit(wait_queue); Monitor.Exit(registry); } }
private void Cleanup(bool close_existing) { Hashtable obj = this.registry; lock (obj) { if (close_existing) { foreach (object obj2 in this.registry.Keys) { HttpListenerContext httpListenerContext = (HttpListenerContext)obj2; httpListenerContext.Connection.Close(); } this.registry.Clear(); } ArrayList obj3 = this.ctx_queue; lock (obj3) { foreach (object obj4 in this.ctx_queue) { HttpListenerContext httpListenerContext2 = (HttpListenerContext)obj4; httpListenerContext2.Connection.Close(); } this.ctx_queue.Clear(); } ArrayList obj5 = this.wait_queue; lock (obj5) { foreach (object obj6 in this.wait_queue) { ListenerAsyncResult listenerAsyncResult = (ListenerAsyncResult)obj6; listenerAsyncResult.Complete("Listener was closed."); } this.wait_queue.Clear(); } } }
internal void RegisterContext(HttpListenerContext context) { lock (registry) registry [context] = context; ListenerAsyncResult ares = null; lock (wait_queue) { if (wait_queue.Count == 0) { lock (ctx_queue) ctx_queue.Add(context); } else { ares = (ListenerAsyncResult)wait_queue [0]; wait_queue.RemoveAt(0); } } if (ares != null) { ares.Complete(context); } }
private static unsafe void WaitCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped) { ListenerAsyncResult asyncResult = (ListenerAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped); IOCompleted(asyncResult, errorCode, numBytes); }
private static void IOCompleted(ListenerAsyncResult asyncResult, uint errorCode, uint numBytes) { object result = null; try { GlobalLog.Print("ListenerAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::WaitCallback() errorCode:[" + errorCode.ToString() + "] numBytes:[" + numBytes.ToString() + "]"); if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA) { asyncResult.ErrorCode = (int)errorCode; result = new HttpListenerException((int)errorCode); } else { HttpListener httpWebListener = asyncResult.AsyncObject as HttpListener; 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 (httpWebListener.ValidateRequest(asyncResult.m_RequestContext)) { result = httpWebListener.HandleAuthentication(asyncResult.m_RequestContext, out stoleBlob); } } finally { if (stoleBlob) { // The request has been handed to the user, which means this code can't reuse the blob. Reset it here. asyncResult.m_RequestContext = result == null ? new AsyncRequestContext(asyncResult) : null; } else { asyncResult.m_RequestContext.Reset(0, 0); } } } else { asyncResult.m_RequestContext.Reset(asyncResult.m_RequestContext.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 (result==null) { 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 result = new HttpListenerException((int)statusCode); } } if (result==null) { return; } } // complete the async IO and invoke the callback GlobalLog.Print("ListenerAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::WaitCallback() calling Complete()"); } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) throw; GlobalLog.Print("ListenerAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::WaitCallback() Caught exception:" + exception.ToString()); result = exception; } asyncResult.InvokeCallback(result); }
private static void IOCompleted(ListenerAsyncResult asyncResult, uint errorCode, uint numBytes) { object result = null; try { if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"errorCode:[{errorCode}] numBytes:[{numBytes}]"); if (errorCode != Interop.HttpApi.ERROR_SUCCESS && errorCode != Interop.HttpApi.ERROR_MORE_DATA) { asyncResult.ErrorCode = (int)errorCode; result = new HttpListenerException((int)errorCode); } else { HttpListener httpWebListener = asyncResult.AsyncObject as HttpListener; if (errorCode == Interop.HttpApi.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 (httpWebListener.ValidateRequest(asyncResult._requestContext)) { result = httpWebListener.HandleAuthentication(asyncResult._requestContext, out stoleBlob); } } finally { if (stoleBlob) { // The request has been handed to the user, which means this code can't reuse the blob. Reset it here. asyncResult._requestContext = result == null ? new AsyncRequestContext(httpWebListener.RequestQueueBoundHandle, asyncResult) : null; } else { asyncResult._requestContext.Reset(httpWebListener.RequestQueueBoundHandle, 0, 0); } } } else { asyncResult._requestContext.Reset(httpWebListener.RequestQueueBoundHandle, asyncResult._requestContext.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 (result == null) { uint statusCode = asyncResult.QueueBeginGetContext(); if (statusCode != Interop.HttpApi.ERROR_SUCCESS && statusCode != Interop.HttpApi.ERROR_IO_PENDING) { // someother bad error, possible return values are: // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED result = new HttpListenerException((int)statusCode); } } if (result == null) { return; } } // complete the async IO and invoke the callback if (NetEventSource.IsEnabled) NetEventSource.Info(null, "Calling Complete()"); } catch (Exception exception) when (!ExceptionCheck.IsFatal(exception)) { if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"Caught exception: {exception}"); result = exception; } asyncResult.InvokeCallback(result); }
public IAsyncResult BeginGetContext (AsyncCallback callback, Object state) { CheckDisposed (); if (!listening) throw new InvalidOperationException ("Please, call Start before using this method."); ListenerAsyncResult ares = new ListenerAsyncResult (callback, state); // lock wait_queue early to avoid race conditions lock (wait_queue) { lock (ctx_queue) { HttpListenerContext ctx = GetContextFromQueue (); if (ctx != null) { ares.Complete (ctx, true); return ares; } } wait_queue.Add (ares); } return ares; }
public IAsyncResult BeginGetContext(AsyncCallback callback, object state) { if (NetEventSource.IsEnabled) NetEventSource.Enter(this); ListenerAsyncResult asyncResult = null; try { CheckDisposed(); if (_state == State.Stopped) { throw new InvalidOperationException(SR.Format(SR.net_listener_mustcall, "Start()")); } // 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 ListenerAsyncResult(this, state, callback); uint statusCode = asyncResult.QueueBeginGetContext(); if (statusCode != Interop.HttpApi.ERROR_SUCCESS && statusCode != Interop.HttpApi.ERROR_IO_PENDING) { // someother bad error, return values are: // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED throw new HttpListenerException((int)statusCode); } } catch (Exception exception) { if (NetEventSource.IsEnabled) NetEventSource.Error(this, $"BeginGetContext {exception}"); throw; } finally { if (NetEventSource.IsEnabled) NetEventSource.Exit(this); } return asyncResult; }
static void InvokeCallback(object o) { ListenerAsyncResult ares = (ListenerAsyncResult)o; ares.cb(ares); }
/// <summary> /// Begins an asynchronous send operation. /// </summary> /// <param name="buffer">The buffer.</param> /// <param name="offset">The offset.</param> /// <param name="length">The sending data length.</param> /// <param name="endPoint">The end point.</param> /// <param name="callback">The callback method.</param> /// <param name="state">The user state.</param> /// <returns>The asynchronous result.</returns> public IAsyncResult BeginSend(byte[] buffer, int offset, int length, IPEndPoint endPoint, AsyncCallback callback, object state) { ListenerAsyncResult result = new ListenerAsyncResult() { Callback = callback, State = state }; result.AsyncResult = this.socket.BeginSendTo(buffer, offset, length, SocketFlags.None, endPoint, OnSocketCallback, result); return result; }
internal AsyncRequestContext(ListenerAsyncResult result) { this.m_Result = result; base.BaseConstruction(this.Allocate(0)); }
private static void IOCompleted(ListenerAsyncResult asyncResult, uint errorCode, uint numBytes) { object result = null; try { GlobalLog.Print("ListenerAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::WaitCallback() errorCode:[" + errorCode.ToString() + "] numBytes:[" + numBytes.ToString() + "]"); if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA) { asyncResult.ErrorCode = (int)errorCode; result = new HttpListenerException((int)errorCode); } else { HttpListener httpWebListener = asyncResult.AsyncObject as HttpListener; 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 (httpWebListener.ValidateRequest(asyncResult.m_RequestContext)) { result = httpWebListener.HandleAuthentication(asyncResult.m_RequestContext, out stoleBlob); } } finally { if (stoleBlob) { // The request has been handed to the user, which means this code can't reuse the blob. Reset it here. asyncResult.m_RequestContext = result == null ? new AsyncRequestContext(asyncResult) : null; } else { asyncResult.m_RequestContext.Reset(0, 0); } } } else { asyncResult.m_RequestContext.Reset(asyncResult.m_RequestContext.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 (result == null) { 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 result = new HttpListenerException((int)statusCode); } } if (result == null) { return; } } // complete the async IO and invoke the callback GlobalLog.Print("ListenerAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::WaitCallback() calling Complete()"); } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) { throw; } GlobalLog.Print("ListenerAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::WaitCallback() Caught exception:" + exception.ToString()); result = exception; } asyncResult.InvokeCallback(result); }
internal void Complete(HttpListenerContext context, bool synch) { if (this.forward != null) { this.forward.Complete(context, synch); return; } this.synch = synch; this.context = context; object obj = this.locker; lock (obj) { AuthenticationSchemes authenticationSchemes = context.Listener.SelectAuthenticationScheme(context); if ((authenticationSchemes == AuthenticationSchemes.Basic || context.Listener.AuthenticationSchemes == AuthenticationSchemes.Negotiate) && context.Request.Headers["Authorization"] == null) { context.Response.StatusCode = 401; context.Response.Headers["WWW-Authenticate"] = string.Concat(new object[] { authenticationSchemes, " realm=\"", context.Listener.Realm, "\"" }); context.Response.OutputStream.Close(); IAsyncResult asyncResult = context.Listener.BeginGetContext(this.cb, this.state); this.forward = (ListenerAsyncResult)asyncResult; object obj2 = this.forward.locker; lock (obj2) { if (this.handle != null) { this.forward.handle = this.handle; } } ListenerAsyncResult listenerAsyncResult = this.forward; int num = 0; while (listenerAsyncResult.forward != null) { if (num > 20) { this.Complete("Too many authentication errors"); } listenerAsyncResult = listenerAsyncResult.forward; num++; } } else { this.completed = true; if (this.handle != null) { this.handle.Set(); } if (this.cb != null) { ThreadPool.QueueUserWorkItem(new WaitCallback(ListenerAsyncResult.InvokeCallback), this); } } } }
private static void IOCompleted(ListenerAsyncResult asyncResult, uint errorCode, uint numBytes) { object result = null; try { if (NetEventSource.IsEnabled) { NetEventSource.Info(null, $"errorCode:[{errorCode}] numBytes:[{numBytes}]"); } if (errorCode != Interop.HttpApi.ERROR_SUCCESS && errorCode != Interop.HttpApi.ERROR_MORE_DATA) { asyncResult.ErrorCode = (int)errorCode; result = new HttpListenerException((int)errorCode); } else { HttpListener httpWebListener = asyncResult.AsyncObject as HttpListener; if (errorCode == Interop.HttpApi.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 (httpWebListener.ValidateRequest(asyncResult._requestContext)) { result = httpWebListener.HandleAuthentication(asyncResult._requestContext, out stoleBlob); } } finally { if (stoleBlob) { // The request has been handed to the user, which means this code can't reuse the blob. Reset it here. asyncResult._requestContext = result == null ? new AsyncRequestContext(httpWebListener.RequestQueueBoundHandle, asyncResult) : null; } else { asyncResult._requestContext.Reset(httpWebListener.RequestQueueBoundHandle, 0, 0); } } } else { asyncResult._requestContext.Reset(httpWebListener.RequestQueueBoundHandle, asyncResult._requestContext.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 (result == null) { uint statusCode = asyncResult.QueueBeginGetContext(); if (statusCode != Interop.HttpApi.ERROR_SUCCESS && statusCode != Interop.HttpApi.ERROR_IO_PENDING) { // someother bad error, possible return values are: // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED result = new HttpListenerException((int)statusCode); } } if (result == null) { return; } } // complete the async IO and invoke the callback if (NetEventSource.IsEnabled) { NetEventSource.Info(null, "Calling Complete()"); } } catch (Exception exception) when(!ExceptionCheck.IsFatal(exception)) { if (NetEventSource.IsEnabled) { NetEventSource.Info(null, $"Caught exception: {exception}"); } result = exception; } asyncResult.InvokeCallback(result); }
WaitCallback( Object state, bool signaled) { GlobalLog.Print("entering the WaitCallback()"); // // take the ListenerAsyncResult object from the state // ListenerAsyncResult AResult = ( ListenerAsyncResult )state; GlobalLog.Print("got the AResult object"); bool syncComplete = AResult.CompletedSynchronously; if (!syncComplete) { // // we've been called by the thread, the event was signaled // call HackedGetOverlappedResult() to find out about the IO // GlobalLog.Print("WaitCallback()!call didn't complete sync calling HackedGetOverlappedResult():"); AResult.m_BytesReturned = Win32.HackedGetOverlappedResult( AResult.m_Overlapped); if (AResult.m_BytesReturned <= 0) { // // something went wrong throw for now, later we should // call into ul call again // throw new InvalidOperationException("UlReceiveHttpRequest(callback) failure m_BytesReturned:" + Convert.ToString(AResult.m_BytesReturned)); } if (AResult.m_BufferSize < AResult.m_BytesReturned) { // // this is anlogous to the syncronous case in which we get // result == NativeMethods.ERROR_MORE_DATA // basically the buffer is not big enought to accomodate the // reqeust that came in, so grow it to the needed size, copy // the valid data, and reissue the async call and queue it // up to the ThreadPool // throw new InvalidOperationException("UlReceiveHttpRequest(callback) buffer too small, was:" + Convert.ToString(AResult.m_BufferSize) + " should be:" + Convert.ToString(AResult.m_BytesReturned)); } } GlobalLog.Print("WaitCallback()!I/O status is" + " AResult.m_BytesReturned: " + Convert.ToString(AResult.m_BytesReturned) + " AResult.m_Overlapped: " + Convert.ToString(AResult.m_Overlapped) + " AResult.m_SyncComplete: " + Convert.ToString(AResult.CompletedSynchronously)); // // complete the async IO and invoke the callback // AResult.InvokeCallback(syncComplete, new HttpListenerWebRequest(AResult.m_Buffer, AResult.m_BytesReturned, m_AppPoolHandle)); return; } // WaitCallback()
private static unsafe void WaitCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped) { ListenerAsyncResult asyncResult = (ListenerAsyncResult)Overlapped.Unpack(nativeOverlapped).AsyncResult; object result = null; try { if ((errorCode != 0) && (errorCode != 0xea)) { asyncResult.ErrorCode = (int)errorCode; result = new HttpListenerException((int)errorCode); } else { HttpListener asyncObject = asyncResult.AsyncObject as HttpListener; if (errorCode == 0) { bool stoleBlob = false; try { result = asyncObject.HandleAuthentication(asyncResult.m_RequestContext, out stoleBlob); } finally { if (stoleBlob) { asyncResult.m_RequestContext = (result == null) ? new AsyncRequestContext(asyncResult) : null; } else { asyncResult.m_RequestContext.Reset(0L, 0); } } } else { asyncResult.m_RequestContext.Reset(asyncResult.m_RequestContext.RequestBlob.RequestId, numBytes); } if (result == null) { uint num = asyncResult.QueueBeginGetContext(); if ((num != 0) && (num != 0x3e5)) { result = new HttpListenerException((int)num); } } if (result == null) { return; } } } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) { throw; } result = exception; } asyncResult.InvokeCallback(result); }
internal AsyncRequestContext(ThreadPoolBoundHandle boundHandle, ListenerAsyncResult result) { _result = result; BaseConstruction(Allocate(boundHandle, 0)); }
BeginGetRequest( AsyncCallback requestCallback, Object stateObject) { // // Validation // if (m_AppPoolHandle == NativeMethods.INVALID_HANDLE_VALUE) { throw new InvalidOperationException("The AppPool handle is invalid"); } // // 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 ) // GlobalLog.Print("BeginGetRequest() creating ListenerAsyncResult"); ListenerAsyncResult AResult = new ListenerAsyncResult( stateObject, requestCallback); AutoResetEvent m_Event = new AutoResetEvent(false); Marshal.WriteIntPtr( AResult.m_Overlapped, Win32.OverlappedhEventOffset, m_Event.Handle); // // issue unmanaged call until we read enough data: // usually starting with a InitialBufferSize==4096 bytes we should be // able to get all the headers ( and part of the entity body, if any // is present ), if we don't, if the call didn't fail for othe reasons, // we get indication in BytesReturned, on how big the buffer should be // to receive the data available, so usually the second call will // succeed, but we have to consider the case of two competing calls // for the same RequestId, and that's why we need a loop and not just // a try/retry-expecting-success fashion // int result; for (;;) { // // check if we're in a healthy state // if (AResult.m_Retries++ > m_MaxRetries) { throw new InvalidOperationException("UlReceiveHttpRequest() Too many retries"); } result = ComNetOS.IsWinNt ? UlSysApi.UlReceiveHttpRequest( m_AppPoolHandle, AResult.m_RequestId, UlConstants.UL_RECEIVE_REQUEST_FLAG_COPY_BODY, AResult.m_Buffer, AResult.m_BufferSize, ref AResult.m_BytesReturned, AResult.m_Overlapped) : UlVxdApi.UlReceiveHttpRequestHeaders( m_AppPoolHandle, AResult.m_RequestId, 0, AResult.m_Buffer, AResult.m_BufferSize, ref AResult.m_BytesReturned, AResult.m_Overlapped); GlobalLog.Print("UlReceiveHttpRequest() returns:" + Convert.ToString(result)); if (result == NativeMethods.ERROR_SUCCESS || result == NativeMethods.ERROR_IO_PENDING) { // // synchronous success or successfull pending: we are done // break; } if (result == NativeMethods.ERROR_INVALID_PARAMETER) { // // we might get this if somebody stole our RequestId, // set RequestId to null // AResult.m_RequestId = 0; // // and start all over again with the buffer we // just allocated // continue; } if (result == NativeMethods.ERROR_MORE_DATA) { // // the buffer was not big enough to fit the headers, we need // to read the RequestId returned, grow the buffer, keeping // the data already transferred // AResult.m_RequestId = Marshal.ReadInt64(IntPtrHelper.Add(AResult.m_Buffer, m_RequestIdOffset)); // // allocate a new buffer of the required size // IntPtr NewBuffer = Marshal.AllocHGlobal(AResult.m_BytesReturned); // // copy the data already read from the old buffer into the // new one // NativeMethods.CopyMemory(NewBuffer, AResult.m_Buffer, AResult.m_BufferSize); // // free the old buffer // Marshal.FreeHGlobal(AResult.m_Buffer); // // update buffer pointer and size // AResult.m_Buffer = NewBuffer; AResult.m_BufferSize = AResult.m_BytesReturned; AResult.m_BytesReturned = 0; // // and start all over again with the new buffer // continue; } // // someother bad error, possible( ? ) return values are: // // ERROR_INVALID_HANDLE // ERROR_INSUFFICIENT_BUFFER // ERROR_OPERATION_ABORTED // ERROR_IO_PENDING // throw new InvalidOperationException("UlReceiveHttpRequest() failed, err#" + Convert.ToString(result)); } // // we get here only if a break happens, i.e. // 1) syncronous completion // 2) the IO pended // if (result == NativeMethods.ERROR_SUCCESS) { // // set syncronous completion to true // AResult.Complete(true); // // and call the internal callback // WaitCallback(AResult, false); } else { // // create a new delegate // and spin a new thread from the thread pool to wake up when the // event is signaled and call the delegate // ThreadPool.RegisterWaitForSingleObject( m_Event, new WaitOrTimerCallback(WaitCallback), AResult, -1, true); } GlobalLog.Print("returning AResult"); return(AResult); } // StartListen()
internal void Complete (HttpListenerContext context, bool synch) { if (forward != null) { forward.Complete (context, synch); return; } this.synch = synch; this.context = context; lock (locker) { AuthenticationSchemes schemes = context.Listener.SelectAuthenticationScheme (context); if ((schemes == AuthenticationSchemes.Basic || context.Listener.AuthenticationSchemes == AuthenticationSchemes.Negotiate) && context.Request.Headers ["Authorization"] == null) { context.Response.StatusCode = 401; context.Response.Headers ["WWW-Authenticate"] = schemes + " realm=\"" + context.Listener.Realm + "\""; context.Response.OutputStream.Close (); IAsyncResult ares = context.Listener.BeginGetContext (cb, state); this.forward = (ListenerAsyncResult) ares; lock (forward.locker) { if (handle != null) forward.handle = handle; } ListenerAsyncResult next = forward; for (int i = 0; next.forward != null; i++) { if (i > 20) Complete (new HttpListenerException (400, "Too many authentication errors")); next = next.forward; } } else { completed = true; if (handle != null) handle.Set (); if (cb != null) ThreadPool.UnsafeQueueUserWorkItem (InvokeCB, this); } } }
internal AsyncRequestContext(ListenerAsyncResult result) { m_Result = result; BaseConstruction(Allocate(0)); }
public IAsyncResult BeginGetContext(AsyncCallback callback, object state) { if (Logging.On) { Logging.Enter(Logging.HttpListener, this, "BeginGetContext", ""); } ListenerAsyncResult objectValue = null; try { this.CheckDisposed(); if (this.m_State == null) { throw new InvalidOperationException(SR.GetString("net_listener_mustcall", new object[] { "Start()" })); } objectValue = new ListenerAsyncResult(this, state, callback); uint num = objectValue.QueueBeginGetContext(); if ((num != 0) && (num != 0x3e5)) { throw new HttpListenerException((int) num); } } catch (Exception exception) { if (Logging.On) { Logging.Exception(Logging.HttpListener, this, "BeginGetContext", exception); } throw; } finally { if (Logging.On) { Logging.Enter(Logging.HttpListener, this, "BeginGetContext", "IAsyncResult#" + ValidationHelper.HashString(objectValue)); } } return objectValue; }
internal void Complete(HttpListenerContext context, bool synch) { if (_forward != null) { _forward.Complete(context, synch); return; } _synch = synch; _context = context; lock (_locker) { bool authFailure = false; try { context.AuthenticationSchemes = context._listener.SelectAuthenticationScheme(context); } catch (OutOfMemoryException oom) { context.AuthenticationSchemes = AuthenticationSchemes.Anonymous; _exception = oom; } catch { authFailure = true; context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; } if (context.AuthenticationSchemes != AuthenticationSchemes.None && (context.AuthenticationSchemes & AuthenticationSchemes.Anonymous) != AuthenticationSchemes.Anonymous && (context.AuthenticationSchemes & AuthenticationSchemes.Basic) != AuthenticationSchemes.Basic) { authFailure = true; context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; } else if (context.AuthenticationSchemes == AuthenticationSchemes.Basic) { HttpStatusCode errorCode = HttpStatusCode.Unauthorized; string authHeader = context.Request.Headers["Authorization"]; if (authHeader == null || !HttpListenerContext.IsBasicHeader(authHeader) || authHeader.Length < AuthenticationTypes.Basic.Length + 2 || !HttpListenerContext.TryParseBasicAuth(authHeader.Substring(AuthenticationTypes.Basic.Length + 1), out errorCode, out string _, out string __)) { authFailure = true; context.Response.StatusCode = (int)errorCode; if (errorCode == HttpStatusCode.Unauthorized) { context.Response.Headers["WWW-Authenticate"] = context.AuthenticationSchemes + " realm=\"" + context._listener.Realm + "\""; } } } if (authFailure) { context.Response.OutputStream.Close(); IAsyncResult ares = context._listener.BeginGetContext(_cb, _state); _forward = (ListenerAsyncResult)ares; lock (_forward._locker) { if (_handle != null) { _forward._handle = _handle; } } ListenerAsyncResult next = _forward; for (int i = 0; next._forward != null; i++) { if (i > 20) { Complete(new HttpListenerException((int)HttpStatusCode.Unauthorized, SR.net_listener_auth_errors)); } next = next._forward; } } else { _completed = true; _synch = false; if (_handle != null) { _handle.Set(); } if (_cb != null) { ThreadPool.UnsafeQueueUserWorkItem(s_invokeCB, this); } } } }
public IAsyncResult BeginGetContext(AsyncCallback callback, object state) { if(Logging.On)Logging.Enter(Logging.HttpListener, this, "BeginGetContext", ""); ListenerAsyncResult asyncResult = null; try { CheckDisposed(); if (m_State==State.Stopped) { throw new InvalidOperationException(SR.GetString(SR.net_listener_mustcall, "Start()")); } // 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 ListenerAsyncResult(this, state, callback); 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 throw new HttpListenerException((int)statusCode); } } catch (Exception exception) { if(Logging.On)Logging.Exception(Logging.HttpListener, this, "BeginGetContext", exception); throw; } finally { if(Logging.On)Logging.Enter(Logging.HttpListener, this, "BeginGetContext", "IAsyncResult#" + ValidationHelper.HashString(asyncResult)); } return asyncResult; }