00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifdef _MSC_VER
00034 #pragma warning(disable:4786)
00035 #endif
00036 #include "HttpBaseSocket.h"
00037
00038 #ifdef SOCKETS_NAMESPACE
00039 namespace SOCKETS_NAMESPACE {
00040 #endif
00041
00042 #ifdef _DEBUG
00043 #define DEB(x) x
00044 #else
00045 #define DEB(x)
00046 #endif
00047
00048
00049 HttpBaseSocket::HttpBaseSocket(ISocketHandler& h)
00050 :HTTPSocket(h)
00051 ,m_b_keepalive(false)
00052 {
00053 }
00054
00055
00056 HttpBaseSocket::~HttpBaseSocket()
00057 {
00058 }
00059
00060
00061 void HttpBaseSocket::OnFirst()
00062 {
00063 DEB(fprintf(stderr, " %s %s %s\n", GetMethod().c_str(), GetUri().c_str(), GetHttpVersion().c_str());)
00064 m_req.SetHttpMethod( GetMethod() );
00065 m_req.SetUri( GetUri() );
00066 m_req.SetHttpVersion( GetHttpVersion() );
00067
00068 if (Utility::ToLower(GetMethod()) == "get" && !GetQueryString().empty())
00069 {
00070 m_req.SetAttribute("query_string", GetQueryString() );
00071 }
00072
00073 m_req.SetRemoteAddr( GetRemoteAddress() );
00074 m_req.SetRemoteHost( "" );
00075 m_req.SetServerName( GetSockAddress() );
00076 m_req.SetServerPort( GetSockPort() );
00077 }
00078
00079
00080 void HttpBaseSocket::OnHeader(const std::string& key,const std::string& value)
00081 {
00082 DEB(fprintf(stderr, " (request)OnHeader %s: %s\n", key.c_str(), value.c_str());)
00083 if (Utility::ToLower(key) == "cookie")
00084 m_req.AddCookie(value);
00085 else
00086 m_req.SetHeader(key, value);
00087 }
00088
00089
00090 void HttpBaseSocket::OnHeaderComplete()
00091 {
00092 m_body_size_left = atol( m_req.Header("content-length").c_str() );
00093 if (m_body_size_left > 0)
00094 {
00095 m_req.InitBody( m_body_size_left );
00096 }
00097 else
00098 {
00099
00100 Execute();
00101 }
00102 }
00103
00104
00105 void HttpBaseSocket::OnData(const char *buf,size_t sz)
00106 {
00107 m_req.Write( buf, sz );
00108 m_body_size_left -= sz;
00109 if (!m_body_size_left)
00110 {
00111 m_req.CloseBody();
00112
00113
00114 Execute();
00115 }
00116 }
00117
00118
00119
00120 void HttpBaseSocket::Execute()
00121 {
00122
00123 m_req.ParseBody();
00124
00125 DEB(printf(" *** http version: %s\n", m_req.HttpVersion().c_str());
00126 printf(" *** connection: %s\n", m_req.Header("connection").c_str());)
00127 if ( !(m_req.HttpVersion().size() > 4 && m_req.HttpVersion().substr(m_req.HttpVersion().size() - 4) == "/1.1") ||
00128 m_req.Header("connection") == "close")
00129 {
00130 m_b_keepalive = false;
00131 DEB(printf(" *** keepalive: false\n");)
00132 }
00133 else
00134 {
00135 m_b_keepalive = true;
00136 DEB(printf(" *** keepalive: true\n");)
00137 }
00138
00139
00140 IHttpServer_OnExec( m_req );
00141
00142 m_req.Reset();
00143 Reset();
00144 }
00145
00146
00147
00148 void HttpBaseSocket::IHttpServer_Respond(const HttpResponse& res)
00149 {
00150 m_res = res;
00151
00152 SetHttpVersion( m_res.HttpVersion() );
00153 SetStatus( Utility::l2string(m_res.HttpStatusCode()) );
00154 SetStatusText( m_res.HttpStatusMsg() );
00155
00156 if (!ResponseHeaderIsSet("content-length"))
00157 {
00158 AddResponseHeader( "content-length", Utility::l2string( m_res.GetFile().size() ) );
00159 }
00160 for (Utility::ncmap<std::string>::const_iterator it = m_res.Headers().begin(); it != m_res.Headers().end(); ++it)
00161 {
00162 AddResponseHeader( it -> first, it -> second );
00163 }
00164 std::list<std::string> vec = m_res.CookieNames();
00165 for (std::list<std::string>::iterator it2 = vec.begin(); it2 != vec.end(); ++it2)
00166 {
00167 AppendResponseHeader( "set-cookie", m_res.Cookie(*it2) );
00168 }
00169 SendResponse();
00170
00171 OnTransferLimit();
00172 }
00173
00174
00175
00176 void HttpBaseSocket::OnTransferLimit()
00177 {
00178 char msg[32768];
00179 size_t n = m_res.GetFile().fread(msg, 1, 32768);
00180 while (n > 0)
00181 {
00182 SendBuf( msg, n );
00183 if (GetOutputLength() > 1)
00184 {
00185 SetTransferLimit( 1 );
00186 break;
00187 }
00188 n = m_res.GetFile().fread(msg, 1, 32768);
00189 }
00190 if (!GetOutputLength())
00191 {
00192 SetTransferLimit(0);
00193 m_res.GetFile().fclose();
00194 IHttpServer_OnResponseComplete();
00195 if (!m_b_keepalive)
00196 {
00197 SetCloseAndDelete();
00198 }
00199 }
00200 }
00201
00202
00203
00204 void HttpBaseSocket::Reset()
00205 {
00206 HTTPSocket::Reset();
00207 m_body_size_left = 0;
00208 }
00209
00210
00211 #ifdef SOCKETS_NAMESPACE
00212 }
00213 #endif
00214
00215