merge r67228-r67235, r67237, r67251 and r67256-67259 to trunk (they are
[mono.git] / mcs / class / System / Test / System.Net / HttpListenerTest.cs
1 //
2 // HttpListenerTest.cs
3 //      - Unit tests for System.Net.HttpListener
4 //
5 // Author:
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //
8 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 #if NET_2_0
30 using System;
31 using System.Net;
32 using System.Threading;
33 using NUnit.Framework;
34
35 namespace MonoTests.System.Net {
36         [TestFixture]
37         public class HttpListenerTest {
38                 [Test]
39                 public void DefaultProperties ()
40                 {
41                         HttpListener listener = new HttpListener ();
42                         Assert.AreEqual (AuthenticationSchemes.Anonymous, listener.AuthenticationSchemes, "#01");
43                         Assert.AreEqual (null, listener.AuthenticationSchemeSelectorDelegate, "#02");
44                         Assert.AreEqual (false, listener.IgnoreWriteExceptions, "#03");
45                         Assert.AreEqual (false, listener.IsListening, "#03");
46                         Assert.AreEqual (0, listener.Prefixes.Count, "#04");
47                         Assert.AreEqual (null, listener.Realm, "#05");
48                         Assert.AreEqual (false, listener.UnsafeConnectionNtlmAuthentication, "#06");
49                 }
50
51                 [Test]
52                 public void Start1 ()
53                 {
54                         HttpListener listener = new HttpListener ();
55                         listener.Start ();
56                 }
57
58                 [Test]
59                 public void Stop1 ()
60                 {
61                         HttpListener listener = new HttpListener ();
62                         listener.Stop ();
63                 }
64
65                 [Test]
66                 [ExpectedException (typeof (InvalidOperationException))]
67                 public void GetContext1 ()
68                 {
69                         HttpListener listener = new HttpListener ();
70                         // "Please call Start () before calling this method"
71                         listener.GetContext ();
72                 }
73
74                 [Test]
75                 [ExpectedException (typeof (InvalidOperationException))]
76                 public void GetContext2 ()
77                 {
78                         HttpListener listener = new HttpListener ();
79                         listener.Start ();
80                         // "Please call AddPrefix () before calling this method"
81                         listener.GetContext ();
82                 }
83
84                 [Test]
85                 [ExpectedException (typeof (InvalidOperationException))]
86                 public void BeginGetContext1 ()
87                 {
88                         HttpListener listener = new HttpListener ();
89                         // "Please call Start () before calling this method"
90                         listener.BeginGetContext (null, null);
91                 }
92
93                 [Test]
94                 public void BeginGetContext2 ()
95                 {
96                         HttpListener listener = new HttpListener ();
97                         listener.Start ();
98                         // One would expect this to fail as BeginGetContext1 does not fail and
99                         // calling EndGetContext will wait forever.
100                         // Lame. They should check that we have no prefixes.
101                         IAsyncResult ares = listener.BeginGetContext (null, null);
102                         Assert.IsFalse (ares.IsCompleted);
103                 }
104
105                 [Test]
106                 public void TwoListeners_SameAddress ()
107                 {
108                         HttpListener listener1 = new HttpListener ();
109                         listener1.Prefixes.Add ("http://127.0.0.1:7777/");
110                         HttpListener listener2 = new HttpListener ();
111                         listener2.Prefixes.Add ("http://127.0.0.1:7777/hola/");
112                         listener1.Start ();
113                         listener2.Start ();
114                 }
115
116                 [Test]
117                 [ExpectedException (typeof (HttpListenerException))]
118                 public void TwoListeners_SameURL ()
119                 {
120                         HttpListener listener1 = new HttpListener ();
121                         listener1.Prefixes.Add ("http://127.0.0.1:7777/hola/");
122                         HttpListener listener2 = new HttpListener ();
123                         listener2.Prefixes.Add ("http://127.0.0.1:7777/hola/");
124                         listener1.Start ();
125                         listener2.Start ();
126                 }
127
128                 [Test]
129                 [ExpectedException (typeof (HttpListenerException))]
130                 public void MultipleSlashes ()
131                 {
132                         HttpListener listener = new HttpListener ();
133                         listener.Prefixes.Add ("http://localhost:7777/hola////");
134                         // this one throws on Start(), not when adding it.
135                         listener.Start ();
136                 }
137
138                 [Test]
139                 [ExpectedException (typeof (HttpListenerException))]
140                 public void PercentSign ()
141                 {
142                         HttpListener listener = new HttpListener ();
143                         listener.Prefixes.Add ("http://localhost:7777/hola%3E/");
144                         // this one throws on Start(), not when adding it.
145                         listener.Start ();
146                 }
147
148                 [Test]
149                 public void CloseBeforeStart ()
150                 {
151                         HttpListener listener = new HttpListener ();
152                         listener.Close ();
153                 }
154
155                 [Test]
156                 public void CloseTwice ()
157                 {
158                         HttpListener listener = new HttpListener ();
159                         listener.Prefixes.Add ("http://localhost:7777/hola/");
160                         listener.Start ();
161                         listener.Close ();
162                         listener.Close ();
163                 }
164
165                 [Test]
166                 public void AbortBeforeStart ()
167                 {
168                         HttpListener listener = new HttpListener ();
169                         listener.Abort ();
170                 }
171
172                 [Test]
173                 public void AbortTwice ()
174                 {
175                         HttpListener listener = new HttpListener ();
176                         listener.Prefixes.Add ("http://localhost:7777/hola/");
177                         listener.Start ();
178                         listener.Abort ();
179                         listener.Abort ();
180                 }
181
182                 [Test]
183                 public void PropertiesWhenClosed1 ()
184                 {
185                         HttpListener listener = new HttpListener ();
186                         listener.Close ();
187                         Assert.AreEqual (AuthenticationSchemes.Anonymous, listener.AuthenticationSchemes, "#01");
188                         Assert.AreEqual (null, listener.AuthenticationSchemeSelectorDelegate, "#02");
189                         Assert.AreEqual (false, listener.IgnoreWriteExceptions, "#03");
190                         Assert.AreEqual (false, listener.IsListening, "#03");
191                         Assert.AreEqual (null, listener.Realm, "#05");
192                         Assert.AreEqual (false, listener.UnsafeConnectionNtlmAuthentication, "#06");
193                 }
194
195                 [Test]
196                 [ExpectedException (typeof (ObjectDisposedException))]
197                 public void PropertiesWhenClosed2 ()
198                 {
199                         HttpListener listener = new HttpListener ();
200                         listener.Close ();
201                         HttpListenerPrefixCollection p = listener.Prefixes;
202                 }
203
204                 [Test]
205                 [ExpectedException (typeof (ObjectDisposedException))]
206                 public void PropertiesWhenClosedSet1 ()
207                 {
208                         HttpListener listener = new HttpListener ();
209                         listener.Close ();
210                         listener.AuthenticationSchemes = AuthenticationSchemes.None;
211                 }
212
213                 [Test]
214                 [ExpectedException (typeof (ObjectDisposedException))]
215                 public void PropertiesWhenClosedSet2 ()
216                 {
217                         HttpListener listener = new HttpListener ();
218                         listener.Close ();
219                         listener.AuthenticationSchemeSelectorDelegate = null;
220                 }
221
222                 [Test]
223                 [ExpectedException (typeof (ObjectDisposedException))]
224                 public void PropertiesWhenClosedSet3 ()
225                 {
226                         HttpListener listener = new HttpListener ();
227                         listener.Close ();
228                         listener.IgnoreWriteExceptions = true;
229                 }
230
231                 [Test]
232                 [ExpectedException (typeof (ObjectDisposedException))]
233                 public void PropertiesWhenClosedSet4 ()
234                 {
235                         HttpListener listener = new HttpListener ();
236                         listener.Close ();
237                         listener.Realm = "hola";
238                 }
239
240                 [Test]
241                 [ExpectedException (typeof (ObjectDisposedException))]
242                 public void PropertiesWhenClosedSet5 ()
243                 {
244                         HttpListener listener = new HttpListener ();
245                         listener.Close ();
246                         listener.UnsafeConnectionNtlmAuthentication = true;
247                 }
248
249                 [Test]
250                 public void PropertiesWhenClosed3 ()
251                 {
252                         HttpListener listener = new HttpListener ();
253                         listener.Close ();
254                         Assert.IsFalse (listener.IsListening);
255                 }
256
257                 [Test]
258                 [Category ("NotWorking")]  // we throw a HttpListenerException
259                 public void CloseWhileBegin ()
260                 {
261                         HttpListener listener = new HttpListener ();
262                         listener.Prefixes.Add ("http://127.0.0.1:9001/closewhilebegin/");
263                         listener.Start ();
264                         CallMe cm = new CallMe ();
265                         listener.BeginGetContext (cm.Callback, listener);
266                         listener.Close ();
267                         if (false == cm.Event.WaitOne (3000, false))
268                                 Assert.Fail ("This should not time out.");
269                         Assert.IsNotNull (cm.Error);
270                         Assert.AreEqual (typeof (ObjectDisposedException), cm.Error.GetType (), "Exception type");
271                         cm.Dispose ();
272                 }
273
274                 [Test]
275                 [Category ("NotWorking")]  // we throw a HttpListenerException
276                 public void AbortWhileBegin ()
277                 {
278                         HttpListener listener = new HttpListener ();
279                         listener.Prefixes.Add ("http://127.0.0.1:9001/abortwhilebegin/");
280                         listener.Start ();
281                         CallMe cm = new CallMe ();
282                         listener.BeginGetContext (cm.Callback, listener);
283                         listener.Abort ();
284                         if (false == cm.Event.WaitOne (3000, false))
285                                 Assert.Fail ("This should not time out.");
286                         Assert.IsNotNull (cm.Error);
287                         Assert.AreEqual (typeof (ObjectDisposedException), cm.Error.GetType (), "Exception type");
288                         cm.Dispose ();
289                 }
290
291                 [Test]
292                 [ExpectedException (typeof (HttpListenerException))]
293                 public void CloseWhileGet ()
294                 {
295                         // "System.Net.HttpListener Exception : The I/O operation has been aborted
296                         // because of either a thread exit or an application request
297                         //   at System.Net.HttpListener.GetContext()
298                         //   at MonoTests.System.Net.HttpListenerTest.CloseWhileGet()
299
300                         HttpListener listener = new HttpListener ();
301                         listener.Prefixes.Add ("http://127.0.0.1:9001/closewhileget/");
302                         listener.Start ();
303                         RunMe rm = new RunMe (1000, new ThreadStart (listener.Close), new object [0]);
304                         rm.Start ();
305                         HttpListenerContext ctx = listener.GetContext ();
306                 }
307
308                 [Test]
309                 [ExpectedException (typeof (HttpListenerException))]
310                 public void AbortWhileGet ()
311                 {
312                         // "System.Net.HttpListener Exception : The I/O operation has been aborted
313                         // because of either a thread exit or an application request
314                         //   at System.Net.HttpListener.GetContext()
315                         //   at MonoTests.System.Net.HttpListenerTest.CloseWhileGet()
316
317                         HttpListener listener = new HttpListener ();
318                         listener.Prefixes.Add ("http://127.0.0.1:9001/abortwhileget/");
319                         listener.Start ();
320                         RunMe rm = new RunMe (1000, new ThreadStart (listener.Abort), new object [0]);
321                         rm.Start ();
322                         HttpListenerContext ctx = listener.GetContext ();
323                 }
324
325                 class RunMe {
326                         Delegate d;
327                         int delay_ms;
328                         object [] args;
329                         public object Result;
330
331                         public RunMe (int delay_ms, Delegate d, object [] args)
332                         {
333                                 this.delay_ms = delay_ms;
334                                 this.d = d;
335                                 this.args = args;
336                         }
337
338                         public void Start ()
339                         {
340                                 Thread th = new Thread (new ThreadStart (Run));
341                                 th.Start ();
342                         }
343
344                         void Run ()
345                         {
346                                 Thread.Sleep (delay_ms);
347                                 Result = d.DynamicInvoke (args);
348                         }
349                 }
350
351                 class CallMe {
352                         public ManualResetEvent Event = new ManualResetEvent (false);
353                         public bool Called;
354                         public HttpListenerContext Context;
355                         public Exception Error;
356
357                         public void Reset ()
358                         {
359                                 Called = false;
360                                 Context = null;
361                                 Error = null;
362                                 Event.Reset ();
363                         }
364
365                         public void Callback (IAsyncResult ares)
366                         {
367                                 Called = true;
368                                 if (ares == null) {
369                                         Error = new ArgumentNullException ("ares");
370                                         return;
371                                 }
372                                 
373                                 try {
374                                         HttpListener listener = (HttpListener) ares.AsyncState;
375                                         Context = listener.EndGetContext (ares);
376                                 } catch (Exception e) {
377                                         Error = e;
378                                 }
379                                 Event.Set ();
380                         }
381
382                         public void Dispose ()
383                         {
384                                 Event.Close ();
385                         }
386                 }
387         }
388 }
389 #endif
390