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 // ***************************************************************************************
42 // NOTE: when adding prefixes, make then unique per test, as MS might take 'some time' to
43 // unregister it even after explicitly closing the listener.
44 // ***************************************************************************************
45 namespace MonoTests.System.Net {
48 public class HttpListener2Test {
50 private HttpListener _listener = null;
52 public class MyNetworkStream : NetworkStream {
53 public MyNetworkStream (Socket sock) : base (sock, true)
57 public Socket GetSocket ()
63 public static HttpListener CreateAndStartListener (string prefix)
65 HttpListener listener = new HttpListener ();
66 listener.Prefixes.Add (prefix);
71 public static HttpListener CreateAndStartListener (string prefix, AuthenticationSchemes authSchemes)
73 HttpListener listener = new HttpListener ();
74 listener.AuthenticationSchemes = authSchemes;
75 listener.Prefixes.Add (prefix);
80 public static MyNetworkStream CreateNS (int port)
82 return CreateNS (port, 5000);
85 public static MyNetworkStream CreateNS (int port, int timeout_ms)
87 Socket sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
88 sock.Connect (new IPEndPoint (IPAddress.Loopback, port));
89 sock.SendTimeout = timeout_ms;
90 sock.ReceiveTimeout = timeout_ms;
91 return new MyNetworkStream (sock);
94 public static void Send (Stream stream, string str)
96 byte [] bytes = Encoding.ASCII.GetBytes (str);
97 stream.Write (bytes, 0, bytes.Length);
100 public static string Receive (Stream stream, int size)
102 byte [] bytes = new byte [size];
103 int nread = stream.Read (bytes, 0, size);
104 return Encoding.ASCII.GetString (bytes, 0, nread);
107 public static string ReceiveWithTimeout (Stream stream, int size, int timeout, out bool timed_out)
109 byte [] bytes = new byte [size];
110 IAsyncResult ares = stream.BeginRead (bytes, 0, size, null, null);
111 timed_out = !ares.AsyncWaitHandle.WaitOne (timeout, false);
114 int nread = stream.EndRead (ares);
115 return Encoding.ASCII.GetString (bytes, 0, nread);
118 public static HttpListenerContext GetContextWithTimeout (HttpListener listener, int timeout, out bool timed_out)
120 IAsyncResult ares = listener.BeginGetContext (null, null);
121 timed_out = !ares.AsyncWaitHandle.WaitOne (timeout, false);
124 return listener.EndGetContext (ares);
128 public void Dispose()
130 if (_listener != null) {
139 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test1/");
140 NetworkStream ns = CreateNS (9000);
141 Send (ns, "GET / HTTP/1.1\r\n\r\n"); // No host
142 string response = Receive (ns, 512);
144 StringAssert.StartsWith ("HTTP/1.1 400", response);
150 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test2/");
151 NetworkStream ns = CreateNS (9000);
152 Send (ns, "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n"); // no prefix
153 string response = Receive (ns, 512);
155 StringAssert.StartsWith ("HTTP/1.1 400", response);
161 StringBuilder bad = new StringBuilder ();
162 for (int i = 0; i < 33; i++){
164 bad.Append ((char) i);
184 foreach (char b in bad.ToString ()){
185 HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test3/");
186 NetworkStream ns = CreateNS (9000);
187 Send (ns, String.Format ("MA{0} / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n", b)); // bad method
189 string response = Receive (ns, 512);
192 StringAssert.StartsWith ("HTTP/1.1 400", response, String.Format ("Failed on {0}", (int) b));
199 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test4/");
200 NetworkStream ns = CreateNS (9000);
201 Send (ns, "POST /test4/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n"); // length required
202 string response = Receive (ns, 512);
204 StringAssert.StartsWith ("HTTP/1.1 411", response);
210 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test5/");
211 NetworkStream ns = CreateNS (9000);
212 Send (ns, "POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nTransfer-Encoding: pepe\r\n\r\n"); // not implemented
213 string response = Receive (ns, 512);
215 StringAssert.StartsWith ("HTTP/1.1 501", response);
221 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test6/");
222 NetworkStream ns = CreateNS (9000);
223 // not implemented! This is against the RFC. Should be a bad request/length required
224 Send (ns, "POST /test6/ HTTP/1.1\r\nHost: 127.0.0.1\r\nTransfer-Encoding: identity\r\n\r\n");
225 string response = Receive (ns, 512);
227 StringAssert.StartsWith ("HTTP/1.1 501", response);
233 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test7/");
234 NetworkStream ns = CreateNS (9000);
235 Send (ns, "POST /test7/ HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
236 HttpListenerContext ctx = _listener.GetContext ();
237 Send (ctx.Response.OutputStream, "%%%OK%%%");
238 ctx.Response.Close ();
239 string response = Receive (ns, 1024);
241 StringAssert.StartsWith ("HTTP/1.1 200", response);
242 StringAssert.Contains ("Transfer-Encoding: chunked", response);
248 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test8/");
249 NetworkStream ns = CreateNS (9000);
250 // Just like Test7, but 1.0
251 Send (ns, "POST /test8/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
252 HttpListenerContext ctx = _listener.GetContext ();
253 Send (ctx.Response.OutputStream, "%%%OK%%%");
254 ctx.Response.Close ();
255 string response = Receive (ns, 512);
257 StringAssert.StartsWith ("HTTP/1.1 200", response);
258 Assert.IsTrue (-1 == response.IndexOf ("Transfer-Encoding: chunked"));
264 // 1.0 + "Transfer-Encoding: chunked"
265 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test9/");
266 NetworkStream ns = CreateNS (9000);
267 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");
269 string response = ReceiveWithTimeout (ns, 512, 1000, out timeout);
271 Assert.IsFalse (timeout);
272 StringAssert.StartsWith ("HTTP/1.1 411", response);
276 public void Test10 ()
278 // Same as Test9, but now we shutdown the socket for sending.
279 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test10/");
280 MyNetworkStream ns = CreateNS (9000);
281 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");
282 ns.GetSocket ().Shutdown (SocketShutdown.Send);
284 string response = ReceiveWithTimeout (ns, 512, 1000, out timeout);
286 Assert.IsFalse (timeout);
287 StringAssert.StartsWith ("HTTP/1.1 411", response);
291 public void Test11 ()
294 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test11/");
295 MyNetworkStream ns = CreateNS (9000);
296 Send (ns, "POST /test11/ HTTP/0.9\r\nHost: 127.0.0.1\r\n\r\n123");
297 ns.GetSocket ().Shutdown (SocketShutdown.Send);
298 string input = Receive (ns, 512);
300 StringAssert.StartsWith ("HTTP/1.1 400", input);
304 public void Test12 ()
307 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test12/");
308 MyNetworkStream ns = CreateNS (9000);
309 Send (ns, "POST /test12/ HTTP/0.9\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
310 ns.GetSocket ().Shutdown (SocketShutdown.Send);
311 string input = Receive (ns, 512);
313 StringAssert.StartsWith ("HTTP/1.1 400", input);
317 public void Test13 ()
320 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test13/");
321 MyNetworkStream ns = CreateNS (9000);
322 Send (ns, "GEt /test13/ HTTP/0.9\r\nHost: 127.0.0.1\r\n\r\n");
323 ns.GetSocket ().Shutdown (SocketShutdown.Send);
324 string input = Receive (ns, 512);
326 StringAssert.StartsWith ("HTTP/1.1 400", input);
329 HttpListenerRequest test14_request;
330 ManualResetEvent test_evt;
333 public void Test14 ()
335 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test14/");
336 MyNetworkStream ns = CreateNS (9000);
337 Send (ns, "POST /test14/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
338 HttpListenerContext c = _listener.GetContext ();
339 test14_request = c.Request;
340 test_evt = new ManualResetEvent (false);
341 Thread thread = new Thread (ReadToEnd);
343 if (test_evt.WaitOne (3000, false) == false) {
344 #if MONO_FEATURE_THREAD_ABORT
350 Assert.IsTrue (false, "Timed out");
355 Assert.AreEqual ("123", read_to_end, "Did not get the expected input.");
361 using (StreamReader r = new StreamReader (test14_request.InputStream)) {
362 read_to_end = r.ReadToEnd ();
368 public void Test15 ()
370 // 2 separate writes -> 2 packets. Body size > 8kB
371 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test15/");
372 MyNetworkStream ns = CreateNS (9000);
373 Send (ns, "POST /test15/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 8888\r\n\r\n");
375 string data = new string ('a', 8888);
377 HttpListenerContext c = _listener.GetContext ();
378 HttpListenerRequest req = c.Request;
379 using (StreamReader r = new StreamReader (req.InputStream)) {
380 read_to_end = r.ReadToEnd ();
382 Assert.AreEqual (read_to_end.Length, data.Length, "Wrong length");
383 Assert.IsTrue (data == read_to_end, "Wrong data");
389 public void Test16 ()
391 // 1 single write with headers + body (size > 8kB)
392 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test16/");
393 MyNetworkStream ns = CreateNS (9000);
394 StringBuilder sb = new StringBuilder ();
395 sb.Append ("POST /test16/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 8888\r\n\r\n");
396 string eights = new string ('b', 8888);
398 string data = sb.ToString ();
400 HttpListenerContext c = _listener.GetContext ();
401 HttpListenerRequest req = c.Request;
402 using (StreamReader r = new StreamReader (req.InputStream)) {
403 read_to_end = r.ReadToEnd ();
405 Assert.AreEqual (read_to_end.Length, read_to_end.Length, "Wrong length");
406 Assert.IsTrue (eights == read_to_end, "Wrong data");
412 public void Test17 ()
414 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test17/");
415 NetworkStream ns = CreateNS (9000);
416 Send (ns, "RANDOM /test17/ HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
417 HttpListenerContext ctx = _listener.GetContext ();
418 Send (ctx.Response.OutputStream, "%%%OK%%%");
419 ctx.Response.Close ();
420 string response = Receive (ns, 1024);
422 StringAssert.StartsWith ("HTTP/1.1 200", response);
423 StringAssert.Contains ("Transfer-Encoding: chunked", response);
427 public void Test_MultipleClosesOnOuputStreamAllowed ()
429 _listener = CreateAndStartListener ("http://127.0.0.1:9000/MultipleCloses/");
430 NetworkStream ns = CreateNS (9000);
431 Send (ns, "GET /MultipleCloses/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
433 HttpListenerContext ctx = _listener.GetContext ();
434 ctx.Response.OutputStream.Close ();
435 ctx.Response.OutputStream.Close ();
436 ctx.Response.OutputStream.Close ();
437 ctx.Response.Close ();
442 NetworkStream ns = CreateNS (9000);
443 Send (ns, "GET /SendCookie/ HTTP/1.1\r\nHost: 127.0.0.1\r\n"+
444 "Cookie:$Version=\"1\"; "+
445 "Cookie1=Value1; $Path=\"/\"; "+
446 "CookieM=ValueM; $Path=\"/p2\"; $Domain=\"test\"; $Port=\"99\";"+
447 "Cookie2=Value2; $Path=\"/foo\";"+
456 public void ReceiveCookiesFromClient ()
458 _listener = CreateAndStartListener ("http://127.0.0.1:9000/SendCookie/");
459 Thread clientThread = new Thread (new ThreadStart (SendCookie));
460 clientThread.Start ();
462 HttpListenerContext context = _listener.GetContext();
463 HttpListenerRequest request = context.Request;
465 Assert.AreEqual (3, request.Cookies.Count, "#1");
466 foreach (Cookie c in request.Cookies) {
467 if (c.Name == "Cookie1") {
468 Assert.AreEqual ("Value1", c.Value, "#2");
469 Assert.AreEqual ("\"/\"", c.Path, "#3");
470 Assert.AreEqual (0, c.Port.Length, "#4");
471 Assert.AreEqual (0, c.Domain.Length, "#5");
472 } else if (c.Name == "CookieM") {
473 Assert.AreEqual ("ValueM", c.Value, "#6");
474 Assert.AreEqual ("\"/p2\"", c.Path, "#7");
475 Assert.AreEqual ("\"99\"", c.Port, "#8");
476 Assert.AreEqual ("\"test\"", c.Domain, "#9");
477 } else if (c.Name == "Cookie2") {
478 Assert.AreEqual ("Value2", c.Value, "#10");
479 Assert.AreEqual ("\"/foo\"", c.Path, "#11");
480 Assert.AreEqual (0, c.Port.Length, "#12");
481 Assert.AreEqual (0, c.Domain.Length, "#13");
483 Assert.Fail ("Invalid cookie name " + c.Name);
487 private object _lock = new Object();
488 private string cookieResponse;
490 void ReceiveCookie () {
492 NetworkStream ns = CreateNS (9000);
493 Send (ns, "GET /ReceiveCookie/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
494 cookieResponse = Receive (ns, 512);
499 public void SendCookiestoClient ()
501 _listener = CreateAndStartListener ("http://127.0.0.1:9000/ReceiveCookie/");
502 Thread clientThread = new Thread (new ThreadStart (ReceiveCookie));
503 clientThread.Start ();
505 HttpListenerContext context = _listener.GetContext();
506 HttpListenerRequest request = context.Request;
507 HttpListenerResponse response = context.Response;
509 Cookie cookie = new Cookie ();
510 cookie.Name = "Name0";
511 cookie.Value = "Value0";
512 cookie.Domain = "blue";
513 cookie.Path = "/path/";
514 cookie.Port = "\"80\"";
516 response.Cookies.Add (cookie);
518 string responseString = "<HTML><BODY>----</BODY></HTML>";
519 byte[] buffer = Encoding.UTF8.GetBytes(responseString);
520 response.ContentLength64 = buffer.Length;
521 Stream output = response.OutputStream;
522 output.Write(buffer, 0, buffer.Length);
527 bool foundCookie = false;
528 foreach (String str in cookieResponse.Split ('\n')) {
529 if (!str.StartsWith ("Set-Cookie"))
531 Dictionary<string, String> dic = new Dictionary<string, String>();
532 foreach (String p in str.Substring (str.IndexOf (":") + 1).Split (';')) {
533 String[] parts = p.Split('=');
534 dic.Add (parts [0].Trim (), parts [1].Trim ());
536 Assert.AreEqual ("Value0", dic ["Name0"], "#1");
537 Assert.AreEqual ("blue", dic ["Domain"], "#2");
538 Assert.AreEqual ("\"/path/\"", dic ["Path"], "#3");
539 Assert.AreEqual ("\"80\"", dic ["Port"], "#4");
540 Assert.AreEqual ("1", dic ["Version"], "#5");
544 Assert.IsTrue (foundCookie, "#6");
549 public void MultiResponses ()
551 Thread srv = new Thread (new ThreadStart (EchoServer));
555 for (int i = 0; i < 10; i++) {
556 string payload = string.Format (CultureInfo.InvariantCulture,
559 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (
560 "http://localhost:8888/foobar/");
561 req.ServicePoint.Expect100Continue = false;
562 req.ServicePoint.UseNagleAlgorithm = false;
564 StreamWriter w = new StreamWriter (req.GetRequestStream ());
565 w.WriteLine (payload);
568 HttpWebResponse resp = (HttpWebResponse) req.GetResponse ();
569 StreamReader r = new StreamReader (resp.GetResponseStream ());
570 Assert.AreEqual ("Hello, " + payload + "!", r.ReadToEnd ().Trim ());
580 _listener = new HttpListener ();
581 _listener.Prefixes.Add ("http://*:8888/foobar/");
584 manualReset = new ManualResetEvent (false);
586 IAsyncResult result = _listener.BeginGetContext (
587 new AsyncCallback (EchoCallback), _listener);
588 manualReset.WaitOne ();
591 void EchoCallback (IAsyncResult result)
593 HttpListener listener = (HttpListener) result.AsyncState;
594 HttpListenerContext context = listener.EndGetContext (result);
595 HttpListenerRequest req = context.Request;
596 StreamReader r = new StreamReader (req.InputStream);
597 string reqBody = r.ReadToEnd ().Trim ();
599 HttpListenerResponse resp = context.Response;
600 StreamWriter o = new StreamWriter (resp.OutputStream);
601 o.WriteLine ("Hello, " + reqBody + "!");
604 listener.BeginGetContext (new AsyncCallback (EchoCallback), listener);
607 private ManualResetEvent manualReset;
612 public class HttpListenerBugs {
614 public void TestNonChunkedAsync ()
616 HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:9123/");
618 listener.BeginGetContext (callback, listener);
620 HttpListener2Test.MyNetworkStream ns = HttpListener2Test.CreateNS (9123);
621 string message = "<script>\n"+
622 " <!-- register the blueprint for our show-headers service -->\n"+
623 " <action verb=\"POST\" path=\"/host/register\">\n" +
625 " <assembly>dream.tutorial.show-headers</assembly>\n" +
626 " <class>MindTouch.Dream.Tutorial.ShowHeadersService</class>\n" +
630 " <!-- instantiate it -->\n" +
631 " <action verb=\"POST\" path=\"/host/start\">\n" +
633 " <path>show-headers</path>\n" +
634 " <class>MindTouch.Dream.Tutorial.ShowHeadersService</class>\n" +
638 string s = String.Format ("POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: {0}\r\n\r\n{1}",
639 message.Length, message);
640 HttpListener2Test.Send (ns, s);
642 string response = HttpListener2Test.ReceiveWithTimeout (ns, 1024, 3000, out timedout);
645 Assert.IsFalse (timedout);
648 void callback (IAsyncResult ar)
650 HttpListener l = (HttpListener) ar.AsyncState;
652 HttpListenerContext c = l.EndGetContext (ar);
653 HttpListenerRequest request = c.Request;
655 StreamReader r = new StreamReader (request.InputStream);
656 string sr =r.ReadToEnd ();
657 HttpListener2Test.Send (c.Response.OutputStream, "Miguel is love");
662 // As it turns out, when we closed the OutputStream,
663 // we were not shutting down the connection, which was
664 // a documented pattern to close the connection
667 public void Test_MultipleConnections ()
669 HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:9000/multiple/");
672 NetworkStream ns = HttpListener2Test.CreateNS (9000);
673 HttpListener2Test.Send (ns, "POST /multiple/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
674 HttpListenerContext ctx = listener.GetContext ();
675 HttpListener2Test.Send (ctx.Response.OutputStream, "%%%OK%%%");
676 ctx.Response.OutputStream.Close ();
677 string response = HttpListener2Test.Receive (ns, 1024);
681 ns = HttpListener2Test.CreateNS (9000);
682 HttpListener2Test.Send (ns, "POST /multiple/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
683 ctx = listener.GetContext ();
684 HttpListener2Test.Send (ctx.Response.OutputStream, "%%%OK%%%");
685 ctx.Response.OutputStream.Close ();
686 response = HttpListener2Test.Receive (ns, 1024);
693 // Test case for bug 341443, an pretty old bug, filed on November of 2007.
696 public void Test_HostInUri ()
698 var wait = new ManualResetEvent (false);
699 var wait2 = new ManualResetEvent (false);
701 Thread t = new Thread (delegate (object a) {
704 NetworkStream ns = HttpListener2Test.CreateNS (9145);
705 HttpListener2Test.Send (ns, "GET http://www.google.com/ HTTP/1.1\r\nHost: www.google.com\r\nContent-Length: 3\r\n\r\n123456");
712 HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://*:9145/");
714 HttpListenerContext ctx = listener.GetContext ();
716 Assert.AreEqual ("http://www.google.com:9145/", ctx.Request.Url.ToString ());
717 Assert.AreEqual ("http://www.google.com/", ctx.Request.RawUrl);
723 [Test] // bug #513849
724 public void ClosePort ()
726 var h = new HttpListener ();
727 h.Prefixes.Add ("http://127.0.0.1:30158/");
729 h.BeginGetContext (null, null);
731 TcpListener t = new TcpListener (IPAddress.Parse ("127.0.0.1"), 30158);
737 // Bugs: #17204, #10818
739 // Sadly, on Unix, if there are different calls to bind
740 // like *:port and host:port that is not an error,
741 // it would only be an error if host:port is done twice, so
742 // the best we can hope for is that listening on a specific interface
743 // does not also listen to another interface.
746 public void BindToSingleInterface ()
748 IPAddress [] machineAddress = null;
751 machineAddress = Dns.GetHostAddresses (Dns.GetHostName ());
752 } catch (SocketException){
753 // The build hosts sometimes can not resolve the hostname
754 Assert.Ignore ("Hostname couldn't be resolved.");
758 var h = new HttpListener ();
759 h.Prefixes.Add ("http://" + machineAddress [0] + ":" + port + "/");
763 var c = new TcpClient ("localhost", port);
764 Assert.Fail ("The TcpClient should have failed to connect since HttpListener is not listening on localhost");
765 } catch (SocketException){
772 public void BindToAllInterfaces ()
774 var h = new HttpListener ();
776 h.Prefixes.Add ("http://*:" + port + "/");
778 var c = new TcpClient ("localhost", port);
782 // Test case for bug #31209
784 public void Test_EmptyLineAtStart ()
786 var listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:9124/");
787 var ns = HttpListener2Test.CreateNS (9124);
789 HttpListener2Test.Send (ns, "\r\nGET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
792 HttpListener2Test.GetContextWithTimeout (listener, 1000, out timedout);
794 Assert.IsFalse (timedout, "timed out");