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); }
/// <summary> /// Begins the asynchronous operation of retrieving an HTTP conext /// </summary> /// <param name="callback">The callback.</param> /// <param name="state">The state.</param> /// <returns></returns> /// <exception cref="System.InvalidOperationException">Please, call Start before using this method.</exception> public IAsyncResult BeginGetContext(AsyncCallback callback, object state) { CheckDisposed(); if (!IsListening) throw new InvalidOperationException("Please, call Start before using this method."); var ares = new ListenerAsyncResult(callback, state); // lock wait_queue early to avoid race conditions lock (_waitQueue) { lock (_ctxQueue) { var ctx = GetContextFromQueue(); if (ctx != null) { ares.Complete(ctx, true); return ares; } } _waitQueue.Add(ares); } return ares; }
internal void Complete(HttpListenerContext context, bool synch) { #if AUTHENTICATION if (_forward != null) { _forward.Complete(context, synch); return; } #endif _synch = synch; _context = context; lock (_locker) { #if AUTHENTICATION var 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.Dispose(); var ares = context.Listener.BeginGetContext(_cb, _state); _forward = (ListenerAsyncResult) ares; lock (_forward._locker) { if (_handle != null) _forward._handle = _handle; } var next = _forward; for (var i = 0; next._forward != null; i++) { if (i > 20) Complete(new HttpListenerException(400, "Too many authentication errors")); next = next._forward; } } else { #endif _completed = true; _synch = false; _handle?.Set(); if (_cb != null) ThreadPool.QueueUserWorkItem(_invokeCb, this); #if AUTHENTICATION } #endif } }