Beispiel #1
0
        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;
        }
Beispiel #2
0
        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);
        }