virtual public bool WaitProcessing() { if (Proxy.Sock(CS.Client).Length() != 0) { return(true); } if (Proxy.Sock(CS.Server).Length() != 0) { return(true); } return(false); }
//プロキシ処理 override public bool Pipe(ILife iLife) { if (!SendServer(iLife))//サーバへの送信 { return(false); } if (!RecvServer(iLife))//サーバからの受信 { return(false); } if (!SendClient(iLife))//クライアントへの送信 { return(false); } if (Proxy.Sock(CS.Server).SockState != SockState.Connect) { if (_indexClient == _ar.Count) { return(false); } } //クライアントから切断された場合は、常に処理終了 if (Proxy.Sock(CS.Client).SockState != SockState.Connect) { Proxy.Logger.Set(LogKind.Debug, null, 999, "□Break ClientSocket!=CONNECT"); return(false); } return(true); }
//データの受信 //パラメータ cs CS.SERVER を設定した場合、buf[CS.SERVER]を処理対象とし、クライアント側に送信する bool RecvBuf(CS cs, ILife iLife) { SockTcp sock = Proxy.Sock(cs); if (sock == null)//サーバ側未接続 { return(true); } var len = sock.Length(); if (len == 0) { return(true); } var b = sock.Recv(len, Proxy.OptionTimeout, iLife); if (b == null) { return(false); } _oneObj.Body[cs].Add(b); _lastRecvServer = DateTime.Now.Ticks; return(true); }
override public void DebugLog() { var list = new List <string>(); //すべてのプロキシが完了している list.Add(string.Format("[SSL] SOCK_STATE sv={0} cl={1} HostName={2}", Proxy.Sock(CS.Server).SockState, Proxy.Sock(CS.Client).SockState, Proxy.HostName)); list.Add(string.Format("[SSL] {0}", _oneObj.Request.RequestStr)); list.Add(string.Format("[SSL] buf sv={0} cl={1} pos sv={2} cl={3} ■WaitTime={4}sec", _oneObj.Body[CS.Server].Length, _oneObj.Body[CS.Client].Length, _oneObj.Pos[CS.Server], _oneObj.Pos[CS.Client], WaitTime)); foreach (string s in list) { Proxy.Logger.Set(LogKind.Debug, null, 999, s); } }
public List <string> Debug() { List <string> list = new List <string>(); //すべてのプロキシが完了している if (indexClient == ar.Count) { list.Add(string.Format("[HTTP] SOCK_STATE sv={0} cl={1} Finish/{2} HostName={3}", proxy.Sock(CS.SERVER).State, proxy.Sock(CS.CLIENT).State, ar.Count, proxy.HostName)); } else { list.Add(string.Format("[HTTP] SOCK_STATE sv={0} cl={1} {2}/{3} HostName={4}", proxy.Sock(CS.SERVER).State, proxy.Sock(CS.CLIENT).State, ar.Count, indexClient, proxy.HostName)); for (int i = 0; i < ar.Count; i++) { List <string> l = ar[i].Debug(i); foreach (string s in l) { list.Add(s); } } } return(list); }
//クライアントへの送信がすべて完了しているかどうかの確認 override public bool IsFinish() { if (_oneObj.Body[CS.Server].Length == _oneObj.Pos[CS.Server]) { if (_oneObj.Body[CS.Client].Length == _oneObj.Pos[CS.Client]) { if (Proxy.Sock(CS.Server).Length() == 0) { return(true); } return(false); } } return(false); }
//bool WaitLine(string cmd,ref bool life) { // string cmdStr = ""; // string paramStr = ""; // string lastStr = ""; // while(life) { // if(!server.WaitLine(proxy.Sock(CS.Server),ref cmdStr,ref paramStr)) { // proxy.Sock(CS.Client).AsciiSend(lastStr); // return false; // } // if (cmdStr == cmd) // return true; // lastStr = cmdStr + " " + paramStr; // //Ver5.3.0 レスポンスコードが500番台(エラー)の場合、処理を中断する // if (cmdStr[cmdStr.Length - 1] != '-') { // //Ver5.6.3 最後が-で終わらない場合に例外が発生していた問題に対処 // //try { // // if (Int32.Parse(cmdStr) / 100 == 5) { // // proxy.Sock(CS.Client).AsciiSend(lastStr); // // return false; // // } // //} catch { // // return false; // //} // int d = 0; // if(Int32.TryParse(cmdStr,out d)){ // if(d/100==5){ // proxy.Sock(CS.Client).AsciiSend(lastStr); // return false; // } // } // } // } // return false; //} bool WaitLine(string cmd, ref string paramStr, ILife iLife) { string cmdStr = ""; //string paramStr = ""; string lastStr = ""; while (iLife.IsLife()) { if (!_server.WaitLine(Proxy.Sock(CS.Server), ref cmdStr, ref paramStr)) { Proxy.Sock(CS.Client).AsciiSend(lastStr); return(false); } if (cmdStr == cmd) { return(true); } lastStr = cmdStr + " " + paramStr; //Ver5.3.0 レスポンスコードが500番台(エラー)の場合、処理を中断する if (cmdStr[cmdStr.Length - 1] != '-') { //Ver5.6.3 最後が-で終わらない場合に例外が発生していた問題に対処 //try { // if (Int32.Parse(cmdStr) / 100 == 5) { // proxy.Sock(CS.Client).AsciiSend(lastStr); // return false; // } //} catch { // return false; //} int d; if (Int32.TryParse(cmdStr, out d)) { if (d / 100 == 5) { Proxy.Sock(CS.Client).AsciiSend(lastStr); return(false); } } } } return(false); }
//サーバ側への送信 bool SendServer(ILife iLife) { for (int i = _indexServer; iLife.IsLife() && i < _ar.Count; i++) { //次のオブジェクトの接続先が現在接続中のサーバと違う場合 if (Proxy.Sock(CS.Server) != null && _ar[i].HostName != Proxy.HostName) { //既存のプロキシ処理が完了するまで、次のサーバ送信(リクエスト送信)は待機となる if (i < _indexClient) { return(true); } } if (!_ar[i].SendServer(iLife)) { return(false); } _indexServer++; } return(true); }
//バッファに残っているデータの送信 //パラメータ cs CS.SERVER を設定した場合、buf[CS.SERVER]を処理対象とし、クライアント側に送信する bool SendBuf(CS cs) { var sock = Proxy.Sock(CS.Client); if (cs == CS.Client) { sock = Proxy.Sock(CS.Server); } var len = _oneObj.Body[cs].Length - _oneObj.Pos[cs]; if (len > 0) { var sendBuf = _oneObj.Body[cs].SendBuf((int)_oneObj.Pos[cs]); if (!Send(sock, sendBuf))//送信 { return(false); } _oneObj.Pos[cs] += len; _lastRecvServer = DateTime.Now.Ticks; } return(true); }
override public void DebugLog() { var list = new List <string>(); //すべてのプロキシが完了している if (_indexClient == _ar.Count) { list.Add(string.Format("[HTTP] SOCK_STATE sv={0} cl={1} Finish/{2} HostName={3}", Proxy.Sock(CS.Server).SockState, Proxy.Sock(CS.Client).SockState, _ar.Count, Proxy.HostName)); } else { list.Add(string.Format("[HTTP] SOCK_STATE sv={0} cl={1} {2}/{3} HostName={4}", Proxy.Sock(CS.Server).SockState, Proxy.Sock(CS.Client).SockState, _ar.Count, _indexClient, Proxy.HostName)); list.AddRange(_ar.Select((t, i) => t.DebugLog(i)).SelectMany(l => l)); } foreach (string s in list) { Proxy.Logger.Set(LogKind.Debug, null, 999, s); } }
//リクエスト行・ヘッダ・POSTデータ public bool RecvRequest(bool useRequestLog, LimitUrl limitUrl, ILife iLife) { //リクエスト取得(内部データは初期化される)ここのタイムアウト値は、大きすぎるとブラウザの切断を取得できないでブロックしてしまう if (!Request.Recv(Proxy.Logger, Proxy.Sock(CS.Client), /*timeout*/ 3, iLife)) { return(false); } //ヘッダの取得 if (!Header[CS.Client].Recv(Proxy.Sock(CS.Client), Proxy.OptionTimeout, iLife)) { return(false); } //POSTの場合は、更にクライアントからのデータを読み込む if (Request.Protocol == ProxyProtocol.Http && Request.HttpMethod == HttpMethod.Post) //POSTの場合 { string strContentLength = Header[CS.Client].GetVal("Content-Length"); if (strContentLength != null) { try { var len = Convert.ToInt32(strContentLength); //Ver5.9.7 // if(0 < len) { // Body[CS.Client].Set(Proxy.Sock(CS.Client).Recv(len,Proxy.OptionTimeout,iLife)); // } if (0 < len) { var buf = new byte[0]; while (iLife.IsLife()) { var size = len - buf.Length; var b = Proxy.Sock(CS.Client).Recv(size, Proxy.OptionTimeout, iLife); buf = Bytes.Create(buf, b); if (len <= buf.Length) { break; } } Body[CS.Client].Set(buf); } } catch { Proxy.Logger.Set(LogKind.Error, null, 22, Request.Uri); return(false); } } } //bool useRequestLog リクエストを通常ログで表示する //proxy.Logger.Set(useRequestLog ? LogKind.Normal : LogKind.Detail,null,0,string.Format("{0}",Request.RequestStr)); Proxy.Logger.Set(useRequestLog ? LogKind.Normal : LogKind.Detail, Proxy.Sock(CS.Client), 0, string.Format("{0}", Request.RequestStr)); //URL制限 string[] tmp = Request.RequestStr.Split(' '); if (tmp.Length != 3) { Proxy.Logger.Set(LogKind.Normal, null, 10, "a parameter includes a problem"); return(false); } string errorStr = ""; if (!limitUrl.IsAllow(tmp[1], ref errorStr)) { Proxy.Logger.Set(LogKind.Normal, null, 10, errorStr); return(false); } return(true); }
public bool SendServer(ILife iLife) { //処置なし if (_sideState[CS.Server] != HttpSideState.Non && _sideState[CS.Server] != HttpSideState.ServerSideSendHeader) { return(true); } //サーバ側との接続処理 if (!_proxy.Connect(iLife, _oneObj.Request.HostName, _oneObj.Request.Port, _oneObj.Request.RequestStr, _oneObj.Request.Protocol)) { _proxy.Logger.Set(LogKind.Debug, null, 999, "□Break http.Connect()==false"); return(false); } //ヘッダ送信 var sendBuf = new byte[0]; if (_sideState[CS.Server] == HttpSideState.Non) { if (_proxy.UpperProxy.Use) { if (_proxy.UpperProxy.UseAuth) { var s = string.Format("{0}:{1}", _proxy.UpperProxy.AuthUser, _proxy.UpperProxy.AuthPass); s = string.Format("Basic {0}\r\n", Base64.Encode(s)); _oneObj.Header[CS.Client].Append("Proxy-Authorization", Encoding.ASCII.GetBytes(s)); } } if (_oneObj.Request.Protocol == ProxyProtocol.Ssl) { if (!_proxy.UpperProxy.Use) { //取得したリクエストをバッファに格納する //sendBuf = new byte[0]; //sendBuf[CS.CLIENT] = Bytes.Create("HTTP/1.0 200 Connection established\r\n\r\n");//CONNECTが成功したことをクライアントに返す } else { //上位プロキシを使用する場合(リクエストラインはそのまま使用される) sendBuf = Bytes.Create(_oneObj.Request.SendLine(_proxy.UpperProxy.Use), _oneObj.Header[CS.Client].GetBytes()); } } else if (_oneObj.Request.Protocol == ProxyProtocol.Http) //HTTPの場合 //Ver5.4.4 //"Proxy-Connection"ヘッダは,"Connection"ヘッダに変換する { var s = _oneObj.Header[CS.Client].GetVal("Proxy-Connection"); if (s != null) //ヘッダが存在する場合 { _oneObj.Header[CS.Client].Replace("Proxy-Connection", "Connection", s); } //header.Remove("Proxy-Connection");//<=■これ入れていいのか? //取得したリクエストをバッファに格納する //上位プロキシを使用する場合(リクエストラインはそのまま使用される) sendBuf = Bytes.Create(_oneObj.Request.SendLine(_proxy.UpperProxy.Use), _oneObj.Header[CS.Client].GetBytes()); } if (!Send(_proxy.Sock(CS.Server), sendBuf))//送信 { return(false); } _sideState[CS.Server] = HttpSideState.ServerSideSendHeader; } if (_sideState[CS.Server] == HttpSideState.ServerSideSendHeader) { //バッファに残っているデータの送信 if (!SendBuf(CS.Client)) { return(false); } } //サーバへの送信完了を確認する(ステータス変更) _sideState[CS.Server] = HttpSideState.ServerSideSendBody; return(true); }
//プロキシ処理 override public bool Pipe(ILife iLife) { DataThread dataThread = null; var paramStr = ""; //サーバ側との接続処理 if (!Proxy.Connect(iLife, _oneObj.Request.HostName, _oneObj.Request.Port, _oneObj.Request.RequestStr, _oneObj.Request.Protocol)) { Proxy.Logger.Set(LogKind.Debug, null, 999, "□Break proxy.Connect()==false"); return(false); } //wait 220 welcome if (!WaitLine("220", ref paramStr, iLife)) { return(false); } Proxy.Sock(CS.Server).AsciiSend(string.Format("USER {0}", _user)); if (!WaitLine("331", ref paramStr, iLife)) { return(false); } Proxy.Sock(CS.Server).AsciiSend(string.Format("PASS {0}", _pass)); if (!WaitLine("230", ref paramStr, iLife)) { return(false); } //Ver5.6.6 if (_path == "/") { Proxy.Sock(CS.Server).AsciiSend("PWD"); if (!WaitLine("257", ref paramStr, iLife)) { return(false); } var tmp = paramStr.Split(' '); if (tmp.Length >= 1) { _path = tmp[0].Trim(new[] { '"' }); if (_path[_path.Length - 1] != '/') { _path = _path + "/"; } } } //リクエスト if (_path != "") { Proxy.Sock(CS.Server).AsciiSend(string.Format("CWD {0}", _path)); if (!WaitLine("250", ref paramStr, iLife)) { goto end; } } Proxy.Sock(CS.Server).AsciiSend(_file == "" ? "TYPE A" : "TYPE I"); if (!WaitLine("200", ref paramStr, iLife)) { goto end; } //PORTコマンド送信 var bindAddr = Proxy.Sock(CS.Server).LocalIp; // 利用可能なデータポートの選定 while (iLife.IsLife()) { DataPort++; if (DataPort >= 9999) { DataPort = 2000; } if (SockServer.IsAvailable(_kernel, bindAddr, DataPort)) { break; } } int listenPort = DataPort; //データスレッドの生成 dataThread = new DataThread(_kernel, bindAddr, listenPort); // サーバ側に送るPORTコマンドを生成する string str = string.Format("PORT {0},{1},{2},{3},{4},{5}", bindAddr.IpV4[0], bindAddr.IpV4[1], bindAddr.IpV4[2], bindAddr.IpV4[3], listenPort / 256, listenPort % 256); Proxy.Sock(CS.Server).AsciiSend(str); if (!WaitLine("200", ref paramStr, iLife)) { goto end; } if (_file == "") { Proxy.Sock(CS.Server).AsciiSend("LIST"); if (!WaitLine("150", ref paramStr, iLife)) { goto end; } } else { Proxy.Sock(CS.Server).AsciiSend("RETR " + _file); if (!WaitLine("150", ref paramStr, iLife)) { goto end; } } //Ver5.0.2 while (iLife.IsLife()) { if (!dataThread.IsRecv) { break; } } if (!WaitLine("226", ref paramStr, iLife)) { goto end; } byte[] doc; if (_file == "") { //受信結果をデータスレッドから取得する List <string> lines = Inet.GetLines(dataThread.ToString()); //FTPサーバから取得したLISTの情報をHTMLにコンバートする doc = ConvFtpList(lines, _path); } else { doc = dataThread.ToBytes(); } //クライアントへリプライ及びヘッダを送信する var header = new Header(); header.Replace("Server", Util.SwapStr("$v", _kernel.Ver.Version(), (string)_conf.Get("serverHeader"))); header.Replace("MIME-Version", "1.0"); if (_file == "") { header.Replace("Date", Util.UtcTime2Str(DateTime.UtcNow)); header.Replace("Content-Type", "text/html"); } else { header.Replace("Content-Type", "none/none"); } header.Replace("Content-Length", doc.Length.ToString()); Proxy.Sock(CS.Client).AsciiSend("HTTP/1.0 200 OK"); //リプライ送信 Proxy.Sock(CS.Client).SendUseEncode(header.GetBytes()); //ヘッダ送信 Proxy.Sock(CS.Client).SendNoEncode(doc); //ボディ送信 end: if (dataThread != null) { dataThread.Dispose(); } return(false); }
public bool SendServer(ref bool life) { //サーバ側との接続処理 if (!proxy.Connect(ref life, oneObj.Request.HostName, oneObj.Request.Port, oneObj.Request.RequestStr, oneObj.Request.Protocol)) { proxy.Logger.Set(LOG_KIND.DEBUG, null, 999, "□Break http.Connect()==false"); return(false); } //ヘッダ送信 byte[] sendBuf = new byte[0]; if (sideState[CS.SERVER] == HTTP_SIDE_STATE.NON) { if (oneObj.Request.Protocol == PROXY_PROTOCOL.SSL) { if (!proxy.UpperProxy.Use) { //取得したリクエストをバッファに格納する //sendBuf = new byte[0]; //sendBuf[CS.CLIENT] = Bytes.Create("HTTP/1.0 200 Connection established\r\n\r\n");//CONNECTが成功したことをクライアントに返す } else { //上位プロキシを使用する場合(リクエストラインはそのまま使用される) sendBuf = Bytes.Create(oneObj.Request.SendLine(proxy.UpperProxy.Use), oneObj.Header[CS.CLIENT].GetBytes()); } } else if (oneObj.Request.Protocol == PROXY_PROTOCOL.HTTP) //HTTPの場合 //header.Remove("Proxy-Connection");//<=■これ入れていいのか? //取得したリクエストをバッファに格納する //上位プロキシを使用する場合(リクエストラインはそのまま使用される) { sendBuf = Bytes.Create(oneObj.Request.SendLine(proxy.UpperProxy.Use), oneObj.Header[CS.CLIENT].GetBytes()); } if (!Send(proxy.Sock(CS.SERVER), sendBuf))//送信 { return(false); } sideState[CS.SERVER] = HTTP_SIDE_STATE.SERVER_SIDE_SEND_HEADER; } if (sideState[CS.SERVER] == HTTP_SIDE_STATE.SERVER_SIDE_SEND_HEADER) { //バッファに残っているデータの送信 if (!SendBuf(CS.CLIENT)) { return(false); } } //サーバへの送信完了を確認する(ステータス変更) sideState[CS.SERVER] = HTTP_SIDE_STATE.SERVER_SIDE_SEND_BODY; return(true); }