public bool Exec(Target target, Env env, WebStream output) { _target = target; //出力用バッファ var sb = new StringBuilder(); var encoding = MLang.GetEncoding(target.FullPath); //*************************************************** // 対象ファイルの読み込み //*************************************************** using (var sr = new StreamReader(target.FullPath, encoding)) { while (true) { var str = sr.ReadLine(); if (str == null) break; //SSIキーワードを検索して置き換える(再帰処理) SsiConvert(ref str, encoding); sb.Append(str + "\r\n"); } sr.Close(); } output.Add(encoding.GetBytes(sb.ToString())); return true; }
public ExecProcess(string cmd, string param, string dir,Env env) { _finish = false; _info = new ProcessStartInfo{ FileName = cmd, Arguments = param, CreateNoWindow = true, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, WorkingDirectory = dir }; //コマンド名 //パラメータ //子プロセスのウィンドウを表示しない。 // StandardInput を使用する場合は、UseShellExecute が false になっている必要がある // 標準入力を使用する // 標準出力を使用する //標準エラー出力を使用する if (env != null) { //環境変数 //Ver5.9.6 //_info.EnvironmentVariables.Clear(); foreach (var e in env) { //Ver5.9.6 if (_info.EnvironmentVariables.ContainsKey(e.Key)){ _info.EnvironmentVariables.Remove(e.Key); } _info.EnvironmentVariables.Add(e.Key, e.Val); } } }
public bool Exec(Target target, string param, Env env, WebStream inputStream, out WebStream outputStream, int cgiTimeout) { var cmd = target.CgiCmd; if(cmd==null){ outputStream = new WebStream(-1); outputStream.Add(Encoding.ASCII.GetBytes("cmd==null")); return false; } if (cmd.ToUpper().IndexOf("COMSPEC") == 0) { cmd = Environment.GetEnvironmentVariable("ComSpec"); // /cがウインドウクローズのために必要 param = "/c " + param; } else if (cmd.ToUpper().IndexOf("CMD.EXE") != -1) { cmd = target.FullPath; } else { param = string.Format("{0} {1}", Path.GetFileName(target.FullPath), param); } var execProcess = new ExecProcess(cmd, param, Path.GetDirectoryName(target.FullPath),env); return execProcess.Start(inputStream,out outputStream); }
public void HeaderTest(string key, string val) { var request = new Request(null,null); var header = new Header(); header.Append("Connection", Encoding.ASCII.GetBytes("keep-alive")); header.Append("User-Agent", Encoding.ASCII.GetBytes("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)")); header.Append("Accept", Encoding.ASCII.GetBytes("text/html,application/xhtml")); header.Append("Accept-Encoding", Encoding.ASCII.GetBytes("gzip,deflate,sdch")); header.Append("Accept-Language", Encoding.ASCII.GetBytes("ja,en-US;q=0.8,en;q=0.6")); header.Append("Accept-Charset", Encoding.ASCII.GetBytes("Shift_JIS,utf-8;q=0.7,*;q=0.3")); header.Append("Cache-Control", Encoding.ASCII.GetBytes("max-age=0")); var tcpObj = new SockTcp(new Kernel(), new Ip("0.0.0.0"), 88, 3,null); const string fileName = ""; var env = new Env(_kernel,new Conf(option), request, header, tcpObj, fileName); foreach (var e in env) { if (e.Key == key) { Assert.AreEqual(e.Val, val); return; } } Assert.AreEqual(key, ""); }
//接続単位の処理 protected override void OnSubThread(SockObj sockObj) { Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); var sockTcp = (SockTcp)sockObj; var remoteIp = sockTcp.RemoteIp; //opBase 及び loggerはバーチャルホストで変更されるので、 //このポインタを初期化に使用できない bool keepAlive = true;//レスポンスが終了したとき接続を切断しないで継続する //1回目の通信でバーチャルホストの検索を実施する var checkVirtual = true; var request = new Request(Logger,sockTcp);//リクエストライン処理クラス //受信ヘッダ var recvHeader = new Header(); //Ver5.1.x string urlStr = null;//http://example.com //接続が継続している間は、このループの中にいる(継続か否かをkeepAliveで保持する) //「continue」は、次のリクエストを待つ 「break」は、接続を切断する事を意味する WebStream inputStream = null; var outputStream = new WebStream(-1); while (keepAlive && IsLife()) { int responseCode; //*************************************************************** // ドキュメント生成クラスの初期化 //*************************************************************** var contentType = new ContentType(Conf); var document = new Document(Kernel, Logger, Conf, sockTcp, contentType); var authrization = new Authorization(Conf, Logger); var authName = ""; //*************************************************************** //データ取得 //*************************************************************** //リクエスト取得 //ここのタイムアウト値は、大きすぎるとブラウザの切断を取得できないでブロックしてしまう var requestStr = sockTcp.AsciiRecv(Timeout, this); if (requestStr == null) break; //\r\nの削除 requestStr = Inet.TrimCrlf(requestStr); //Ver5.8.8 リクエストの解釈に失敗した場合に、処理を中断する //request.Init(requestStr); if (!request.Init(requestStr)){ break; } //ヘッダ取得(内部データは初期化される) if (!recvHeader.Recv(sockTcp,(int)Conf.Get("timeOut"),this)) break; { //Ver5.1.x var hostStr = recvHeader.GetVal("host"); urlStr = hostStr==null ? null : string.Format("{0}://{1}",(ssl != null)?"https":"http",hostStr); } //入力取得(POST及びPUTの場合) var contentLengthStr = recvHeader.GetVal("Content-Length"); if(contentLengthStr != null) { try{ //max,lenはともにlong var max = Convert.ToInt64(contentLengthStr); if(max!=0){//送信データあり inputStream = new WebStream((256000<max)?-1:(int)max); var errorCount = 0; while(inputStream.Length<max && IsLife()){ var len = max - inputStream.Length; if (len > 51200000) { len = 51200000; } var b = sockTcp.Recv((int)len, (int)Conf.Get("timeOut"),this); if (!inputStream.Add(b)) { errorCount++;//エラー蓄積 Logger.Set(LogKind.Error, null, 41, string.Format("content-Length={0} Recv={1}", max, inputStream.Length)); } else { errorCount = 0;//初期化 } Logger.Set(LogKind.Detail, null,38, string.Format("Content-Length={0} {1}bytes Received.", max, inputStream.Length)); if (errorCount > 5){//5回連続して受信が無かった場合、サーバエラー responseCode = 500; goto SEND;//サーバエラー } Thread.Sleep(10); } Logger.Set(LogKind.Detail, null, 39, string.Format("Content-Length={0} {1}bytes", max, inputStream.Length)); } }catch(Exception ex){ Logger.Set(LogKind.Error, null, 40, ex.Message); } } // /によるパラメータ渡しに対応 //for (int i = 0;i < Option->CgiExt->Count;i++) { // wsprintf(TmpBuf,".%s/",Option->CgiExt->Strings[i]); // strupr(TmpBuf); // strcpy(Buf,Headers->Uri); // strupr(Buf); // if (NULL != (p = strstr(Buf,TmpBuf))) { // i = p - Buf; // i += strlen(TmpBuf) - 1; // p = &Headers->Uri[i]; // *p = '\0'; // p = &Headers->UriNoConversion[i]; // *p = '\0'; // wsprintf(TmpBuf,"/%s",p + 1); // Headers->PathInfo = new char[strlen(TmpBuf) + 1]; // strcpy(Headers->PathInfo,TmpBuf); // break; // } //} //*************************************************************** //バーチャルホストの検索を実施し、opBase、logger及び webDavDb を置き換える //*************************************************************** if (checkVirtual) {//初回のみ ReplaceVirtualHost(recvHeader.GetVal("host"),sockTcp.LocalAddress.Address,sockTcp.LocalAddress.Port); checkVirtual = false; } //*************************************************************** //接続を継続するかどうかの判断 keepAliveの初期化 //*************************************************************** if (ssl != null) { keepAlive = false;//SSL通信では、1回づつコネクションが必要 }else{ if (request.Ver == "HTTP/1.1") {//HTTP1.1はデフォルトで keepAlive=true keepAlive = true; } else { // HTTP/1.1以外の場合、継続接続は、Connection: Keep-Aliveの有無に従う keepAlive = recvHeader.GetVal("Connection") == "Keep-Alive"; } } //*************************************************************** // ドキュメント生成クラスの初期化 //*************************************************************** //var contentType = new ContentType(OneOption); //var document = new Document(kernel,Logger,OneOption,sockTcp,contentType); //*************************************************************** // ログ //*************************************************************** Logger.Set(LogKind.Normal, sockTcp, ssl != null ? 23 : 24, request.LogStr); //*************************************************************** // 認証 //*************************************************************** //var authrization = new Authorization(OneOption,Logger); //string authName = ""; if (!authrization.Check(request.Uri, recvHeader.GetVal("authorization"), ref authName)) { responseCode = 401; keepAlive = false;//切断 goto SEND; } //*************************************************************** // 不正なURIに対するエラー処理 //*************************************************************** //URIを点検して不正な場合はエラーコードを返す responseCode = CheckUri(sockTcp, request, recvHeader); if (responseCode != 200) { keepAlive = false;//切断 goto SEND; } //*************************************************************** //ターゲットオブジェクトの初期化 //*************************************************************** var target = new Target(Conf,Logger); if (target.DocumentRoot == null) { Logger.Set(LogKind.Error,sockTcp,14,string.Format("documentRoot={0}",Conf.Get("documentRoot")));//ドキュメントルートで指定されたフォルダが存在しません(処理を継続できません) break;//ドキュメントルートが無効な場合は、処理を継続できない } target.InitFromUri(request.Uri); //*************************************************************** // 送信ヘッダの追加 //*************************************************************** // 特別拡張 BlackJumboDog経由のリクエストの場合 送信ヘッダにRemoteHostを追加する if ((bool)Conf.Get("useExpansion")) { if (recvHeader.GetVal("Host") != null) { document.AddHeader("RemoteHost",sockTcp.RemoteAddress.Address.ToString()); } } //受信ヘッダに「PathInfo:」が設定されている場合、送信ヘッダに「PathTranslated」を追加する var pathInfo = recvHeader.GetVal("PathInfo"); if (pathInfo != null) { pathInfo = target.DocumentRoot + pathInfo; document.AddHeader("PathTranslated",Util.SwapChar('/','\\',pathInfo)); } //*************************************************************** //メソッドに応じた処理 OPTIONS 対応 Ver5.1.x //*************************************************************** if(WebDav.IsTarget(request.Method)){ var webDav = new WebDav(Logger, _webDavDb, target, document, urlStr, recvHeader.GetVal("Depth"), contentType,(bool)Conf.Get("useEtag")); var inputBuf = new byte[0]; if(inputStream!=null){ inputBuf = inputStream.GetBytes(); } switch(request.Method) { case HttpMethod.Options: responseCode = webDav.Option(); break; case HttpMethod.Delete: responseCode = webDav.Delete(); break; case HttpMethod.Put: responseCode = webDav.Put(inputBuf); break; case HttpMethod.Proppatch: responseCode = webDav.PropPatch(inputBuf); break; case HttpMethod.Propfind: responseCode = webDav.PropFind(); break; case HttpMethod.Mkcol: responseCode = webDav.MkCol(); break; case HttpMethod.Copy: case HttpMethod.Move: responseCode = 405; //Destnationで指定されたファイルは書き込み許可されているか? var dstTarget = new Target(Conf,Logger); string destinationStr = recvHeader.GetVal("Destination"); if(destinationStr != null) { if(destinationStr.IndexOf("://") == -1) { destinationStr = urlStr + destinationStr; } var uri = new Uri(destinationStr); dstTarget.InitFromUri(uri.LocalPath); if(dstTarget.WebDavKind == WebDavKind.Write) { var overwrite = false; var overwriteStr = recvHeader.GetVal("Overwrite"); if(overwriteStr != null) { if(overwriteStr == "F") { overwrite = true; } } responseCode = webDav.MoveCopy(dstTarget,overwrite,request.Method); document.AddHeader("Location",destinationStr); } } break; } //WebDAVに対するリクエストは、ここで処理完了 goto SEND; } //以下 label SENDまでの間は、GET/POSTに関する処理 //*************************************************************** //ターゲットの種類に応じた処理 //*************************************************************** if (target.TargetKind == TargetKind.Non) { //見つからない場合 responseCode = 404; goto SEND; } if (target.TargetKind == TargetKind.Move) { //ターゲットはディレクトリの場合 responseCode = 301; goto SEND; } if (target.TargetKind == TargetKind.Dir) { //ディレクトリ一覧表示の場合 //インデックスドキュメントを生成する if (!document.CreateFromIndex(request, target.FullPath)) break; goto SEND; } //*************************************************************** // 隠し属性のファイルへのアクセス制御 //*************************************************************** if (!(bool)Conf.Get("useHidden")) { if ((target.Attr & FileAttributes.Hidden) == FileAttributes.Hidden) { //エラーキュメントを生成する responseCode = 404; keepAlive = false;//切断 goto SEND; } } if (target.TargetKind == TargetKind.Cgi || target.TargetKind == TargetKind.Ssi) { keepAlive = false;//デフォルトで切断 //環境変数作成 var env = new Env(Kernel,Conf,request, recvHeader,sockTcp, target.FullPath); // 詳細ログ Logger.Set(LogKind.Detail,sockTcp,18,string.Format("{0} {1}",target.CgiCmd,Path.GetFileName(target.FullPath))); if (target.TargetKind == TargetKind.Cgi) { var cgi = new Cgi(); var cgiTimeout = (int)Conf.Get("cgiTimeout"); if (!cgi.Exec(target,request.Param,env,inputStream,out outputStream,cgiTimeout)) { // エラー出力 var errStr = Encoding.ASCII.GetString(outputStream.GetBytes()); Logger.Set(LogKind.Error,sockTcp,16,errStr); responseCode = 500; goto SEND; } //*************************************************** // NPH (Non-Parsed Header CGI)スクリプト nph-で始まる場合、サーバ処理(レスポンスコードやヘッダの追加)を経由しない //*************************************************** if (Path.GetFileName(target.FullPath).IndexOf("nph-") == 0) { sockTcp.SendUseEncode(outputStream.GetBytes());//CGI出力をそのまま送信する break; } // CGIで得られた出力から、本体とヘッダを分離する if(!document.CreateFromCgi(outputStream.GetBytes())) break; // cgi出力で、Location:が含まれる場合、レスポンスコードを302にする if (document.SearchLocation())//Location:ヘッダを含むかどうか responseCode = 302; goto SEND; } //SSI var ssi = new Ssi(Kernel, Logger,Conf, sockTcp, request, recvHeader); if (!ssi.Exec(target,env,outputStream)) { // エラー出力 Logger.Set(LogKind.Error,sockTcp,22,MLang.GetString(outputStream.GetBytes())); responseCode = 500; goto SEND; } document.CreateFromSsi(outputStream.GetBytes(),target.FullPath); goto SEND; } //以下は、通常ファイルの処理 TARGET_KIND.FILE //******************************************************************** //Modified処理 //******************************************************************** if (recvHeader.GetVal("If_Modified_Since") != null) { var dt = Util.Str2Time(recvHeader.GetVal("If-Modified-Since")); if (target.FileInfo.LastWriteTimeUtc.Ticks / 10000000 <= dt.Ticks / 10000000) { responseCode = 304; goto SEND; } } if (recvHeader.GetVal("If_Unmodified_Since") != null) { var dt = Util.Str2Time(recvHeader.GetVal("If_Unmodified_Since")); if (target.FileInfo.LastWriteTimeUtc.Ticks / 10000000 > dt.Ticks / 10000000) { responseCode = 412; goto SEND; } } document.AddHeader("Last-Modified",Util.UtcTime2Str(target.FileInfo.LastWriteTimeUtc)); //******************************************************************** //ETag処理 //******************************************************************** // (1) useEtagがtrueの場合は、送信時にETagを付加する // (2) If-None-Match 若しくはIf-Matchヘッダが指定されている場合は、排除対象かどうかの判断が必要になる if ((bool)Conf.Get("useEtag") || recvHeader.GetVal("If-Match") != null || recvHeader.GetVal("If-None-Match") != null) { //Ver5.1.5 //string etagStr = string.Format("\"{0:x}-{1:x}\"", target.FileInfo.Length, (target.FileInfo.LastWriteTimeUtc.Ticks / 10000000)); var etagStr = WebServerUtil.Etag(target.FileInfo); string str; if (null != (str = recvHeader.GetVal("If-Match"))) { if (str != "*" && str != etagStr) { responseCode = 412; goto SEND; } } if (null != (str = recvHeader.GetVal("If-None-Match"))) { if (str != "*" && str == etagStr) { responseCode = 304; goto SEND; } } if ((bool)Conf.Get("useEtag")) document.AddHeader("ETag",etagStr); } //******************************************************************** //Range処理 //******************************************************************** document.AddHeader("Accept-Range","bytes"); var rangeFrom = 0L;//デフォルトは最初から var rangeTo = target.FileInfo.Length;//デフォルトは最後まで(ファイルサイズ) if (recvHeader.GetVal("Range") != null) {//レンジ指定のあるリクエストの場合 var range = recvHeader.GetVal("Range"); //指定範囲を取得する(マルチ指定には未対応) if (range.IndexOf("bytes=") == 0) { range = range.Substring(6); var tmp = range.Split('-'); //Ver5.3.5 ApacheKiller対処 if (tmp.Length > 20) { Logger.Set(LogKind.Secure, sockTcp,9000054, string.Format("[ Apache Killer ]Range:{0}", range)); AutoDeny(false, remoteIp); responseCode = 503; keepAlive = false;//切断 goto SEND; } if(tmp.Length == 2) { //Ver5.3.6 のデバッグ用 //tmp[1] = "499"; if(tmp[0] != "") { if(tmp[1] != "") {// bytes=0-10 0~10の11バイト //Ver5.5.9 rangeFrom = Convert.ToInt64(tmp[0]); if (tmp[1] != "") { //Ver5.5.9 rangeTo = Convert.ToInt64(tmp[1]); if (target.FileInfo.Length <= rangeTo) { rangeTo = target.FileInfo.Length - 1; } else { document.SetRangeTo = true;//Ver5.4.0 } } } else {// bytes=3- 3~最後まで rangeTo = target.FileInfo.Length - 1; rangeFrom = Convert.ToInt64(tmp[0]); } } else { if(tmp[1] != "") {// bytes=-3 最後から3バイト var len = Convert.ToInt64(tmp[1]); rangeTo = target.FileInfo.Length - 1; rangeFrom = rangeTo-len+1; if(rangeFrom<0) rangeFrom=0; document.SetRangeTo = true;//Ver5.4.0 } } if(rangeFrom <= rangeTo) { //正常に範囲を取得できた場合、事後Rangeモードで動作する document.AddHeader("Content-Range",string.Format("bytes {0}-{1}/{2}",rangeFrom,rangeTo,target.FileInfo.Length)); responseCode = 206; } } } } //通常ファイルのドキュメント if (request.Method != HttpMethod.Head) { if (!document.CreateFromFile(target.FullPath,rangeFrom,rangeTo)) break; } SEND: //レスポンスコードが200以外の場合は、ドキュメント(及び送信ヘッダ)をエラー用に変更する if(responseCode != 200 && responseCode != 302 && responseCode != 206 && responseCode != 207 && responseCode != 204 && responseCode != 201) { //ResponceCodeの応じてエラードキュメントを生成する if (!document.CreateFromErrorCode(request,responseCode)) break; if (responseCode == 301) {//ターゲットがファイルではなくディレクトの間違いの場合 if(urlStr != null) { var str = string.Format("{0}{1}/",urlStr,request.Uri); document.AddHeader("Location",Encoding.UTF8.GetBytes(str)); } } if (responseCode == 304 || responseCode == 301) {//304 or 301 の場合は、ヘッダのみになる document.Clear(); } else { if (responseCode == 401) { document.AddHeader("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", authName)); } } } //Ver5.6.2 request.Send()廃止 var responseStr = request.CreateResponse(responseCode); sockTcp.AsciiSend(responseStr);//レスポンス送信 Logger.Set(LogKind.Detail, sockTcp, 4, responseStr);//ログ document.Send(keepAlive,this);//ドキュメント本体送信 } if(inputStream!=null) inputStream.Dispose(); if (outputStream != null) outputStream.Dispose(); //end://このソケット接続の終了 if (sockTcp != null) { sockTcp.Close(); } }
//ファイルのインクルード bool SsiInclude(string tag, string val, ref string str, Encoding encoding) { var newTarget = CreateTarget(tag, val); if (newTarget == null) return false; //ループに陥るため、自分自身はインクルードできない if (_target.FullPath == newTarget.FullPath) { _logger.Set(LogKind.Error, null, 15, string.Format("{0}", newTarget.FullPath)); return false; } if (newTarget.TargetKind == TargetKind.Cgi) { var cgi = new Cgi(); //TODO 変数削除 リファクタリング対象 //IPAddress remoteAddress = tcpObj.RemoteEndPoint.Address; //string remoteHostName = tcpObj.RemoteHost; //環境変数作成 //Ver5.6.2 //Env env = new Env(kernel, request, recvHeader, remoteAddress, remoteHostName, newTarget.FullPath); var env = new Env(_kernel, _conf,_request, _recvHeader,_sockTcp,newTarget.FullPath); const string param = ""; WebStream output; var cgiTimeout = (int)_conf.Get("cgiTimeout"); cgi.Exec(newTarget, param, env,null, out output, cgiTimeout); str = Encoding.ASCII.GetString(output.GetBytes()); //Ver5.9.1 CGI出力は、ヘッダをカットする var lines = str.Split('\n').ToList(); var index = lines.IndexOf("\r"); if (index != -1) { var sb = new StringBuilder(); for (int i = index + 1; i < lines.Count(); i++) { sb.Append(lines[i] + "\n"); } str = sb.ToString(); } } else if (newTarget.TargetKind == TargetKind.File || newTarget.TargetKind == TargetKind.Ssi) { if (File.Exists(newTarget.FullPath)) { using (var sr = new StreamReader(newTarget.FullPath, encoding)) { str = sr.ReadToEnd(); sr.Close(); } } else { return false; } } else { return false; } return true; }
//プログラム実行 bool SsiExec(string tag, string val, ref string str, Encoding encoding, SockTcp tcpObj) { Target newTarget; var param = ""; if (tag.ToLower() == "cmd") { param = val; newTarget = CreateTarget("comspec", null); if (newTarget == null) { return false; } } else if (tag.ToLower() == "cgi") { var cmd = val; var tmp = val.Split(new[] { ' ' }, 2); if (tmp.Length == 2) { cmd = tmp[0]; param = tmp[1]; } newTarget = CreateTarget("file", cmd); if (newTarget == null) { return false; } if (newTarget.TargetKind != TargetKind.Cgi) { _logger.Set(LogKind.Error, tcpObj, 27, string.Format("<!--#exec cgi=\"{0}\"-->", val)); return false; } } else { // cmd="" cgi="" 以外の場合はエラー _logger.Set(LogKind.Error, tcpObj, 28, ""); return false; } var cgi = new Cgi(); //TODO 変数削除リファクタリング対象 //IPAddress remoteAddress = tcpObj.RemoteEndPoint.Address; //string remoteHost = tcpObj.RemoteHost; //環境変数作成 //Env env = new Env(kernel, request, recvHeader, remoteAddress, remoteHost, newTarget.FullPath); var env = new Env(_kernel,_conf, _request, _recvHeader, tcpObj, newTarget.FullPath); WebStream output;//標準出力 const string err = ""; var cgiTimeout = (int)_conf.Get("cgiTimeout"); if (!cgi.Exec(newTarget, param, env, null, out output,cgiTimeout)) { str = err; } else{ var b = new byte[output.Length]; output.Read(b, 0, b.Length); str = encoding.GetString(b); } return true; }
public void OptionTest(string key, string val) { var request = new Request(null,null); var conf = new Conf(option); conf.Set("documentRoot", val); var header = new Header(); var tcpObj = new SockTcp(new Kernel(), new Ip("0.0.0.0"), 88, 1, null); const string fileName = ""; var env = new Env(_kernel,conf, request, header,tcpObj, fileName); foreach (var e in env) { if (e.Key == key) { Assert.AreEqual(e.Val, val); return; } } Assert.AreEqual(key, ""); }
public void TcpObjTest(string key, string val) { var conf = new Conf(option); var request = new Request(null,null); var header = new Header(); var tcpObj = new SockTcp(new Kernel(), new Ip("0.0.0.0"), 88, 1,null); tcpObj.LocalAddress = new IPEndPoint((new Ip("127.0.0.1")).IPAddress,80); tcpObj.RemoteAddress = new IPEndPoint((new Ip("10.0.0.100")).IPAddress, 5000); const string fileName = ""; var env = new Env(_kernel,conf, request, header, tcpObj, fileName); foreach (var e in env) { if (e.Key == key) { Assert.AreEqual(e.Val, val); return; } } Assert.AreEqual(key, ""); }
public void OtherTest(string key, string val) { var request = new Request(null,null); var header = new Header(); var tcpObj = new SockTcp(new Kernel(), new Ip(IpKind.V4_0), 88, 3,null); const string fileName = ""; var env = new Env(_kernel,new Conf(option),request,header,tcpObj,fileName); foreach(var e in env){ if(e.Key == key){ if (e.Key == "SERVER_SOFTWARE" && e.Val.IndexOf(".1478") > 0){ Assert.AreEqual(e.Val.ToLower(), "BlackJumboDog/7.1.2000.1478 (Windows)".ToLower()); } else{ Assert.AreEqual(e.Val.ToLower(), val.ToLower()); } return; } } Assert.AreEqual(key,""); }