X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem%2FSystem.Net%2FListenerAsyncResult.cs;h=c0b6854a2d3c198479a1e80846cd73919824f947;hb=9cb87907d7629f7dddc9d27a757446b73071822f;hp=f926f8d46f03ff20bf7b7c8f2d37b7ae55e50d2e;hpb=7da033a75a92da379a8fbf862ef31a901a1b4c6f;p=mono.git diff --git a/mcs/class/System/System.Net/ListenerAsyncResult.cs b/mcs/class/System/System.Net/ListenerAsyncResult.cs index f926f8d46f0..c0b6854a2d3 100644 --- a/mcs/class/System/System.Net/ListenerAsyncResult.cs +++ b/mcs/class/System/System.Net/ListenerAsyncResult.cs @@ -41,6 +41,7 @@ namespace System.Net { Exception exception; HttpListenerContext context; object locker = new object (); + ListenerAsyncResult forward; public ListenerAsyncResult (AsyncCallback cb, object state) { @@ -50,6 +51,10 @@ namespace System.Net { internal void Complete (string error) { + if (forward != null) { + forward.Complete (error); + return; + } //FIXME: error_code? exception = new HttpListenerException (0, error); lock (locker) { @@ -65,7 +70,14 @@ namespace System.Net { static void InvokeCallback (object o) { ListenerAsyncResult ares = (ListenerAsyncResult) o; - ares.cb (ares); + if (ares.forward != null) { + InvokeCallback (ares.forward); + return; + } + try { + ares.cb (ares); + } catch { + } } internal void Complete (HttpListenerContext context) @@ -75,20 +87,45 @@ namespace System.Net { internal void Complete (HttpListenerContext context, bool synch) { + if (forward != null) { + forward.Complete (context, synch); + return; + } this.synch = synch; this.context = context; lock (locker) { - completed = true; - if (handle != null) - handle.Set (); - - if (cb != null) - ThreadPool.QueueUserWorkItem (InvokeCallback, this); + 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 ("Too many authentication errors"); + next = next.forward; + } + } else { + completed = true; + if (handle != null) + handle.Set (); + + if (cb != null) + ThreadPool.QueueUserWorkItem (InvokeCallback, this); + } } } internal HttpListenerContext GetContext () { + if (forward != null) + return forward.GetContext (); if (exception != null) throw exception; @@ -96,11 +133,18 @@ namespace System.Net { } public object AsyncState { - get { return state; } + get { + if (forward != null) + return forward.AsyncState; + return state; + } } public WaitHandle AsyncWaitHandle { get { + if (forward != null) + return forward.AsyncWaitHandle; + lock (locker) { if (handle == null) handle = new ManualResetEvent (completed); @@ -111,11 +155,19 @@ namespace System.Net { } public bool CompletedSynchronously { - get { return synch; } + get { + if (forward != null) + return forward.CompletedSynchronously; + return synch; + } + } public bool IsCompleted { get { + if (forward != null) + return forward.IsCompleted; + lock (locker) { return completed; }