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