2 // System.Net.ListenerAsyncResult
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // Copyright (c) 2005 Ximian, Inc (http://www.ximian.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System
.Threading
;
34 namespace System
.Net
{
35 class ListenerAsyncResult
: IAsyncResult
{
36 ManualResetEvent handle
;
42 HttpListenerContext context
;
43 object locker
= new object ();
44 ListenerAsyncResult forward
;
45 internal bool EndCalled
;
48 public ListenerAsyncResult (AsyncCallback cb
, object state
)
54 internal void Complete (Exception exc
)
56 if (forward
!= null) {
57 forward
.Complete (exc
);
61 if (InGet
&& (exc
is ObjectDisposedException
))
62 exception
= new HttpListenerException (500, "Listener closed");
69 ThreadPool
.UnsafeQueueUserWorkItem (InvokeCB
, this);
73 static WaitCallback InvokeCB
= new WaitCallback (InvokeCallback
);
74 static void InvokeCallback (object o
)
76 ListenerAsyncResult ares
= (ListenerAsyncResult
) o
;
77 if (ares
.forward
!= null) {
78 InvokeCallback (ares
.forward
);
87 internal void Complete (HttpListenerContext context
)
89 Complete (context
, false);
92 internal void Complete (HttpListenerContext context
, bool synch
)
94 if (forward
!= null) {
95 forward
.Complete (context
, synch
);
99 this.context
= context
;
101 AuthenticationSchemes schemes
= context
.Listener
.SelectAuthenticationScheme (context
);
102 if ((schemes
== AuthenticationSchemes
.Basic
|| context
.Listener
.AuthenticationSchemes
== AuthenticationSchemes
.Negotiate
) && context
.Request
.Headers
["Authorization"] == null) {
103 context
.Response
.StatusCode
= 401;
104 context
.Response
.Headers
["WWW-Authenticate"] = schemes
+ " realm=\"" + context
.Listener
.Realm
+ "\"";
105 context
.Response
.OutputStream
.Close ();
106 IAsyncResult ares
= context
.Listener
.BeginGetContext (cb
, state
);
107 this.forward
= (ListenerAsyncResult
) ares
;
108 lock (forward
.locker
) {
110 forward
.handle
= handle
;
112 ListenerAsyncResult next
= forward
;
113 for (int i
= 0; next
.forward
!= null; i
++) {
115 Complete (new HttpListenerException (400, "Too many authentication errors"));
126 ThreadPool
.UnsafeQueueUserWorkItem (InvokeCB
, this);
131 internal HttpListenerContext
GetContext ()
134 return forward
.GetContext ();
135 if (exception
!= null)
141 public object AsyncState
{
144 return forward
.AsyncState
;
149 public WaitHandle AsyncWaitHandle
{
152 return forward
.AsyncWaitHandle
;
156 handle
= new ManualResetEvent (completed
);
163 public bool CompletedSynchronously
{
166 return forward
.CompletedSynchronously
;
172 public bool IsCompleted
{
175 return forward
.IsCompleted
;