In corlib/System.Runtime.InteropServices:
[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 #if TARGET_JVM
38         [Ignore ("The class HttpListener is not implemented")]
39 #endif
40         public class HttpListenerTest {
41 #if !TARGET_JVM
42                 [Test]
43                 public void DefaultProperties ()
44                 {
45                         HttpListener listener = new HttpListener ();
46                         Assert.AreEqual (AuthenticationSchemes.Anonymous, listener.AuthenticationSchemes, "#01");
47                         Assert.AreEqual (null, listener.AuthenticationSchemeSelectorDelegate, "#02");
48                         Assert.AreEqual (false, listener.IgnoreWriteExceptions, "#03");
49                         Assert.AreEqual (false, listener.IsListening, "#03");
50                         Assert.AreEqual (0, listener.Prefixes.Count, "#04");
51                         Assert.AreEqual (null, listener.Realm, "#05");
52                         Assert.AreEqual (false, listener.UnsafeConnectionNtlmAuthentication, "#06");
53                 }
54
55                 [Test]
56                 public void Start1 ()
57                 {
58                         HttpListener listener = new HttpListener ();
59                         listener.Start ();
60                 }
61
62                 [Test]
63                 public void Stop1 ()
64                 {
65                         HttpListener listener = new HttpListener ();
66                         listener.Stop ();
67                 }
68
69                 [Test]
70                 [ExpectedException (typeof (InvalidOperationException))]
71                 public void GetContext1 ()
72                 {
73                         HttpListener listener = new HttpListener ();
74                         // "Please call Start () before calling this method"
75                         listener.GetContext ();
76                 }
77
78                 [Test]
79                 [ExpectedException (typeof (InvalidOperationException))]
80                 public void GetContext2 ()
81                 {
82                         HttpListener listener = new HttpListener ();
83                         listener.Start ();
84                         // "Please call AddPrefix () before calling this method"
85                         listener.GetContext ();
86                 }
87
88                 [Test]
89                 [ExpectedException (typeof (InvalidOperationException))]
90                 public void BeginGetContext1 ()
91                 {
92                         HttpListener listener = new HttpListener ();
93                         // "Please call Start () before calling this method"
94                         listener.BeginGetContext (null, null);
95                 }
96
97                 [Test]
98                 public void BeginGetContext2 ()
99                 {
100                         HttpListener listener = new HttpListener ();
101                         listener.Start ();
102                         // One would expect this to fail as BeginGetContext1 does not fail and
103                         // calling EndGetContext will wait forever.
104                         // Lame. They should check that we have no prefixes.
105                         IAsyncResult ares = listener.BeginGetContext (null, null);
106                         Assert.IsFalse (ares.IsCompleted);
107                 }
108
109                 [Test]
110                 public void TwoListeners_SameAddress ()
111                 {
112                         HttpListener listener1 = new HttpListener ();
113                         listener1.Prefixes.Add ("http://127.0.0.1:7777/");
114                         HttpListener listener2 = new HttpListener ();
115                         listener2.Prefixes.Add ("http://127.0.0.1:7777/hola/");
116                         listener1.Start ();
117                         listener2.Start ();
118                 }
119
120                 [Test]
121                 [ExpectedException (typeof (HttpListenerException))]
122                 public void TwoListeners_SameURL ()
123                 {
124                         HttpListener listener1 = new HttpListener ();
125                         listener1.Prefixes.Add ("http://127.0.0.1:7777/hola/");
126                         HttpListener listener2 = new HttpListener ();
127                         listener2.Prefixes.Add ("http://127.0.0.1:7777/hola/");
128                         listener1.Start ();
129                         listener2.Start ();
130                 }
131
132                 [Test]
133                 [ExpectedException (typeof (HttpListenerException))]
134                 public void MultipleSlashes ()
135                 {
136                         HttpListener listener = new HttpListener ();
137                         listener.Prefixes.Add ("http://localhost:7777/hola////");
138                         // this one throws on Start(), not when adding it.
139                         listener.Start ();
140                 }
141
142                 [Test]
143                 [ExpectedException (typeof (HttpListenerException))]
144                 public void PercentSign ()
145                 {
146                         HttpListener listener = new HttpListener ();
147                         listener.Prefixes.Add ("http://localhost:7777/hola%3E/");
148                         // this one throws on Start(), not when adding it.
149                         listener.Start ();
150                 }
151
152                 [Test]
153                 public void CloseBeforeStart ()
154                 {
155                         HttpListener listener = new HttpListener ();
156                         listener.Close ();
157                 }
158
159                 [Test]
160                 public void CloseTwice ()
161                 {
162                         HttpListener listener = new HttpListener ();
163                         listener.Prefixes.Add ("http://localhost:7777/hola/");
164                         listener.Start ();
165                         listener.Close ();
166                         listener.Close ();
167                 }
168
169                 [Test]
170                 public void AbortBeforeStart ()
171                 {
172                         HttpListener listener = new HttpListener ();
173                         listener.Abort ();
174                 }
175
176                 [Test]
177                 public void AbortTwice ()
178                 {
179                         HttpListener listener = new HttpListener ();
180                         listener.Prefixes.Add ("http://localhost:7777/hola/");
181                         listener.Start ();
182                         listener.Abort ();
183                         listener.Abort ();
184                 }
185
186                 [Test]
187                 public void PropertiesWhenClosed1 ()
188                 {
189                         HttpListener listener = new HttpListener ();
190                         listener.Close ();
191                         Assert.AreEqual (AuthenticationSchemes.Anonymous, listener.AuthenticationSchemes, "#01");
192                         Assert.AreEqual (null, listener.AuthenticationSchemeSelectorDelegate, "#02");
193                         Assert.AreEqual (false, listener.IgnoreWriteExceptions, "#03");
194                         Assert.AreEqual (false, listener.IsListening, "#03");
195                         Assert.AreEqual (null, listener.Realm, "#05");
196                         Assert.AreEqual (false, listener.UnsafeConnectionNtlmAuthentication, "#06");
197                 }
198
199                 [Test]
200                 [ExpectedException (typeof (ObjectDisposedException))]
201                 public void PropertiesWhenClosed2 ()
202                 {
203                         HttpListener listener = new HttpListener ();
204                         listener.Close ();
205                         HttpListenerPrefixCollection p = listener.Prefixes;
206                 }
207
208                 [Test]
209                 [ExpectedException (typeof (ObjectDisposedException))]
210                 public void PropertiesWhenClosedSet1 ()
211                 {
212                         HttpListener listener = new HttpListener ();
213                         listener.Close ();
214                         listener.AuthenticationSchemes = AuthenticationSchemes.None;
215                 }
216
217                 [Test]
218                 [ExpectedException (typeof (ObjectDisposedException))]
219                 public void PropertiesWhenClosedSet2 ()
220                 {
221                         HttpListener listener = new HttpListener ();
222                         listener.Close ();
223                         listener.AuthenticationSchemeSelectorDelegate = null;
224                 }
225
226                 [Test]
227                 [ExpectedException (typeof (ObjectDisposedException))]
228                 public void PropertiesWhenClosedSet3 ()
229                 {
230                         HttpListener listener = new HttpListener ();
231                         listener.Close ();
232                         listener.IgnoreWriteExceptions = true;
233                 }
234
235                 [Test]
236                 [ExpectedException (typeof (ObjectDisposedException))]
237                 public void PropertiesWhenClosedSet4 ()
238                 {
239                         HttpListener listener = new HttpListener ();
240                         listener.Close ();
241                         listener.Realm = "hola";
242                 }
243
244                 [Test]
245                 [ExpectedException (typeof (ObjectDisposedException))]
246                 public void PropertiesWhenClosedSet5 ()
247                 {
248                         HttpListener listener = new HttpListener ();
249                         listener.Close ();
250                         listener.UnsafeConnectionNtlmAuthentication = true;
251                 }
252
253                 [Test]
254                 public void PropertiesWhenClosed3 ()
255                 {
256                         HttpListener listener = new HttpListener ();
257                         listener.Close ();
258                         Assert.IsFalse (listener.IsListening);
259                 }
260
261                 [Test]
262                 [Category ("NotWorking")]  // we throw a HttpListenerException
263                 public void CloseWhileBegin ()
264                 {
265                         HttpListener listener = new HttpListener ();
266                         listener.Prefixes.Add ("http://127.0.0.1:9001/closewhilebegin/");
267                         listener.Start ();
268                         CallMe cm = new CallMe ();
269                         listener.BeginGetContext (cm.Callback, listener);
270                         listener.Close ();
271                         if (false == cm.Event.WaitOne (3000, false))
272                                 Assert.Fail ("This should not time out.");
273                         Assert.IsNotNull (cm.Error);
274                         Assert.AreEqual (typeof (ObjectDisposedException), cm.Error.GetType (), "Exception type");
275                         cm.Dispose ();
276                 }
277
278                 [Test]
279                 [Category ("NotWorking")]  // we throw a HttpListenerException
280                 public void AbortWhileBegin ()
281                 {
282                         HttpListener listener = new HttpListener ();
283                         listener.Prefixes.Add ("http://127.0.0.1:9001/abortwhilebegin/");
284                         listener.Start ();
285                         CallMe cm = new CallMe ();
286                         listener.BeginGetContext (cm.Callback, listener);
287                         listener.Abort ();
288                         if (false == cm.Event.WaitOne (3000, false))
289                                 Assert.Fail ("This should not time out.");
290                         Assert.IsNotNull (cm.Error);
291                         Assert.AreEqual (typeof (ObjectDisposedException), cm.Error.GetType (), "Exception type");
292                         cm.Dispose ();
293                 }
294
295                 [Test]
296                 [ExpectedException (typeof (HttpListenerException))]
297                 public void CloseWhileGet ()
298                 {
299                         // "System.Net.HttpListener Exception : The I/O operation has been aborted
300                         // because of either a thread exit or an application request
301                         //   at System.Net.HttpListener.GetContext()
302                         //   at MonoTests.System.Net.HttpListenerTest.CloseWhileGet()
303
304                         HttpListener listener = new HttpListener ();
305                         listener.Prefixes.Add ("http://127.0.0.1:9001/closewhileget/");
306                         listener.Start ();
307                         RunMe rm = new RunMe (1000, new ThreadStart (listener.Close), new object [0]);
308                         rm.Start ();
309                         HttpListenerContext ctx = listener.GetContext ();
310                 }
311
312                 [Test]
313                 [ExpectedException (typeof (HttpListenerException))]
314                 public void AbortWhileGet ()
315                 {
316                         // "System.Net.HttpListener Exception : The I/O operation has been aborted
317                         // because of either a thread exit or an application request
318                         //   at System.Net.HttpListener.GetContext()
319                         //   at MonoTests.System.Net.HttpListenerTest.CloseWhileGet()
320
321                         HttpListener listener = new HttpListener ();
322                         listener.Prefixes.Add ("http://127.0.0.1:9001/abortwhileget/");
323                         listener.Start ();
324                         RunMe rm = new RunMe (1000, new ThreadStart (listener.Abort), new object [0]);
325                         rm.Start ();
326                         HttpListenerContext ctx = listener.GetContext ();
327                 }
328
329                 class RunMe {
330                         Delegate d;
331                         int delay_ms;
332                         object [] args;
333                         public object Result;
334
335                         public RunMe (int delay_ms, Delegate d, object [] args)
336                         {
337                                 this.delay_ms = delay_ms;
338                                 this.d = d;
339                                 this.args = args;
340                         }
341
342                         public void Start ()
343                         {
344                                 Thread th = new Thread (new ThreadStart (Run));
345                                 th.Start ();
346                         }
347
348                         void Run ()
349                         {
350                                 Thread.Sleep (delay_ms);
351                                 Result = d.DynamicInvoke (args);
352                         }
353                 }
354
355                 class CallMe {
356                         public ManualResetEvent Event = new ManualResetEvent (false);
357                         public bool Called;
358                         public HttpListenerContext Context;
359                         public Exception Error;
360
361                         public void Reset ()
362                         {
363                                 Called = false;
364                                 Context = null;
365                                 Error = null;
366                                 Event.Reset ();
367                         }
368
369                         public void Callback (IAsyncResult ares)
370                         {
371                                 Called = true;
372                                 if (ares == null) {
373                                         Error = new ArgumentNullException ("ares");
374                                         return;
375                                 }
376                                 
377                                 try {
378                                         HttpListener listener = (HttpListener) ares.AsyncState;
379                                         Context = listener.EndGetContext (ares);
380                                 } catch (Exception e) {
381                                         Error = e;
382                                 }
383                                 Event.Set ();
384                         }
385
386                         public void Dispose ()
387                         {
388                                 Event.Close ();
389                         }
390                 }
391 #endif
392         }
393 }
394 #endif
395