public static byte[] GetUnMaskedFrame(HttpContext Context) { while (Context.Client.Available < 2) Thread.Sleep(10); long DataSize = 0; long NowSize = 0; long HdrSize = 2; byte[] Buffer = new byte[1024]; int Size; int TotalSize = 0; List<byte> MaskBuffer = new List<byte>(); while (TotalSize < 2) //Headerの全長を知るための2byteをRead { Size = Context.HttpStream.Read(Buffer, 0, 2); MaskBuffer.AddRange(Buffer.Take(Size)); TotalSize += Size; } HdrSize = GetHeaderLength(MaskBuffer.ToArray()); //Headerの全長 if (TotalSize < HdrSize) //Headerをすべて読んでいない { HdrSize -= TotalSize; //今まで読んだ分 while (HdrSize > 0) { Size = Context.HttpStream.Read(Buffer, 0, HdrSize > Buffer.Length ? Buffer.Length : (int)HdrSize); //HeaderがBufferを超えるならBuffer分、それ以下ならHeaderの全長一気に MaskBuffer.AddRange(Buffer.Take(Size)); TotalSize += Size; HdrSize -= Size; } } DataSize = GetLength(MaskBuffer.ToArray()); //データの長さ NowSize = DataSize - TotalSize; //読むべき残りデータ while (NowSize > 0) { if (NowSize < Buffer.Length) //DataがBufferを超えないならData分 { Size = Context.HttpStream.Read(Buffer, 0, (int)NowSize); } else { Size = Context.HttpStream.Read(Buffer, 0, Buffer.Length); } MaskBuffer.AddRange(Buffer.Take(Size)); NowSize -= Size; } DataSize = 0; if ((byte)(MaskBuffer[0] & 0x0f) == 0x8)//Close { Context.Close(); return null; } else if ((byte)(MaskBuffer[0] & 0x0f) == 0x9) //Pingに返す { var SendFrame = MaskBuffer.ToArray(); SendFrame[0] = 0x8A; HttpResponse.SendResponseBody(Context, SendFrame); return null; } return UnMask(MaskBuffer.ToArray()); //全部まとめてアンマスク }
public static void SetupProcess(HttpContext Context) { if (Context.Request.Url.StartsWith("/update")) { bool OK = false; var Param = HttpUtility.ParseQueryString(Context.Request.PostString); byte[] Form; if (Param["code"] == PrivateSetting.Instance.SetupCode) { try { if (Param["ctrlhost"] == null || Param["ctrlport"] == null || Param["cbport"] == null || Param["http"] == null || Param["user"] == null || Param["pass"] == null) throw new Exception("Bad Param"); string Host = Param["ctrlhost"]; int CtrlPort = int.Parse(Param["ctrlport"]); int CbPort = int.Parse(Param["cbport"]); int HttpPort = int.Parse(Param["http"]); if (PrivateSetting.Instance.CmdConnect.StartConnect(Host, CbPort, CtrlPort)) { Setting.Instance.HttpPort = (uint)HttpPort; Setting.Instance.CtrlHost = Host; Setting.Instance.CtrlPort = (uint)CtrlPort; Setting.Instance.CallbackPort = (uint)CbPort; if (Param["user"] != null && Param["pass"] != null) { Setting.Instance.LoginUser = Param["user"]; Setting.Instance.LoginPassword = Param["pass"]; } Form = Encoding.UTF8.GetBytes("<html>\n<head></head>\n<body onload=\"setTimeout(function(){location.href = 'http://' + location.hostname + ':" + HttpPort + "\';}, 1500);\">\nplease wait....\n</body>\n</html>"); OK = true; } else { throw new Exception("Bad Connect or Auth File Not Found"); } } catch (Exception ex) { Form = Encoding.Default.GetBytes(ex.Message); } } else { Form = Encoding.UTF8.GetBytes("Invalid Code"); } if (OK) { Setting.SaveToXmlFile(PrivateSetting.Instance.ConfigPath); PrivateSetting.Instance.CmdConnect.StopConnect(); CtrlCmdConnect.Connect(); Context.Response.OutputStream.Write(Form, 0, Form.Length); Context.Response.Headers["Content-Type"] = "text/html"; Context.Response.Send(); Context.Close(); PrivateSetting.Instance.SetupMode = false; PrivateSetting.Instance.Server.Stop(); PrivateSetting.Instance.Server = new WebServer((int)Setting.Instance.HttpPort); PrivateSetting.Instance.Server.Start(); } else { Context.Response.OutputStream.Write(Form, 0, Form.Length); Context.Response.Headers["Content-Type"] = "text/html"; Context.Response.Send(); Context.Close(); } } else { byte[] Form = Encoding.UTF8.GetBytes(@" <html> \t<head> \t\t<title>Setup</title> \t</head> \t<body> \t\t<h1>EpgTimerWeb2 Configure</h1> \t\t<form action='/update' method='post'> \t\t\t<p>EDCB Server:<input name='ctrlhost' placeholder='127.0.0.1' value='127.0.0.1' /></p> \t\t\t<p>EDCB Port:<input name='ctrlport' placeholder='4510' value='4510' /></p> \t\t\t<p>Callback Port:<input name='cbport' placeholder='4521' value='4521' /></p> \t\t\t<p>Username:<input name='user' placeholder='user' /></p> \t\t\t<p>Password:<input name='pass' placeholder='pass' /></p> \t\t\t<p>Http Port:<input name='http' placeholder='8080' value='8080' /></p> \t\t\t<p>Pin Code:<input name='code' /></p> \t\t\t<p><input type='submit' value='Update config' /></p> \t\t</form> \t</body> </html> ".Replace("'", "\"")); Context.Response.OutputStream.Write(Form, 0, Form.Length); Context.Response.Headers["Content-Type"] = "text/html"; Context.Response.Headers["Cache-Control"] = "no-cache"; Context.Response.Send(); Context.Close(); } }
public static void DoProcess(TcpClient Client) { var Info = new HttpContext(Client); try { if (Info.Request.Url == "/index.htm") Info.Request.Url = "/index.html"; if (Info.Request.Url == "/") Info.Request.Url = "/index.html"; bool IsAuth = CheckCookie(Info); if (PrivateSetting.Instance.SetupMode) { Setup.SetupProcess(Info); return; } else if (Info.Request.Url.ToLower() == "/logout") { LogoutURL(Info); } else if (Info.Request.Url.ToLower() == "/login") { LoginURL(Info); } else if (Info.Request.Url.ToLower() == "/dologin") { DoLoginURL(Info); } else if (Info.Request.Url == "/index.html" && !IsAuth) { Info.Response.Headers["Cache-Control"] = "no-cache"; HttpContext.Redirect(Info, "/login"); } else if (new HttpContent().RequestUrl(Info, IsAuth)) { //Do not something... } else { if (!IsAuth) throw new HttpResponseException(401, "Unauthorized", "You need to login"); if (Info.Request.Url.ToLower() == "/resource") { Info.Response.Headers["Content-Type"] = "application/javascript; charset=utf8"; string cb = "if(typeof(ETW)==='undefined')ETW={};\nETW.Resource=" + JsonUtil.Serialize(CommonManagerJson.Instance, false) + ";"; byte[] Res = Encoding.UTF8.GetBytes(cb); Info.Response.OutputStream.Write(Res, 0, Res.Length); Info.Response.Send(); } else if (Info.Request.Url.ToLower() == "/ws") //WebSocket { Info.Response.Headers["Cache-Control"] = "no-cache"; SocketAction.Process(Info); } else if (r.IsMatch(Info.Request.Url)) { Info.Response.Headers["Cache-Control"] = "no-cache"; string Result = HTTPAPIRequest(r.Match(Info.Request.Url).Groups[1].Value); string cb = r.Match(Info.Request.Url).Groups[2].Value + "("; byte[] Res = Encoding.UTF8.GetBytes(cb + Result + ");"); Info.Response.Headers["Content-Type"] = "application/javascript; charset=utf8"; Info.Response.OutputStream.Write(Res, 0, Res.Length); Info.Response.Send(); } else if (r1.IsMatch(Info.Request.Url)) { Info.Response.Headers["Cache-Control"] = "no-cache"; string Result = HTTPAPIRequest(r1.Match(Info.Request.Url).Groups[1].Value); byte[] Res = Encoding.UTF8.GetBytes(Result); Info.Response.Headers["Content-Type"] = "application/javascript; charset=utf8"; Info.Response.OutputStream.Write(Res, 0, Res.Length); Info.Response.Send(); } else { throw new HttpResponseException(404, "Not Found", "File not found"); } } } catch (HttpResponseException http) { Info.Response.SetStatus(http.StatusCode, http.StatusText); HttpResponse.StatusPage(Info, http.Reason); Info.Response.Send(); } catch (Exception ex) { byte[] NotFound = Encoding.UTF8.GetBytes(@"<html> <body> <h1>500</h1><p>詳細: " + ex.Message + @"</p> <hr /> EpgTimerWeb(v2) by YUKI </body> </html>"); Info.Response.SetStatus(500, "Internal Server Error"); Info.Response.OutputStream.Write(NotFound, 0, NotFound.Length); Info.Response.Send(); Console.WriteLine("\n!!!! Exception !!!!"); } Info.Close(); }