00001
00005
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 #ifdef _WIN32
00031 #pragma warning(disable:4786)
00032 #endif
00033 #include "HTTPSocket.h"
00034 #include <stdarg.h>
00035 #include "Parse.h"
00036 #include "ISocketHandler.h"
00037
00038 #ifdef SOCKETS_NAMESPACE
00039 namespace SOCKETS_NAMESPACE {
00040 #endif
00041
00042
00043
00044
00045 HTTPSocket::HTTPSocket(ISocketHandler& h)
00046 :TcpSocket(h)
00047 ,m_first(true)
00048 ,m_header(true)
00049 ,m_http_version("HTTP/1.0")
00050 ,m_request(false)
00051 ,m_response(false)
00052 {
00053 SetLineProtocol();
00054 DisableInputBuffer();
00055 }
00056
00057
00058 HTTPSocket::~HTTPSocket()
00059 {
00060 }
00061
00062
00063 void HTTPSocket::OnRawData(const char *buf,size_t len)
00064 {
00065 if (!m_header)
00066 {
00067 OnData(buf, len);
00068 }
00069 }
00070
00071
00072 void HTTPSocket::OnLine(const std::string& line)
00073 {
00074 if (m_first)
00075 {
00076 Parse pa(line);
00077 std::string str = pa.getword();
00078 if (str.substr(0,4) == "HTTP")
00079 {
00080 m_http_version = str;
00081 m_status = pa.getword();
00082 m_status_text = pa.getrest();
00083 m_response = true;
00084 }
00085 else
00086 {
00087 m_method = str;
00088 m_url = pa.getword();
00089 size_t spl = m_url.find("?");
00090 if (spl != std::string::npos)
00091 {
00092 m_uri = m_url.substr(0,spl);
00093 m_query_string = m_url.substr(spl + 1);
00094 }
00095 else
00096 {
00097 m_uri = m_url;
00098 }
00099 m_http_version = pa.getword();
00100 m_request = true;
00101 }
00102 m_first = false;
00103 OnFirst();
00104 return;
00105 }
00106 if (!line.size())
00107 {
00108 SetLineProtocol(false);
00109 m_header = false;
00110 OnHeaderComplete();
00111 return;
00112 }
00113 Parse pa(line,":");
00114 std::string key = pa.getword();
00115 std::string value = pa.getrest();
00116 OnHeader(key,value);
00117
00118
00119
00120 #ifdef ENABLE_POOL
00121 if (!strcasecmp(key.c_str(), "connection") &&
00122 !strcasecmp(value.c_str(), "keep-alive") )
00123 {
00124 SetRetain();
00125 }
00126 #endif
00127 }
00128
00129
00130 void HTTPSocket::SendResponse()
00131 {
00132 std::string msg;
00133 msg = m_http_version + " " + m_status + " " + m_status_text + "\r\n";
00134 for (string_m::iterator it = m_response_header.begin(); it != m_response_header.end(); it++)
00135 {
00136 std::string key = (*it).first;
00137 std::string val = (*it).second;
00138 msg += key + ": " + val + "\r\n";
00139 }
00140 msg += "\r\n";
00141 Send( msg );
00142 }
00143
00144
00145 void HTTPSocket::AddResponseHeader(const std::string& header, const char *format, ...)
00146 {
00147 char slask[5000];
00148 va_list ap;
00149
00150 va_start(ap, format);
00151 #ifdef _WIN32
00152 vsprintf(slask, format, ap);
00153 #else
00154 vsnprintf(slask, 5000, format, ap);
00155 #endif
00156 va_end(ap);
00157
00158 m_response_header[header] = slask;
00159 }
00160
00161
00162 void HTTPSocket::SendRequest()
00163 {
00164 std::string msg;
00165 msg = m_method + " " + m_url + " " + m_http_version + "\r\n";
00166 for (string_m::iterator it = m_response_header.begin(); it != m_response_header.end(); it++)
00167 {
00168 std::string key = (*it).first;
00169 std::string val = (*it).second;
00170 msg += key + ": " + val + "\r\n";
00171 }
00172 msg += "\r\n";
00173 Send( msg );
00174 }
00175
00176
00177 std::string HTTPSocket::MyUseragent()
00178 {
00179 std::string version = "C++Sockets/";
00180 #ifdef _VERSION
00181 version += _VERSION;
00182 #endif
00183 return version;
00184 }
00185
00186
00187 void HTTPSocket::Reset()
00188 {
00189 m_first = true;
00190 m_header = true;
00191 m_request = false;
00192 m_response = false;
00193 SetLineProtocol(true);
00194 while (m_response_header.size())
00195 {
00196 string_m::iterator it = m_response_header.begin();
00197 m_response_header.erase(it);
00198 }
00199
00200 }
00201
00202
00203 const std::string& HTTPSocket::GetMethod()
00204 {
00205 return m_method;
00206 }
00207
00208
00209 void HTTPSocket::SetMethod(const std::string& x)
00210 {
00211 m_method = x;
00212 }
00213
00214
00215 const std::string& HTTPSocket::GetUrl()
00216 {
00217 return m_url;
00218 }
00219
00220
00221 void HTTPSocket::SetUrl(const std::string& x)
00222 {
00223 m_url = x;
00224 }
00225
00226
00227 const std::string& HTTPSocket::GetUri()
00228 {
00229 return m_uri;
00230 }
00231
00232
00233 const std::string& HTTPSocket::GetQueryString()
00234 {
00235 return m_query_string;
00236 }
00237
00238
00239 const std::string& HTTPSocket::GetHttpVersion()
00240 {
00241 return m_http_version;
00242 }
00243
00244
00245 const std::string& HTTPSocket::GetStatus()
00246 {
00247 return m_status;
00248 }
00249
00250
00251 const std::string& HTTPSocket::GetStatusText()
00252 {
00253 return m_status_text;
00254 }
00255
00256
00257 bool HTTPSocket::IsRequest()
00258 {
00259 return m_request;
00260 }
00261
00262
00263 bool HTTPSocket::IsResponse()
00264 {
00265 return m_response;
00266 }
00267
00268
00269 void HTTPSocket::SetHttpVersion(const std::string& x)
00270 {
00271 m_http_version = x;
00272 }
00273
00274
00275 void HTTPSocket::SetStatus(const std::string& x)
00276 {
00277 m_status = x;
00278 }
00279
00280
00281 void HTTPSocket::SetStatusText(const std::string& x)
00282 {
00283 m_status_text = x;
00284 }
00285
00286
00287 void HTTPSocket::AddResponseHeader(const std::string& x,const std::string& y)
00288 {
00289 m_response_header[x] = y;
00290 }
00291
00292
00293 void HTTPSocket::SetUri(const std::string& x)
00294 {
00295 m_uri = x;
00296 }
00297
00298
00299 void HTTPSocket::url_this(const std::string& url_in,std::string& protocol,std::string& host,port_t& port,std::string& url,std::string& file)
00300 {
00301 Parse pa(url_in,"/");
00302 protocol = pa.getword();
00303 if (!strcasecmp(protocol.c_str(), "https:"))
00304 {
00305 #ifdef HAVE_OPENSSL
00306 EnableSSL();
00307 #else
00308 Handler().LogError(this, "url_this", -1, "SSL not available", LOG_LEVEL_WARNING);
00309 #endif
00310 port = 443;
00311 }
00312 else
00313 {
00314 port = 80;
00315 }
00316 host = pa.getword();
00317 if (strstr(host.c_str(),":"))
00318 {
00319 Parse pa(host,":");
00320 pa.getword(host);
00321 port = static_cast<port_t>(pa.getvalue());
00322 }
00323 url = "/" + pa.getrest();
00324 {
00325 Parse pa(url,"/");
00326 std::string tmp = pa.getword();
00327 while (tmp.size())
00328 {
00329 file = tmp;
00330 tmp = pa.getword();
00331 }
00332 }
00333 }
00334
00335
00336 #ifdef SOCKETS_NAMESPACE
00337 }
00338 #endif
00339