コード例 #1
0
        public IEnumerable <LangToken> Process(MLang lang)
        {
            var used = new HashSet <LangToken>();

            if (Target != null)
            {
                foreach (var x in Target.Action.ProcessGroup(Tokens, lang))
                {
                    if (used.Add(x))
                    {
                        yield return(x);
                    }
                }
            }
            foreach (var child in Childs)
            {
                foreach (var x in child.Process(lang))
                {
                    if (used.Add(x))
                    {
                        yield return(x);
                    }
                }
            }
        }
コード例 #2
0
ファイル: Ssi.cs プロジェクト: schifflee/bjd5
        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);
        }
コード例 #3
0
 public IEnumerable <LangToken> ProcessGroup(IEnumerable <LangToken> group, MLang lang)
 {
     foreach (var tagExport in TagExport)
     {
         var tag = new TokenTag
         {
             Key   = tagExport.Key,
             Value = tagExport.Value
         };
         foreach (var token in group)
         {
             token.Tags[tag.Key] = tag;
             tag.AddParent(token);
         }
     }
     foreach (var tagPriority in TagPriority)
     {
         foreach (var token in group)
         {
             if (token.Tags.TryGetValue(tagPriority.Key, out TokenTag tag))
             {
                 tag.Priority = tagPriority.Value;
             }
         }
     }
     if (Handlers.Count == 0)
     {
         foreach (var token in group)
         {
             yield return(token);
         }
     }
     else
     {
         var used = new HashSet <LangToken>();
         foreach (var handler in Handlers)
         {
             if (lang.TextProcessors.TryGetValue(handler, out ITokenProcessor processor))
             {
                 foreach (var r in processor.Process(group))
                 {
                     used.Add(r);
                 }
             }
         }
         foreach (var result in group)
         {
             if (used.Contains(result))
             {
                 yield return(result);
             }
         }
     }
 }
コード例 #4
0
        public AirBotWorker(MLang mlang, ITelegramBotClient telegramApi, Config config, Database database)
        {
            SessionsTable = new Dictionary <string, TgSession>();
            Database      = database;

            MLang       = mlang;
            TelegramApi = telegramApi;
            Config      = config;
            GeneralApi  = new General.Api(config.GeneralApi);
            TextApi     = new airbot.TextApi.Api(config.TextApi);
            BotInfo     = telegramApi.GetMeAsync().Result;
        }
コード例 #5
0
ファイル: MLang.cs プロジェクト: schifflee/bjd5
        public void getEncoding及びgetstringの確認()
        {
            //setUp
            string str = "あいうえお";

            string[] charsetList = new[] { "utf-8", "euc-jp", "iso-2022-jp", "shift_jis" };

            //verify
            foreach (string charset in charsetList)
            {
                byte[] bytes = Encoding.GetEncoding(charset).GetBytes(str);
                Assert.That(MLang.GetEncoding(bytes).WebName, Is.EqualTo(charset));
                Assert.That(MLang.GetString(bytes), Is.EqualTo(str));
            }
        }
コード例 #6
0
ファイル: MLang.cs プロジェクト: schifflee/bjd5
        public void getEncoding_fileName_の確認()
        {
            //setUp
            string tempFile = Path.GetTempFileName();
            //File tempFile = File.createTempFile("tmp", ".txt");
            List <string> lines = new List <string>();

            lines.Add("あいうえお");
            File.WriteAllLines(tempFile, lines);

            Encoding sut      = MLang.GetEncoding(tempFile);
            string   expected = "utf-8";
            //exercise
            string actual = sut.WebName;

            //verify
            Assert.That(actual, Is.EqualTo(expected));
            //TearDown
            File.Delete(tempFile);
        }
コード例 #7
0
ファイル: SockObj.cs プロジェクト: schifflee/bjd5
        //バイナリデータであることが判明している場合は、noEncodeをtrueに設定する
        //これによりテキスト判断ロジックを省略できる
        protected void Trace(TraceKind traceKind, byte[] buf, bool noEncode)
        {
            if (buf == null || buf.Length == 0)
            {
                return;
            }

            if (Kernel.RunMode == RunMode.Remote)
            {
                return; //リモートクライアントの場合は、ここから追加されることはない
            }

            //Ver5.0.0-a22 サービス起動の場合は、このインスタンスは生成されていない
            bool enableDlg = Kernel.TraceDlg != null && Kernel.TraceDlg.Visible;

            if (!enableDlg && Kernel.RemoteConnect == null)
            {
                //どちらも必要ない場合は処置なし
                return;
            }

            bool     isText   = false; //対象がテキストかどうかの判断
            Encoding encoding = null;

            if (!noEncode)
            {
                //エンコード試験が必要な場合
                try{
                    encoding = MLang.GetEncoding(buf);
                } catch {
                    encoding = null;
                }
                if (encoding != null)
                {
                    //int codePage = encoding.CodePage;
                    if (encoding.CodePage == 20127 || encoding.CodePage == 65001 || encoding.CodePage == 51932 || encoding.CodePage == 1200 || encoding.CodePage == 932 || encoding.CodePage == 50220)
                    {
                        //"US-ASCII" 20127
                        //"Unicode (UTF-8)" 65001
                        //"日本語(EUC)" 51932
                        //"Unicode" 1200
                        //"日本語(シフトJIS)" 932
                        //日本語(JIS) 50220
                        isText = true;
                    }
                }
            }

            var ar = new List <String>();

            if (isText)
            {
                var lines = Inet.GetLines(buf);
                ar.AddRange(lines.Select(line => encoding.GetString(Inet.TrimCrlf(line))));
            }
            else
            {
                ar.Add(noEncode ? string.Format("binary {0} byte", buf.Length) : string.Format("Binary {0} byte", buf.Length));
            }
            foreach (var str in ar)
            {
                Ip ip = RemoteIp;

                if (enableDlg)
                {
                    //トレースダイアログが表示されてい場合、データを送る
                    Kernel.TraceDlg.AddTrace(traceKind, str, ip);
                }
                if (Kernel.RemoteConnect != null)
                {
                    //リモートサーバへもデータを送る(クライアントが接続中の場合は、クライアントへ送信される)
                    Kernel.RemoteConnect.AddTrace(traceKind, str, ip);
                }
            }
        }
コード例 #8
0
ファイル: MapGroup.cs プロジェクト: sunsx0/s7hackaton
 public MapGroup(MLang lang)
 {
     Lang = lang;
 }
コード例 #9
0
        //接続単位の処理
        override protected 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();
            }
        }
コード例 #10
0
ファイル: Request.cs プロジェクト: schifflee/bjd5
        //�f�[�^�擾�i����f�[�^�́A�����������j
        public bool Recv(Logger logger, SockTcp tcpObj, int timeout, ILife iLife)
        {
            var buf = tcpObj.LineRecv(timeout, iLife);

            if (buf == null)
            {
                return(false);
            }
            buf = Inet.TrimCrlf(buf);

            _urlEncoding = MLang.GetEncoding(buf);//URL�G���R�[�h�̌`����ۑ�����

            //Ver5.9.8
            if (_urlEncoding == null)
            {
                var sb = new StringBuilder();
                for (int i = 0; i < buf.Length; i++)
                {
                    sb.Append(String.Format("0x{0:X},", buf[i]));
                }
                logger.Set(LogKind.Error, tcpObj, 9999, String.Format("_urlEncoding==null buf.Length={0} buf={1}", buf.Length, sb.ToString()));
                //���̂܂ܗ�O�֓˓�������
            }

            var str = _urlEncoding.GetString(buf);

            // ���\�b�h�EURI�E�o�[�W�����ɕ���
            //"GET http://hostname:port@user:pass/path/filename.ext?param HTTP/1.1"
            RequestStr = str;

            //(�󔒂ŕ�������)�@"GET <=> http://hostname:port@user:pass/path/filename.ext?param HTTP/1.1"
            var index = str.IndexOf(' ');

            if (index < 0) //Ver5.0.0-a8
            {
                return(false);
            }

            //(�O��) "GET"
            var methodStr = str.Substring(0, index);

            foreach (HttpMethod m in Enum.GetValues(typeof(HttpMethod)))
            {
                if (methodStr.ToUpper() == m.ToString().ToUpper())
                {
                    HttpMethod = m;
                    break;
                }
            }
            if (HttpMethod == HttpMethod.Unknown)
            {
                logger.Set(LogKind.Secure, tcpObj, 1, string.Format("{0}", RequestStr));//�T�|�[�g�O�̃��\�b�h�ł��i������p���ł��܂���j
                return(false);
            }
            if (HttpMethod == HttpMethod.Connect)
            {
                Protocol = ProxyProtocol.Ssl;
                Port     = 443;//�f�t�H���g�̃|�[�g�ԍ���443�ɂȂ�
            }

            //(�㔼) "http://*****:*****@user:pass/path/filename.ext?param HTTP/1.1"
            str = str.Substring(index + 1);


            //(�󔒂ŕ�������)�@"http://*****:*****@user:pass/path/filename.ext?param <=> HTTP/1.1"
            index = str.IndexOf(' ');
            if (index < 0) //Ver5.0.0-a8
            {
                return(false);
            }
            //(�㔼) "HTTP/1.1"
            HttpVer = str.Substring(index + 1);

            if (HttpVer != "HTTP/0.9" && HttpVer != "HTTP/1.0" && HttpVer != "HTTP/1.1")
            {
                logger.Set(LogKind.Secure, tcpObj, 2, RequestStr);//�T�|�[�g�O�̃o�[�W�����ł��i������p���ł��܂���j
                return(false);
            }

            //(�O��) "http://*****:*****@user:pass/path/filename.ext?param"
            str = str.Substring(0, index);

            if (Protocol == ProxyProtocol.Unknown)  //�v���g�R���擾
            //("://"�������)�@"http <=> hostname:port@user:pass/path/filename.ext?param <=> HTTP/1.1"
            {
                index = str.IndexOf("://");
                if (index < 0) //Ver5.0.0-a8
                {
                    return(false);
                }
                //(�O��) "http"
                var protocolStr = str.Substring(0, index);

                if (protocolStr.ToLower() == "ftp")
                {
                    Protocol = ProxyProtocol.Ftp; //�v���g�R����FTP�ɏC��
                    Port     = 21;                //FTP�ڑ��̃f�t�H���g�̃|�[�g�ԍ���21�ɂȂ�
                }
                else if (protocolStr.ToLower() != "http")
                {
                    //Ver5.6.7
                    //Msg.Show(MsgKind.Error,"�݌v�G���[�@Request.Recv()");
                    //�G���[�\����|�b�v�A�b�v���烍�O�ɕύX
                    logger.Set(LogKind.Error, tcpObj, 29, string.Format("protocolStr={0}", protocolStr));
                    return(false);
                }
                else
                {
                    Protocol = ProxyProtocol.Http;
                }
                //(�㔼) "hostname:port@user:pass/path/filename.ext?param"
                str = str.Substring(index + 3);
            }
            //(�ŏ���"/"�ŕ�������)�@"hostname:port@user:pass <=> /path/filename.ext?param"
            index    = str.IndexOf('/');
            HostName = str;
            if (0 <= index)
            {
                //(�O��) ""hostname:port@user:pass"
                HostName = str.Substring(0, index);

                //(�㔼) "/path/filename.ext?param"
                str = str.Substring(index);
            }
            else
            {
                // GET http://hostname HTTP/1.0 �̂悤�ɁA���[�g�f�B���N�g�����w�肳��Ă��Ȃ��ꍇ�̑Ώ�
                str = "/";
            }

            //�z�X�g�������Ƀ��[�U���F�p�X���[�h�������Ă���ꍇ�̏���
            index = HostName.IndexOf("@");
            if (0 <= index)
            {
                var userpass = HostName.Substring(0, index);

                //���[�U���F�p�X���[�h��j������
                HostName = HostName.Substring(index + 1);

                var i = userpass.IndexOf(':');
                if (i == -1)
                {
                    User = userpass;
                }
                else
                {
                    User = userpass.Substring(0, i);
                    Pass = userpass.Substring(i + 1);
                }
            }
            //Ver5.1.2 IPv6�A�h���X�\�L�̃z�X�g���ɑΉ�
            var tmp = HostName.Split(new[] { '[', ']' });

            if (tmp.Length == 3) //IPv6�A�h���X�\�L�ł���Ɣ��f����
            {
                HostName = string.Format("[{0}]", tmp[1]);
                index    = tmp[2].IndexOf(":");
                if (0 <= index)
                {
                    var s = tmp[2].Substring(index + 1);
                    Port = Convert.ToInt32(s);
                }
            }
            else
            {
                //�z�X�g�������Ƀ|�[�g�ԍ��������Ă���ꍇ�̏���
                index = HostName.IndexOf(":");
                if (0 <= index)
                {
                    var s = HostName.Substring(index + 1);
                    Port     = Convert.ToInt32(s);
                    HostName = HostName.Substring(0, index);
                }
            }

            Uri = str;

            //CGI����
            if (-1 != Uri.LastIndexOf('?'))
            {
                Cgi = true;
            }

            //�g���q�擾
            if (!Cgi)
            {
                index = Uri.LastIndexOf('/');
                if (index != -1)
                {
                    str = Uri.Substring(index + 1);
                }
                index = str.LastIndexOf('.');
                if (index != -1)
                {
                    Ext = str.Substring(index + 1);
                }
            }
            return(true);
        }