2 // HttpListener2Test.cs
3 // - Unit tests for System.Net.HttpListener - connection testing
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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.
31 using System.Collections.Generic;
32 using System.Globalization;
35 using System.Net.Sockets;
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 {
50 [Category ("RequiresBSDSockets")]
51 public class HttpListener2Test {
53 private HttpListener _listener = null;
55 public class MyNetworkStream : NetworkStream {
56 public MyNetworkStream (Socket sock) : base (sock, true)
60 public Socket GetSocket ()
66 public static HttpListener CreateAndStartListener (string prefix)
68 HttpListener listener = new HttpListener ();
69 listener.Prefixes.Add (prefix);
74 public static HttpListener CreateAndStartListener (string prefix, AuthenticationSchemes authSchemes)
76 HttpListener listener = new HttpListener ();
77 listener.AuthenticationSchemes = authSchemes;
78 listener.Prefixes.Add (prefix);
83 public static MyNetworkStream CreateNS (int port)
85 return CreateNS (IPAddress.Loopback, port, 5000);
88 public static MyNetworkStream CreateNS (int port, int timeout_ms)
90 return CreateNS (IPAddress.Loopback, port, timeout_ms);
93 public static MyNetworkStream CreateNS (IPAddress ip, int port)
95 return CreateNS (ip, port, 5000);
98 public static MyNetworkStream CreateNS (IPAddress ip, int port, int timeout_ms)
100 Socket sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
101 sock.Connect (new IPEndPoint (ip, port));
102 sock.SendTimeout = timeout_ms;
103 sock.ReceiveTimeout = timeout_ms;
104 return new MyNetworkStream (sock);
107 public static void Send (Stream stream, string str)
109 byte [] bytes = Encoding.ASCII.GetBytes (str);
110 stream.Write (bytes, 0, bytes.Length);
113 public static string Receive (Stream stream, int size)
115 byte [] bytes = new byte [size];
116 int nread = stream.Read (bytes, 0, size);
117 return Encoding.ASCII.GetString (bytes, 0, nread);
120 public static string ReceiveWithTimeout (Stream stream, int size, int timeout, out bool timed_out)
122 byte [] bytes = new byte [size];
123 IAsyncResult ares = stream.BeginRead (bytes, 0, size, null, null);
124 timed_out = !ares.AsyncWaitHandle.WaitOne (timeout, false);
127 int nread = stream.EndRead (ares);
128 return Encoding.ASCII.GetString (bytes, 0, nread);
131 public static HttpListenerContext GetContextWithTimeout (HttpListener listener, int timeout, out bool timed_out)
133 IAsyncResult ares = listener.BeginGetContext (null, null);
134 timed_out = !ares.AsyncWaitHandle.WaitOne (timeout, false);
137 return listener.EndGetContext (ares);
141 public void Dispose()
143 if (_listener != null) {
152 var port = NetworkHelpers.FindFreePort ();
153 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test1/");
154 NetworkStream ns = CreateNS (port);
155 Send (ns, "GET / HTTP/1.1\r\n\r\n"); // No host
156 string response = Receive (ns, 512);
158 Assert.IsTrue(response.StartsWith ("HTTP/1.1 400"));
164 var port = NetworkHelpers.FindFreePort ();
165 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test2/");
166 NetworkStream ns = CreateNS (port);
167 Send (ns, "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n"); // no prefix
168 string response = Receive (ns, 512);
170 Assert.IsTrue(response.StartsWith ("HTTP/1.1 400"));
176 StringBuilder bad = new StringBuilder ();
177 for (int i = 0; i < 33; i++){
179 bad.Append ((char) i);
199 foreach (char b in bad.ToString ()){
200 var port = NetworkHelpers.FindFreePort ();
201 HttpListener listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test3/");
202 NetworkStream ns = CreateNS (port);
203 Send (ns, String.Format ("MA{0} / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n", b)); // bad method
205 string response = Receive (ns, 512);
208 Assert.IsTrue(response.StartsWith ("HTTP/1.1 400"), String.Format ("Failed on {0}", (int) b));
215 var port = NetworkHelpers.FindFreePort ();
216 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test4/");
217 NetworkStream ns = CreateNS (port);
218 Send (ns, "POST /test4/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n"); // length required
219 string response = Receive (ns, 512);
221 Assert.IsTrue(response.StartsWith ("HTTP/1.1 411"));
227 var port = NetworkHelpers.FindFreePort ();
228 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test5/");
229 NetworkStream ns = CreateNS (port);
230 Send (ns, "POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nTransfer-Encoding: pepe\r\n\r\n"); // not implemented
231 string response = Receive (ns, 512);
233 Assert.IsTrue(response.StartsWith ("HTTP/1.1 501"));
239 var port = NetworkHelpers.FindFreePort ();
240 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test6/");
241 NetworkStream ns = CreateNS (port);
242 // not implemented! This is against the RFC. Should be a bad request/length required
243 Send (ns, "POST /test6/ HTTP/1.1\r\nHost: 127.0.0.1\r\nTransfer-Encoding: identity\r\n\r\n");
244 string response = Receive (ns, 512);
246 Assert.IsTrue(response.StartsWith ("HTTP/1.1 501"));
252 var port = NetworkHelpers.FindFreePort ();
253 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test7/");
254 NetworkStream ns = CreateNS (port);
255 Send (ns, "POST /test7/ HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
256 HttpListenerContext ctx = _listener.GetContext ();
257 Send (ctx.Response.OutputStream, "%%%OK%%%");
258 ctx.Response.Close ();
259 string response = Receive (ns, 1024);
261 Assert.IsTrue(response.StartsWith ("HTTP/1.1 200"));
262 Assert.IsTrue(response.Contains ("Transfer-Encoding: chunked"));
268 var port = NetworkHelpers.FindFreePort ();
269 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test8/");
270 NetworkStream ns = CreateNS (port);
271 // Just like Test7, but 1.0
272 Send (ns, "POST /test8/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
273 HttpListenerContext ctx = _listener.GetContext ();
274 Send (ctx.Response.OutputStream, "%%%OK%%%");
275 ctx.Response.Close ();
276 string response = Receive (ns, 512);
278 Assert.IsTrue(response.StartsWith ("HTTP/1.1 200"));
279 Assert.IsTrue (-1 == response.IndexOf ("Transfer-Encoding: chunked"));
285 var port = NetworkHelpers.FindFreePort ();
286 // 1.0 + "Transfer-Encoding: chunked"
287 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test9/");
288 NetworkStream ns = CreateNS (port);
289 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");
291 string response = ReceiveWithTimeout (ns, 512, 1000, out timeout);
293 Assert.IsFalse (timeout);
294 Assert.IsTrue(response.StartsWith ("HTTP/1.1 411"));
298 public void Test10 ()
300 var port = NetworkHelpers.FindFreePort ();
301 // Same as Test9, but now we shutdown the socket for sending.
302 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test10/");
303 MyNetworkStream ns = CreateNS (port);
304 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");
305 ns.GetSocket ().Shutdown (SocketShutdown.Send);
307 string response = ReceiveWithTimeout (ns, 512, 1000, out timeout);
309 Assert.IsFalse (timeout);
310 Assert.IsTrue(response.StartsWith ("HTTP/1.1 411"));
314 public void Test11 ()
316 var port = NetworkHelpers.FindFreePort ();
318 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test11/");
319 MyNetworkStream ns = CreateNS (port);
320 Send (ns, "POST /test11/ HTTP/0.9\r\nHost: 127.0.0.1\r\n\r\n123");
321 ns.GetSocket ().Shutdown (SocketShutdown.Send);
322 string input = Receive (ns, 512);
324 Assert.IsTrue(input.StartsWith ("HTTP/1.1 400"));
328 public void Test12 ()
330 var port = NetworkHelpers.FindFreePort ();
332 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test12/");
333 MyNetworkStream ns = CreateNS (port);
334 Send (ns, "POST /test12/ HTTP/0.9\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
335 ns.GetSocket ().Shutdown (SocketShutdown.Send);
336 string input = Receive (ns, 512);
338 Assert.IsTrue(input.StartsWith ("HTTP/1.1 400"));
342 public void Test13 ()
344 var port = NetworkHelpers.FindFreePort ();
346 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test13/");
347 MyNetworkStream ns = CreateNS (port);
348 Send (ns, "GEt /test13/ HTTP/0.9\r\nHost: 127.0.0.1\r\n\r\n");
349 ns.GetSocket ().Shutdown (SocketShutdown.Send);
350 string input = Receive (ns, 512);
352 Assert.IsTrue(input.StartsWith ("HTTP/1.1 400"));
355 HttpListenerRequest test14_request;
356 ManualResetEvent test_evt;
359 public void Test14 ()
361 var port = NetworkHelpers.FindFreePort ();
362 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test14/");
363 MyNetworkStream ns = CreateNS (port);
364 Send (ns, "POST /test14/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
365 HttpListenerContext c = _listener.GetContext ();
366 test14_request = c.Request;
367 test_evt = new ManualResetEvent (false);
368 Thread thread = new Thread (ReadToEnd);
370 if (test_evt.WaitOne (3000, false) == false) {
371 #if MONO_FEATURE_THREAD_ABORT
377 Assert.IsTrue (false, "Timed out");
382 Assert.AreEqual ("123", read_to_end, "Did not get the expected input.");
388 using (StreamReader r = new StreamReader (test14_request.InputStream)) {
389 read_to_end = r.ReadToEnd ();
395 public void Test15 ()
397 var port = NetworkHelpers.FindFreePort ();
398 // 2 separate writes -> 2 packets. Body size > 8kB
399 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test15/");
400 MyNetworkStream ns = CreateNS (port);
401 Send (ns, "POST /test15/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 8888\r\n\r\n");
403 string data = new string ('a', 8888);
405 HttpListenerContext c = _listener.GetContext ();
406 HttpListenerRequest req = c.Request;
407 using (StreamReader r = new StreamReader (req.InputStream)) {
408 read_to_end = r.ReadToEnd ();
410 Assert.AreEqual (read_to_end.Length, data.Length, "Wrong length");
411 Assert.IsTrue (data == read_to_end, "Wrong data");
417 public void Test16 ()
419 var port = NetworkHelpers.FindFreePort ();
420 // 1 single write with headers + body (size > 8kB)
421 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test16/");
422 MyNetworkStream ns = CreateNS (port);
423 StringBuilder sb = new StringBuilder ();
424 sb.Append ("POST /test16/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 8888\r\n\r\n");
425 string eights = new string ('b', 8888);
427 string data = sb.ToString ();
429 HttpListenerContext c = _listener.GetContext ();
430 HttpListenerRequest req = c.Request;
431 using (StreamReader r = new StreamReader (req.InputStream)) {
432 read_to_end = r.ReadToEnd ();
434 Assert.AreEqual (read_to_end.Length, read_to_end.Length, "Wrong length");
435 Assert.IsTrue (eights == read_to_end, "Wrong data");
441 public void Test17 ()
443 var port = NetworkHelpers.FindFreePort ();
444 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/test17/");
445 NetworkStream ns = CreateNS (port);
446 Send (ns, "RANDOM /test17/ HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
447 HttpListenerContext ctx = _listener.GetContext ();
448 Send (ctx.Response.OutputStream, "%%%OK%%%");
449 ctx.Response.Close ();
450 string response = Receive (ns, 1024);
452 Assert.IsTrue(response.StartsWith ("HTTP/1.1 200"));
453 Assert.IsTrue(response.Contains ("Transfer-Encoding: chunked"));
457 public void Test_MultipleClosesOnOuputStreamAllowed ()
459 var port = NetworkHelpers.FindFreePort ();
460 _listener = CreateAndStartListener ("http://127.0.0.1:" + port + "/MultipleCloses/");
461 NetworkStream ns = CreateNS (port);
462 Send (ns, "GET /MultipleCloses/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
464 HttpListenerContext ctx = _listener.GetContext ();
465 ctx.Response.OutputStream.Close ();
466 ctx.Response.OutputStream.Close ();
467 ctx.Response.OutputStream.Close ();
468 ctx.Response.Close ();
473 NetworkStream ns = CreateNS (sendCookiePort);
474 Send (ns, "GET /SendCookie/ HTTP/1.1\r\nHost: 127.0.0.1\r\n"+
475 "Cookie:$Version=\"1\"; "+
476 "Cookie1=Value1; $Path=\"/\"; "+
477 "CookieM=ValueM; $Path=\"/p2\"; $Domain=\"test\"; $Port=\"99\";"+
478 "Cookie2=Value2; $Path=\"/foo\";"+
487 public void ReceiveCookiesFromClient ()
489 sendCookiePort = NetworkHelpers.FindFreePort ();
490 _listener = CreateAndStartListener ("http://127.0.0.1:" + sendCookiePort + "/SendCookie/");
491 Thread clientThread = new Thread (new ThreadStart (SendCookie));
492 clientThread.Start ();
494 HttpListenerContext context = _listener.GetContext();
495 HttpListenerRequest request = context.Request;
497 Assert.AreEqual (3, request.Cookies.Count, "#1");
498 foreach (Cookie c in request.Cookies) {
499 if (c.Name == "Cookie1") {
500 Assert.AreEqual ("Value1", c.Value, "#2");
501 Assert.AreEqual ("\"/\"", c.Path, "#3");
502 Assert.AreEqual (0, c.Port.Length, "#4");
503 Assert.AreEqual (0, c.Domain.Length, "#5");
504 } else if (c.Name == "CookieM") {
505 Assert.AreEqual ("ValueM", c.Value, "#6");
506 Assert.AreEqual ("\"/p2\"", c.Path, "#7");
507 Assert.AreEqual ("\"99\"", c.Port, "#8");
508 Assert.AreEqual ("\"test\"", c.Domain, "#9");
509 } else if (c.Name == "Cookie2") {
510 Assert.AreEqual ("Value2", c.Value, "#10");
511 Assert.AreEqual ("\"/foo\"", c.Path, "#11");
512 Assert.AreEqual (0, c.Port.Length, "#12");
513 Assert.AreEqual (0, c.Domain.Length, "#13");
515 Assert.Fail ("Invalid cookie name " + c.Name);
519 private object _lock = new Object();
520 private string cookieResponse;
521 private int receiveCookiePort;
522 private int sendCookiePort;
524 void ReceiveCookie () {
526 NetworkStream ns = CreateNS (receiveCookiePort);
527 Send (ns, "GET /ReceiveCookie/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
528 cookieResponse = Receive (ns, 512);
533 public void SendCookiestoClient ()
535 receiveCookiePort = NetworkHelpers.FindFreePort ();
536 _listener = CreateAndStartListener ("http://127.0.0.1:" + receiveCookiePort + "/ReceiveCookie/");
537 Thread clientThread = new Thread (new ThreadStart (ReceiveCookie));
538 clientThread.Start ();
540 HttpListenerContext context = _listener.GetContext();
541 HttpListenerRequest request = context.Request;
542 HttpListenerResponse response = context.Response;
544 Cookie cookie = new Cookie ();
545 cookie.Name = "Name0";
546 cookie.Value = "Value0";
547 cookie.Domain = "blue";
548 cookie.Path = "/path/";
549 cookie.Port = "\"80\"";
551 response.Cookies.Add (cookie);
553 string responseString = "<HTML><BODY>----</BODY></HTML>";
554 byte[] buffer = Encoding.UTF8.GetBytes(responseString);
555 response.ContentLength64 = buffer.Length;
556 Stream output = response.OutputStream;
557 output.Write(buffer, 0, buffer.Length);
562 bool foundCookie = false;
563 foreach (String str in cookieResponse.Split ('\n')) {
564 if (!str.StartsWith ("Set-Cookie"))
566 Dictionary<string, String> dic = new Dictionary<string, String>();
567 foreach (String p in str.Substring (str.IndexOf (":") + 1).Split (';')) {
568 String[] parts = p.Split('=');
569 dic.Add (parts [0].Trim (), parts [1].Trim ());
571 Assert.AreEqual ("Value0", dic ["Name0"], "#1");
572 Assert.AreEqual ("blue", dic ["Domain"], "#2");
573 Assert.AreEqual ("\"/path/\"", dic ["Path"], "#3");
574 Assert.AreEqual ("\"80\"", dic ["Port"], "#4");
575 Assert.AreEqual ("1", dic ["Version"], "#5");
579 Assert.IsTrue (foundCookie, "#6");
584 public void MultiResponses ()
586 echoServerPort = NetworkHelpers.FindFreePort ();
587 Thread srv = new Thread (new ThreadStart (EchoServer));
591 for (int i = 0; i < 10; i++) {
592 string payload = string.Format (CultureInfo.InvariantCulture,
595 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (
596 "http://localhost:" + echoServerPort + "/foobar/");
597 req.ServicePoint.Expect100Continue = false;
598 req.ServicePoint.UseNagleAlgorithm = false;
600 StreamWriter w = new StreamWriter (req.GetRequestStream ());
601 w.WriteLine (payload);
604 HttpWebResponse resp = (HttpWebResponse) req.GetResponse ();
605 StreamReader r = new StreamReader (resp.GetResponseStream ());
606 Assert.AreEqual ("Hello, " + payload + "!", r.ReadToEnd ().Trim ());
617 _listener = new HttpListener ();
618 _listener.Prefixes.Add ("http://*:" + echoServerPort + "/foobar/");
621 manualReset = new ManualResetEvent (false);
623 IAsyncResult result = _listener.BeginGetContext (
624 new AsyncCallback (EchoCallback), _listener);
625 manualReset.WaitOne ();
628 void EchoCallback (IAsyncResult result)
630 HttpListener listener = (HttpListener) result.AsyncState;
631 HttpListenerContext context = listener.EndGetContext (result);
632 HttpListenerRequest req = context.Request;
633 StreamReader r = new StreamReader (req.InputStream);
634 string reqBody = r.ReadToEnd ().Trim ();
636 HttpListenerResponse resp = context.Response;
637 StreamWriter o = new StreamWriter (resp.OutputStream);
638 o.WriteLine ("Hello, " + reqBody + "!");
641 listener.BeginGetContext (new AsyncCallback (EchoCallback), listener);
644 private ManualResetEvent manualReset;
649 [Category ("RequiresBSDSockets")]
650 public class HttpListenerBugs {
652 public void TestNonChunkedAsync ()
654 var port = NetworkHelpers.FindFreePort ();
655 HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:" + port + "/");
657 listener.BeginGetContext (callback, listener);
659 HttpListener2Test.MyNetworkStream ns = HttpListener2Test.CreateNS (port);
660 string message = "<script>\n"+
661 " <!-- register the blueprint for our show-headers service -->\n"+
662 " <action verb=\"POST\" path=\"/host/register\">\n" +
664 " <assembly>dream.tutorial.show-headers</assembly>\n" +
665 " <class>MindTouch.Dream.Tutorial.ShowHeadersService</class>\n" +
669 " <!-- instantiate it -->\n" +
670 " <action verb=\"POST\" path=\"/host/start\">\n" +
672 " <path>show-headers</path>\n" +
673 " <class>MindTouch.Dream.Tutorial.ShowHeadersService</class>\n" +
677 string s = String.Format ("POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: {0}\r\n\r\n{1}",
678 message.Length, message);
679 HttpListener2Test.Send (ns, s);
681 string response = HttpListener2Test.ReceiveWithTimeout (ns, 1024, 3000, out timedout);
684 Assert.IsFalse (timedout);
687 void callback (IAsyncResult ar)
689 HttpListener l = (HttpListener) ar.AsyncState;
691 HttpListenerContext c = l.EndGetContext (ar);
692 HttpListenerRequest request = c.Request;
694 StreamReader r = new StreamReader (request.InputStream);
695 string sr =r.ReadToEnd ();
696 HttpListener2Test.Send (c.Response.OutputStream, "Miguel is love");
701 // As it turns out, when we closed the OutputStream,
702 // we were not shutting down the connection, which was
703 // a documented pattern to close the connection
706 public void Test_MultipleConnections ()
708 var port = NetworkHelpers.FindFreePort ();
709 HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:" + port + "/multiple/");
712 NetworkStream ns = HttpListener2Test.CreateNS (port);
713 HttpListener2Test.Send (ns, "POST /multiple/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
714 HttpListenerContext ctx = listener.GetContext ();
715 HttpListener2Test.Send (ctx.Response.OutputStream, "%%%OK%%%");
716 ctx.Response.OutputStream.Close ();
717 string response = HttpListener2Test.Receive (ns, 1024);
721 ns = HttpListener2Test.CreateNS (port);
722 HttpListener2Test.Send (ns, "POST /multiple/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
723 ctx = listener.GetContext ();
724 HttpListener2Test.Send (ctx.Response.OutputStream, "%%%OK%%%");
725 ctx.Response.OutputStream.Close ();
726 response = HttpListener2Test.Receive (ns, 1024);
733 // Test case for bug 341443, an pretty old bug, filed on November of 2007.
736 public void Test_HostInUri ()
738 var wait = new ManualResetEvent (false);
739 var wait2 = new ManualResetEvent (false);
740 var port = NetworkHelpers.FindFreePort ();
742 Thread t = new Thread (delegate (object a) {
745 NetworkStream ns = HttpListener2Test.CreateNS (port);
746 HttpListener2Test.Send (ns, "GET http://www.google.com/ HTTP/1.1\r\nHost: www.google.com\r\nContent-Length: 3\r\n\r\n123456");
753 HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://*:" + port + "/");
755 HttpListenerContext ctx = listener.GetContext ();
757 Assert.AreEqual ("http://www.google.com:" + port + "/", ctx.Request.Url.ToString ());
758 Assert.AreEqual ("http://www.google.com/", ctx.Request.RawUrl);
764 [Test] // bug #513849
765 public void ClosePort ()
767 var port = NetworkHelpers.FindFreePort ();
768 var h = new HttpListener ();
769 h.Prefixes.Add ("http://127.0.0.1:" + port + "/");
771 h.BeginGetContext (null, null);
773 TcpListener t = new TcpListener (IPAddress.Parse ("127.0.0.1"), port);
779 // Bugs: #17204, #10818
781 // Sadly, on Unix, if there are different calls to bind
782 // like *:port and host:port that is not an error,
783 // it would only be an error if host:port is done twice, so
784 // the best we can hope for is that listening on a specific interface
785 // does not also listen to another interface.
788 public void BindToSingleInterface ()
790 IPAddress [] machineAddress = null;
793 machineAddress = Dns.GetHostAddresses (Dns.GetHostName ());
794 } catch (SocketException){
795 // The build hosts sometimes can not resolve the hostname
796 Assert.Ignore ("Hostname couldn't be resolved.");
799 int port = NetworkHelpers.FindFreePort ();;
800 var h = new HttpListener ();
801 h.Prefixes.Add ("http://" + machineAddress [0] + ":" + port + "/");
805 var c = new TcpClient ("localhost", port);
806 Assert.Fail ("The TcpClient should have failed to connect since HttpListener is not listening on localhost");
807 } catch (SocketException){
814 public void BindToAllInterfaces ()
816 var h = new HttpListener ();
817 int port = NetworkHelpers.FindFreePort ();
818 h.Prefixes.Add ("http://*:" + port + "/");
820 var c = new TcpClient ("localhost", port);
824 // Test case for bug #31209
826 public void Test_EmptyLineAtStart ()
828 var port = NetworkHelpers.FindFreePort ();
829 var listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:" + port + "/");
830 var ns = HttpListener2Test.CreateNS (port);
832 HttpListener2Test.Send (ns, "\r\nGET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
835 HttpListener2Test.GetContextWithTimeout (listener, 1000, out timedout);
837 Assert.IsFalse (timedout, "timed out");