//
#if NET_2_0
using System;
+using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Sockets;
// ***************************************************************************************
namespace MonoTests.System.Net {
[TestFixture]
+#if TARGET_JVM
+ [Ignore ("The class HttpListener is not supported")]
+#endif
public class HttpListener2Test {
public class MyNetworkStream : NetworkStream {
public MyNetworkStream (Socket sock) : base (sock, true)
return listener;
}
+ public static HttpListener CreateAndStartListener (string prefix, AuthenticationSchemes authSchemes)
+ {
+ HttpListener listener = new HttpListener ();
+ listener.AuthenticationSchemes = authSchemes;
+ listener.Prefixes.Add (prefix);
+ listener.Start ();
+ return listener;
+ }
+
public static MyNetworkStream CreateNS (int port)
{
Socket sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
[Test]
public void Test3 ()
{
- HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test3/");
- NetworkStream ns = CreateNS (9000);
- Send (ns, "MET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n"); // bad method
- string response = Receive (ns, 512);
- ns.Close ();
- listener.Close ();
- Assert.IsTrue (response.StartsWith ("HTTP/1.1 400"));
+ StringBuilder bad = new StringBuilder ();
+ for (int i = 0; i < 33; i++){
+ if (i != 13)
+ bad.Append ((char) i);
+ }
+ bad.Append ('(');
+ bad.Append (')');
+ bad.Append ('[');
+ bad.Append (']');
+ bad.Append ('<');
+ bad.Append ('>');
+ bad.Append ('@');
+ bad.Append (',');
+ bad.Append (';');
+ bad.Append (':');
+ bad.Append ('\\');
+ bad.Append ('"');
+ bad.Append ('/');
+ bad.Append ('?');
+ bad.Append ('=');
+ bad.Append ('{');
+ bad.Append ('}');
+
+ foreach (char b in bad.ToString ()){
+ HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test3/");
+ NetworkStream ns = CreateNS (9000);
+ Send (ns, String.Format ("MA{0} / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n", b)); // bad method
+
+ string response = Receive (ns, 512);
+ ns.Close ();
+ listener.Close ();
+ Assert.AreEqual (true, response.StartsWith ("HTTP/1.1 400"), String.Format ("Failed on {0}", (int) b));
+ }
}
[Test]
c.Response.Close ();
ns.Close ();
}
+
+ [Test]
+ public void Test17 ()
+ {
+ HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test17/");
+ NetworkStream ns = CreateNS (9000);
+ Send (ns, "RANDOM /test17/ HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
+ HttpListenerContext ctx = listener.GetContext ();
+ Send (ctx.Response.OutputStream, "%%%OK%%%");
+ string response = Receive (ns, 1024);
+ ns.Close ();
+ listener.Close ();
+ Assert.IsTrue (response.StartsWith ("HTTP/1.1 200"));
+ Assert.IsTrue (-1 != response.IndexOf ("Transfer-Encoding: chunked"));
+ }
+
+ [Test]
+ public void Test_MultipleClosesOnOuputStreamAllowed ()
+ {
+ HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/MultipleCloses/");
+ NetworkStream ns = CreateNS (9000);
+ Send (ns, "GET /MultipleCloses/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
+
+ HttpListenerContext ctx = listener.GetContext ();
+ ctx.Response.OutputStream.Close ();
+ ctx.Response.OutputStream.Close ();
+ ctx.Response.OutputStream.Close ();
+ ctx.Response.Close ();
+ listener.Close ();
+ }
+
+ void SendCookie ()
+ {
+ NetworkStream ns = CreateNS (9000);
+ Send (ns, "GET /SendCookie/ HTTP/1.1\r\nHost: 127.0.0.1\r\n"+
+ "Cookie:$Version=\"1\"; "+
+ "Cookie1=Value1; $Path=\"/\"; "+
+ "CookieM=ValueM; $Path=\"/p2\"; $Domain=\"test\"; $Port=\"99\";"+
+ "Cookie2=Value2; $Path=\"/foo\";"+
+ "\r\n"+
+ "\r\n");
+ ns.Flush ();
+ Thread.Sleep (200);
+ ns.Close();
+ }
+
+ [Test]
+ public void ReceiveCookiesFromClient ()
+ {
+ HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/SendCookie/");
+ Thread clientThread = new Thread (new ThreadStart (SendCookie));
+ clientThread.Start ();
+
+ HttpListenerContext context = listener.GetContext();
+ HttpListenerRequest request = context.Request;
+
+ Assert.AreEqual (3, request.Cookies.Count, "#1");
+ foreach (Cookie c in request.Cookies) {
+ if (c.Name == "Cookie1") {
+ Assert.AreEqual ("Value1", c.Value, "#2");
+ Assert.AreEqual ("\"/\"", c.Path, "#3");
+ Assert.AreEqual (0, c.Port.Length, "#4");
+ Assert.AreEqual (0, c.Domain.Length, "#5");
+ } else if (c.Name == "CookieM") {
+ Assert.AreEqual ("ValueM", c.Value, "#6");
+ Assert.AreEqual ("\"/p2\"", c.Path, "#7");
+ Assert.AreEqual ("\"99\"", c.Port, "#8");
+ Assert.AreEqual ("\"test\"", c.Domain, "#9");
+ } else if (c.Name == "Cookie2") {
+ Assert.AreEqual ("Value2", c.Value, "#10");
+ Assert.AreEqual ("\"/foo\"", c.Path, "#11");
+ Assert.AreEqual (0, c.Port.Length, "#12");
+ Assert.AreEqual (0, c.Domain.Length, "#13");
+ } else
+ Assert.Fail ("Invalid cookie name " + c.Name);
+ }
+
+ listener.Close ();
+ }
+
+ private object _lock = new Object();
+ private string cookieResponse;
+
+ void ReceiveCookie () {
+ lock (_lock) {
+ NetworkStream ns = CreateNS (9000);
+ Send (ns, "GET /ReceiveCookie/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
+ cookieResponse = Receive (ns, 512);
+ }
+ }
+
+ [Test]
+ public void SendCookiestoClient ()
+ {
+ HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/ReceiveCookie/");
+ Thread clientThread = new Thread (new ThreadStart (ReceiveCookie));
+ clientThread.Start ();
+
+ HttpListenerContext context = listener.GetContext();
+ HttpListenerRequest request = context.Request;
+ HttpListenerResponse response = context.Response;
+
+ Cookie cookie = new Cookie ();
+ cookie.Name = "Name0";
+ cookie.Value = "Value0";
+ cookie.Domain = "blue";
+ cookie.Path = "/path/";
+ cookie.Port = "\"80\"";
+ cookie.Version = 1;
+ response.Cookies.Add (cookie);
+
+ string responseString = "<HTML><BODY>----</BODY></HTML>";
+ byte[] buffer = Encoding.UTF8.GetBytes(responseString);
+ response.ContentLength64 = buffer.Length;
+ Stream output = response.OutputStream;
+ output.Write(buffer, 0, buffer.Length);
+ output.Flush ();
+ response.Close();
+
+ lock (_lock) {
+ bool foundCookie = false;
+ foreach (String str in cookieResponse.Split ('\n')) {
+ if (!str.StartsWith ("Set-Cookie2"))
+ continue;
+ Dictionary<string, String> dic = new Dictionary<string, String>();
+ foreach (String p in str.Substring (str.IndexOf (":") + 1).Split (';')) {
+ String[] parts = p.Split('=');
+ dic.Add (parts [0].Trim (), parts [1].Trim ());
+ }
+ Assert.AreEqual ("Value0", dic ["Name0"], "#1");
+ Assert.AreEqual ("blue", dic ["Domain"], "#2");
+ Assert.AreEqual ("\"/path/\"", dic ["Path"], "#3");
+ Assert.AreEqual ("\"80\"", dic ["Port"], "#4");
+ Assert.AreEqual ("1", dic ["Version"], "#5");
+ foundCookie = true;
+ break;
+ }
+ Assert.IsTrue (foundCookie, "#6");
+ }
+
+ listener.Close ();
+ }
+
+ [Test]
+ public void MultiResponses ()
+ {
+ Thread srv = new Thread (new ThreadStart (EchoServer));
+ srv.Start ();
+ Thread.Sleep (200);
+
+ for (int i = 0; i < 10; i++) {
+ string payload = string.Format (CultureInfo.InvariantCulture,
+ "Client{0}", i);
+
+ HttpWebRequest req = (HttpWebRequest) WebRequest.Create (
+ "http://localhost:8888/foobar/");
+ req.ServicePoint.Expect100Continue = false;
+ req.ServicePoint.UseNagleAlgorithm = false;
+ req.Method = "POST";
+ StreamWriter w = new StreamWriter (req.GetRequestStream ());
+ w.WriteLine (payload);
+ w.Close ();
+
+ HttpWebResponse resp = (HttpWebResponse) req.GetResponse ();
+ StreamReader r = new StreamReader (resp.GetResponseStream ());
+ Assert.AreEqual ("Hello, " + payload + "!", r.ReadToEnd ().Trim ());
+ r.Close ();
+ }
+
+ manualReset.Set ();
+ srv.Join ();
+ }
+
+ void EchoServer ()
+ {
+ HttpListener listener = new HttpListener ();
+ listener.Prefixes.Add ("http://*:8888/foobar/");
+ listener.Start ();
+
+ manualReset = new ManualResetEvent (false);
+
+ IAsyncResult result = listener.BeginGetContext (
+ new AsyncCallback (EchoCallback), listener);
+ manualReset.WaitOne ();
+ }
+
+ void EchoCallback (IAsyncResult result)
+ {
+ HttpListener listener = (HttpListener) result.AsyncState;
+ HttpListenerContext context = listener.EndGetContext (result);
+ HttpListenerRequest req = context.Request;
+ StreamReader r = new StreamReader (req.InputStream);
+ string reqBody = r.ReadToEnd ().Trim ();
+
+ HttpListenerResponse resp = context.Response;
+ StreamWriter o = new StreamWriter (resp.OutputStream);
+ o.WriteLine ("Hello, " + reqBody + "!");
+ o.Close ();
+
+ listener.BeginGetContext (new AsyncCallback (EchoCallback), listener);
+ }
+
+ private ManualResetEvent manualReset;
+
}
[TestFixture]