//キャッシュ確認 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; } } } } }
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; }
//キャッシュ確認 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; } } } } }
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); }