merge 99762:100015
[mono.git] / mcs / class / System / Test / System.Net / HttpListener2Test.cs
1 //
2 // HttpListener2Test.cs
3 //      - Unit tests for System.Net.HttpListener - connection testing
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.Collections.Generic;
32 using System.IO;
33 using System.Net;
34 using System.Net.Sockets;
35 using System.Text;
36 using System.Threading;
37 using NUnit.Framework;
38
39 // ***************************************************************************************
40 // NOTE: when adding prefixes, make then unique per test, as MS might take 'some time' to
41 // unregister it even after explicitly closing the listener.
42 // ***************************************************************************************
43 namespace MonoTests.System.Net {
44         [TestFixture]
45 #if TARGET_JVM  
46         [Ignore ("The class HttpListener is not supported")]
47 #endif
48         public class HttpListener2Test {
49                 public class MyNetworkStream : NetworkStream {
50                         public MyNetworkStream (Socket sock) : base (sock, true)
51                         {
52                         }
53
54                         public Socket GetSocket ()
55                         {
56                                 return Socket;
57                         }
58                 }
59
60                 public static HttpListener CreateAndStartListener (string prefix)
61                 {
62                         HttpListener listener = new HttpListener ();
63                         listener.Prefixes.Add (prefix);
64                         listener.Start ();
65                         return listener;
66                 }
67
68                 public static HttpListener CreateAndStartListener (string prefix, AuthenticationSchemes authSchemes)
69                 {
70                         HttpListener listener = new HttpListener ();
71                         listener.AuthenticationSchemes = authSchemes;
72                         listener.Prefixes.Add (prefix);
73                         listener.Start ();
74                         return listener;
75                 }
76
77                 public static MyNetworkStream CreateNS (int port)
78                 {
79                         Socket sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
80                         sock.Connect (new IPEndPoint (IPAddress.Loopback, port));
81                         return new MyNetworkStream (sock);
82                 }
83
84                 public static void Send (Stream stream, string str)
85                 {
86                         byte [] bytes = Encoding.ASCII.GetBytes (str);
87                         stream.Write (bytes, 0, bytes.Length);
88                 }
89
90                 public static string Receive (Stream stream, int size)
91                 {
92                         byte [] bytes = new byte [size];
93                         int nread = stream.Read (bytes, 0, size);
94                         return Encoding.ASCII.GetString (bytes, 0, nread);
95                 }
96
97                 public static string ReceiveWithTimeout (Stream stream, int size, int timeout, out bool timed_out)
98                 {
99                         byte [] bytes = new byte [size];
100                         IAsyncResult ares = stream.BeginRead (bytes, 0, size, null, null);
101                         timed_out = !ares.AsyncWaitHandle.WaitOne (timeout, false);
102                         if (timed_out)
103                                 return null;
104                         int nread = stream.EndRead (ares);
105                         return Encoding.ASCII.GetString (bytes, 0, nread);
106                 }
107
108                 public static HttpListenerContext GetContextWithTimeout (HttpListener listener, int timeout, out bool timed_out)
109                 {
110                         IAsyncResult ares = listener.BeginGetContext (null, null);
111                         timed_out = !ares.AsyncWaitHandle.WaitOne (timeout, false);
112                         if (timed_out)
113                                 return null;
114                         return listener.EndGetContext (ares);
115                 }
116
117                 [Test]
118                 public void Test1 ()
119                 {
120                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test1/");
121                         NetworkStream ns = CreateNS (9000);
122                         Send (ns, "GET / HTTP/1.1\r\n\r\n"); // No host
123                         string response = Receive (ns, 512);
124                         ns.Close ();
125                         listener.Close ();
126                         Assert.IsTrue (response.StartsWith ("HTTP/1.1 400"));
127                 }
128
129                 [Test]
130                 public void Test2 ()
131                 {
132                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test2/");
133                         NetworkStream ns = CreateNS (9000);
134                         Send (ns, "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n"); // no prefix
135                         string response = Receive (ns, 512);
136                         ns.Close ();
137                         listener.Close ();
138                         Assert.IsTrue (response.StartsWith ("HTTP/1.1 400"));
139                 }
140
141                 [Test]
142                 public void Test3 ()
143                 {
144                         StringBuilder bad = new StringBuilder ();
145                         for (int i = 0; i < 33; i++){
146                                 if (i != 13)
147                                         bad.Append ((char) i);
148                         }
149                         bad.Append ('(');
150                         bad.Append (')');
151                         bad.Append ('[');
152                         bad.Append (']');
153                         bad.Append ('<');
154                         bad.Append ('>');
155                         bad.Append ('@');
156                         bad.Append (',');
157                         bad.Append (';');
158                         bad.Append (':');
159                         bad.Append ('\\');
160                         bad.Append ('"');
161                         bad.Append ('/');
162                         bad.Append ('?');
163                         bad.Append ('=');
164                         bad.Append ('{');
165                         bad.Append ('}');
166
167                         foreach (char b in bad.ToString ()){
168                                 HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test3/");
169                                 NetworkStream ns = CreateNS (9000);
170                                 Send (ns, String.Format ("MA{0} / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n", b)); // bad method
171                                 
172                                 string response = Receive (ns, 512);
173                                 ns.Close ();
174                                 listener.Close ();
175                                 Assert.AreEqual (true, response.StartsWith ("HTTP/1.1 400"), String.Format ("Failed on {0}", (int) b));
176                         }
177                 }
178
179                 [Test]
180                 public void Test4 ()
181                 {
182                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test4/");
183                         NetworkStream ns = CreateNS (9000);
184                         Send (ns, "POST /test4/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n"); // length required
185                         string response = Receive (ns, 512);
186                         ns.Close ();
187                         listener.Close ();
188                         Assert.IsTrue (response.StartsWith ("HTTP/1.1 411"));
189                 }
190
191                 [Test]
192                 public void Test5 ()
193                 {
194                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test5/");
195                         NetworkStream ns = CreateNS (9000);
196                         Send (ns, "POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nTransfer-Encoding: pepe\r\n\r\n"); // not implemented
197                         string response = Receive (ns, 512);
198                         ns.Close ();
199                         listener.Close ();
200                         Assert.IsTrue (response.StartsWith ("HTTP/1.1 501"));
201                 }
202
203                 [Test]
204                 public void Test6 ()
205                 {
206                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test6/");
207                         NetworkStream ns = CreateNS (9000);
208                          // not implemented! This is against the RFC. Should be a bad request/length required
209                         Send (ns, "POST /test6/ HTTP/1.1\r\nHost: 127.0.0.1\r\nTransfer-Encoding: identity\r\n\r\n");
210                         string response = Receive (ns, 512);
211                         ns.Close ();
212                         listener.Close ();
213                         Assert.IsTrue (response.StartsWith ("HTTP/1.1 501"));
214                 }
215
216                 [Test]
217                 public void Test7 ()
218                 {
219                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test7/");
220                         NetworkStream ns = CreateNS (9000);
221                         Send (ns, "POST /test7/ HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
222                         HttpListenerContext ctx = listener.GetContext ();
223                         Send (ctx.Response.OutputStream, "%%%OK%%%");
224                         string response = Receive (ns, 1024);
225                         ns.Close ();
226                         listener.Close ();
227                         Assert.IsTrue (response.StartsWith ("HTTP/1.1 200"));
228                         Assert.IsTrue (-1 != response.IndexOf ("Transfer-Encoding: chunked"));
229                 }
230
231                 [Test]
232                 public void Test8 ()
233                 {
234                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test8/");
235                         NetworkStream ns = CreateNS (9000);
236                         // Just like Test7, but 1.0
237                         Send (ns, "POST /test8/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
238                         HttpListenerContext ctx = listener.GetContext ();
239                         Send (ctx.Response.OutputStream, "%%%OK%%%");
240                         string response = Receive (ns, 512);
241                         ns.Close ();
242                         listener.Close ();
243                         Assert.IsTrue (response.StartsWith ("HTTP/1.1 200"));
244                         Assert.IsTrue (-1 == response.IndexOf ("Transfer-Encoding: chunked"));
245                 }
246
247                 [Test]
248                 public void Test9 ()
249                 {
250                         // 1.0 + "Transfer-Encoding: chunked"
251                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test9/");
252                         NetworkStream ns = CreateNS (9000);
253                         Send (ns, "POST /test9/ HTTP/1.0\r\nHost: 127.0.0.1\r\nTransfer-Encoding: chunked\r\n\r\n3\r\n123\r\n0\r\n\r\n");
254                         bool timeout;
255                         string response = ReceiveWithTimeout (ns, 512, 1000, out timeout);
256                         Assert.IsFalse (timeout);
257                         listener.Close ();
258                         ns.Close ();
259                         Assert.IsTrue (response.StartsWith ("HTTP/1.1 411"));
260                 }
261
262                 [Test]
263                 public void Test10 ()
264                 {
265                         // Same as Test9, but now we shutdown the socket for sending.
266                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test10/");
267                         MyNetworkStream ns = CreateNS (9000);
268                         Send (ns, "POST /test10/ HTTP/1.0\r\nHost: 127.0.0.1\r\nTransfer-Encoding: chunked\r\n\r\n3\r\n123\r\n0\r\n\r\n");
269                         ns.GetSocket ().Shutdown (SocketShutdown.Send);
270                         bool timeout;
271                         string response = ReceiveWithTimeout (ns, 512, 1000, out timeout);
272                         Assert.IsFalse (timeout);
273                         listener.Close ();
274                         ns.Close ();
275                         Assert.IsTrue (response.StartsWith ("HTTP/1.1 411"));
276                 }
277
278                 [Test]
279                 public void Test11 ()
280                 {
281                         // 0.9
282                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test11/");
283                         MyNetworkStream ns = CreateNS (9000);
284                         Send (ns, "POST /test11/ HTTP/0.9\r\nHost: 127.0.0.1\r\n\r\n123");
285                         ns.GetSocket ().Shutdown (SocketShutdown.Send);
286                         string input = Receive (ns, 512);
287                         ns.Close ();
288                         listener.Close ();
289                         Assert.IsTrue (input.StartsWith ("HTTP/1.1 400"));
290                 }
291
292                 [Test]
293                 public void Test12 ()
294                 {
295                         // 0.9
296                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test12/");
297                         MyNetworkStream ns = CreateNS (9000);
298                         Send (ns, "POST /test12/ HTTP/0.9\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
299                         ns.GetSocket ().Shutdown (SocketShutdown.Send);
300                         string input = Receive (ns, 512);
301                         ns.Close ();
302                         listener.Close ();
303                         Assert.IsTrue (input.StartsWith ("HTTP/1.1 400"));
304                 }
305
306                 [Test]
307                 public void Test13 ()
308                 {
309                         // 0.9
310                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test13/");
311                         MyNetworkStream ns = CreateNS (9000);
312                         Send (ns, "GEt /test13/ HTTP/0.9\r\nHost: 127.0.0.1\r\n\r\n");
313                         ns.GetSocket ().Shutdown (SocketShutdown.Send);
314                         string input = Receive (ns, 512);
315                         ns.Close ();
316                         listener.Close ();
317                         Assert.IsTrue (input.StartsWith ("HTTP/1.1 400"));
318                 }
319
320                 HttpListenerRequest test14_request;
321                 ManualResetEvent test_evt;
322                 bool test14_error;
323                 [Test]
324                 public void Test14 ()
325                 {
326                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test14/");
327                         MyNetworkStream ns = CreateNS (9000);
328                         Send (ns, "POST /test14/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
329                         HttpListenerContext c = listener.GetContext ();
330                         test14_request = c.Request;
331                         test_evt = new ManualResetEvent (false);
332                         Thread thread = new Thread (ReadToEnd);
333                         thread.Start ();
334                         if (test_evt.WaitOne (3000, false) == false) {
335                                 thread.Abort ();
336                                 test_evt.Close ();
337                                 Assert.IsTrue (false, "Timed out");
338                         }
339                         test_evt.Close ();
340                         Assert.AreEqual ("123", read_to_end, "Did not get the expected input.");
341                         c.Response.Close ();
342                         ns.Close ();
343                 }
344
345                 string read_to_end;
346                 void ReadToEnd ()
347                 {
348                         using (StreamReader r = new StreamReader (test14_request.InputStream)) {
349                                 read_to_end = r.ReadToEnd ();
350                                 test_evt.Set ();
351                         }
352                 }
353
354                 [Test]
355                 public void Test15 ()
356                 {
357                         // 2 separate writes -> 2 packets. Body size > 8kB
358                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test15/");
359                         MyNetworkStream ns = CreateNS (9000);
360                         Send (ns, "POST /test15/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 8888\r\n\r\n");
361                         Thread.Sleep (800);
362                         string data = new string ('a', 8888);
363                         Send (ns, data);
364                         HttpListenerContext c = listener.GetContext ();
365                         HttpListenerRequest req = c.Request;
366                         using (StreamReader r = new StreamReader (req.InputStream)) {
367                                 read_to_end = r.ReadToEnd ();
368                         }
369                         Assert.AreEqual (read_to_end.Length, data.Length, "Wrong length");
370                         Assert.IsTrue (data == read_to_end, "Wrong data");
371                         c.Response.Close ();
372                         ns.Close ();
373                 }
374
375                 [Test]
376                 public void Test16 ()
377                 {
378                         // 1 single write with headers + body (size > 8kB)
379                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test16/");
380                         MyNetworkStream ns = CreateNS (9000);
381                         StringBuilder sb = new StringBuilder ();
382                         sb.Append ("POST /test16/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 8888\r\n\r\n");
383                         string eights = new string ('b', 8888);
384                         sb.Append (eights);
385                         string data = sb.ToString ();
386                         Send (ns, data);
387                         HttpListenerContext c = listener.GetContext ();
388                         HttpListenerRequest req = c.Request;
389                         using (StreamReader r = new StreamReader (req.InputStream)) {
390                                 read_to_end = r.ReadToEnd ();
391                         }
392                         Assert.AreEqual (read_to_end.Length, read_to_end.Length, "Wrong length");
393                         Assert.IsTrue (eights == read_to_end, "Wrong data");
394                         c.Response.Close ();
395                         ns.Close ();
396                 }
397
398                 [Test]
399                 public void Test17 ()
400                 {
401                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test17/");
402                         NetworkStream ns = CreateNS (9000);
403                         Send (ns, "RANDOM /test17/ HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
404                         HttpListenerContext ctx = listener.GetContext ();
405                         Send (ctx.Response.OutputStream, "%%%OK%%%");
406                         string response = Receive (ns, 1024);
407                         ns.Close ();
408                         listener.Close ();
409                         Assert.IsTrue (response.StartsWith ("HTTP/1.1 200"));
410                         Assert.IsTrue (-1 != response.IndexOf ("Transfer-Encoding: chunked"));
411                 }
412
413                 void SendCookie ()
414                 {
415                         NetworkStream ns = CreateNS (9000);
416                         Send (ns, "GET /SendCookie/ HTTP/1.1\r\nHost: 127.0.0.1\r\n"+
417                                 "Cookie:$Version=\"1\"; "+
418                                 "Cookie1=Value1; $Path=\"/\"; "+
419                                 "CookieM=ValueM; $Path=\"/p2\"; $Domain=\"test\"; $Port=\"99\";"+
420                                 "Cookie2=Value2; $Path=\"/foo\";"+
421                                 "\r\n"+
422                                 "\r\n");
423                         ns.Flush ();
424                         Thread.Sleep (200);
425                         ns.Close();
426                 }
427
428                 [Test]
429                 public void ReceiveCookiesFromClient ()
430                 {
431                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/SendCookie/");
432                         Thread clientThread = new Thread (new ThreadStart (SendCookie));
433                         clientThread.Start ();
434
435                         HttpListenerContext context = listener.GetContext();
436                         HttpListenerRequest request = context.Request;
437
438                         Assert.AreEqual (3, request.Cookies.Count, "#1");
439                         foreach (Cookie c in request.Cookies) {
440                                 if (c.Name == "Cookie1") {
441                                         Assert.AreEqual ("Value1", c.Value, "#2");
442                                         Assert.AreEqual ("\"/\"", c.Path, "#3");
443                                         Assert.AreEqual (0, c.Port.Length, "#4");
444                                         Assert.AreEqual (0, c.Domain.Length, "#5");
445                                 } else if (c.Name == "CookieM") {
446                                         Assert.AreEqual ("ValueM", c.Value, "#6");
447                                         Assert.AreEqual ("\"/p2\"", c.Path, "#7");
448                                         Assert.AreEqual ("\"99\"", c.Port, "#8");
449                                         Assert.AreEqual ("\"test\"", c.Domain, "#9");
450                                 } else if (c.Name == "Cookie2") {
451                                         Assert.AreEqual ("Value2", c.Value, "#10");
452                                         Assert.AreEqual ("\"/foo\"", c.Path, "#11");
453                                         Assert.AreEqual (0, c.Port.Length, "#12");
454                                         Assert.AreEqual (0, c.Domain.Length, "#13");
455                                 } else
456                                         Assert.Fail ("Invalid cookie name " + c.Name);
457                         }
458
459                         listener.Close ();
460                 }
461
462                 private object _lock = new Object();
463                 private string cookieResponse;
464
465                 void ReceiveCookie () {
466                         lock (_lock) {
467                                 NetworkStream ns = CreateNS (9000);
468                                 Send (ns, "GET /ReceiveCookie/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
469                                 cookieResponse = Receive (ns, 512);
470                         }
471                 }
472
473                 [Test]
474                 public void SendCookiestoClient ()
475                 {
476                         HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/ReceiveCookie/");
477                         Thread clientThread = new Thread (new ThreadStart (ReceiveCookie));
478                         clientThread.Start ();
479
480                         HttpListenerContext context = listener.GetContext();
481                         HttpListenerRequest request = context.Request;
482                         HttpListenerResponse response = context.Response;
483
484                         Cookie cookie = new Cookie ();
485                         cookie.Name = "Name0";
486                         cookie.Value = "Value0";
487                         cookie.Domain = "blue";
488                         cookie.Path = "/path/";
489                         cookie.Port = "\"80\"";
490                         cookie.Version = 1;
491                         response.Cookies.Add (cookie);
492
493                         string responseString = "<HTML><BODY>----</BODY></HTML>";
494                         byte[] buffer = Encoding.UTF8.GetBytes(responseString);
495                         response.ContentLength64 = buffer.Length;
496                         Stream output = response.OutputStream;
497                         output.Write(buffer, 0, buffer.Length);
498                         output.Flush ();
499                         response.Close();
500                         
501                         lock (_lock) {
502                                 bool foundCookie = false;
503                                 foreach (String str in cookieResponse.Split ('\n')) {
504                                         if (!str.StartsWith ("Set-Cookie2"))
505                                                 continue;
506                                         Dictionary<string, String> dic = new Dictionary<string, String>();
507                                         foreach (String p in str.Substring (str.IndexOf (":") + 1).Split (';')) {
508                                                 String[] parts = p.Split('=');
509                                                 dic.Add (parts [0].Trim (), parts [1].Trim ());
510                                         }
511                                         Assert.AreEqual ("Value0", dic ["Name0"], "#1");
512                                         Assert.AreEqual ("blue", dic ["Domain"], "#2");
513                                         Assert.AreEqual ("\"/path/\"", dic ["Path"], "#3");
514                                         Assert.AreEqual ("\"80\"", dic ["Port"], "#4");
515                                         Assert.AreEqual ("1", dic ["Version"], "#5");
516                                         foundCookie = true;
517                                         break;
518                                 }
519                                 Assert.IsTrue (foundCookie, "#6");
520                         }
521
522                         listener.Close ();
523                 }
524         }
525
526         [TestFixture]
527         public class HttpListenerBugs {
528                 [Test]
529                 public void TestNonChunkedAsync ()
530                 {
531                         HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:9123/");
532
533                         listener.BeginGetContext (callback, listener);
534                         
535                         HttpListener2Test.MyNetworkStream ns = HttpListener2Test.CreateNS (9123);
536                         string message = "<script>\n"+
537                                 " <!-- register the blueprint for our show-headers service -->\n"+
538                                 " <action verb=\"POST\" path=\"/host/register\">\n" +
539                                 "    <blueprint>\n" +
540                                 "      <assembly>dream.tutorial.show-headers</assembly>\n" +
541                                 "      <class>MindTouch.Dream.Tutorial.ShowHeadersService</class>\n" +
542                                 "    </blueprint>\n" +
543                                 "  </action>\n" +
544                                 "\n" +
545                                 "  <!-- instantiate it -->\n" +
546                                 "  <action verb=\"POST\" path=\"/host/start\">\n" +
547                                 "    <config>\n" +
548                                 "      <path>show-headers</path>\n" +
549                                 "      <class>MindTouch.Dream.Tutorial.ShowHeadersService</class>\n" +
550                                 "    </config>\n" +
551                                 "  </action>\n" +
552                                 "</script>";
553                         string s = String.Format ("POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: {0}\r\n\r\n{1}",
554                                                 message.Length, message);  
555                         HttpListener2Test.Send (ns, s);
556                         bool timedout;
557                         string response = HttpListener2Test.ReceiveWithTimeout (ns, 1024, 3000, out timedout);
558                         ns.Close ();
559                         Assert.IsFalse (timedout);
560                 }
561
562                 void callback (IAsyncResult ar)
563                 {
564                         HttpListener l = (HttpListener) ar.AsyncState;
565
566                         HttpListenerContext c = l.EndGetContext (ar);
567                         HttpListenerRequest request = c.Request;
568
569                         StreamReader r = new StreamReader (request.InputStream);
570                         string sr =r.ReadToEnd ();
571                         HttpListener2Test.Send (c.Response.OutputStream, "Miguel is love");
572                 }
573         }
574 }
575 #endif
576