[System*] Throw a PlatformNotSupported exception when using the networking stack...
[mono-project.git] / mcs / class / System / Test / System.Net / HttpListener2Test.cs
blob51e2990c0d18129f63dc2a748c8aa79707e1f4fa
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.
30 using System;
31 using System.Collections.Generic;
32 using System.Globalization;
33 using System.IO;
34 using System.Net;
35 using System.Net.Sockets;
36 using System.Text;
37 using System.Threading;
39 using NUnit.Framework;
41 using MonoTests.Helpers;
43 // ***************************************************************************************
44 // NOTE: when adding prefixes, make then unique per test, as MS might take 'some time' to
45 // unregister it even after explicitly closing the listener.
46 // ***************************************************************************************
47 namespace MonoTests.System.Net {
49 [TestFixture]
50 public class HttpListener2Test {
52 private HttpListener _listener = null;
54 public class MyNetworkStream : NetworkStream {
55 public MyNetworkStream (Socket sock) : base (sock, true)
59 public Socket GetSocket ()
61 return Socket;
65 public static HttpListener CreateAndStartListener (string prefix)
67 HttpListener listener = new HttpListener ();
68 listener.Prefixes.Add (prefix);
69 listener.Start ();
70 return listener;
73 public static HttpListener CreateAndStartListener (string prefix, AuthenticationSchemes authSchemes)
75 HttpListener listener = new HttpListener ();
76 listener.AuthenticationSchemes = authSchemes;
77 listener.Prefixes.Add (prefix);
78 listener.Start ();
79 return listener;
82 public static MyNetworkStream CreateNS (int port)
84 return CreateNS (IPAddress.Loopback, port, 5000);
87 public static MyNetworkStream CreateNS (int port, int timeout_ms)
89 return CreateNS (IPAddress.Loopback, port, timeout_ms);
92 public static MyNetworkStream CreateNS (IPAddress ip, int port)
94 return CreateNS (ip, port, 5000);
97 public static MyNetworkStream CreateNS (IPAddress ip, int port, int timeout_ms)
99 Socket sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
100 sock.Connect (new IPEndPoint (ip, port));
101 sock.SendTimeout = timeout_ms;
102 sock.ReceiveTimeout = timeout_ms;
103 return new MyNetworkStream (sock);
106 public static void Send (Stream stream, string str)
108 byte [] bytes = Encoding.ASCII.GetBytes (str);
109 stream.Write (bytes, 0, bytes.Length);
112 public static string Receive (Stream stream, int size)
114 byte [] bytes = new byte [size];
115 int nread = stream.Read (bytes, 0, size);
116 return Encoding.ASCII.GetString (bytes, 0, nread);
119 public static string ReceiveWithTimeout (Stream stream, int size, int timeout, out bool timed_out)
121 byte [] bytes = new byte [size];
122 IAsyncResult ares = stream.BeginRead (bytes, 0, size, null, null);
123 timed_out = !ares.AsyncWaitHandle.WaitOne (timeout, false);
124 if (timed_out)
125 return null;
126 int nread = stream.EndRead (ares);
127 return Encoding.ASCII.GetString (bytes, 0, nread);
130 public static HttpListenerContext GetContextWithTimeout (HttpListener listener, int timeout, out bool timed_out)
132 IAsyncResult ares = listener.BeginGetContext (null, null);
133 timed_out = !ares.AsyncWaitHandle.WaitOne (timeout, false);
134 if (timed_out)
135 return null;
136 return listener.EndGetContext (ares);
139 [TearDown]
140 public void Dispose()
142 if (_listener != null) {
143 _listener.Close();
144 _listener = null;
148 [Test]
149 #if FEATURE_NO_BSD_SOCKETS
150 [ExpectedException (typeof (PlatformNotSupportedException))]
151 #endif
152 public void Test1 ()
154 var port = NetworkHelpers.FindFreePort ();
155 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test1/");
156 NetworkStream ns = CreateNS (port);
157 Send (ns, "GET / HTTP/1.1\r\n\r\n"); // No host
158 string response = Receive (ns, 512);
159 ns.Close ();
160 Assert.IsTrue(response.StartsWith ("HTTP/1.1 400"));
163 [Test]
164 #if FEATURE_NO_BSD_SOCKETS
165 [ExpectedException (typeof (PlatformNotSupportedException))]
166 #endif
167 public void Test2 ()
169 var port = NetworkHelpers.FindFreePort ();
170 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test2/");
171 NetworkStream ns = CreateNS (port);
172 Send (ns, "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n"); // no prefix
173 string response = Receive (ns, 512);
174 ns.Close ();
175 Assert.IsTrue(response.StartsWith ("HTTP/1.1 400"));
178 [Test]
179 #if FEATURE_NO_BSD_SOCKETS
180 [ExpectedException (typeof (PlatformNotSupportedException))]
181 #endif
182 public void Test3 ()
184 StringBuilder bad = new StringBuilder ();
185 for (int i = 0; i < 33; i++){
186 if (i != 13)
187 bad.Append ((char) i);
189 bad.Append ('(');
190 bad.Append (')');
191 bad.Append ('[');
192 bad.Append (']');
193 bad.Append ('<');
194 bad.Append ('>');
195 bad.Append ('@');
196 bad.Append (',');
197 bad.Append (';');
198 bad.Append (':');
199 bad.Append ('\\');
200 bad.Append ('"');
201 bad.Append ('/');
202 bad.Append ('?');
203 bad.Append ('=');
204 bad.Append ('{');
205 bad.Append ('}');
207 foreach (char b in bad.ToString ()){
208 var port = NetworkHelpers.FindFreePort ();
209 HttpListener listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test3/");
210 NetworkStream ns = CreateNS (port);
211 Send (ns, String.Format ("MA{0} / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n", b)); // bad method
213 string response = Receive (ns, 512);
214 ns.Close ();
215 listener.Close ();
216 Assert.IsTrue(response.StartsWith ("HTTP/1.1 400"), String.Format ("Failed on {0}", (int) b));
220 [Test]
221 #if FEATURE_NO_BSD_SOCKETS
222 [ExpectedException (typeof (PlatformNotSupportedException))]
223 #endif
224 public void Test4 ()
226 var port = NetworkHelpers.FindFreePort ();
227 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test4/");
228 NetworkStream ns = CreateNS (port);
229 Send (ns, "POST /test4/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n"); // length required
230 string response = Receive (ns, 512);
231 ns.Close ();
232 Assert.IsTrue(response.StartsWith ("HTTP/1.1 411"));
235 [Test]
236 #if FEATURE_NO_BSD_SOCKETS
237 [ExpectedException (typeof (PlatformNotSupportedException))]
238 #endif
239 public void Test5 ()
241 var port = NetworkHelpers.FindFreePort ();
242 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test5/");
243 NetworkStream ns = CreateNS (port);
244 Send (ns, "POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nTransfer-Encoding: pepe\r\n\r\n"); // not implemented
245 string response = Receive (ns, 512);
246 ns.Close ();
247 Assert.IsTrue(response.StartsWith ("HTTP/1.1 501"));
250 [Test]
251 #if FEATURE_NO_BSD_SOCKETS
252 [ExpectedException (typeof (PlatformNotSupportedException))]
253 #endif
254 public void Test6 ()
256 var port = NetworkHelpers.FindFreePort ();
257 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test6/");
258 NetworkStream ns = CreateNS (port);
259 // not implemented! This is against the RFC. Should be a bad request/length required
260 Send (ns, "POST /test6/ HTTP/1.1\r\nHost: 127.0.0.1\r\nTransfer-Encoding: identity\r\n\r\n");
261 string response = Receive (ns, 512);
262 ns.Close ();
263 Assert.IsTrue(response.StartsWith ("HTTP/1.1 501"));
266 [Test]
267 #if FEATURE_NO_BSD_SOCKETS
268 [ExpectedException (typeof (PlatformNotSupportedException))]
269 #endif
270 public void Test7 ()
272 var port = NetworkHelpers.FindFreePort ();
273 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test7/");
274 NetworkStream ns = CreateNS (port);
275 Send (ns, "POST /test7/ HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
276 HttpListenerContext ctx = _listener.GetContext ();
277 Send (ctx.Response.OutputStream, "%%%OK%%%");
278 ctx.Response.Close ();
279 string response = Receive (ns, 1024);
280 ns.Close ();
281 Assert.IsTrue(response.StartsWith ("HTTP/1.1 200"));
282 Assert.IsTrue(response.Contains ("Transfer-Encoding: chunked"));
285 [Test]
286 #if FEATURE_NO_BSD_SOCKETS
287 [ExpectedException (typeof (PlatformNotSupportedException))]
288 #endif
289 public void Test8 ()
291 var port = NetworkHelpers.FindFreePort ();
292 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test8/");
293 NetworkStream ns = CreateNS (port);
294 // Just like Test7, but 1.0
295 Send (ns, "POST /test8/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
296 HttpListenerContext ctx = _listener.GetContext ();
297 Send (ctx.Response.OutputStream, "%%%OK%%%");
298 ctx.Response.Close ();
299 string response = Receive (ns, 512);
300 ns.Close ();
301 Assert.IsTrue(response.StartsWith ("HTTP/1.1 200"));
302 Assert.IsTrue (-1 == response.IndexOf ("Transfer-Encoding: chunked"));
305 [Test]
306 #if FEATURE_NO_BSD_SOCKETS
307 [ExpectedException (typeof (PlatformNotSupportedException))]
308 #endif
309 public void Test9 ()
311 var port = NetworkHelpers.FindFreePort ();
312 // 1.0 + "Transfer-Encoding: chunked"
313 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test9/");
314 NetworkStream ns = CreateNS (port);
315 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");
316 bool timeout;
317 string response = ReceiveWithTimeout (ns, 512, 1000, out timeout);
318 ns.Close ();
319 Assert.IsFalse (timeout);
320 Assert.IsTrue(response.StartsWith ("HTTP/1.1 411"));
323 [Test]
324 #if FEATURE_NO_BSD_SOCKETS
325 [ExpectedException (typeof (PlatformNotSupportedException))]
326 #endif
327 public void Test10 ()
329 var port = NetworkHelpers.FindFreePort ();
330 // Same as Test9, but now we shutdown the socket for sending.
331 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test10/");
332 MyNetworkStream ns = CreateNS (port);
333 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");
334 ns.GetSocket ().Shutdown (SocketShutdown.Send);
335 bool timeout;
336 string response = ReceiveWithTimeout (ns, 512, 1000, out timeout);
337 ns.Close ();
338 Assert.IsFalse (timeout);
339 Assert.IsTrue(response.StartsWith ("HTTP/1.1 411"));
342 [Test]
343 #if FEATURE_NO_BSD_SOCKETS
344 [ExpectedException (typeof (PlatformNotSupportedException))]
345 #endif
346 public void Test11 ()
348 var port = NetworkHelpers.FindFreePort ();
349 // 0.9
350 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test11/");
351 MyNetworkStream ns = CreateNS (port);
352 Send (ns, "POST /test11/ HTTP/0.9\r\nHost: 127.0.0.1\r\n\r\n123");
353 ns.GetSocket ().Shutdown (SocketShutdown.Send);
354 string input = Receive (ns, 512);
355 ns.Close ();
356 Assert.IsTrue(input.StartsWith ("HTTP/1.1 400"));
359 [Test]
360 #if FEATURE_NO_BSD_SOCKETS
361 [ExpectedException (typeof (PlatformNotSupportedException))]
362 #endif
363 public void Test12 ()
365 var port = NetworkHelpers.FindFreePort ();
366 // 0.9
367 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test12/");
368 MyNetworkStream ns = CreateNS (port);
369 Send (ns, "POST /test12/ HTTP/0.9\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
370 ns.GetSocket ().Shutdown (SocketShutdown.Send);
371 string input = Receive (ns, 512);
372 ns.Close ();
373 Assert.IsTrue(input.StartsWith ("HTTP/1.1 400"));
376 [Test]
377 #if FEATURE_NO_BSD_SOCKETS
378 [ExpectedException (typeof (PlatformNotSupportedException))]
379 #endif
380 public void Test13 ()
382 var port = NetworkHelpers.FindFreePort ();
383 // 0.9
384 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test13/");
385 MyNetworkStream ns = CreateNS (port);
386 Send (ns, "GEt /test13/ HTTP/0.9\r\nHost: 127.0.0.1\r\n\r\n");
387 ns.GetSocket ().Shutdown (SocketShutdown.Send);
388 string input = Receive (ns, 512);
389 ns.Close ();
390 Assert.IsTrue(input.StartsWith ("HTTP/1.1 400"));
393 HttpListenerRequest test14_request;
394 ManualResetEvent test_evt;
395 bool test14_error;
396 [Test]
397 #if FEATURE_NO_BSD_SOCKETS
398 [ExpectedException (typeof (PlatformNotSupportedException))]
399 #endif
400 public void Test14 ()
402 var port = NetworkHelpers.FindFreePort ();
403 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test14/");
404 MyNetworkStream ns = CreateNS (port);
405 Send (ns, "POST /test14/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
406 HttpListenerContext c = _listener.GetContext ();
407 test14_request = c.Request;
408 test_evt = new ManualResetEvent (false);
409 Thread thread = new Thread (ReadToEnd);
410 thread.Start ();
411 if (test_evt.WaitOne (3000, false) == false) {
412 #if MONO_FEATURE_THREAD_ABORT
413 thread.Abort ();
414 #else
415 thread.Interrupt ();
416 #endif
417 test_evt.Close ();
418 Assert.IsTrue (false, "Timed out");
420 test_evt.Close ();
421 c.Response.Close ();
422 ns.Close ();
423 Assert.AreEqual ("123", read_to_end, "Did not get the expected input.");
426 string read_to_end;
427 void ReadToEnd ()
429 using (StreamReader r = new StreamReader (test14_request.InputStream)) {
430 read_to_end = r.ReadToEnd ();
431 test_evt.Set ();
435 [Test]
436 #if FEATURE_NO_BSD_SOCKETS
437 [ExpectedException (typeof (PlatformNotSupportedException))]
438 #endif
439 public void Test15 ()
441 var port = NetworkHelpers.FindFreePort ();
442 // 2 separate writes -> 2 packets. Body size > 8kB
443 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test15/");
444 MyNetworkStream ns = CreateNS (port);
445 Send (ns, "POST /test15/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 8888\r\n\r\n");
446 Thread.Sleep (800);
447 string data = new string ('a', 8888);
448 Send (ns, data);
449 HttpListenerContext c = _listener.GetContext ();
450 HttpListenerRequest req = c.Request;
451 using (StreamReader r = new StreamReader (req.InputStream)) {
452 read_to_end = r.ReadToEnd ();
454 Assert.AreEqual (read_to_end.Length, data.Length, "Wrong length");
455 Assert.IsTrue (data == read_to_end, "Wrong data");
456 c.Response.Close ();
457 ns.Close ();
460 [Test]
461 #if FEATURE_NO_BSD_SOCKETS
462 [ExpectedException (typeof (PlatformNotSupportedException))]
463 #endif
464 public void Test16 ()
466 var port = NetworkHelpers.FindFreePort ();
467 // 1 single write with headers + body (size > 8kB)
468 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test16/");
469 MyNetworkStream ns = CreateNS (port);
470 StringBuilder sb = new StringBuilder ();
471 sb.Append ("POST /test16/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 8888\r\n\r\n");
472 string eights = new string ('b', 8888);
473 sb.Append (eights);
474 string data = sb.ToString ();
475 Send (ns, data);
476 HttpListenerContext c = _listener.GetContext ();
477 HttpListenerRequest req = c.Request;
478 using (StreamReader r = new StreamReader (req.InputStream)) {
479 read_to_end = r.ReadToEnd ();
481 Assert.AreEqual (read_to_end.Length, read_to_end.Length, "Wrong length");
482 Assert.IsTrue (eights == read_to_end, "Wrong data");
483 c.Response.Close ();
484 ns.Close ();
487 [Test]
488 #if FEATURE_NO_BSD_SOCKETS
489 [ExpectedException (typeof (PlatformNotSupportedException))]
490 #endif
491 public void Test17 ()
493 var port = NetworkHelpers.FindFreePort ();
494 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test17/");
495 NetworkStream ns = CreateNS (port);
496 Send (ns, "RANDOM /test17/ HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
497 HttpListenerContext ctx = _listener.GetContext ();
498 Send (ctx.Response.OutputStream, "%%%OK%%%");
499 ctx.Response.Close ();
500 string response = Receive (ns, 1024);
501 ns.Close ();
502 Assert.IsTrue(response.StartsWith ("HTTP/1.1 200"));
503 Assert.IsTrue(response.Contains ("Transfer-Encoding: chunked"));
506 [Test]
507 #if FEATURE_NO_BSD_SOCKETS
508 [ExpectedException (typeof (PlatformNotSupportedException))]
509 #endif
510 public void Test_MultipleClosesOnOuputStreamAllowed ()
512 var port = NetworkHelpers.FindFreePort ();
513 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/MultipleCloses/");
514 NetworkStream ns = CreateNS (port);
515 Send (ns, "GET /MultipleCloses/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
517 HttpListenerContext ctx = _listener.GetContext ();
518 ctx.Response.OutputStream.Close ();
519 ctx.Response.OutputStream.Close ();
520 ctx.Response.OutputStream.Close ();
521 ctx.Response.Close ();
524 void SendCookie ()
526 NetworkStream ns = CreateNS (sendCookiePort);
527 Send (ns, "GET /SendCookie/ HTTP/1.1\r\nHost: 127.0.0.1\r\n"+
528 "Cookie:$Version=\"1\"; "+
529 "Cookie1=Value1; $Path=\"/\"; "+
530 "CookieM=ValueM; $Path=\"/p2\"; $Domain=\"test\"; $Port=\"99\";"+
531 "Cookie2=Value2; $Path=\"/foo\";"+
532 "\r\n"+
533 "\r\n");
534 ns.Flush ();
535 Thread.Sleep (200);
536 ns.Close();
539 [Test]
540 #if FEATURE_NO_BSD_SOCKETS
541 [ExpectedException (typeof (PlatformNotSupportedException))]
542 #endif
543 public void ReceiveCookiesFromClient ()
545 sendCookiePort = NetworkHelpers.FindFreePort ();
546 _listener = CreateAndStartListener ("http://127.0.0.1:" + sendCookiePort + "/SendCookie/");
547 Thread clientThread = new Thread (new ThreadStart (SendCookie));
548 clientThread.Start ();
550 HttpListenerContext context = _listener.GetContext();
551 HttpListenerRequest request = context.Request;
553 Assert.AreEqual (3, request.Cookies.Count, "#1");
554 foreach (Cookie c in request.Cookies) {
555 if (c.Name == "Cookie1") {
556 Assert.AreEqual ("Value1", c.Value, "#2");
557 Assert.AreEqual ("\"/\"", c.Path, "#3");
558 Assert.AreEqual (0, c.Port.Length, "#4");
559 Assert.AreEqual (0, c.Domain.Length, "#5");
560 } else if (c.Name == "CookieM") {
561 Assert.AreEqual ("ValueM", c.Value, "#6");
562 Assert.AreEqual ("\"/p2\"", c.Path, "#7");
563 Assert.AreEqual ("\"99\"", c.Port, "#8");
564 Assert.AreEqual ("\"test\"", c.Domain, "#9");
565 } else if (c.Name == "Cookie2") {
566 Assert.AreEqual ("Value2", c.Value, "#10");
567 Assert.AreEqual ("\"/foo\"", c.Path, "#11");
568 Assert.AreEqual (0, c.Port.Length, "#12");
569 Assert.AreEqual (0, c.Domain.Length, "#13");
570 } else
571 Assert.Fail ("Invalid cookie name " + c.Name);
575 private object _lock = new Object();
576 private string cookieResponse;
577 private int receiveCookiePort;
578 private int sendCookiePort;
580 void ReceiveCookie () {
581 lock (_lock) {
582 NetworkStream ns = CreateNS (receiveCookiePort);
583 Send (ns, "GET /ReceiveCookie/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
584 cookieResponse = Receive (ns, 512);
588 [Test]
589 #if FEATURE_NO_BSD_SOCKETS
590 [ExpectedException (typeof (PlatformNotSupportedException))]
591 #endif
592 public void SendCookiestoClient ()
594 receiveCookiePort = NetworkHelpers.FindFreePort ();
595 _listener = CreateAndStartListener ("http://127.0.0.1:" + receiveCookiePort + "/ReceiveCookie/");
596 Thread clientThread = new Thread (new ThreadStart (ReceiveCookie));
597 clientThread.Start ();
599 HttpListenerContext context = _listener.GetContext();
600 HttpListenerRequest request = context.Request;
601 HttpListenerResponse response = context.Response;
603 Cookie cookie = new Cookie ();
604 cookie.Name = "Name0";
605 cookie.Value = "Value0";
606 cookie.Domain = "blue";
607 cookie.Path = "/path/";
608 cookie.Port = "\"80\"";
609 cookie.Version = 1;
610 response.Cookies.Add (cookie);
612 string responseString = "<HTML><BODY>----</BODY></HTML>";
613 byte[] buffer = Encoding.UTF8.GetBytes(responseString);
614 response.ContentLength64 = buffer.Length;
615 Stream output = response.OutputStream;
616 output.Write(buffer, 0, buffer.Length);
617 output.Flush ();
618 response.Close();
620 lock (_lock) {
621 bool foundCookie = false;
622 foreach (String str in cookieResponse.Split ('\n')) {
623 if (!str.StartsWith ("Set-Cookie"))
624 continue;
625 Dictionary<string, String> dic = new Dictionary<string, String>();
626 foreach (String p in str.Substring (str.IndexOf (":") + 1).Split (';')) {
627 String[] parts = p.Split('=');
628 dic.Add (parts [0].Trim (), parts [1].Trim ());
630 Assert.AreEqual ("Value0", dic ["Name0"], "#1");
631 Assert.AreEqual ("blue", dic ["Domain"], "#2");
632 Assert.AreEqual ("\"/path/\"", dic ["Path"], "#3");
633 Assert.AreEqual ("\"80\"", dic ["Port"], "#4");
634 Assert.AreEqual ("1", dic ["Version"], "#5");
635 foundCookie = true;
636 break;
638 Assert.IsTrue (foundCookie, "#6");
642 [Test]
643 #if FEATURE_NO_BSD_SOCKETS
644 [ExpectedException (typeof (PlatformNotSupportedException))]
645 #endif
646 public void MultiResponses ()
648 echoServerPort = NetworkHelpers.FindFreePort ();
649 Thread srv = new Thread (new ThreadStart (EchoServer));
650 srv.Start ();
651 Thread.Sleep (200);
653 for (int i = 0; i < 10; i++) {
654 string payload = string.Format (CultureInfo.InvariantCulture,
655 "Client{0}", i);
657 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (
658 "http://localhost:" + echoServerPort + "/foobar/");
659 req.ServicePoint.Expect100Continue = false;
660 req.ServicePoint.UseNagleAlgorithm = false;
661 req.Method = "POST";
662 StreamWriter w = new StreamWriter (req.GetRequestStream ());
663 w.WriteLine (payload);
664 w.Close ();
666 HttpWebResponse resp = (HttpWebResponse) req.GetResponse ();
667 StreamReader r = new StreamReader (resp.GetResponseStream ());
668 Assert.AreEqual ("Hello, " + payload + "!", r.ReadToEnd ().Trim ());
669 r.Close ();
672 manualReset.Set ();
673 srv.Join ();
676 int echoServerPort;
677 void EchoServer ()
679 _listener = new HttpListener ();
680 _listener.Prefixes.Add ("http://*:" + echoServerPort + "/foobar/");
681 _listener.Start ();
683 manualReset = new ManualResetEvent (false);
685 IAsyncResult result = _listener.BeginGetContext (
686 new AsyncCallback (EchoCallback), _listener);
687 manualReset.WaitOne ();
690 void EchoCallback (IAsyncResult result)
692 HttpListener listener = (HttpListener) result.AsyncState;
693 HttpListenerContext context = listener.EndGetContext (result);
694 HttpListenerRequest req = context.Request;
695 StreamReader r = new StreamReader (req.InputStream);
696 string reqBody = r.ReadToEnd ().Trim ();
698 HttpListenerResponse resp = context.Response;
699 StreamWriter o = new StreamWriter (resp.OutputStream);
700 o.WriteLine ("Hello, " + reqBody + "!");
701 o.Close ();
703 listener.BeginGetContext (new AsyncCallback (EchoCallback), listener);
706 private ManualResetEvent manualReset;
710 [TestFixture]
711 public class HttpListenerBugs {
712 [Test]
713 #if FEATURE_NO_BSD_SOCKETS
714 [ExpectedException (typeof (PlatformNotSupportedException))]
715 #endif
716 public void TestNonChunkedAsync ()
718 var port = NetworkHelpers.FindFreePort ();
719 HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:" + port + "/");
721 listener.BeginGetContext (callback, listener);
723 HttpListener2Test.MyNetworkStream ns = HttpListener2Test.CreateNS (port);
724 string message = "<script>\n"+
725 " <!-- register the blueprint for our show-headers service -->\n"+
726 " <action verb=\"POST\" path=\"/host/register\">\n" +
727 " <blueprint>\n" +
728 " <assembly>dream.tutorial.show-headers</assembly>\n" +
729 " <class>MindTouch.Dream.Tutorial.ShowHeadersService</class>\n" +
730 " </blueprint>\n" +
731 " </action>\n" +
732 "\n" +
733 " <!-- instantiate it -->\n" +
734 " <action verb=\"POST\" path=\"/host/start\">\n" +
735 " <config>\n" +
736 " <path>show-headers</path>\n" +
737 " <class>MindTouch.Dream.Tutorial.ShowHeadersService</class>\n" +
738 " </config>\n" +
739 " </action>\n" +
740 "</script>";
741 string s = String.Format ("POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: {0}\r\n\r\n{1}",
742 message.Length, message);
743 HttpListener2Test.Send (ns, s);
744 bool timedout;
745 string response = HttpListener2Test.ReceiveWithTimeout (ns, 1024, 3000, out timedout);
746 ns.Close ();
747 listener.Close ();
748 Assert.IsFalse (timedout);
751 void callback (IAsyncResult ar)
753 HttpListener l = (HttpListener) ar.AsyncState;
755 HttpListenerContext c = l.EndGetContext (ar);
756 HttpListenerRequest request = c.Request;
758 StreamReader r = new StreamReader (request.InputStream);
759 string sr =r.ReadToEnd ();
760 HttpListener2Test.Send (c.Response.OutputStream, "Miguel is love");
761 c.Response.Close ();
765 // As it turns out, when we closed the OutputStream,
766 // we were not shutting down the connection, which was
767 // a documented pattern to close the connection
769 [Test]
770 #if FEATURE_NO_BSD_SOCKETS
771 [ExpectedException (typeof (PlatformNotSupportedException))]
772 #endif
773 public void Test_MultipleConnections ()
775 var port = NetworkHelpers.FindFreePort ();
776 HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:" + port + "/multiple/");
778 // First one
779 NetworkStream ns = HttpListener2Test.CreateNS (port);
780 HttpListener2Test.Send (ns, "POST /multiple/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
781 HttpListenerContext ctx = listener.GetContext ();
782 HttpListener2Test.Send (ctx.Response.OutputStream, "%%%OK%%%");
783 ctx.Response.OutputStream.Close ();
784 string response = HttpListener2Test.Receive (ns, 1024);
785 ns.Close ();
787 // Second one
788 ns = HttpListener2Test.CreateNS (port);
789 HttpListener2Test.Send (ns, "POST /multiple/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
790 ctx = listener.GetContext ();
791 HttpListener2Test.Send (ctx.Response.OutputStream, "%%%OK%%%");
792 ctx.Response.OutputStream.Close ();
793 response = HttpListener2Test.Receive (ns, 1024);
794 ns.Close ();
796 listener.Close ();
800 // Test case for bug 341443, an pretty old bug, filed on November of 2007.
802 [Test]
803 #if FEATURE_NO_BSD_SOCKETS
804 [ExpectedException (typeof (PlatformNotSupportedException))]
805 #endif
806 public void Test_HostInUri ()
808 var wait = new ManualResetEvent (false);
809 var wait2 = new ManualResetEvent (false);
810 var port = NetworkHelpers.FindFreePort ();
812 Thread t = new Thread (delegate (object a) {
813 wait.WaitOne ();
815 NetworkStream ns = HttpListener2Test.CreateNS (port);
816 HttpListener2Test.Send (ns, "GET http://www.google.com/ HTTP/1.1\r\nHost: www.google.com\r\nContent-Length: 3\r\n\r\n123456");
818 wait2.WaitOne ();
819 ns.Close ();
821 t.Start ();
823 HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://*:" + port + "/");
824 wait.Set ();
825 HttpListenerContext ctx = listener.GetContext ();
827 Assert.AreEqual ("http://www.google.com:" + port + "/", ctx.Request.Url.ToString ());
828 Assert.AreEqual ("http://www.google.com/", ctx.Request.RawUrl);
829 wait2.Set ();
831 listener.Close ();
834 [Test] // bug #513849
835 #if FEATURE_NO_BSD_SOCKETS
836 [ExpectedException (typeof (PlatformNotSupportedException))]
837 #endif
838 public void ClosePort ()
840 var port = NetworkHelpers.FindFreePort ();
841 var h = new HttpListener ();
842 h.Prefixes.Add ("http://127.0.0.1:" + port + "/");
843 h.Start ();
844 h.BeginGetContext (null, null);
845 h.Stop ();
846 TcpListener t = new TcpListener (IPAddress.Parse ("127.0.0.1"), port);
847 t.Start ();
848 t.Stop ();
852 // Bugs: #17204, #10818
854 // Sadly, on Unix, if there are different calls to bind
855 // like *:port and host:port that is not an error,
856 // it would only be an error if host:port is done twice, so
857 // the best we can hope for is that listening on a specific interface
858 // does not also listen to another interface.
860 [Test]
861 #if FEATURE_NO_BSD_SOCKETS
862 [ExpectedException (typeof (PlatformNotSupportedException))]
863 #endif
864 public void BindToSingleInterface ()
866 IPAddress [] machineAddress = null;
868 try {
869 machineAddress = Dns.GetHostAddresses (Dns.GetHostName ());
870 } catch (SocketException){
871 // The build hosts sometimes can not resolve the hostname
872 Assert.Ignore ("Hostname couldn't be resolved.");
875 int port = NetworkHelpers.FindFreePort ();;
876 var h = new HttpListener ();
877 h.Prefixes.Add ("http://" + machineAddress [0] + ":" + port + "/");
878 h.Start ();
880 try {
881 var c = new TcpClient ("localhost", port);
882 Assert.Fail ("The TcpClient should have failed to connect since HttpListener is not listening on localhost");
883 } catch (SocketException){
884 // Pass
886 h.Stop ();
889 [Test]
890 #if FEATURE_NO_BSD_SOCKETS
891 [ExpectedException (typeof (PlatformNotSupportedException))]
892 #endif
893 public void BindToAllInterfaces ()
895 var h = new HttpListener ();
896 int port = NetworkHelpers.FindFreePort ();
897 h.Prefixes.Add ("http://*:" + port + "/");
898 h.Start ();
899 var c = new TcpClient ("localhost", port);
900 h.Stop ();
903 // Test case for bug #31209
904 [Test]
905 #if FEATURE_NO_BSD_SOCKETS
906 [ExpectedException (typeof (PlatformNotSupportedException))]
907 #endif
908 public void Test_EmptyLineAtStart ()
910 var port = NetworkHelpers.FindFreePort ();
911 var listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:" + port + "/");
912 var ns = HttpListener2Test.CreateNS (port);
914 HttpListener2Test.Send (ns, "\r\nGET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
916 bool timedout;
917 HttpListener2Test.GetContextWithTimeout (listener, 1000, out timedout);
919 Assert.IsFalse (timedout, "timed out");
921 ns.Close ();
922 listener.Close ();