//再帰処理関数 //long GetInfo1(ref List<CacheInfo> infoList, string path, int sleep, ref bool life) { long GetInfo1(ref List <CacheInfo> infoList, string path, int sleep, ILife iLife) { var dt = new DateTime(0); var size = 0L; foreach (string file in Directory.GetDirectories(path)) { size += GetInfo1(ref infoList, file, sleep, iLife); if (!iLife.IsLife()) { return(0); } Thread.Sleep(sleep); foreach (string name in Directory.GetFiles(file)) { if (!iLife.IsLife()) { return(0); } Thread.Sleep(sleep); var fi = new FileInfo(name); var str = name.Substring(_dir.Length + 1); str = Util.SwapChar('\\', '/', str); str = Util.SwapStr("$$$", "", str); var index = str.IndexOf('/'); if (0 <= index) { var host = str.Substring(0, index); var uri = str.Substring(index); index = host.LastIndexOf('_'); if (0 <= index) { var hostName = host.Substring(0, index); var portStr = host.Substring(index + 1); var port = Convert.ToInt32(portStr); infoList.Add(new CacheInfo(hostName, port, uri, dt, dt, fi.CreationTime, fi.LastAccessTime, fi.Length)); } } size += fi.Length; } } return(size); }
//1行受信 //切断・タイムアウトでnullが返される public byte[] LineRecv(int sec, ILife iLife) { var tout = new util.Timeout(sec); while (iLife.IsLife()) { //Ver5.1.6 if (_sockQueue.Length == 0) { Thread.Sleep(100); } byte[] buf = _sockQueue.DequeueLine(); //noEncode = false;//テキストである事が分かっている Trace(TraceKind.Recv, buf, false); if (buf.Length != 0) { //Ver5.8.6 Java fix tout.Update(); //タイムアウトの更新 return(buf); } if (SockState != SockState.Connect) { return(null); } if (tout.IsFinish()) { return(null); //タイムアウト } Thread.Sleep(1); } return(null); }
//指定したアドレス・ポートで待ち受けて、接続されたら、そのソケットを返す //失敗した時nullが返る //Ver5.9.2 Java fix //public static SockTcp CreateConnection(Kernel kernel,Ip ip, int port,ILife iLife){ public static SockTcp CreateConnection(Kernel kernel, Ip ip, int port, Ssl ssl, ILife iLife) { //Ver5.9.2 Java fix //var sockServer = new SockServer(kernel,ProtocolKind.Tcp); var sockServer = new SockServer(kernel, ProtocolKind.Tcp, ssl); if (sockServer.SockState != SockState.Error) { const int listenMax = 1; if (sockServer.Bind(ip, port, listenMax)) { while (iLife.IsLife()) { var child = (SockTcp)sockServer.Select(iLife); if (child == null) { break; } sockServer.Close(); //これ大丈夫? return(child); } } } sockServer.Close(); return(null); }
//クライアント側への送信 bool SendClient(ILife iLife) { for (int i = _indexClient; iLife.IsLife() && i < _ar.Count; i++) { if (!_ar[i].SendClient(iLife)) { return(false); } //クライアントへの送信が完了しているかどうかの確認 if (_ar[i].SideState(CS.Client) != HttpSideState.ClientSideSendBody) { break; } //送信が完了している場合は、次のデータオブジェクトの処理に移行する //proxy.Logger.Set(LogKind.Debug,null,999,string.Format("■indexClient {0}->{1}",indexClient,indexClient + 1)); //キャッシュが可能な場合は、ここでキャッシュされる _ar[_indexClient].CacheWrite(_cache); //ここでオブジェクトは破棄される _ar[_indexClient].Dispose(); _indexClient++; } return(true); }
//キャッシュ情報取得処理 // public override long GetInfo(ref List<CacheInfo> infoList, int sleep, ref bool life) { public override long GetInfo(ref List<CacheInfo> infoList, int sleep, ILife iLife) { var size = 0L; foreach (var o in _ar) { if (!iLife.IsLife()) return 0; infoList.Add(new CacheInfo(o.HostName, o.Port, o.Uri, o.LastModified, o.Expires, o.CreateDt, o.LastAccess, o.Length)); size += o.Length; } return size; }
//キャッシュ情報取得処理 // public override long GetInfo(ref List<CacheInfo> infoList, int sleep, ref bool life) { public override long GetInfo(ref List <CacheInfo> infoList, int sleep, ILife iLife) { var size = 0L; foreach (var o in _ar) { if (!iLife.IsLife()) { return(0); } infoList.Add(new CacheInfo(o.HostName, o.Port, o.Uri, o.LastModified, o.Expires, o.CreateDt, o.LastAccess, o.Length)); size += o.Length; } return(size); }
//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); }
//受信(無効な場合 return null) public static OneRemoteData Recv(SockTcp sockTcp, ILife iLife) { if (sockTcp != null) { //Ver5.8.6 var sec = 10; //最初はタイムアウト値を最小に設定する var b = sockTcp.Recv(1, sec, iLife); //REMOTE_DATA_KINDの受信 if (b != null && b.Length == 1) { var kind = (RemoteDataKind)b[0]; //これ以降は、データが到着しているはずなので、タイムアウト値を上げて待機する //timeout = 3000; //Ver5.8.6 sec = 10; Thread.Sleep(1); b = sockTcp.Recv(4, sec, iLife);//データサイズの受信 if (b != null && b.Length == 4) { var len = BitConverter.ToInt32(b, 0); if (len == 0) { return(new OneRemoteData(kind, ""));//データ本体はサイズ0 } //Ver5.8.6 b = new byte[0]; while (iLife.IsLife()) { Thread.Sleep(1); var buf = sockTcp.Recv(len, sec, iLife);//データ本体の受信 if (buf == null) { return(null); } b = Bytes.Create(b, buf); if (b.Length == len) { return(new OneRemoteData(kind, Encoding.GetEncoding(932).GetString(b))); } } } } } return(null); }
//サーバ側からの受信 bool RecvServer(ILife iLife) { for (int i = _indexRecv; iLife.IsLife() && i < _ar.Count; i++) { if (!_ar[i].RecvServer(iLife)) { Proxy.Logger.Set(LogKind.Debug, null, 999, "[HTTP] Break RecvServer()"); return(false); } //サーバ側からの受信が完了しているかどうかの確認 if (_ar[i].SideState(CS.Server) != HttpSideState.ServerSideRecvBody) { break; } //送信が完了しているばあは、次のデータオブジェクトの処理に移る _indexRecv++; } return(true); }
public SockObj Select(ILife iLife) { while (iLife.IsLife()) { if (sockQueue.Count > 0) { IAsyncResult ar = sockQueue.Dequeue(); if (ProtocolKind == ProtocolKind.Udp) { SockUdp sockUdp = null; var ep = (EndPoint) new IPEndPoint(IPAddress.Any, 0); try{ int len = _socket.EndReceiveFrom(ar, ref ep); sockUdp = new SockUdp(Kernel, _socket, _udpBuf, len, (IPEndPoint)ep); //ACCEPT } catch (Exception) { sockUdp = null; } //受信開始 BeginReceive(); return(sockUdp); } else { //自分自身を複製するため、いったん別のSocketで受け取る必要がある var newSocket = _socket.EndAccept(ar); //ACCEPT //受信開始 BeginReceive(); //Ver5.9.2 Java fix //return new SockTcp(Kernel, newSocket); return(new SockTcp(Kernel, _ssl, newSocket)); } } //Ver5.8.1 //Thread.Sleep(0); Thread.Sleep(1); } SetError("isLife()==false"); return(null); }
//通常はこれを使用する public bool Recv(SockTcp sockTcp, int sec, Logger logger, ILife iLife) { var dtLast = DateTime.Now; //受信が20秒無かった場合は、処理を中断する while (iLife.IsLife()) { if (dtLast.AddSeconds(sec) < DateTime.Now) { return(false); //タイムアウト } var len = sockTcp.Length(); if (len == 0) { continue; } var buf = sockTcp.Recv(len, sec, iLife); if (buf == null) { return(false); //切断された } dtLast = DateTime.Now; var recvStatus = Append(buf); if (recvStatus == RecvStatus.Limit) { //サイズ制限 if (logger != null) { logger.Set(LogKind.Secure, sockTcp, 7, string.Format("Limit:{0}KByte", _sizeLimit)); } sockTcp.AsciiSend("552 Requested mail action aborted: exceeded storage allocation"); return(false); } if (recvStatus == RecvStatus.Finish) { return(true); } } return(false); }
//指定したアドレス・ポートで待ち受けて、接続されたら、そのソケットを返す //失敗した時nullが返る //Ver5.9.2 Java fix //public static SockTcp CreateConnection(Kernel kernel,Ip ip, int port,ILife iLife){ public static SockTcp CreateConnection(Kernel kernel,Ip ip, int port, Ssl ssl,ILife iLife) { //Ver5.9.2 Java fix //var sockServer = new SockServer(kernel,ProtocolKind.Tcp); var sockServer = new SockServer(kernel, ProtocolKind.Tcp,ssl); if (sockServer.SockState != SockState.Error) { const int listenMax = 1; if (sockServer.Bind(ip, port, listenMax)){ while (iLife.IsLife()){ var child = (SockTcp) sockServer.Select(iLife); if (child == null){ break; } sockServer.Close(); //これ大丈夫? return child; } } } sockServer.Close(); return null; }
//サーバ側への送信 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); }
//受信(無効な場合 return null) public static OneRemoteData Recv(SockTcp sockTcp, ILife iLife) { if (sockTcp != null) { //Ver5.8.6 var sec = 10;//最初はタイムアウト値を最小に設定する var b = sockTcp.Recv(1, sec, iLife);//REMOTE_DATA_KINDの受信 if (b != null && b.Length == 1) { var kind = (RemoteDataKind)b[0]; //これ以降は、データが到着しているはずなので、タイムアウト値を上げて待機する //timeout = 3000; //Ver5.8.6 sec = 10; Thread.Sleep(1); b = sockTcp.Recv(4, sec, iLife);//データサイズの受信 if (b != null && b.Length == 4) { var len = BitConverter.ToInt32(b, 0); if (len == 0) { return new OneRemoteData(kind, "");//データ本体はサイズ0 } //Ver5.8.6 b = new byte[0]; while (iLife.IsLife()) { Thread.Sleep(1); var buf = sockTcp.Recv(len, sec, iLife);//データ本体の受信 if (buf == null) { return null; } b = Bytes.Create(b, buf); if (b.Length == len){ return new OneRemoteData(kind, Encoding.GetEncoding(932).GetString(b)); } } } } } return null; }
//.行までを受信する byte [] RecvData() { var dt = DateTime.Now; var line = new byte[0]; while (_iLife.IsLife()) { var now = DateTime.Now; if (dt.AddSeconds(_sec) < now) { return(null); //タイムアウト } var len = _sockTcp.Length(); if (len == 0) { continue; } var buf = _sockTcp.Recv(len, _sec, _iLife); if (buf == null) { return(null); //切断された } dt = now; var tmp = new byte[line.Length + buf.Length]; Buffer.BlockCopy(line, 0, tmp, 0, line.Length); Buffer.BlockCopy(buf, 0, tmp, line.Length, buf.Length); line = tmp; if (line.Length >= 3) { if (line[line.Length - 1] == '\n' && line[line.Length - 2] == '\r' && line[line.Length - 3] == '.') { return(line); } } } return(null); }
public bool Recv(SockTcp sockTcp, int timeout, ILife iLife) { //�w�b�_�擾�i�f�[�^�͏����������j _ar.Clear(); var key = ""; while (iLife.IsLife()) { var line = sockTcp.LineRecv(timeout, iLife); if (line == null) { return(false); } line = Inet.TrimCrlf(line); if (line.Length == 0) { return(true);//�w�b�_�̏I�� } //�P�s���̃f�[�^����Key��Val��擾���� byte[] val = GetKeyVal(line, ref key); if (key != "") { Append(key, val); } else { //Ver5.4.4 HTTP/1.0 200 OK��Q�s�Ԃ��T�[�o�������̂ɑΏ� var s = Encoding.ASCII.GetString(line); if (s.IndexOf("HTTP/") != 0) { return(false);//�w�b�_�ُ� } } } return(false); }
bool RecvStatus(int no) { while (_iLife.IsLife()) { var buf = _sockTcp.LineRecv(_sec, _iLife); if (buf == null) { SetLastError("Timeout in SmtpClient RecvStatus()"); break; } _recvStr = Encoding.ASCII.GetString(buf); if (_recvStr.Length < 3) { SetLastError("str.Length<3 in SmtpClient RecvStatus()"); break; } if (_recvStr.Length > 3 && _recvStr[4] == '-') { continue; } int result; if (!Int32.TryParse(_recvStr.Substring(0, 3), out result)) { SetLastError("Faild TryPatse() in SmtpClient RecvStatus()"); break; } if (result == no) { return(true); } SetLastError(_recvStr); break; } ConfirmConnect();//接続確認 return(false); }
//チャンク形式の受信(RecvServer()から使用される) bool RecvServerChunk(ILife iLife) { var len = _proxy.Sock(CS.Server).Length(); if (len <= 0) return true; while (iLife.IsLife()) { byte[] b; if (_chunkLen == -1) { //チャンクサイズの取得 //サイズ取得 b = _proxy.Sock(CS.Server).LineRecv(_proxy.OptionTimeout,iLife); if (b == null || b.Length < 2) { _proxy.Logger.Set(LogKind.Debug, null, 999, string.Format("chunk ERROR b==null or b.Lenght<2")); return false; } _oneObj.Body[CS.Server].Add(b); _lastRecvServer = DateTime.Now.Ticks; //サイズ変換 string str = Encoding.ASCII.GetString(b, 0, b.Length - 2); if (str == "") { _chunkLen = -1;//次回はサイズ取得 continue; } try { _chunkLen = Convert.ToInt32(str.Trim(), 16); } catch { _proxy.Logger.Set(LogKind.Debug, null, 999, string.Format("【例外】Convert.ToInt32(str,16) str=\"{0}\"", str)); break; } if (_chunkLen == 0) { //受信完了 //残りのデータ(空行)ある場合 int l = _proxy.Sock(CS.Server).Length(); if (0 < l) { b = _proxy.Sock(CS.Server).Recv(l, _proxy.OptionTimeout,iLife); if (b != null) _oneObj.Body[CS.Server].Add(b); } SetServerSideBody(); //Ver5.7.2 //_sideState[CS.Server] = HttpSideState.ServerSideRecvBody; break; } } len = _proxy.Sock(CS.Server).Length(); if (_chunkLen > len) { //データ受信が可能かどうかの判断 Thread.Sleep(300);//待機 break;//受信は、次回に回す } //データ受信(サイズ分) b = _proxy.Sock(CS.Server).Recv(_chunkLen, _proxy.OptionTimeout,iLife); if (b == null || b.Length != _chunkLen) return false; _oneObj.Body[CS.Server].Add(b); if (_isText) { _textData = Bytes.Create(_textData, b); //コンテンツ制限の確認 if (IsHitLimitString(_textData)) return false; } _lastRecvServer = DateTime.Now.Ticks; _chunkLen = -1;//次回はサイズ取得 } return true; }
//protected override byte[] AssumptionLine(byte[] buf,ILife iLife) { byte[] AssumptionLine(byte[] buf, ILife iLife) { //stringに変換してから処理する var str = Encoding.ASCII.GetString(buf); Logger.Set(LogKind.Detail, null, 7, str); var index = str.IndexOf(" "); if (index < 0) { goto end; } var cmdStr = str.Substring(0, index); var paramStr = str.Substring(index + 1); if (cmdStr == "227") { //PASVに対するレスポンス //********************************************************************** // 「PASV 192.168.22.102,23,15」コマンドからサーバ側の情報を取得する //********************************************************************** var tmp2 = paramStr.Split('(', ')'); if (tmp2.Length != 3) { Logger.Set(LogKind.Error, null, 5, str); goto end; } string[] tmp = tmp2[1].Split(','); if (tmp.Length != 6) { Logger.Set(LogKind.Error, null, 6, str); goto end; } var connectIp = new Ip(string.Format("{0}.{1}.{2}.{3}", tmp[0], tmp[1], tmp[2], tmp[3])); var connectPort = Convert.ToInt32(tmp[4]) * 256 + Convert.ToInt32(tmp[5]); //********************************************************************** // クライアント側用のListenソケットを生成する //********************************************************************** var listenIp = Sock[CS.Client].LocalIp; // 利用可能なデータポートの選定 int listenPort = 0; while (iLife.IsLife()) { _dataPort++; if (SockServer.IsAvailable(_kernel, listenIp, _dataPort)) { listenPort = _dataPort; break; } } //********************************************************************** // クライアント側に送る227レスポンスを生成する //********************************************************************** str = string.Format("227 Entering Passive Mode ({0},{1},{2},{3},{4},{5})\r\n", listenIp.IpV4[0], listenIp.IpV4[1], listenIp.IpV4[2], listenIp.IpV4[3], listenPort / 256, listenPort % 256); buf = Encoding.ASCII.GetBytes(str); //データスレッドの準備 if (_dataTunnel != null) { _dataTunnel.Dispose(); } _dataTunnel = new DataTunnel(_kernel, Logger, listenIp, listenPort, connectIp, connectPort, this); _dataTunnel.Start(); Thread.Sleep(3); //Listenが完了してから 227を送信する } else if (cmdStr == "226") //Transfer complete. //_dataTunnel.WaitComplate(); //Thread.Sleep(10); //_dataTunnel.Stop(); { } else if (cmdStr.ToUpper() == "PORT") { //********************************************************************** //「PORT 192.168.22.102,23,15」コマンドからクライアント側の情報を取得する //********************************************************************** var tmp = paramStr.Split(','); if (tmp.Length != 6) { Logger.Set(LogKind.Error, null, 4, str); goto end; } var connectIp = new Ip(string.Format("{0}.{1}.{2}.{3}", tmp[0], tmp[1], tmp[2], tmp[3])); var connectPort = Convert.ToInt32(tmp[4]) * 256 + Convert.ToInt32(tmp[5]); //********************************************************************** // サーバ側用のListenソケットを生成する //********************************************************************** var listenIp = Sock[CS.Server].LocalIp; // 利用可能なデータポートの選定 int listenPort = 0; while (iLife.IsLife()) { _dataPort++; if (SockServer.IsAvailable(_kernel, listenIp, _dataPort)) { listenPort = _dataPort; break; } } //********************************************************************** // サーバ側に送るPORTコマンドを生成する //********************************************************************** //置き換えたPORTコマンドをセットする str = string.Format("PORT {0},{1},{2},{3},{4},{5}\r\n", listenIp.IpV4[0], listenIp.IpV4[1], listenIp.IpV4[2], listenIp.IpV4[3], listenPort / 256, listenPort % 256); buf = Encoding.ASCII.GetBytes(str); //データスレッドの準備 if (_dataTunnel != null) { _dataTunnel.Dispose(); } _dataTunnel = new DataTunnel(_kernel, Logger, listenIp, listenPort, connectIp, connectPort, this); _dataTunnel.Start(); Thread.Sleep(3); //Listenが完了してから PORTを送信する } end: return(buf); }
//string esmtpUser��null�łȂ��ꍇ�ASMTP�F��g�p���� public SmtpClientResult Send(SockTcp sockTcp,string serverName,Mail mail,MailAddress from,MailAddress to,string authUser,string authPass,ILife iLife) { var state = State.Ehlo; const int timeout = 3; var result = SmtpClientResult.Faild; //AUTH_STATE authState = AUTH_STATE.LOGIN; var smtpAuthClient = new SmtpAuthClient(authUser,authPass); LastLog.Clear();//���M���s���̋L�^�̓N���A���� while (iLife.IsLife()) { //******************************************************************** // �T�[�o����̃��X�|���X�R�[�h(response)��M //******************************************************************** int response; //var recvBuf = sockTcp.LineRecv(timeout,OperateCrlf.No,ref life); //Ver5.7.3 �^�C���A�E�g���������āA�Ԏ��̒x���T�[�o�ŃG���[�ƂȂ��Ă��܂� var recvBuf = sockTcp.LineRecv(timeout+30, iLife); if (recvBuf == null) { //���M���s���̍Ō�̑���M�L�^ LastLog.Add(sockTcp.LastLineSend); //LastLog.Add(recvStr); break; } if(recvBuf.Length==0){ Thread.Sleep(10); continue; } recvBuf = Inet.TrimCrlf(recvBuf);//\r\n�̔r�� var recvStr = Encoding.ASCII.GetString(recvBuf); if (state == State.Ehlo) { smtpAuthClient.Ehlo(recvStr);//AUTH�̑Ή���擾 } if (recvStr[3] == '-') { //string paramStr = recvStr.Substring(4); continue; } if (recvStr.IndexOf(' ') == 3) { response = Convert.ToInt32(recvStr.Substring(0, 3)); } else { //���M���s���̍Ō�̑���M�L�^ LastLog.Add(sockTcp.LastLineSend); LastLog.Add(recvStr); break; } //******************************************************************** // ��M�������X�|���X�R�[�h(response)�ɂ����(mode)�̕ύX //******************************************************************** if (response == 220) { state = State.Ehlo; } else if (response == 221) { if (state == State.Quit) break; } else if (response == 250) { if (state == State.Ehlo || state == State.Helo) { state = State.Mail; } else if (state == State.Mail) { state = State.Rcpt; } else if (state == State.Rcpt) { state = State.Data; } else if (state == State.Send) { result = SmtpClientResult.Success;//���M���� state = State.Quit; } } else if (response == 354) { if (state == State.Data) state = State.Send; } else if (response / 100 == 5) { // �]����SMTP�F��K�v�Ƃ��Ȃ��ꍇ�AEHLO�Ɏ��s������HELO�ōĐڑ�����݂� //if (Mode == 1 && TryEhlo && SmtpAuthClient == NULL) { if (state == State.Ehlo) { state = State.Helo;//HELO��500�������ꍇ�̓G���[�����ɉ�� } else {//���M���s //���M���s���̍Ō�̑���M�L�^ LastLog.Add(sockTcp.LastLineSend); LastLog.Add(recvStr); result = SmtpClientResult.ErrorCode;//�G���[�R�[�h��M state = State.Quit; } } //SMTP�F�� var ret = smtpAuthClient.Set(recvStr); if (ret != null) { sockTcp.AsciiSend(ret); continue; } //******************************************************************** // ���(mode)���Ƃ̏��� //******************************************************************** if (state == State.Ehlo) { sockTcp.AsciiSend(string.Format("EHLO {0}",serverName)); }else if (state == State.Helo) { sockTcp.AsciiSend(string.Format("HELO {0}",serverName)); } else if (state == State.Mail) { //Ver5.0.0-a24 //sockTcp.AsciiSend(string.Format("MAIL From:{0}",from),OPERATE_CRLF.YES); sockTcp.AsciiSend(string.Format("MAIL From: <{0}>",from)); } else if(state == State.Rcpt) { //Ver5.0.0-a24 //sockTcp.AsciiSend(string.Format("RCPT To:{0}",to),OPERATE_CRLF.YES); sockTcp.AsciiSend(string.Format("RCPT To: <{0}>",to)); } else if(state == State.Data) { sockTcp.AsciiSend("DATA"); } else if (state == State.Send) { if (mail == null) { //���M���s���̍Ō�̑���M�L�^ LastLog.Add(sockTcp.LastLineSend); LastLog.Add(recvStr); break;//�G���[���� } const int count = -1; //count ���M����{���̍s���i-1�̏ꍇ�͑S���j if (!mail.Send(sockTcp, count)){ //_logger.Set(LogKind.Error, null, 9000058, ex.Message); //mail.GetLastError()�𖢏��� break;//�G���[���� } sockTcp.AsciiSend("."); } else if (state == State.Quit) { sockTcp.AsciiSend("QUIT"); } } return result; }
//string esmtpUser��null�łȂ��ꍇ�ASMTP�F��g�p���� public SmtpClientResult Send(SockTcp sockTcp, string serverName, Mail mail, MailAddress from, MailAddress to, string authUser, string authPass, ILife iLife) { var state = State.Ehlo; const int timeout = 3; var result = SmtpClientResult.Faild; //AUTH_STATE authState = AUTH_STATE.LOGIN; var smtpAuthClient = new SmtpAuthClient(authUser, authPass); LastLog.Clear();//���M���s���̋L�^�̓N���A���� while (iLife.IsLife()) { //******************************************************************** // �T�[�o����̃��X�|���X�R�[�h(response)��M //******************************************************************** int response; //var recvBuf = sockTcp.LineRecv(timeout,OperateCrlf.No,ref life); //Ver5.7.3 �^�C���A�E�g���������āA�Ԏ��̒x���T�[�o�ŃG���[�ƂȂ��Ă��܂� var recvBuf = sockTcp.LineRecv(timeout + 30, iLife); if (recvBuf == null) { //���M���s���̍Ō�̑���M�L�^ LastLog.Add(sockTcp.LastLineSend); //LastLog.Add(recvStr); break; } if (recvBuf.Length == 0) { Thread.Sleep(10); continue; } recvBuf = Inet.TrimCrlf(recvBuf);//\r\n�̔r�� var recvStr = Encoding.ASCII.GetString(recvBuf); if (state == State.Ehlo) { smtpAuthClient.Ehlo(recvStr);//AUTH�̑Ή���擾 } if (recvStr[3] == '-') { //string paramStr = recvStr.Substring(4); continue; } if (recvStr.IndexOf(' ') == 3) { response = Convert.ToInt32(recvStr.Substring(0, 3)); } else { //���M���s���̍Ō�̑���M�L�^ LastLog.Add(sockTcp.LastLineSend); LastLog.Add(recvStr); break; } //******************************************************************** // ��M�������X�|���X�R�[�h(response)�ɂ����(mode)�̕ύX //******************************************************************** if (response == 220) { state = State.Ehlo; } else if (response == 221) { if (state == State.Quit) { break; } } else if (response == 250) { if (state == State.Ehlo || state == State.Helo) { state = State.Mail; } else if (state == State.Mail) { state = State.Rcpt; } else if (state == State.Rcpt) { state = State.Data; } else if (state == State.Send) { result = SmtpClientResult.Success;//���M���� state = State.Quit; } } else if (response == 354) { if (state == State.Data) { state = State.Send; } } else if (response / 100 == 5) { // �]����SMTP�F��K�v�Ƃ��Ȃ��ꍇ�AEHLO�Ɏ��s������HELO�ōĐڑ�����݂� //if (Mode == 1 && TryEhlo && SmtpAuthClient == NULL) { if (state == State.Ehlo) { state = State.Helo; //HELO��500�������ꍇ�̓G���[�����ɉ�� } else //���M���s //���M���s���̍Ō�̑���M�L�^ { LastLog.Add(sockTcp.LastLineSend); LastLog.Add(recvStr); result = SmtpClientResult.ErrorCode;//�G���[�R�[�h��M state = State.Quit; } } //SMTP�F�� var ret = smtpAuthClient.Set(recvStr); if (ret != null) { sockTcp.AsciiSend(ret); continue; } //******************************************************************** // ���(mode)���Ƃ̏��� //******************************************************************** if (state == State.Ehlo) { sockTcp.AsciiSend(string.Format("EHLO {0}", serverName)); } else if (state == State.Helo) { sockTcp.AsciiSend(string.Format("HELO {0}", serverName)); } else if (state == State.Mail) { //Ver5.0.0-a24 //sockTcp.AsciiSend(string.Format("MAIL From:{0}",from),OPERATE_CRLF.YES); sockTcp.AsciiSend(string.Format("MAIL From: <{0}>", from)); } else if (state == State.Rcpt) { //Ver5.0.0-a24 //sockTcp.AsciiSend(string.Format("RCPT To:{0}",to),OPERATE_CRLF.YES); sockTcp.AsciiSend(string.Format("RCPT To: <{0}>", to)); } else if (state == State.Data) { sockTcp.AsciiSend("DATA"); } else if (state == State.Send) { if (mail == null) { //���M���s���̍Ō�̑���M�L�^ LastLog.Add(sockTcp.LastLineSend); LastLog.Add(recvStr); break; //�G���[���� } const int count = -1; //count ���M����{���̍s���i-1�̏ꍇ�͑S���j if (!mail.Send(sockTcp, count)) { //_logger.Set(LogKind.Error, null, 9000058, ex.Message); //mail.GetLastError()�𖢏��� break;//�G���[���� } sockTcp.AsciiSend("."); } else if (state == State.Quit) { sockTcp.AsciiSend("QUIT"); } } return(result); }
//public bool Send(SockTcp tcpObj,bool encode,ref bool life){ public bool Send(SockTcp tcpObj,bool encode,ILife iLife) { if(_kindBuf == KindBuf.Memory) { if(encode) { if(-1 == tcpObj.SendUseEncode(_doc)) return false; } else { if(-1 == tcpObj.SendNoEncode(_doc)) return false; } } else { using(var fs = new FileStream(_fileName,FileMode.Open,FileAccess.Read,FileShare.ReadWrite)) { using(var br = new BinaryReader(fs)) { fs.Seek(_rangeFrom,SeekOrigin.Begin); var start = _rangeFrom; while(iLife.IsLife()) { long size = _rangeTo - start + 1; if(size > 1048560) size = 1048560; if(size <= 0) break; _doc = new byte[size]; int len = br.Read(_doc,0,(int)size); if(len <= 0) break; if(len != size) { var tmp = new byte[len]; Buffer.BlockCopy(_doc,0,tmp,0,len); _doc = tmp; } if(encode) { if(-1 == tcpObj.SendUseEncode(_doc)) { return false; } } else { if(-1 == tcpObj.SendNoEncode(_doc)) { return false; } } start += _doc.Length; if(_rangeTo - start <= 0) break; Thread.Sleep(1); } br.Close(); } fs.Close(); } } return true; }
//1行受信 //切断・タイムアウトでnullが返される public byte[] LineRecv(int sec, ILife iLife) { var tout = new util.Timeout(sec); while (iLife.IsLife()){ //Ver5.1.6 if (_sockQueue.Length == 0){ Thread.Sleep(100); } byte[] buf = _sockQueue.DequeueLine(); //noEncode = false;//テキストである事が分かっている Trace(TraceKind.Recv, buf, false); if (buf.Length != 0){ //Ver5.8.6 Java fix tout.Update(); //タイムアウトの更新 return buf; } if (SockState != SockState.Connect){ return null; } if (tout.IsFinish()){ return null; //タイムアウト } Thread.Sleep(1); } return null; }
//クライアント側への送信 bool SendClient(ILife iLife) { for (int i = _indexClient; iLife.IsLife() && i < _ar.Count; i++) { if (!_ar[i].SendClient(iLife)) { return false; } //クライアントへの送信が完了しているかどうかの確認 if (_ar[i].SideState(CS.Client) != HttpSideState.ClientSideSendBody) { break; } //送信が完了している場合は、次のデータオブジェクトの処理に移行する //proxy.Logger.Set(LogKind.Debug,null,999,string.Format("■indexClient {0}->{1}",indexClient,indexClient + 1)); //キャッシュが可能な場合は、ここでキャッシュされる _ar[_indexClient].CacheWrite(_cache); //ここでオブジェクトは破棄される _ar[_indexClient].Dispose(); _indexClient++; } return true; }
public bool RecvServer(ILife iLife) { //処置なし if (_sideState[CS.Server] == HttpSideState.ServerSideRecvBody) { return(true); } //int timeout=3; //レスポンス・ヘッダの受信 if (_sideState[CS.Server] == HttpSideState.ServerSideSendBody) { //Ver5.0.5 //int c = proxy.OptionTimeout; //本当は、OptionTimeout*10 だけど、最初のレスポンスがあまりに遅いとプログラムがロックするので10分の1に設定する var c = _proxy.OptionTimeout * 10; while (iLife.IsLife() && _proxy.Sock(CS.Server).SockState == SockState.Connect && _proxy.Sock(CS.Client).SockState == SockState.Connect && _proxy.Sock(CS.Server).Length() == 0) { Thread.Sleep(100); c--; if (c < 0) { return(false);//レスポンスが遅い場合、あまり待ちすぎると処理が止まってしまうので、エラーとする } } //レスポンスの取得 //int len = proxy.Sock(CS.SERVER).Length(); if (!_response.Recv(_proxy.Logger, _proxy.Sock(CS.Server), _proxy.OptionTimeout, iLife)) { _proxy.Logger.Set(LogKind.Error, _proxy.Sock(CS.Server), 6, ""); return(false); } //ヘッダの受信 if (!_oneObj.Header[CS.Server].Recv(_proxy.Sock(CS.Server), _proxy.OptionTimeout, iLife)) { _proxy.Logger.Set(LogKind.Error, _proxy.Sock(CS.Server), 7, ""); return(false); } //データ転送形式の判別 if (_oneObj.Request.HttpMethod == HttpMethod.Head) { _oneHttpKind = OneHttpKind.ContentLength; _contentLength = 0; } if (_oneHttpKind == OneHttpKind.Unknown) { string strTransferEncoding = _oneObj.Header[CS.Server].GetVal("Transfer-Encoding"); if (strTransferEncoding != null) { if (strTransferEncoding == "chunked") { _oneHttpKind = OneHttpKind.Chunk; } } } if (_oneHttpKind == OneHttpKind.Unknown) { string strContentLength = _oneObj.Header[CS.Server].GetVal("Content-Length"); if (strContentLength != null) { //Ver5.3.3 //contentLength = Convert.ToInt32(strContentLength); //oneHttpKind = ONE_HTTP_KIND.CONTENT_LENGTH; //Ver5.6.1 //int i; //if (Int32.TryParse(strContentLength, out i)) { long i; if (Int64.TryParse(strContentLength, out i)) { _contentLength = i; _oneHttpKind = OneHttpKind.ContentLength; } } else { if (_response.Code != 200) { _oneHttpKind = OneHttpKind.ContentLength; _contentLength = 0; } } } //コンテンツ制限の対象かどうかのフラグを設定する if (ProxyHttp.LimitString != null) //コンテンツ制限に文字列が設定されている場合 { string contentType = _oneObj.Header[CS.Server].GetVal("Content-Type"); if (contentType != null) { if (contentType.ToLower().IndexOf("text/h") == 0) { _isText = true; } if (contentType.ToLower().IndexOf("text/t") == 0) { _isText = true; } } //Content-Encoding:gzipが指定された場合は、テキスト扱いしない if (_isText) { string contentEncoding = _oneObj.Header[CS.Server].GetVal("Content-Encoding"); if (contentEncoding != null) { if (contentEncoding.ToLower().IndexOf("gzip") != -1) { //Ver6.0.8 _isGzip = true; //_isText = false; } } } } _sideState[CS.Server] = HttpSideState.ServerSideRecvHeader; //ヘッダ受信完了 CheckCharset(_oneObj.Header[CS.Server].GetBytes()); //キャラクタセットのチェック _lastRecvServer = DateTime.Now.Ticks; } //データ本体の受信 if (_oneHttpKind == OneHttpKind.Chunk) //チャンク形式の場合 //チャンク形式の受信 { if (!RecvServerChunk(iLife)) { return(false); } } else //Content-Length形式の受信 { if (!RecvServerContentLength(iLife)) { return(false); } } //受信完了の確認 if (_oneHttpKind == OneHttpKind.ContentLength) { if (_contentLength <= _oneObj.Body[CS.Server].Length) { //_sideState[CS.Server] = HttpSideState.ServerSideRecvBody;//受信完了 SetServerSideBody();//Ver5.7.2 } else { //データが未到着の場合は、しばらく他のスレッドを優先する //while(life && proxy.Sock(CS.SERVER).Length() == 0) // Thread.Sleep(100); //Ver5.6.1 2012.05.05 速度向上 //for (int i = 0; i < 100 && life; i++) // Thread.Sleep(10); Thread.Sleep(1); } } if (_proxy.Sock(CS.Server).SockState == Bjd.sock.SockState.Error && _proxy.Sock(CS.Server).Length() == 0) { //サーバ側が切断されており、取得できるデータが残っていないときは、常に受信完了とする _sideState[CS.Server] = HttpSideState.ServerSideRecvBody;//受信完了 } return(true); }
//チャンク形式の受信(RecvServer()から使用される) bool RecvServerChunk(ILife iLife) { var len = _proxy.Sock(CS.Server).Length(); if (len <= 0) { return(true); } while (iLife.IsLife()) { byte[] b; if (_chunkLen == -1) //チャンクサイズの取得 //サイズ取得 { b = _proxy.Sock(CS.Server).LineRecv(_proxy.OptionTimeout, iLife); if (b == null || b.Length < 2) { _proxy.Logger.Set(LogKind.Debug, null, 999, string.Format("chunk ERROR b==null or b.Lenght<2")); return(false); } _oneObj.Body[CS.Server].Add(b); _lastRecvServer = DateTime.Now.Ticks; //サイズ変換 string str = Encoding.ASCII.GetString(b, 0, b.Length - 2); if (str == "") { _chunkLen = -1;//次回はサイズ取得 continue; } try { _chunkLen = Convert.ToInt32(str.Trim(), 16); } catch { _proxy.Logger.Set(LogKind.Debug, null, 999, string.Format("【例外】Convert.ToInt32(str,16) str=\"{0}\"", str)); break; } if (_chunkLen == 0) //受信完了 //残りのデータ(空行)ある場合 { int l = _proxy.Sock(CS.Server).Length(); if (0 < l) { b = _proxy.Sock(CS.Server).Recv(l, _proxy.OptionTimeout, iLife); if (b != null) { _oneObj.Body[CS.Server].Add(b); } } SetServerSideBody(); //Ver5.7.2 //_sideState[CS.Server] = HttpSideState.ServerSideRecvBody; break; } } len = _proxy.Sock(CS.Server).Length(); if (_chunkLen > len) //データ受信が可能かどうかの判断 { Thread.Sleep(300); //待機 break; //受信は、次回に回す } //データ受信(サイズ分) b = _proxy.Sock(CS.Server).Recv(_chunkLen, _proxy.OptionTimeout, iLife); if (b == null || b.Length != _chunkLen) { return(false); } _oneObj.Body[CS.Server].Add(b); if (_isText) { _textData = Bytes.Create(_textData, b); //コンテンツ制限の確認 if (IsHitLimitString(_textData)) { return(false); } } _lastRecvServer = DateTime.Now.Ticks; _chunkLen = -1;//次回はサイズ取得 } return(true); }
public void Pipe(SockTcp server, SockTcp client, ILife iLife) { Sock[CS.Client] = client; Sock[CS.Server] = server; //�A�C�h�������p�̃^�C�}������ ResetIdle(); var cs = CS.Server; while (iLife.IsLife()) { cs = Reverse(cs);//�T�[�o���ƃN���C�A���g�����݂ɏ������� Thread.Sleep(1); // �N���C�A���g�̐ؒf�̊m�F if (Sock[CS.Client].SockState != SockState.Connect) { //Ver5.2.8 //�N���C�A���g���ؒf���ꂽ�ꍇ�ł�A�T�[�o�����ڑ����ő��M����ׂ��f�[�^���c���Ă���ꍇ�͏�����p������ if (Sock[CS.Server].SockState == SockState.Connect && Sock[CS.Client].Length() != 0) { } else { Logger.Set(LogKind.Detail, Sock[CS.Server], 9000043, "close client"); break; } } //******************************************************* //��������f�[�^���������Ă��Ȃ��ꍇ�̏��� //******************************************************* if (Sock[CS.Client].Length() == 0 && Sock[CS.Server].Length() == 0 && _byteBuf[CS.Client].Length == 0 && _byteBuf[CS.Server].Length == 0) { // �T�[�o�̐ؒf�̊m�F if (Sock[CS.Server].SockState != SockState.Connect) { //���M����ׂ��f�[�^���Ȃ��A�T�[�o���ؒf���ꂽ�ꍇ�́A�����I�� Logger.Set(LogKind.Detail, Sock[CS.Server], 9000044, "close server"); break; } Thread.Sleep(100); //�A�C�h������ �^�C���A�E�g�̊m�F if (IsTimeout()) { Logger.Set(LogKind.Normal, Sock[CS.Server], 9000019, string.Format("option IDLETIME={0}min", IdleTime)); break; } } else { //�A�C�h�������p�̃^�C�}������ ResetIdle(); } //******************************************************* // ��M���� //******************************************************* if (_byteBuf[cs].Length == 0) //�o�b�t�@����̎������������� //�������ׂ��f�[�^���̎擾 { var len = Sock[cs].Length(); if (len > 0) { const int sec = 10; //��M�o�C�g�����킩���Ă���̂ŁA�����ł̃^�C���A�E�g�l�͂��܂�Ӗ������� var b = Sock[cs].Recv(len, sec, iLife); if (b != null) { //Assumption() ��M���̏��� _byteBuf[cs] = Bytes.Create(_byteBuf[cs], Assumption(b, iLife)); } } } //******************************************************* // ���M���� //******************************************************* if (_byteBuf[cs].Length != 0) //�o�b�t�@�Ƀf�[�^�������Ă���ꍇ������������ { var c = Sock[Reverse(cs)].SendUseEncode(_byteBuf[cs]); if (c == _byteBuf[cs].Length) { _byteBuf[cs] = new byte[0]; } else { Logger.Set(LogKind.Error, server, 9000020, string.Format("sock.Send() return {0}", c)); break; } } } }
//再帰処理関数 //long GetInfo1(ref List<CacheInfo> infoList, string path, int sleep, ref bool life) { long GetInfo1(ref List<CacheInfo> infoList, string path, int sleep, ILife iLife) { var dt = new DateTime(0); var size = 0L; foreach (string file in Directory.GetDirectories(path)) { size += GetInfo1(ref infoList, file, sleep, iLife); if (!iLife.IsLife()) return 0; Thread.Sleep(sleep); foreach (string name in Directory.GetFiles(file)) { if (!iLife.IsLife()) return 0; Thread.Sleep(sleep); var fi = new FileInfo(name); var str = name.Substring(_dir.Length + 1); str = Util.SwapChar('\\', '/', str); str = Util.SwapStr("$$$", "", str); var index = str.IndexOf('/'); if (0 <= index) { var host = str.Substring(0, index); var uri = str.Substring(index); index = host.LastIndexOf('_'); if (0 <= index) { var hostName = host.Substring(0, index); var portStr = host.Substring(index + 1); var port = Convert.ToInt32(portStr); infoList.Add(new CacheInfo(hostName, port, uri, dt, dt, fi.CreationTime, fi.LastAccessTime, fi.Length)); } } size += fi.Length; } } return size; }
//リクエスト行・ヘッダ・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 void Pipe(SockTcp server, SockTcp client,ILife iLife) { Sock[CS.Client] = client; Sock[CS.Server] = server; //�A�C�h�������p�̃^�C�}������ ResetIdle(); var cs = CS.Server; while(iLife.IsLife()) { cs = Reverse(cs);//�T�[�o���ƃN���C�A���g�����݂ɏ������� Thread.Sleep(1); // �N���C�A���g�̐ؒf�̊m�F if(Sock[CS.Client].SockState != SockState.Connect) { //Ver5.2.8 //�N���C�A���g���ؒf���ꂽ�ꍇ�ł�A�T�[�o�����ڑ����ő��M����ׂ��f�[�^���c���Ă���ꍇ�͏�����p������ if (Sock[CS.Server].SockState == SockState.Connect && Sock[CS.Client].Length() != 0) { } else { Logger.Set(LogKind.Detail, Sock[CS.Server], 9000043, "close client"); break; } } //******************************************************* //��������f�[�^���������Ă��Ȃ��ꍇ�̏��� //******************************************************* if(Sock[CS.Client].Length() == 0 && Sock[CS.Server].Length() == 0 && _byteBuf[CS.Client].Length == 0 && _byteBuf[CS.Server].Length == 0) { // �T�[�o�̐ؒf�̊m�F if(Sock[CS.Server].SockState != SockState.Connect) { //���M����ׂ��f�[�^���Ȃ��A�T�[�o���ؒf���ꂽ�ꍇ�́A�����I�� Logger.Set(LogKind.Detail,Sock[CS.Server],9000044,"close server"); break; } Thread.Sleep(100); //�A�C�h������ �^�C���A�E�g�̊m�F if(IsTimeout()){ Logger.Set(LogKind.Normal,Sock[CS.Server],9000019,string.Format("option IDLETIME={0}min",IdleTime)); break; } } else { //�A�C�h�������p�̃^�C�}������ ResetIdle(); } //******************************************************* // ��M���� //******************************************************* if(_byteBuf[cs].Length == 0) { //�o�b�t�@����̎������������� //�������ׂ��f�[�^���̎擾 var len = Sock[cs].Length(); if(len > 0) { const int sec = 10; //��M�o�C�g�����킩���Ă���̂ŁA�����ł̃^�C���A�E�g�l�͂��܂�Ӗ������� var b = Sock[cs].Recv(len,sec,iLife); if(b != null){ //Assumption() ��M���̏��� _byteBuf[cs] = Bytes.Create(_byteBuf[cs],Assumption(b,iLife)); } } } //******************************************************* // ���M���� //******************************************************* if(_byteBuf[cs].Length != 0) { //�o�b�t�@�Ƀf�[�^�������Ă���ꍇ������������ var c = Sock[Reverse(cs)].SendUseEncode(_byteBuf[cs]); if(c == _byteBuf[cs].Length) { _byteBuf[cs] = new byte[0]; } else { Logger.Set(LogKind.Error,server,9000020,string.Format("sock.Send() return {0}",c)); break; } } } }
public bool RecvServer(ILife iLife) { //処置なし if (_sideState[CS.Server] == HttpSideState.ServerSideRecvBody) return true; //int timeout=3; //レスポンス・ヘッダの受信 if (_sideState[CS.Server] == HttpSideState.ServerSideSendBody) { //Ver5.0.5 //int c = proxy.OptionTimeout; //本当は、OptionTimeout*10 だけど、最初のレスポンスがあまりに遅いとプログラムがロックするので10分の1に設定する var c = _proxy.OptionTimeout * 10; while (iLife.IsLife() && _proxy.Sock(CS.Server).SockState == SockState.Connect && _proxy.Sock(CS.Client).SockState == SockState.Connect && _proxy.Sock(CS.Server).Length() == 0) { Thread.Sleep(100); c--; if (c < 0) return false;//レスポンスが遅い場合、あまり待ちすぎると処理が止まってしまうので、エラーとする } //レスポンスの取得 //int len = proxy.Sock(CS.SERVER).Length(); if (!_response.Recv(_proxy.Logger, _proxy.Sock(CS.Server), _proxy.OptionTimeout, iLife)) { _proxy.Logger.Set(LogKind.Error, _proxy.Sock(CS.Server), 6, ""); return false; } //ヘッダの受信 if (!_oneObj.Header[CS.Server].Recv(_proxy.Sock(CS.Server), _proxy.OptionTimeout, iLife)) { _proxy.Logger.Set(LogKind.Error, _proxy.Sock(CS.Server), 7, ""); return false; } //データ転送形式の判別 if (_oneObj.Request.HttpMethod == HttpMethod.Head) { _oneHttpKind = OneHttpKind.ContentLength; _contentLength = 0; } if (_oneHttpKind == OneHttpKind.Unknown) { string strTransferEncoding = _oneObj.Header[CS.Server].GetVal("Transfer-Encoding"); if (strTransferEncoding != null) { if (strTransferEncoding == "chunked") _oneHttpKind = OneHttpKind.Chunk; } } if (_oneHttpKind == OneHttpKind.Unknown) { string strContentLength = _oneObj.Header[CS.Server].GetVal("Content-Length"); if (strContentLength != null) { //Ver5.3.3 //contentLength = Convert.ToInt32(strContentLength); //oneHttpKind = ONE_HTTP_KIND.CONTENT_LENGTH; //Ver5.6.1 //int i; //if (Int32.TryParse(strContentLength, out i)) { long i; if (Int64.TryParse(strContentLength, out i)) { _contentLength = i; _oneHttpKind = OneHttpKind.ContentLength; } } else { if (_response.Code != 200) { _oneHttpKind = OneHttpKind.ContentLength; _contentLength = 0; } } } //コンテンツ制限の対象かどうかのフラグを設定する if (ProxyHttp.LimitString != null) { //コンテンツ制限に文字列が設定されている場合 string contentType = _oneObj.Header[CS.Server].GetVal("Content-Type"); if (contentType != null) { if (contentType.ToLower().IndexOf("text/h") == 0) { _isText = true; } if (contentType.ToLower().IndexOf("text/t") == 0) { _isText = true; } } //Content-Encoding:gzipが指定された場合は、テキスト扱いしない if (_isText) { string contentEncoding = _oneObj.Header[CS.Server].GetVal("Content-Encoding"); if (contentEncoding != null) { if (contentEncoding.ToLower().IndexOf("gzip") != -1){ //Ver6.0.8 _isGzip = true; //_isText = false; } } } } _sideState[CS.Server] = HttpSideState.ServerSideRecvHeader;//ヘッダ受信完了 CheckCharset(_oneObj.Header[CS.Server].GetBytes());//キャラクタセットのチェック _lastRecvServer = DateTime.Now.Ticks; } //データ本体の受信 if (_oneHttpKind == OneHttpKind.Chunk) { //チャンク形式の場合 //チャンク形式の受信 if (!RecvServerChunk(iLife)) return false; } else { //Content-Length形式の受信 if (!RecvServerContentLength(iLife)) return false; } //受信完了の確認 if (_oneHttpKind == OneHttpKind.ContentLength) { if (_contentLength <= _oneObj.Body[CS.Server].Length){ //_sideState[CS.Server] = HttpSideState.ServerSideRecvBody;//受信完了 SetServerSideBody();//Ver5.7.2 } else { //データが未到着の場合は、しばらく他のスレッドを優先する //while(life && proxy.Sock(CS.SERVER).Length() == 0) // Thread.Sleep(100); //Ver5.6.1 2012.05.05 速度向上 //for (int i = 0; i < 100 && life; i++) // Thread.Sleep(10); Thread.Sleep(1); } } if (_proxy.Sock(CS.Server).SockState == Bjd.sock.SockState.Error && _proxy.Sock(CS.Server).Length() == 0) { //サーバ側が切断されており、取得できるデータが残っていないときは、常に受信完了とする _sideState[CS.Server] = HttpSideState.ServerSideRecvBody;//受信完了 } return true; }
//サーバ側からの受信 bool RecvServer(ILife iLife) { for (int i = _indexRecv; iLife.IsLife() && i < _ar.Count; i++) { if (!_ar[i].RecvServer(iLife)) { Proxy.Logger.Set(LogKind.Debug, null, 999, "[HTTP] Break RecvServer()"); return false; } //サーバ側からの受信が完了しているかどうかの確認 if (_ar[i].SideState(CS.Server) != HttpSideState.ServerSideRecvBody) break; //送信が完了しているばあは、次のデータオブジェクトの処理に移る _indexRecv++; } return true; }
//プロキシ処理 public override 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; }
//サーバ側への送信 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; }
//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; }
//受信<br> //切断・タイムアウトでnullが返される public byte[] Recv(int len, int sec, ILife iLife) { var tout = new util.Timeout(sec); var buffer = new byte[0]; try{ if (len <= _sockQueue.Length){ // キューから取得する buffer = _sockQueue.Dequeue(len); } else{ while (iLife.IsLife()){ Thread.Sleep(0); if (0 < _sockQueue.Length){ //Java fix tout.Update(); //少しでも受信があった場合は、タイムアウトを更新する //size=受信が必要なバイト数 int size = len - buffer.Length; //受信に必要なバイト数がバッファにない場合 if (size > _sockQueue.Length){ size = _sockQueue.Length; //とりあえずバッファサイズ分だけ受信する } byte[] tmp = _sockQueue.Dequeue(size); buffer = Bytes.Create(buffer, tmp); //Java fix Ver5.8.2 if (buffer.Length != 0){ break; } } else{ if (SockState != SockState.Connect){ return null; } Thread.Sleep(10); } if (tout.IsFinish()){ buffer = _sockQueue.Dequeue(len); //タイムアウト break; } } } } catch (Exception){ //ex.printStackTrace(); return null; } Trace(TraceKind.Recv, buffer, false); return buffer; }
//public bool Send(SockTcp tcpObj,bool encode,ref bool life){ public bool Send(SockTcp tcpObj, bool encode, ILife iLife) { if (_kindBuf == KindBuf.Memory) { if (encode) { if (-1 == tcpObj.SendUseEncode(_doc)) { return(false); } } else { if (-1 == tcpObj.SendNoEncode(_doc)) { return(false); } } } else { using (var fs = new FileStream(_fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (var br = new BinaryReader(fs)) { fs.Seek(_rangeFrom, SeekOrigin.Begin); var start = _rangeFrom; while (iLife.IsLife()) { long size = _rangeTo - start + 1; if (size > 1048560) { size = 1048560; } if (size <= 0) { break; } _doc = new byte[size]; int len = br.Read(_doc, 0, (int)size); if (len <= 0) { break; } if (len != size) { var tmp = new byte[len]; Buffer.BlockCopy(_doc, 0, tmp, 0, len); _doc = tmp; } if (encode) { if (-1 == tcpObj.SendUseEncode(_doc)) { return(false); } } else { if (-1 == tcpObj.SendNoEncode(_doc)) { return(false); } } start += _doc.Length; if (_rangeTo - start <= 0) { break; } Thread.Sleep(1); } br.Close(); } fs.Close(); } } return(true); }
//通常はこれを使用する public bool Recv(SockTcp sockTcp, int sec,Logger logger, ILife iLife) { var dtLast = DateTime.Now; //受信が20秒無かった場合は、処理を中断する while (iLife.IsLife()){ if (dtLast.AddSeconds(sec) < DateTime.Now){ return false; //タイムアウト } var len = sockTcp.Length(); if (len == 0){ continue; } var buf = sockTcp.Recv(len, sec, iLife); if (buf == null){ return false; //切断された } dtLast = DateTime.Now; var recvStatus = Append(buf); if (recvStatus == RecvStatus.Limit){ //サイズ制限 if (logger != null){ logger.Set(LogKind.Secure, sockTcp, 7, string.Format("Limit:{0}KByte", _sizeLimit)); } sockTcp.AsciiSend("552 Requested mail action aborted: exceeded storage allocation"); return false; } if (recvStatus == RecvStatus.Finish){ return true; } } return false; }
//リクエスト行・ヘッダ・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 SockObj Select(ILife iLife) { while (iLife.IsLife()){ if (sockQueue.Count > 0){ IAsyncResult ar = sockQueue.Dequeue(); if (ProtocolKind == ProtocolKind.Udp){ SockUdp sockUdp = null; var ep = (EndPoint)new IPEndPoint(IPAddress.Any, 0); try{ int len = _socket.EndReceiveFrom(ar, ref ep); sockUdp = new SockUdp(Kernel,_socket, _udpBuf, len, (IPEndPoint) ep); //ACCEPT } catch (Exception){ sockUdp = null; } //受信開始 BeginReceive(); return sockUdp; } else { //自分自身を複製するため、いったん別のSocketで受け取る必要がある var newSocket = _socket.EndAccept(ar); //ACCEPT //受信開始 BeginReceive(); //Ver5.9.2 Java fix //return new SockTcp(Kernel, newSocket); return new SockTcp(Kernel, _ssl, newSocket); } } //Ver5.8.1 //Thread.Sleep(0); Thread.Sleep(1); } SetError("isLife()==false"); return null; }
//受信<br> //切断・タイムアウトでnullが返される public byte[] Recv(int len, int sec, ILife iLife) { var tout = new util.Timeout(sec); var buffer = new byte[0]; try{ if (len <= _sockQueue.Length) { // キューから取得する buffer = _sockQueue.Dequeue(len); } else { while (iLife.IsLife()) { Thread.Sleep(0); if (0 < _sockQueue.Length) { //Java fix tout.Update(); //少しでも受信があった場合は、タイムアウトを更新する //size=受信が必要なバイト数 int size = len - buffer.Length; //受信に必要なバイト数がバッファにない場合 if (size > _sockQueue.Length) { size = _sockQueue.Length; //とりあえずバッファサイズ分だけ受信する } byte[] tmp = _sockQueue.Dequeue(size); buffer = Bytes.Create(buffer, tmp); //Java fix Ver5.8.2 if (buffer.Length != 0) { break; } } else { if (SockState != SockState.Connect) { return(null); } Thread.Sleep(10); } if (tout.IsFinish()) { buffer = _sockQueue.Dequeue(len); //タイムアウト break; } } } } catch (Exception) { //ex.printStackTrace(); return(null); } Trace(TraceKind.Recv, buffer, false); return(buffer); }
//protected override byte[] AssumptionLine(byte[] buf,ILife iLife) { byte[] AssumptionLine(byte[] buf,ILife iLife) { //stringに変換してから処理する var str = Encoding.ASCII.GetString(buf); Logger.Set(LogKind.Detail, null, 7, str); var index = str.IndexOf(" "); if (index < 0) goto end; var cmdStr = str.Substring(0, index); var paramStr = str.Substring(index + 1); if (cmdStr == "227"){ //PASVに対するレスポンス //********************************************************************** // 「PASV 192.168.22.102,23,15」コマンドからサーバ側の情報を取得する //********************************************************************** var tmp2 = paramStr.Split('(', ')'); if (tmp2.Length != 3){ Logger.Set(LogKind.Error, null, 5, str); goto end; } string[] tmp = tmp2[1].Split(','); if (tmp.Length != 6){ Logger.Set(LogKind.Error, null, 6, str); goto end; } var connectIp = new Ip(string.Format("{0}.{1}.{2}.{3}", tmp[0], tmp[1], tmp[2], tmp[3])); var connectPort = Convert.ToInt32(tmp[4])*256 + Convert.ToInt32(tmp[5]); //********************************************************************** // クライアント側用のListenソケットを生成する //********************************************************************** var listenIp = Sock[CS.Client].LocalIp; // 利用可能なデータポートの選定 int listenPort = 0; while (iLife.IsLife()){ _dataPort++; if (SockServer.IsAvailable(_kernel, listenIp, _dataPort)){ listenPort = _dataPort; break; } } //********************************************************************** // クライアント側に送る227レスポンスを生成する //********************************************************************** str = string.Format("227 Entering Passive Mode ({0},{1},{2},{3},{4},{5})\r\n", listenIp.IpV4[0], listenIp.IpV4[1], listenIp.IpV4[2], listenIp.IpV4[3], listenPort/256, listenPort%256); buf = Encoding.ASCII.GetBytes(str); //データスレッドの準備 if (_dataTunnel != null){ _dataTunnel.Dispose(); } _dataTunnel = new DataTunnel(_kernel, Logger, listenIp, listenPort, connectIp, connectPort,this); _dataTunnel.Start(); Thread.Sleep(3); //Listenが完了してから 227を送信する } else if (cmdStr == "226") { //Transfer complete. //_dataTunnel.WaitComplate(); //Thread.Sleep(10); //_dataTunnel.Stop(); } else if (cmdStr.ToUpper() == "PORT") { //********************************************************************** //「PORT 192.168.22.102,23,15」コマンドからクライアント側の情報を取得する //********************************************************************** var tmp = paramStr.Split(','); if (tmp.Length != 6) { Logger.Set(LogKind.Error, null, 4, str); goto end; } var connectIp = new Ip(string.Format("{0}.{1}.{2}.{3}", tmp[0], tmp[1], tmp[2], tmp[3])); var connectPort = Convert.ToInt32(tmp[4]) * 256 + Convert.ToInt32(tmp[5]); //********************************************************************** // サーバ側用のListenソケットを生成する //********************************************************************** var listenIp = Sock[CS.Server].LocalIp; // 利用可能なデータポートの選定 int listenPort = 0; while (iLife.IsLife()){ _dataPort++; if (SockServer.IsAvailable(_kernel,listenIp,_dataPort)){ listenPort = _dataPort; break; } } //********************************************************************** // サーバ側に送るPORTコマンドを生成する //********************************************************************** //置き換えたPORTコマンドをセットする str = string.Format("PORT {0},{1},{2},{3},{4},{5}\r\n", listenIp.IpV4[0], listenIp.IpV4[1], listenIp.IpV4[2], listenIp.IpV4[3], listenPort / 256, listenPort % 256); buf = Encoding.ASCII.GetBytes(str); //データスレッドの準備 if (_dataTunnel != null) { _dataTunnel.Dispose(); } _dataTunnel = new DataTunnel(_kernel, Logger, listenIp, listenPort, connectIp, connectPort,this); _dataTunnel.Start(); Thread.Sleep(3); //Listenが完了してから PORTを送信する } end: return buf; }
//プロキシ処理 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); }