//データオブジェクトの追加 public void Add(OneObj oneObj) { //オプション指定によるヘッダの追加処理 if (!opBase.ValBool("useBrowserHedaer")) { if (opBase.ValBool("addHeaderRemoteHost")) { // oneObj.Header[cs].Append(key,val); oneObj.Header[CS.CLIENT].Append("Remote-Host-Wp", Define.ServerAddress()); } if (opBase.ValBool("addHeaderXForwardedFor")) { oneObj.Header[CS.CLIENT].Append("X-Forwarded-For", Define.ServerAddress()); } if (opBase.ValBool("addHeaderForwarded")) { string str = string.Format("by {0} (Version {1}) for {2}", Define.ApplicationName(), kanel.Ver.Version(), Define.ServerAddress()); oneObj.Header[CS.CLIENT].Append("Forwarded", str); } } OneHttp oneHttp = new OneHttp(proxy, this, oneObj); //キャッシュの確認 oneHttp.CacheConform(); ar.Add(oneHttp); }
//データオブジェクトの追加 override public void Add(OneObj oneObj) { //オプション指定によるヘッダの追加処理 if (!(bool)_conf.Get("useBrowserHedaer")) { if ((bool)_conf.Get("addHeaderRemoteHost")) { // oneObj.Header[cs].Append(key,val); oneObj.Header[CS.Client].Append("Remote-Host-Wp", Encoding.ASCII.GetBytes(Define.ServerAddress())); } if ((bool)_conf.Get("addHeaderXForwardedFor")) { oneObj.Header[CS.Client].Append("X-Forwarded-For", Encoding.ASCII.GetBytes(Define.ServerAddress())); } if ((bool)_conf.Get("addHeaderForwarded")) { string str = string.Format("by {0} (Version {1}) for {2}", Define.ApplicationName(), _kernel.Ver.Version(), Define.ServerAddress()); oneObj.Header[CS.Client].Append("Forwarded", Encoding.ASCII.GetBytes(str)); } } if (_ar.Count == 0) { if (oneObj.Request.HttpVer != "HTTP/1.1") { KeepAlive = false;//非継続型 } } var oneProxyHttp = new OneProxyHttp(Proxy, this, oneObj); //キャッシュの確認 oneProxyHttp.CacheConform(_cache); _ar.Add(oneProxyHttp); }
public bool CreateFromErrorCode(Request request, int responseCode) { //Ver5.0.0-a20 �G���R�[�h�̓I�v�V�����ݒ�ɏ]�� Encoding encoding; string charset; if (!GetEncodeOption(out encoding, out charset)) { return(false); } //���X�|���X�p�̐��`�擾 var lines = Inet.GetLines((string)_conf.Get("errorDocument")); if (lines.Count == 0) { _logger.Set(LogKind.Error, null, 25, ""); return(false); } //�o�b�t�@�̏����� var sb = new StringBuilder(); //������uri��o�͗p�ɃT�C�^�C�Y����i�N���X�T�C�g�X�N���v�e�B���O�Ή��j var uri = Inet.Sanitize(request.Uri); //���`��P�s�Âǂݍ���ŃL�[���[�h�ϊ������̂��o�͗p�o�b�t�@�ɒ~�ς��� foreach (string line in lines) { string str = line; str = Util.SwapStr("$MSG", request.StatusMessage(responseCode), str); str = Util.SwapStr("$CODE", responseCode.ToString(), str); str = Util.SwapStr("$SERVER", Define.ApplicationName(), str); str = Util.SwapStr("$VER", request.Ver, str); str = Util.SwapStr("$URI", uri, str); sb.Append(str + "\r\n"); } _body.Set(encoding.GetBytes(sb.ToString())); _sendHeader.Replace("Content-Length", _body.Length.ToString()); _sendHeader.Replace("Content-Type", string.Format("text/html;charset={0}", charset)); return(true); }
//投稿 public bool Post(Mail mail, MlEnvelope mlEnvelope) { //var no = mlDb.IncNo(mlAddr.Name);//インクリメントした記事番号の取得 var incNo = _mlDb.Count() + 1;//インクリメントした記事番号の取得 //記事メールの編集 //Subject:の変更 mail.ConvertHeader("subject", _mlSubject.Get(mail.GetHeader("subject"), incNo)); //Reply-To:の追加 mail.ConvertHeader("Reply-To", string.Format("\"{0}\"<{1}>", _mlAddr.Name, _mlAddr.Post)); //List-Id:の追加 mail.ConvertHeader("List-Id", string.Format("{0}.{1}", _mlAddr.Name, _mlAddr.DomainList[0])); //List-Software:の追加 mail.ConvertHeader("List-Software", string.Format("{0}", Define.ApplicationName())); //List-Post:の追加 mail.ConvertHeader("List-Post", string.Format("<mailto:{0}>", _mlAddr.Post)); //List-Owner:の追加 mail.ConvertHeader("List-Owner", string.Format("<mailto:{0}>", _mlAddr.Admin)); //List-Help:の追加 mail.ConvertHeader("List-Help", string.Format("<mailto:{0}?body=help>", _mlAddr.Ctrl)); //List-Unsubscribe:の追加 mail.ConvertHeader("List-Unsubscribe", string.Format("<mailto:{0}?body=unsubscribe>", _mlAddr.Ctrl)); //ライブラリへの保存 _mlDb.Save(mail); //各メンバーへの配信 foreach (MlOneUser to in _mlUserList) { if (to.Enable && to.IsReader) //「配信する」のみが対象となる { if (!_mlSender.Send(mlEnvelope.ChangeTo(to.MailAddress), mail)) { //配信に失敗したメールを管理者に転送する var subject = string.Format("DELIVERY ERROR article to {0} ({1} ML)", to, _mlAddr.Name); return(AttachToAmdin(mail, subject, mlEnvelope)); } } } return(true); }
public bool CreateFromIndex(Request request, string path) { //Ver5.0.0-a20 �G���R�[�h�̓I�v�V�����ݒ�ɏ]�� Encoding encoding; string charset; if (!GetEncodeOption(out encoding, out charset)) { return(false); } //���X�|���X�p�̐��`�擾 var lines = Inet.GetLines((string)_conf.Get("indexDocument")); if (lines.Count == 0) { _logger.Set(LogKind.Error, null, 26, ""); return(false); } //�o�b�t�@�̏����� var sb = new StringBuilder(); //������uri��o�͗p�ɃT�C�^�C�Y����i�N���X�T�C�g�X�N���v�e�B���O�Ή��j var uri = Inet.Sanitize(request.Uri); //���`��P�s�Âǂݍ���ŃL�[���[�h�ϊ������̂��o�͗p�o�b�t�@�ɒ~�ς��� foreach (string line in lines) { var str = line; if (str.IndexOf("<!--$LOOP-->") == 0) { str = str.Substring(12);//�P�s�̐��^ //�ꗗ���̎擾(�P�s����LineData) var lineDataList = new List <LineData>(); var dir = request.Uri; if (1 < dir.Length) { if (dir[dir.Length - 1] != '/') { dir = dir + '/'; } } //string dirStr = dir.Substring(0,dir.LastIndexOf('/')); if (dir != "/") { //string parentDirStr = dirStr.Substring(0,dirStr.LastIndexOf('/') + 1); //lineDataList.Add(new LineData(parentDirStr,"Parent Directory","<DIR>","-")); lineDataList.Add(new LineData("../", "Parent Directory", "<DIR>", "-")); } var di = new DirectoryInfo(path); foreach (var info in di.GetDirectories("*.*")) { var href = Uri.EscapeDataString(info.Name) + '/'; lineDataList.Add(new LineData(href, info.Name, "<DIR>", "-")); } foreach (var info in di.GetFiles("*.*")) { string href = Uri.EscapeDataString(info.Name); lineDataList.Add(new LineData(href, info.Name, info.LastWriteTime.ToString(), info.Length.ToString())); } //�ʒu���`�Ő��`����StringBuilder�ɒlj����� foreach (var lineData in lineDataList) { sb.Append(lineData.Get(str) + "\r\n"); } } else //�ꗗ�s�ȊO�̏��� { str = Util.SwapStr("$URI", uri, str); str = Util.SwapStr("$SERVER", Define.ApplicationName(), str); str = Util.SwapStr("$VER", request.Ver, str); sb.Append(str + "\r\n"); } } _body.Set(encoding.GetBytes(sb.ToString())); _sendHeader.Replace("Content-Length", _body.Length.ToString()); _sendHeader.Replace("Content-Type", string.Format("text/html;charset={0}", charset)); return(true); }
//�ڑ��P�ʂ̏��� override protected void OnSubThread(SockObj sockObj) { var timeout = (int)Conf.Get("timeOut"); var client = (SockTcp)sockObj; SockTcp server = null; var user = ""; //���[�U�� string pass; //�p�X���[�h var hostName = ""; //�z�X�g�� //*************************************************************** //�O�����i�ڑ���E���[�U���E�p�X���[�h�̎擾) //*************************************************************** { var str = string.Format("220 {0} {1}", Define.ApplicationName(), Define.Copyright()); client.AsciiSend(str); var cmdStr = ""; var paramStr = ""; //wait USER user@hostName if (!WaitLine(client, ref cmdStr, ref paramStr)) { goto end; } if (cmdStr.ToUpper() != "USER") { goto end; } //paramStr = "user@hostName" if (paramStr != null) { //string[] tmp = paramStr.Split('@'); //if(tmp.Length == 2) { // user = tmp[0];//���[�U���擾 // hostName = tmp[1];//�z�X�g���擾 //} var i = paramStr.LastIndexOf('@'); if (i != -1) { user = paramStr.Substring(0, i); //���[�U���擾 hostName = paramStr.Substring(i + 1); //�z�X�g���擾 } } if (hostName == "") { Logger.Set(LogKind.Error, sockObj, 8, ""); goto end; } client.AsciiSend("331 USER OK enter password"); //wait PASS password if (!WaitLine(client, ref cmdStr, ref paramStr)) { goto end; } if (cmdStr.ToUpper() != "PASS") { goto end; } //paramStr = "password" pass = paramStr;//�p�X���[�h�擾 } //*************************************************************** // �T�[�o�Ƃ̐ڑ� //*************************************************************** { const int port = 21; //var ipList = new List<Ip>{new Ip(hostName)}; //if (ipList[0].ToString() == "0.0.0.0") { // ipList = Kernel.DnsCache.Get(hostName); // if (ipList.Count == 0) { // goto end; // } //} var ipList = Kernel.GetIpList(hostName); if (ipList.Count == 0) { goto end; } Ssl ssl = null; foreach (var ip in ipList) { server = Inet.Connect(Kernel, ip, port, Timeout, ssl); if (server != null) { break; } } if (server == null) { goto end; } } //*************************************************************** //�㏈���i���[�U���E�p�X���[�h�̑��M) //*************************************************************** { var cmdStr = ""; var paramStr = ""; //wait 220 welcome while (cmdStr != "220") { if (!WaitLine(server, ref cmdStr, ref paramStr)) { goto end; } } server.AsciiSend(string.Format("USER {0}", user)); //wait 331 USER OK enter password while (cmdStr != "331") { if (!WaitLine(server, ref cmdStr, ref paramStr)) { goto end; } } server.AsciiSend(string.Format("PASS {0}", pass)); if (!WaitLine(server, ref cmdStr, ref paramStr)) { goto end; } client.AsciiSend(string.Format("{0} {1}", cmdStr, paramStr)); } //*************************************************************** // �p�C�v //*************************************************************** var ftpTunnel = new FtpTunnel(Kernel, Logger, (int)Conf.Get("idleTime"), _dataPort, timeout); //Ver5.0.5 //ftpTunnel.BytePipe(ref life, server,client); ftpTunnel.Pipe(server, client, this); _dataPort = ftpTunnel.Dispose(); if (_dataPort > DataPortMax) { _dataPort = DataPortMin; } end: client.Close(); if (server != null) { server.Close(); } }
//public Env(Kernel kernel, Request request, Header recvHeader, System.Net.IPAddress remoteAddress, string remoteHostName, string fileName) { public Env(Kernel kernel, Conf conf, Request request, Header recvHeader, SockTcp tcpObj, string fileName) { //Ver5.6.2 var documetnRoot = (string)conf.Get("documentRoot"); _ar.Add(new OneEnv("DOCUMENT_ROOT", documetnRoot)); var serverAdmin = (string)conf.Get("serverAdmin"); _ar.Add(new OneEnv("SERVER_ADMIN", serverAdmin)); _ar.Add(new OneEnv("SystemRoot", Environment.GetEnvironmentVariable("SystemRoot"))); _ar.Add(new OneEnv("Path", Environment.GetEnvironmentVariable("Path"))); //Ver5.6.2追加 _ar.Add(new OneEnv("COMSPEC", Environment.GetEnvironmentVariable("COMSPEC"))); _ar.Add(new OneEnv("PATHEXT", Environment.GetEnvironmentVariable("PATHEXT"))); _ar.Add(new OneEnv("WINDIR", Environment.GetEnvironmentVariable("windir"))); _ar.Add(new OneEnv("SERVER_SOFTWARE", string.Format("{0}/{1} (Windows)", Define.ApplicationName(), kernel.Ver.Version()))); _ar.Add(new OneEnv("REQUEST_METHOD", request.Method.ToString().ToUpper())); _ar.Add(new OneEnv("REQUEST_URI", request.Uri)); if (request.Uri == "/") // ルートディレクトリか? { _ar.Add(new OneEnv("SCRIPT_NAME", Path.GetFileName(fileName))); // Welcomeファイルを設定する } else // URIで指定されたCGIを設定する { _ar.Add(new OneEnv("SCRIPT_NAME", request.Uri)); } _ar.Add(new OneEnv("SERVER_PROTOCOL", request.Ver)); _ar.Add(new OneEnv("QUERY_STRING", request.Param)); _ar.Add(new OneEnv("REMOTE_HOST", tcpObj.RemoteHostname)); //Ver5.6.2 //ar.Add(new OneEnv("REMOTE_ADDR", tcpObj.RemoteAddr.IPAddress.ToString())); var addr = (tcpObj.RemoteAddress != null) ? tcpObj.RemoteAddress.Address.ToString() : ""; _ar.Add(new OneEnv("REMOTE_ADDR", addr)); //Ver5.6.2 int port = (tcpObj.RemoteAddress != null)?tcpObj.RemoteAddress.Port:0; _ar.Add(new OneEnv("REMOTE_PORT", port.ToString())); port = (tcpObj.LocalAddress != null) ? tcpObj.LocalAddress.Port : 0; _ar.Add(new OneEnv("SERVER_PORT", port.ToString())); addr = (tcpObj.LocalAddress != null) ? tcpObj.LocalAddress.Address.ToString() : ""; _ar.Add(new OneEnv("SERVER_ADDR", addr)); //Ver5.6.2 SetEnvValue(recvHeader, _ar, "accept-charset", "HTTP_ACCEPT_CHARSET"); SetEnvValue(recvHeader, _ar, "accept-encoding", "HTTP_ACCEPT_ENCODING"); SetEnvValue(recvHeader, _ar, "accept-language", "HTTP_ACCEPT_LANGUAGE"); SetEnvValue(recvHeader, _ar, "User-Agent", "HTTP_USER_AGENT"); SetEnvValue(recvHeader, _ar, "Content-Type", "CONTENT_TYPE"); SetEnvValue(recvHeader, _ar, "host", "SERVER_NAME"); SetEnvValue(recvHeader, _ar, "Content-Length", "CONTENT_LENGTH"); SetEnvValue(recvHeader, _ar, "AuthUser", "REMOTE_USER"); //PathInfo/PathTranslatedの取得と環境変数へのセットについて再考察 SetEnvValue(recvHeader, _ar, "PathInfo", "PATH_INFO"); SetEnvValue(recvHeader, _ar, "PathTranslated", "PATH_TRANSLATED"); _ar.Add(new OneEnv("SCRIPT_FILENAME", fileName)); //HTTP_で環境変数をセットしないヘッダの(除外)リスト var exclusionList = new List <string> { "accept-charset", "accept-encoding", "accept-language", "authorization", "content-length", "content-type", "date", "expires", "from", "host", "if-modified-since", "if-match", "if-none-match", "if-range", "if-unmodified-since", "last-modified", "pragma", "range", "remote-user", "remote-host-wp", "transfer-encoding", "upgrade", "user-agent" }; //Ver5.6.2 //exclusionList.Add("connection"); //DEBUG //recvHeader.Append("accept", Encoding.ASCII.GetBytes("ABC")); foreach (var line in recvHeader) { //取得したタグが除外リストにヒットしない場合 //HTTP_を付加して環境変数にセットする if (exclusionList.IndexOf(line.Key.ToLower()) < 0) { //5.5.4重複による例外を回避 //ar.Add("HTTP_" + line.Key.ToUpper(), recvHeader.GetVal(line.Key)); var tag = "HTTP_" + line.Key.ToUpper(); //if (null == ar[tag]) { // ar.Add(tag, recvHeader.GetVal(line.Key)); //} bool find = _ar.Any(a => a.Key == tag); if (!find) { _ar.Add(new OneEnv(tag, recvHeader.GetVal(line.Key))); } } } }
override protected void OnRunThread() { //ログ用文字列の生成 string mailStr = string.Format("{0} retry:{1}", _oneQueue.MailInfo, _oneQueue.MailInfo.RetryCounter); //[C#] ThreadBaseKind = ThreadBaseKind.Running; //開始ログ _logger.Set(LogKind.Normal, null, 10, mailStr); //ここで、1通のメールを1回処理する //成功か失敗かの処理は、この関数の最後にもってくるべき? //失敗の理由によって、再試行にまわしたり、リターンメールを作成したり・・・・ //リターンのリターンはループの危険性がある var retryMax = (int)_conf.Get("retryMax"); //リトライ回数 var deleteTarget = false; //処理対象のメールを削除するかどうかのフラグ //0.サーバ検索が終わっていない状態からスタート var result = SmtpClientResult.Faild; //Ver5.7.3 無効データの削除 if (_oneQueue.MailInfo.To.Domain == "") { deleteTarget = true; goto end; } //サーバ(アドレス)検索 List <OneSmtpServer> smtpServerList = GetSmtpServerList(_oneQueue.MailInfo.To.Domain); if (smtpServerList.Count == 0) { //サーバ(アドレス)検索失敗(リトライ対象) _logger.Set(LogKind.Error, null, 12, string.Format("domain={0}", _oneQueue.MailInfo.To.Domain));//失敗 } else { //送信処理 foreach (OneSmtpServer oneSmtpServer in smtpServerList) { Ssl ssl = null; if (oneSmtpServer.Ssl) { //クライアント用SSLの初期化 //ssl = new Ssl(server.Logger,oneSmtpServer.TargetServer); ssl = new Ssl(oneSmtpServer.TargetServer); } var timeout = 5; var tcpObj = Inet.Connect(_kernel, oneSmtpServer.Ip, oneSmtpServer.Port, timeout, ssl); if (tcpObj == null) { //serverMain.Logger.Set(LogKind.Error, xx, string.Format("to={0} address={1}", oneQueue.MailInfo.To.ToString(), ip.IpStr)); continue; } //Ver5.9.8 if (tcpObj.SockState != SockState.Connect) { _logger.Set(LogKind.Error, tcpObj, 56, tcpObj.GetLastEror());//失敗 break; } string esmtpUser = null; string esmtpPass = null; if (oneSmtpServer.UseSmtp) { esmtpUser = oneSmtpServer.User; esmtpPass = oneSmtpServer.Pass; } result = _smtpClient2.Send(tcpObj, _kernel.ServerName, _oneQueue.Mail(_mailQueue), _oneQueue.MailInfo.From, _oneQueue.MailInfo.To, esmtpUser, esmtpPass, this); tcpObj.Close(); if (result == SmtpClientResult.Success) { //送信成功 _logger.Set(LogKind.Normal, tcpObj, 11, mailStr);//成功 deleteTarget = true; break; } if (result == SmtpClientResult.ErrorCode) { //明確なエラーの発生 _logger.Set(LogKind.Error, tcpObj, 14, mailStr);//失敗 break; } } if (result == SmtpClientResult.Faild) { _logger.Set(LogKind.Error, null, 13, mailStr);//失敗 } } //エラーコードが返された場合及びリトライ回数を超えている場合、リターンメールを作成する if (result == SmtpClientResult.ErrorCode || retryMax <= _oneQueue.MailInfo.RetryCounter) { var from = new MailAddress((string)_conf.Get("errorFrom")); var to = _oneQueue.MailInfo.From; //Ver_Ml //メール本体からMLメールかどうかを確認する //List-Software: BlackJumboDog Ver 5.0.0-b13 //List-Owner: <mailto:[email protected]> var orgMail = _oneQueue.Mail(_mailQueue); var listSoftware = orgMail.GetHeader("List-Software"); if (listSoftware != null && listSoftware.IndexOf(Define.ApplicationName()) == 0) { var listOwner = orgMail.GetHeader("List-Owner"); if (listOwner != null) { //<mailto:[email protected]> listOwner = listOwner.Trim(new char[] { '<', '>' }); //mailto:[email protected] var admin = listOwner.Substring(7); //[email protected] to = new MailAddress(admin);//宛先をML管理者に変更する } } const string reason = "550 Host unknown"; var mail = MakeErrorMail(from, to, reason, _smtpClient2.LastLog); _logger.Set(LogKind.Normal, null, 15, string.Format("from:{0} to:{1}", from, to)); if (_server.MailSave2(from, to, mail, _oneQueue.MailInfo.Host, _oneQueue.MailInfo.Addr)) { deleteTarget = true; //メール削除 } } end: if (deleteTarget) { _oneQueue.Delete(_mailQueue); //メール削除 } }
//接続単位の処理 override public void _subThread(SockObj sockObj) { // 上位プロキシを使用するかどうかのフラグ bool useUpperProxy = this.OpBase.ValBool("useUpperProxy"); Dictionary <CS, TcpObj> sock = new Dictionary <CS, TcpObj>(2); sock[CS.CLIENT] = (TcpObj)sockObj; sock[CS.SERVER] = null; sock[CS.CLIENT].Timeout = timeout; //クライアント及びサーバ双方のヘッダを処理するクラス Dictionary <CS, Header> header = new Dictionary <CS, Header>(2); header[CS.CLIENT] = new Header(); header[CS.SERVER] = new Header(); //クライアント及びサーバ双方のバッファ Dictionary <CS, byte[]> buf = new Dictionary <CS, byte[]>(2); buf[CS.CLIENT] = new byte[0]; buf[CS.SERVER] = new byte[0]; Request request = new Request();//クライアントからのリクエストを処理するクラス //Response response = new Response();//サーバからのレスポンスを処理するクラス OneCache oneCache = null; while (true) { //*************************************************************** //クライアントからのデータを読み込む //*************************************************************** { //while (life && sock[CS.CLIENT].Length() == 0) { // Thread.Sleep(30); //} //接続されたが、クライアントからのリクエストが5秒間来ない場合は、スレッドを破棄する for (int i = 0; life && sock[CS.CLIENT].Length() == 0; i++) { Thread.Sleep(50); if (i > 100) { Logger.Set(LOG_KIND.DEBUG, sock[CS.CLIENT], 999, "デバッグ中 クライアントから5秒以上データが来ないので切断する"); goto end;//Ver5.0.0-a21 } } //リクエスト取得(内部データは初期化される)ここのタイムアウト値は、大きすぎるとブラウザの切断を取得できないでブロックしてしまう if (!request.Recv(this.Logger, sock[CS.CLIENT], timeout, ref life)) { //Logger goto end; } //bool useRequestLog リクエストを通常ログで表示する this.Logger.Set(useRequestLog ? LOG_KIND.NOMAL : LOG_KIND.DETAIL, null, 0, string.Format("{0}", request.RequestStr)); //*************************************************************** //URL制限 //*************************************************************** if (limitUrl.IsHit(request.RequestStr)) { this.Logger.Set(LOG_KIND.NOMAL, null, 10, request.RequestStr); goto end; } //*************************************************************** //上位プロキシのチェック //*************************************************************** if (useUpperProxy) { // 上位プロキシを経由しないサーバの確認 foreach (string hostName in disableAddressList) { if (request.Protocol == PROXY_PROTOCOL.SSL) { if (request.HostName.IndexOf(hostName) == 0) { useUpperProxy = false; break; } } else { string str = request.RequestStr.Substring(11); if (str.IndexOf(hostName) == 0) { useUpperProxy = false; break; } } } } //ヘッダの取得 if (!header[CS.CLIENT].Recv(sock[CS.CLIENT], timeout, ref life)) { //Logger goto end; } //ヘッダの追加処理 if (request.Protocol == PROXY_PROTOCOL.HTTP) { if (!this.OpBase.ValBool("useBrowserHedaer")) { if (this.OpBase.ValBool("addHeaderRemoteHost")) { header[CS.CLIENT].Append("Remote-Host-Wp", Define.ServerAddress()); } if (this.OpBase.ValBool("addHeaderXForwardedFor")) { header[CS.CLIENT].Append("X-Forwarded-For", Define.ServerAddress()); } if (this.OpBase.ValBool("addHeaderForwarded")) { string str = string.Format("by {0} (Version {1}) for {2}", Define.ApplicationName(), kanel.Ver.Version(), Define.ServerAddress()); header[CS.CLIENT].Append("Forwarded", str); } } } if (request.Protocol == PROXY_PROTOCOL.SSL) { if (!useUpperProxy) { //取得したリクエストをバッファに格納する buf[CS.CLIENT] = new byte[0]; buf[CS.SERVER] = Bytes.Create("HTTP/1.0 200 Connection established\r\n\r\n");//CONNECTが成功したことをクライアントに返す } else { //上位プロキシを使用する場合(リクエストラインはそのまま使用される) buf[CS.CLIENT] = Bytes.Create(request.SendLine(useUpperProxy), header[CS.CLIENT].GetBytes()); } } else if (request.Protocol == PROXY_PROTOCOL.HTTP) //HTTPの場合 //Ver5.0.0-b3 削除 //header[CS.CLIENT].Remove("Proxy-Connection"); //取得したリクエストをバッファに格納する //上位プロキシを使用する場合(リクエストラインはそのまま使用される) { buf[CS.CLIENT] = Bytes.Create(request.SendLine(useUpperProxy), header[CS.CLIENT].GetBytes()); //Ver5.0.0-a5 //POSTの場合は、更にクライアントからのデータを読み込む if (request.Method == HTTP_METHOD.POST) { //int len = 0; string strContentLength = header[CS.CLIENT].GetVal("Content-Length"); if (strContentLength != null) { try { int len = Convert.ToInt32(strContentLength); if (0 < len) { byte[] data = sock[CS.CLIENT].Recv(len, timeout); buf[CS.CLIENT] = Bytes.Create(buf[CS.CLIENT], data); } } catch { this.Logger.Set(LOG_KIND.ERROR, null, 22, request.Uri); goto end; } } } } } //キャッシュ対象のリクエストかどうかの確認 if (request.Protocol == PROXY_PROTOCOL.HTTP && !request.Cgi) { if (cache.IsTarget(request.HostName, request.Uri, request.Ext)) { string headerStr = header[CS.CLIENT].ToString(); bool noCache = false; if (headerStr.ToLower().IndexOf("no-cache") >= 0) { noCache = true; //キャッシュしない this.Logger.Set(LOG_KIND.DETAIL, null, 16, request.Uri); cache.Remove(request.HostName, request.Port, request.Uri); //存在する場合は、無効化する } else { string modifiedStr = header[CS.CLIENT].GetVal("If-Modified-Since"); DateTime modified = Util.Str2Time(modifiedStr); byte[] dat = cache.Get(request, modified); if (dat != null) //キャッシュが見つかった場合 { this.Logger.Set(LOG_KIND.DETAIL, null, 14, request.Uri); sock[CS.CLIENT].AsciiSend("HTTP/1.0 200 OK", OPERATE_CRLF.YES); int c = sock[CS.CLIENT].Send(dat); goto end; } } if (!noCache) { string url = string.Format("{0}:{1}{2}", request.HostName, request.Port, request.Uri); //キャッシュ対象の場合だけ、受信用のオブジェクトを生成する oneCache = new OneCache(request.HostName, request.Port, request.Uri); } } } //*************************************************************** // サーバとの接続 //*************************************************************** { string hostName = request.HostName; int port = request.Port; if (useUpperProxy) //上位プロキシを使用する場合 { hostName = this.OpBase.ValString("upperProxyServer"); port = this.OpBase.ValInt("upperProxyPort"); } List <Ip> ipList = new List <Ip>(); ipList.Add(new Ip(hostName)); if (ipList[0].ToString() == "0.0.0.0") { ipList = kanel.dnsCache.Get(hostName); if (ipList == null || ipList.Count == 0) { this.Logger.Set(LOG_KIND.ERROR, null, 11, hostName); goto end; } } SSL ssl = null; foreach (Ip ip in ipList) { sock[CS.SERVER] = Inet.Connect(ref life, kanel, this.Logger, ip, port, ssl); if (sock[CS.SERVER] != null) { break; } } if (sock[CS.SERVER] == null) { Logger.Set(LOG_KIND.DETAIL, sock[CS.CLIENT], 26, string.Format("{0}:{1}", ipList[0].ToString(), port)); return; } sock[CS.SERVER].Timeout = timeout; } //*************************************************************** // パイプ処理 //*************************************************************** if (request.Protocol == PROXY_PROTOCOL.HTTP || request.Protocol == PROXY_PROTOCOL.SSL) { // パイプ(HTTP/SSL) PipeHttp(sock, buf, request, header, oneCache);//パイプ処理 } else if (request.Protocol == PROXY_PROTOCOL.FTP) { // パイプ(FTP) dataPort = PipeFtp(sock, request, dataPort);//パイプ処理 if (dataPort > dataPortMax) { dataPort = dataPortMin; } } continue; end: break; //*************************************************************** // 終了処理 //*************************************************************** //if(sock[CS.CLIENT] != null) // sock[CS.CLIENT].Close(); //if(sock[CS.SERVER] != null) // sock[CS.SERVER].Close(); } //*************************************************************** // 終了処理 //*************************************************************** if (sock[CS.CLIENT] != null) { sock[CS.CLIENT].Close(); } if (sock[CS.SERVER] != null) { sock[CS.SERVER].Close(); } }