public static Thread CreateServer(IPAddress ipa, int port, Action <string> Console_WriteLine) { var random = new System.Random(); // Error 312 (net::ERR_UNSAFE_PORT): Unknown error. if (port < 1024) { port = random.Next(1024, 32000); } var cid = 0; NetworkStreamAction AtConnection = s => { var id = cid++; Console_WriteLine("#" + cid); //log("AtConnection"); var r = new SmartStreamReader(s); var HTTP_METHOD_PATH_QUERY = r.ReadLine(); Console_WriteLine("#" + cid + HTTP_METHOD_PATH_QUERY); var HTTP_METHOD = HTTP_METHOD_PATH_QUERY.TakeUntilOrEmpty(" "); if (HTTP_METHOD != "POST") { if (HTTP_METHOD != "GET") { var m = new MemoryStream(); Action <string> WriteLineASCII = (string e) => { var x = Encoding.ASCII.GetBytes(e + "\r\n"); m.Write(x, 0, x.Length); }; Console_WriteLine("#" + cid + " 500"); WriteLineASCII("HTTP/1.1 500 OK"); WriteLineASCII("Connection: close"); var oa = m.ToArray(); s.Write(oa, 0, oa.Length); s.Flush(); s.Close(); return; } } var HTTP_PATH_QUERY = HTTP_METHOD_PATH_QUERY.SkipUntilOrEmpty(" ").TakeUntilLastOrEmpty(" "); var HTTP_PATH = HTTP_PATH_QUERY.TakeUntilIfAny("?"); var HTTP_QUERY = HTTP_PATH_QUERY.SkipUntilOrEmpty("?"); var HTTP_HEADERS = new List <string>(); var br = r.ReadLine(); while (!string.IsNullOrEmpty(br)) { HTTP_HEADERS.Add(br); br = r.ReadLine(); } var data = r.ReadToMemoryStream(); //log("ReadLine done"); { var m = new MemoryStream(); Action <string> WriteLineASCII = (string e) => { var x = Encoding.ASCII.GetBytes(e + "\r\n"); m.Write(x, 0, x.Length); }; Console_WriteLine("#" + cid + " 200"); WriteLineASCII("HTTP/1.1 200 OK"); WriteLineASCII("Content-Type: text/html; charset=utf-8"); //WriteLineASCII("Content-Length: " + data.Length); WriteLineASCII("Connection: close"); WriteLineASCII(""); WriteLineASCII(""); WriteLineASCII("<html>"); WriteLineASCII("<body>"); //WriteLineASCII("<pre style='color: blue;'>" + new { HTTP_METHOD, HTTP_PATH, HTTP_QUERY, data = data.Length } + "</pre>"); WriteLineASCII("<code style='color: green;'>HTTP_METHOD: " + HTTP_METHOD + "</code><br />"); WriteLineASCII("<code style='color: green;'>HTTP_PATH: " + HTTP_PATH + "</code><br />"); WriteLineASCII("<code style='color: green;'>HTTP_QUERY: " + HTTP_QUERY + "</code><br />"); WriteLineASCII("<code style='color: green;'>data: " + data.Length + "</code><br />"); WriteLineASCII("<code style='color: green;'>data: 0x" + data.Length.ToString("x8") + "</code><br />"); var boundary = ""; foreach (var item in HTTP_HEADERS.ToArray()) { var HeaderKey = item.TakeUntilOrEmpty(":"); var HeaderValue = item.SkipUntilIfAny(":"); // http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 // http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html if (HeaderKey == "Content-Type") { boundary = HeaderValue.SkipUntilOrEmpty("multipart/form-data; boundary="); } WriteLineASCII("<code style='color: gray;'>" + HeaderKey + "</code>:"); WriteLineASCII("<code style='color: green;'>" + HeaderValue + "</code><br />"); } WriteLineASCII("<hr />"); WriteLineASCII("<pre>" + boundary + "</pre>"); WriteLineASCII("<hr />"); WriteLineASCII("<h1 style='color: red;'>Hello world</h2><h3>jsc</h3>"); WriteLineASCII("<pre>" + HTTP_METHOD_PATH_QUERY + "</pre>"); if (string.IsNullOrEmpty(boundary)) { WriteLineASCII("<pre>" + WriteHexDump(data.ToBytes()) + "</pre>"); } if (!string.IsNullOrEmpty(boundary)) { boundary = "--" + boundary; var bytes = data.ToBytes(); var boundarybytes = Encoding.ASCII.GetBytes(boundary); var boundaries = new List <Int32Box>(); for (int i = 0; i < bytes.Length - boundarybytes.Length; i++) { var AtBoundary = false; // is i at boundary? for (int j = 0; j < boundarybytes.Length; j++) { if (bytes[i + j] != boundarybytes[j]) { AtBoundary = false; break; } AtBoundary = true; } if (AtBoundary) { boundaries.Add(new Int32Box { value = i }); } } var boundaries_a = boundaries.ToArray(); for (int i = 0; i < boundaries_a.Length - 1; i++) { var start = boundaries_a[i].value + boundarybytes.Length + 2; var end = boundaries_a[i + 1].value; var chunk = new byte[end - start]; Array.Copy(bytes, start, chunk, 0, chunk.Length); WriteLineASCII("<hr />"); WriteLineASCII("<pre>" + WriteHexDump(chunk) + "</pre>"); } } WriteLineASCII("<hr />"); WriteLineASCII("<form target='_blank' action='?WebMethod=06000048' method='POST'><br /> <img src='http://i.msdn.microsoft.com/deshae98.pubmethod(en-us,VS.90).gif' /> method: <code><a href='?WebMethod=06000048'>Hello</a></code><input type='submit' value='Invoke' /><br /> <img src='http://i.msdn.microsoft.com/yxcx7skw.pubclass(en-us,VS.90).gif' /> parameter: <code>data</code> = <input type='text' name='_06000048_data' value='' /><br /> <img src='http://i.msdn.microsoft.com/yxcx7skw.pubdelegate(en-us,VS.90).gif' /> parameter: <code>result</code></form>"); WriteLineASCII("<form target='_blank' action='?WebMethod=06000048' method='POST' enctype='multipart/form-data'>"); WriteLineASCII(" <input type='file' name='pic' size='40' accept='image/*' />"); WriteLineASCII(" <input type='file' name='foo' />"); WriteLineASCII(" <br /> <img src='http://i.msdn.microsoft.com/deshae98.pubmethod(en-us,VS.90).gif' /> method: <code><a href='?WebMethod=06000048'>Hello</a></code><input type='submit' value='Invoke' /><br /> <img src='http://i.msdn.microsoft.com/yxcx7skw.pubclass(en-us,VS.90).gif' /> parameter: <code>data</code> = <input type='text' name='_06000048_data' value='' /><br /> <img src='http://i.msdn.microsoft.com/yxcx7skw.pubdelegate(en-us,VS.90).gif' /> parameter: <code>result</code></form>"); WriteLineASCII("</body>"); WriteLineASCII("</body>"); WriteLineASCII("</html>"); var oa = m.ToArray(); s.Write(oa, 0, oa.Length); s.Flush(); s.Close(); } }; var t = new Thread( delegate() { Console_WriteLine(ipa + ":" + port); var r = new TcpListener(ipa, port); //try //{ r.Start(); while (true) { //log("AcceptTcpClient"); var c = r.AcceptTcpClient(); //log("AcceptTcpClient done, GetStream"); var s = c.GetStream(); //log("AcceptTcpClient done, GetStream done"); //AtConnection(s); new Thread( delegate() { //log("before AtConnection"); AtConnection(s); } ) { IsBackground = true, }.Start(); } //} //catch //{ // log("AcceptTcpClient error!"); // throw; //} } ) { IsBackground = true, }; return(t); }
public static Thread CreateServer( ContextWrapper InternalContext, IPAddress ipa, int port, Action <string> Console_WriteLine, InternalFileInfo[] Files) { var random = new System.Random(); // Error 312 (net::ERR_UNSAFE_PORT): Unknown error. if (port < 1024) { port = random.Next(1024, 32000); } var cid = 0; NetworkStreamAction AtConnection = InternalStream => { var id = cid++; Console_WriteLine("#" + cid); //log("AtConnection"); var r = new SmartStreamReader(InternalStream); #region __Global var __Request = new __HttpRequest(); var __Response = new __HttpResponse { InternalStream = InternalStream, InternalContext = InternalContext }; var __Global = new __Global(); __Global.Files = Files; __Global.WebMethods = new InternalWebMethodInfo[] { new InternalWebMethodInfo { Name = "WebMethod2", TypeFullName = "TestGAE.ApplicationWebService", MetadataToken = "06000001", Parameters = new InternalWebMethodParameterInfo[] { new InternalWebMethodParameterInfo { Name = "e", Value = "", IsDelegate = false }, new InternalWebMethodParameterInfo { Name = "y", Value = "", IsDelegate = true } } } }; __Global.ScriptApplications = new[] { new WebServiceScriptApplication { TypeName = "Application", TypeFullName = "TestGAE.Application", PageSource = "<body>\r\n <noscript>Error: This Application requires JavaScript.</noscript>\r\n <link rel=\"stylesheet\" href=\"assets/TestGAE/Default.css\" />\r\n <div id=\"PageContainer\">\r\n <h1 id=\"Header\">JSC - The .NET crosscompiler for web platforms.</h1>\r\n <p id=\"Content\" style=\"padding: 2em; color: blue;\">Hello world</p>\r\n </div>\r\n</body>", References = new [] { new WebServiceScriptApplication.Reference { AssemblyFile = "ScriptCoreLib.dll" }, new WebServiceScriptApplication.Reference { AssemblyFile = "TestGAE.Application.exe" } } } }; ((__HttpApplication)(object)__Global).Request = (HttpRequest)(object)__Request; ((__HttpApplication)(object)__Global).Response = (HttpResponse)(object)__Response; var Context = __Global.Context; #endregion #region __Request { HttpMethod, QueryString, Headers } var HTTP_METHOD_PATH_QUERY = r.ReadLine(); var HTTP_METHOD = HTTP_METHOD_PATH_QUERY.TakeUntilOrEmpty(" "); __Request.HttpMethod = HTTP_METHOD; Console.WriteLine("#" + cid + " " + HTTP_METHOD_PATH_QUERY); #region check METHOD if (HTTP_METHOD != "POST") { if (HTTP_METHOD != "GET") { var m = new MemoryStream(); Action <string> WriteLineASCII = (string e) => { var x = Encoding.ASCII.GetBytes(e + "\r\n"); m.Write(x, 0, x.Length); }; Console_WriteLine("#" + cid + " 500"); WriteLineASCII("HTTP/1.1 500 OK"); WriteLineASCII("Connection: close"); var oa = m.ToArray(); InternalStream.Write(oa, 0, oa.Length); InternalStream.Flush(); InternalStream.Close(); return; } } #endregion var HTTP_PATH_QUERY = HTTP_METHOD_PATH_QUERY.SkipUntilOrEmpty(" ").TakeUntilLastOrEmpty(" "); var HTTP_PATH = HTTP_PATH_QUERY.TakeUntilIfAny("?"); __Request.Path = HTTP_PATH; #region QueryString var HTTP_QUERY = HTTP_PATH_QUERY.SkipUntilOrEmpty("?"); var __QueryStringItems = HTTP_QUERY.Split('&'); foreach (var item in __QueryStringItems) { var Key = item.TakeUntilOrEmpty("="); if (!string.IsNullOrEmpty(Key)) { var Value = item.SkipUntilIfAny("="); __Request.QueryString[Key] = Value; } } #endregion __Request.Headers["Content-Type"] = ""; #region Headers var NextHeader = r.ReadLine(); while (!string.IsNullOrEmpty(NextHeader)) { // http://www.nextthing.org/archives/2005/08/07/fun-with-http-headers var HeaderKey = NextHeader.TakeUntilOrEmpty(":"); var HeaderValue = NextHeader.SkipUntilIfAny(":").Trim(); __Request.Headers[HeaderKey] = HeaderValue; NextHeader = r.ReadLine(); } #endregion #endregion var data = r.ReadToMemoryStream(); var boundary = __Request.Headers["Content-Type"].SkipUntilOrEmpty("multipart/form-data; boundary="); #region Form if (__Request.Headers["Content-Type"] == "application/x-www-form-urlencoded") { var p = Encoding.UTF8.GetString(data.ToBytes()); var q = p.Split('&'); foreach (var item in q) { var Key = item.TakeUntilOrEmpty("="); var Value = item.SkipUntilIfAny("="); __Request.Form[Key] = Value; } } #endregion #region selected_item var selected_item = default(InternalFileInfo); foreach (var item in Files) { // LINQ please! if (HTTP_PATH == "/" + item.Name) { selected_item = item; } } #endregion { if (__Request.Path == "/jsc") { __InternalGlobalExtensions.InternalApplication_BeginRequest(__Global); } else { InternalGlobalExtensions.InternalApplication_BeginRequest(__Global); } Console.WriteLine("#" + cid + " " + HTTP_METHOD_PATH_QUERY + " done"); return; //} #region selected_item if (selected_item != null) { var path = selected_item.Name; __Response.StatusCode = 200; __Response.Headers["X-Handler"] = "http://jsc-solutions.net"; if (path.EndsWith(".gif")) { __Response.ContentType = ("image/gif"); } else if (path.EndsWith(".png")) { __Response.ContentType = ("image/png"); } else if (path.EndsWith(".htm")) { __Response.ContentType = ("text/html; charset=utf-8"); } else { __Response.ContentType = ("application/octet-stream"); } __Response.WriteFile(path); InternalStream.Close(); __Global.CompleteRequest(); return; } #endregion __Response.StatusCode = 200; __Response.ContentType = ("text/html; charset=utf-8"); __Response.Headers["X-Handler"] = "http://jsc-solutions.net"; #region index #region WriteLineASCII Action <string> WriteLine = (string e) => { __Response.Write(e + "\r\n"); }; #endregion #region html index WriteLine("<html>"); WriteLine("<body>"); foreach (var HeaderKey in Context.Request.Headers.AllKeys) { var HeaderValue = Context.Request.Headers[HeaderKey]; WriteLine("<code style='color: gray;'>" + HeaderKey + "</code>:"); WriteLine("<code style='color: green;'>" + HeaderValue + "</code><br />"); } WriteLine("<h3>data: 0x" + data.Length.ToString("x8") + "</h3>"); WriteLine("<pre>" + boundary + "</pre>"); WriteLine("<hr />"); WriteLine("<pre>" + HTTP_METHOD_PATH_QUERY + "</pre>"); if (string.IsNullOrEmpty(boundary)) { WriteLine("<pre>" + WriteHexDump(data.ToBytes()) + "</pre>"); } #region by boundary if (!string.IsNullOrEmpty(boundary)) { boundary = "--" + boundary; var bytes = data.ToBytes(); var boundarybytes = Encoding.ASCII.GetBytes(boundary); var boundaries = new List <Int32Box>(); for (int i = 0; i < bytes.Length - boundarybytes.Length; i++) { var AtBoundary = false; // is i at boundary? for (int j = 0; j < boundarybytes.Length; j++) { if (bytes[i + j] != boundarybytes[j]) { AtBoundary = false; break; } AtBoundary = true; } if (AtBoundary) { boundaries.Add(new Int32Box { value = i }); } } var boundaries_a = boundaries.ToArray(); for (int i = 0; i < boundaries_a.Length - 1; i++) { var start = boundaries_a[i].value + boundarybytes.Length + 2; var end = boundaries_a[i + 1].value; var chunk = new byte[end - start]; Array.Copy(bytes, start, chunk, 0, chunk.Length); WriteLine("<hr />"); WriteLine("<pre>" + WriteHexDump(chunk) + "</pre>"); } } #endregion WriteLine("<hr />"); WriteLine("<form target='_blank' action='/jsc?WebMethod=06000048' method='POST'><br /> <img src='http://i.msdn.microsoft.com/deshae98.pubmethod(en-us,VS.90).gif' /> method: <code><a href='?WebMethod=06000048'>Hello</a></code><input type='submit' value='Invoke' /><br />"); WriteLine(" <img src='http://i.msdn.microsoft.com/yxcx7skw.pubclass(en-us,VS.90).gif' /> parameter: <code>data</code> = <input type='text' name='_06000048_data' value='' /><br />"); WriteLine(" <img src='http://i.msdn.microsoft.com/yxcx7skw.pubclass(en-us,VS.90).gif' /> parameter: <code>foo</code> = <input type='text' name='_06000048_foo' value='' /><br />"); WriteLine(" <img src='http://i.msdn.microsoft.com/yxcx7skw.pubdelegate(en-us,VS.90).gif' /> parameter: <code>result</code></form>"); WriteLine("<hr />"); WriteLine("<form target='_blank' action='/jsc?WebMethod=06000048' method='POST' enctype='multipart/form-data'>"); WriteLine(" <br /> <img src='http://i.msdn.microsoft.com/deshae98.pubmethod(en-us,VS.90).gif' /> method: <code><a href='?WebMethod=06000048'>Hello</a></code><input type='submit' value='Invoke' /><br />"); WriteLine(" <img src='http://i.msdn.microsoft.com/yxcx7skw.pubclass(en-us,VS.90).gif' /> parameter: <code>data</code> = <input type='text' name='_06000048_data' value='' /><br />"); WriteLine(" <img src='http://i.msdn.microsoft.com/yxcx7skw.pubclass(en-us,VS.90).gif' /> parameter: <code>foo</code> = <input type='text' name='_06000048_foo' value='' /><br />"); WriteLine(" <img src='http://i.msdn.microsoft.com/yxcx7skw.pubdelegate(en-us,VS.90).gif' /> parameter: <code>result</code></form>"); WriteLine("<hr />"); WriteLine("<form target='_blank' action='?WebMethod=06000048' method='POST' enctype='multipart/form-data'>"); WriteLine(" <input type='file' name='pic' size='40' accept='image/*' />"); WriteLine(" <input type='file' name='foo' />"); WriteLine(" <br /> <img src='http://i.msdn.microsoft.com/deshae98.pubmethod(en-us,VS.90).gif' /> method: <code><a href='?WebMethod=06000048'>Hello</a></code><input type='submit' value='Invoke' /><br />"); WriteLine(" <img src='http://i.msdn.microsoft.com/yxcx7skw.pubclass(en-us,VS.90).gif' /> parameter: <code>data</code> = <input type='text' name='_06000048_data' value='' /><br />"); WriteLine(" <img src='http://i.msdn.microsoft.com/yxcx7skw.pubclass(en-us,VS.90).gif' /> parameter: <code>foo</code> = <input type='text' name='_06000048_foo' value='' /><br />"); WriteLine(" <img src='http://i.msdn.microsoft.com/yxcx7skw.pubdelegate(en-us,VS.90).gif' /> parameter: <code>result</code></form>"); WriteLine("</body>"); WriteLine("</html>"); #endregion InternalStream.Flush(); InternalStream.Close(); #endregion } }; var t = new Thread( delegate() { Console_WriteLine(ipa + ":" + port); var r = new TcpListener(ipa, port); //try //{ r.Start(); while (true) { //log("AcceptTcpClient"); var c = r.AcceptTcpClient(); //log("AcceptTcpClient done, GetStream"); var s = c.GetStream(); //log("AcceptTcpClient done, GetStream done"); //AtConnection(s); new Thread( delegate() { //log("before AtConnection"); AtConnection(s); } ) { IsBackground = true, }.Start(); } //} //catch //{ // log("AcceptTcpClient error!"); // throw; //} } ) { IsBackground = true, }; return(t); }