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
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
00113
00114
00115 if(_parser.GetRequestType() == "POST")
00116 {
00117 int context_length = _parser.getContentLength();
00118 if(context_length > 0)
00119 {
00120
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);
00148 if(fans < 0)
00149 return -1;
00150
00151 if(_writer.AmountBuffered() <= 0)
00152 return -1;
00153
00154 if(_Timer.Expired(currentTime) == true)
00155 return -1;
00156
00157 return 0;
00158 }
00159
00160
00161 void HttpConnection::Reset()
00162 {
00163 _state = ABORTING;
00164 Close();
00165 _Timer.ForceToExpired();
00166 }
00167
00168