Exemple #1
0
        //キャッシュ確認
        public void CacheConform(Cache cache)
        {
            //キャッシュ対象のリクエストかどうかの確認
            if (!_oneObj.Request.Cgi)
            {
                if (cache.IsTarget(_oneObj.Request.HostName, _oneObj.Request.Uri, _oneObj.Request.Ext))
                {
                    _isCacheTarget = true;

                    // Pragma: no-cache が指定されている場合は、蓄積されたキャッシュを否定する
                    var pragmaStr = _oneObj.Header[CS.Client].GetVal("Pragma");

                    if (pragmaStr != null && pragmaStr.ToLower().IndexOf("no-cache") >= 0)
                    {
                        _proxy.Logger.Set(LogKind.Detail, null, 16, _oneObj.Request.Uri);
                        cache.Remove(_oneObj.Request.HostName, _oneObj.Request.Port, _oneObj.Request.Uri);//存在する場合は、無効化する
                    }
                    else
                    {
                        string   modifiedStr = _oneObj.Header[CS.Client].GetVal("If-Modified-Since");
                        DateTime modified    = Util.Str2Time(modifiedStr);
                        OneCache oneCache    = cache.Get(_oneObj.Request, modified);
                        if (oneCache != null)   //キャッシュが見つかった場合
                        {
                            _proxy.Logger.Set(LogKind.Detail, null, 14, _oneObj.Request.Uri);

                            _sideState[CS.Server] = HttpSideState.ServerSideRecvBody;    //一気に受信完了
                            _sideState[CS.Client] = HttpSideState.ClientSideRecvRequest; //リクエスト受信完了まで進める

                            _response.Recv("HTTP/1.1 200 OK");
                            _oneObj.Header[CS.Server] = new Header(oneCache.Header);
                            _oneObj.Body[CS.Server].Set(new byte[oneCache.Body.Length]);

                            //Buffer.BlockCopy(oneCache.Body, 0, oneObj.Body[CS.Server], 0, oneCache.Body.Length);
                            _oneObj.Body[CS.Server].Set(oneCache.Body);

                            _proxy.NoConnect(_oneObj.Request.HostName, _oneObj.Request.Port);

                            //擬似的にContentLength形式で処理する
                            _oneHttpKind   = OneHttpKind.ContentLength;
                            _contentLength = _oneObj.Body[CS.Server].Length;

                            //キャッシュによる返答(このオブジェクトはキャッシュしない)
                            _isCacheTarget = false;
                        }
                    }
                }
            }
        }
Exemple #2
0
        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;
        }
Exemple #3
0
        //キャッシュ確認
        public void CacheConform(Cache cache)
        {
            //キャッシュ対象のリクエストかどうかの確認
            if (!_oneObj.Request.Cgi) {
                if (cache.IsTarget(_oneObj.Request.HostName, _oneObj.Request.Uri, _oneObj.Request.Ext)) {
                    _isCacheTarget = true;

                    // Pragma: no-cache が指定されている場合は、蓄積されたキャッシュを否定する
                    var pragmaStr = _oneObj.Header[CS.Client].GetVal("Pragma");

                    if (pragmaStr != null && pragmaStr.ToLower().IndexOf("no-cache") >= 0) {
                        _proxy.Logger.Set(LogKind.Detail, null, 16, _oneObj.Request.Uri);
                        cache.Remove(_oneObj.Request.HostName, _oneObj.Request.Port, _oneObj.Request.Uri);//存在する場合は、無効化する
                    } else {
                        string modifiedStr = _oneObj.Header[CS.Client].GetVal("If-Modified-Since");
                        DateTime modified = Util.Str2Time(modifiedStr);
                        OneCache oneCache = cache.Get(_oneObj.Request, modified);
                        if (oneCache != null) { //キャッシュが見つかった場合
                            _proxy.Logger.Set(LogKind.Detail, null, 14, _oneObj.Request.Uri);

                            _sideState[CS.Server] = HttpSideState.ServerSideRecvBody;//一気に受信完了
                            _sideState[CS.Client] = HttpSideState.ClientSideRecvRequest;//リクエスト受信完了まで進める

                            _response.Recv("HTTP/1.1 200 OK");
                            _oneObj.Header[CS.Server] = new Header(oneCache.Header);
                            _oneObj.Body[CS.Server].Set(new byte[oneCache.Body.Length]);

                            //Buffer.BlockCopy(oneCache.Body, 0, oneObj.Body[CS.Server], 0, oneCache.Body.Length);
                            _oneObj.Body[CS.Server].Set(oneCache.Body);

                            _proxy.NoConnect(_oneObj.Request.HostName, _oneObj.Request.Port);

                            //擬似的にContentLength形式で処理する
                            _oneHttpKind = OneHttpKind.ContentLength;
                            _contentLength = _oneObj.Body[CS.Server].Length;

                            //キャッシュによる返答(このオブジェクトはキャッシュしない)
                            _isCacheTarget = false;
                        }
                    }
                }
            }
        }
Exemple #4
0
        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);
        }