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. }
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; }
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; this.synch = false; if (handle != null) { handle.Set(); } if (cb != null) { ThreadPool.UnsafeQueueUserWorkItem(InvokeCB, this); } } } }