public bool RecvServer(ref bool life) { //int timeout=3; //レスポンス・ヘッダの受信 if(sideState[CS.SERVER] == HTTP_SIDE_STATE.SERVER_SIDE_SEND_BODY) { int c = proxy.OptionTimeout; //本当は、OptionTimeout*10 だけど、最初のレスポンスがあまりに遅いとプログラムがロックするので10分の1に設定する while(life && proxy.Sock(CS.SERVER).State == SOCKET_OBJ_STATE.CONNECT && proxy.Sock(CS.CLIENT).State == SOCKET_OBJ_STATE.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,ref life)) { proxy.Logger.Set(LOG_KIND.ERROR,proxy.Sock(CS.SERVER),6,""); return false; } //ヘッダの受信 if(!oneObj.Header[CS.SERVER].Recv(proxy.Sock(CS.SERVER),proxy.OptionTimeout,ref life)) { proxy.Logger.Set(LOG_KIND.ERROR,proxy.Sock(CS.SERVER),7,""); return false; } //データ転送形式の判別 if(oneObj.Request.Method == HTTP_METHOD.HEAD) { oneHttpKind = ONE_HTTP_KIND.CONTENT_LENGTH; contentLength = 0; } if(oneHttpKind == ONE_HTTP_KIND.UNKNOWN) { string strTransferEncoding = oneObj.Header[CS.SERVER].GetVal("Transfer-Encoding"); if(strTransferEncoding != null) { if(strTransferEncoding == "chunked") oneHttpKind = ONE_HTTP_KIND.CHUNK; } } if(oneHttpKind == ONE_HTTP_KIND.UNKNOWN) { string strContentLength = oneObj.Header[CS.SERVER].GetVal("Content-Length"); if(strContentLength != null) { oneHttpKind = ONE_HTTP_KIND.CONTENT_LENGTH; contentLength = Convert.ToInt32(strContentLength); } else { if(response.Code != 200) { oneHttpKind = ONE_HTTP_KIND.CONTENT_LENGTH; contentLength = 0; } } } //コンテンツ制限の対象かどうかのフラグを設定する if(Http.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.ToUpper().IndexOf("gzip") != -1) { isText = false; } } } } sideState[CS.SERVER] = HTTP_SIDE_STATE.SERVER_SIDE_RECV_HEADER;//ヘッダ受信完了 CheckCharset(oneObj.Header[CS.SERVER].GetBytes());//キャラクタセットのチェック lastRecvServer = DateTime.Now.Ticks; } //データ本体の受信 if(oneHttpKind == ONE_HTTP_KIND.CHUNK) {//チャンク形式の場合 //チャンク形式の受信 if(!RecvServerChunk(ref life)) return false; } else {//Content-Length形式の受信 if(!RecvServerContentLength()) return false; } //受信完了の確認 if(oneHttpKind == ONE_HTTP_KIND.CONTENT_LENGTH) { if(contentLength <= oneObj.Buf[CS.SERVER].Length) { sideState[CS.SERVER] = HTTP_SIDE_STATE.SERVER_SIDE_RECV_BODY;//受信完了 } else { //データが未到着の場合は、しばらく他のスレッドを優先する //while(life && proxy.Sock(CS.SERVER).Length() == 0) // Thread.Sleep(100); for(int i = 0;i < 100 && life;i++) Thread.Sleep(10); } } if(proxy.Sock(CS.SERVER).State == SOCKET_OBJ_STATE.DISCONNECT && proxy.Sock(CS.SERVER).Length() == 0) { //サーバ側が切断されており、取得できるデータが残っていないときは、常に受信完了とする sideState[CS.SERVER] = HTTP_SIDE_STATE.SERVER_SIDE_RECV_BODY;//受信完了 } return true; }
public bool RecvServer(ref bool life) { //int timeout=3; //レスポンス・ヘッダの受信 if (sideState[CS.SERVER] == HTTP_SIDE_STATE.SERVER_SIDE_SEND_BODY) { int c = proxy.OptionTimeout; //本当は、OptionTimeout*10 だけど、最初のレスポンスがあまりに遅いとプログラムがロックするので10分の1に設定する while (life && proxy.Sock(CS.SERVER).State == SOCKET_OBJ_STATE.CONNECT && proxy.Sock(CS.CLIENT).State == SOCKET_OBJ_STATE.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, ref life)) { proxy.Logger.Set(LOG_KIND.ERROR, proxy.Sock(CS.SERVER), 6, ""); return(false); } //ヘッダの受信 if (!oneObj.Header[CS.SERVER].Recv(proxy.Sock(CS.SERVER), proxy.OptionTimeout, ref life)) { proxy.Logger.Set(LOG_KIND.ERROR, proxy.Sock(CS.SERVER), 7, ""); return(false); } //データ転送形式の判別 if (oneObj.Request.Method == HTTP_METHOD.HEAD) { oneHttpKind = ONE_HTTP_KIND.CONTENT_LENGTH; contentLength = 0; } if (oneHttpKind == ONE_HTTP_KIND.UNKNOWN) { string strTransferEncoding = oneObj.Header[CS.SERVER].GetVal("Transfer-Encoding"); if (strTransferEncoding != null) { if (strTransferEncoding == "chunked") { oneHttpKind = ONE_HTTP_KIND.CHUNK; } } } if (oneHttpKind == ONE_HTTP_KIND.UNKNOWN) { string strContentLength = oneObj.Header[CS.SERVER].GetVal("Content-Length"); if (strContentLength != null) { oneHttpKind = ONE_HTTP_KIND.CONTENT_LENGTH; contentLength = Convert.ToInt32(strContentLength); } else { if (response.Code != 200) { oneHttpKind = ONE_HTTP_KIND.CONTENT_LENGTH; contentLength = 0; } } } //コンテンツ制限の対象かどうかのフラグを設定する if (Http.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.ToUpper().IndexOf("gzip") != -1) { isText = false; } } } } sideState[CS.SERVER] = HTTP_SIDE_STATE.SERVER_SIDE_RECV_HEADER; //ヘッダ受信完了 CheckCharset(oneObj.Header[CS.SERVER].GetBytes()); //キャラクタセットのチェック lastRecvServer = DateTime.Now.Ticks; } //データ本体の受信 if (oneHttpKind == ONE_HTTP_KIND.CHUNK) //チャンク形式の場合 //チャンク形式の受信 { if (!RecvServerChunk(ref life)) { return(false); } } else //Content-Length形式の受信 { if (!RecvServerContentLength()) { return(false); } } //受信完了の確認 if (oneHttpKind == ONE_HTTP_KIND.CONTENT_LENGTH) { if (contentLength <= oneObj.Buf[CS.SERVER].Length) { sideState[CS.SERVER] = HTTP_SIDE_STATE.SERVER_SIDE_RECV_BODY;//受信完了 } else { //データが未到着の場合は、しばらく他のスレッドを優先する //while(life && proxy.Sock(CS.SERVER).Length() == 0) // Thread.Sleep(100); for (int i = 0; i < 100 && life; i++) { Thread.Sleep(10); } } } if (proxy.Sock(CS.SERVER).State == SOCKET_OBJ_STATE.DISCONNECT && proxy.Sock(CS.SERVER).Length() == 0) { //サーバ側が切断されており、取得できるデータが残っていないときは、常に受信完了とする sideState[CS.SERVER] = HTTP_SIDE_STATE.SERVER_SIDE_RECV_BODY;//受信完了 } return(true); }