예제 #1
0
        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.
        }
예제 #2
0
        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;
        }
예제 #3
0
        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);
                    }
                }
            }
        }
예제 #4
0
        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);
                    }
                }
            }
        }