Panda3D
|
00001 #include "http_connection.h" 00002 00003 TypeHandle HttpConnection::_type_handle; 00004 00005 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 00006 HttpConnection::HttpConnection(SOCKET sck,Socket_Address &inaddr) : 00007 _Timer(Time_Span(10,0)) , 00008 _MyAddress(inaddr), 00009 _state(READING_HEADER) 00010 { 00011 SetSocket(sck); 00012 SetNonBlocking(); 00013 SetReuseAddress(); 00014 00015 _writer.reserve(102400); 00016 } 00017 00018 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 00019 HttpConnection::~HttpConnection(void) 00020 { 00021 } 00022 00023 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 00024 const Socket_Address & HttpConnection::GetMyAddress(void) 00025 { 00026 return _MyAddress; 00027 }; 00028 00029 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 00030 int HttpConnection::DoReadHeader(char * message, int buffersize,Time_Clock ¤tTime) 00031 { 00032 int ans = _Reader.PumpHTTPHeaderRead(message,buffersize,*this); 00033 00034 if(ans != 0) 00035 { 00036 if(ans > 0) 00037 _headerDetail.assign(message,buffersize); 00038 00039 return ans; 00040 } 00041 00042 if(_Timer.Expired(currentTime) == true) 00043 { 00044 return -1; 00045 } 00046 00047 return 0; 00048 } 00049 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 00050 int HttpConnection::DoReadBody(char * message1, int buffersize,Time_Clock ¤tTime) 00051 { 00052 int ans = _Reader.PumpSizeRead(_bodyDetail,*this); 00053 00054 if(ans != 0) 00055 { 00056 00057 return ans; 00058 } 00059 00060 if(_Timer.Expired(currentTime) == true) 00061 { 00062 return -1; 00063 } 00064 00065 // ok lets process this thing.. 00066 _state = WAITING_TO_FINALIZE; 00067 00068 return 0; 00069 } 00070 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 00071 int HttpConnection::ReadIt(char * message, int buffersize,Time_Clock ¤tTime) 00072 { 00073 switch (_state) 00074 { 00075 case(READING_HEADER): 00076 return DoReadHeader(message, buffersize,currentTime); 00077 break; 00078 00079 case(READING_POST): 00080 return DoReadBody(message, buffersize,currentTime); 00081 break; 00082 00083 case(WAITING_TO_FINALIZE): 00084 return TryAndFinalize(); 00085 break; 00086 00087 case(WRITING_DATA): 00088 return CloseStateWriter(currentTime); 00089 break; 00090 default: 00091 break; 00092 00093 }; 00094 return ConnectionDoClose; 00095 } 00096 00097 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 00098 CloseState HttpConnection::ProcessMessage(char * message,Time_Clock ¤tTime) 00099 { 00100 if(_state == READING_POST ) 00101 { 00102 _state = WAITING_TO_FINALIZE; 00103 return ConnectionDoClose; 00104 } 00105 00106 00107 if(_parser.ParseThis(message) != true) 00108 { 00109 Reset(); 00110 return ConnectionDoClose; 00111 } 00112 // if it is a post go into read details mode and 00113 // wait to get the post data.. 00114 // we do not support any other methoid today 00115 if(_parser.GetRequestType() == "POST") 00116 { 00117 int context_length = _parser.getContentLength(); 00118 if(context_length > 0) 00119 { 00120 //_DoingExtraRead = true; 00121 _state = READING_POST; 00122 _bodyDetail.SetDataSize(context_length); 00123 return ConnectionDoNotClose; 00124 } 00125 } 00126 00127 _state = WAITING_TO_FINALIZE; 00128 00129 _parser.SetBodyText(_bodyDetail); 00130 _Timer.ResetTime(currentTime); 00131 00132 if(BuildPage(_writer,_parser) != true) 00133 return ConnectionDoClose; 00134 00135 if(_state == WRITING_DATA) 00136 { 00137 if(CloseStateWriter(currentTime) <0) 00138 return ConnectionDoClose; 00139 } 00140 00141 return ConnectionDoNotClose; 00142 } 00143 00144 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 00145 int HttpConnection::CloseStateWriter(Time_Clock ¤tTime) 00146 { 00147 int fans = _writer.Flush(*this); // write error 00148 if(fans < 0) 00149 return -1; 00150 00151 if(_writer.AmountBuffered() <= 0) // all done 00152 return -1; 00153 00154 if(_Timer.Expired(currentTime) == true) // too long 00155 return -1; 00156 00157 return 0; // keep trying 00158 } 00159 00160 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 00161 void HttpConnection::Reset() 00162 { 00163 _state = ABORTING; 00164 Close(); 00165 _Timer.ForceToExpired(); 00166 } 00167 00168