Beispiel #1
0
        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);
        }
Beispiel #2
0
        /// <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
            }
        }