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 "HttpClientSocket.h"
00037 #include "StdLog.h"
00038 #include "ISocketHandler.h"
00039 #include "File.h"
00040
00041
00042 #ifdef SOCKETS_NAMESPACE
00043 namespace SOCKETS_NAMESPACE {
00044 #endif
00045
00046
00047 HttpClientSocket::HttpClientSocket(ISocketHandler& h)
00048 :HTTPSocket(h)
00049 ,m_data_ptr(NULL)
00050 ,m_data_size(0)
00051 ,m_content_length(0)
00052 ,m_content_length_is_set(false)
00053 ,m_data_ptr_set(false)
00054 ,m_fil(NULL)
00055 ,m_content_ptr(0)
00056 ,m_b_complete(false)
00057 ,m_b_close_when_complete(false)
00058 {
00059 }
00060
00061
00062 HttpClientSocket::HttpClientSocket(ISocketHandler& h,const std::string& url_in)
00063 :HTTPSocket(h)
00064 ,m_data_ptr(NULL)
00065 ,m_data_size(0)
00066 ,m_content_length(0)
00067 ,m_content_length_is_set(false)
00068 ,m_data_ptr_set(false)
00069 ,m_fil(NULL)
00070 ,m_content_ptr(0)
00071 ,m_b_complete(false)
00072 ,m_b_close_when_complete(false)
00073 {
00074 std::string url;
00075 url_this(url_in, m_protocol, m_host, m_port, url, m_url_filename);
00076 SetUrl( url );
00077 }
00078
00079
00080 HttpClientSocket::HttpClientSocket(ISocketHandler& h,const std::string& host, port_t port, const std::string& url_in)
00081 :HTTPSocket(h)
00082 ,m_data_ptr(NULL)
00083 ,m_data_size(0)
00084 ,m_content_length(0)
00085 ,m_content_length_is_set(false)
00086 ,m_data_ptr_set(false)
00087 ,m_fil(NULL)
00088 ,m_content_ptr(0)
00089 ,m_b_complete(false)
00090 ,m_b_close_when_complete(false)
00091 {
00092 std::string url;
00093 std::string tmp = "http://" + host + ":" + Utility::l2string(port) + url_in;
00094 url_this(tmp, m_protocol, m_host, m_port, url, m_url_filename);
00095 SetUrl( url );
00096 }
00097
00098
00099 HttpClientSocket::~HttpClientSocket()
00100 {
00101 if (m_data_ptr && !m_data_ptr_set)
00102 {
00103 delete[] m_data_ptr;
00104 }
00105 if (m_fil)
00106 {
00107 m_fil -> fclose();
00108 }
00109 }
00110
00111
00112 void HttpClientSocket::OnFirst()
00113 {
00114 if (!IsResponse())
00115 {
00116 Handler().LogError(this, "OnFirst", 0, "Response expected but not received - aborting", LOG_LEVEL_FATAL);
00117 SetCloseAndDelete();
00118 }
00119 m_content = GetHttpVersion() + " " + GetStatus() + " " + GetStatusText() + "\r\n";
00120 }
00121
00122
00123 void HttpClientSocket::OnHeader(const std::string& key,const std::string& value)
00124 {
00125 m_content += key + ": " + value + "\r\n";
00126 if (!strcasecmp(key.c_str(), "content-length"))
00127 {
00128 m_content_length = atoi(value.c_str());
00129 m_content_length_is_set = true;
00130 }
00131 else
00132 if (!strcasecmp(key.c_str(), "content-type"))
00133 {
00134 m_content_type = value;
00135 }
00136 }
00137
00138
00139 void HttpClientSocket::OnHeaderComplete()
00140 {
00141 if (m_filename.size())
00142 {
00143 m_fil = new File;
00144 if (!m_fil -> fopen(m_filename, "wb"))
00145 {
00146 delete m_fil;
00147 m_fil = NULL;
00148 }
00149 }
00150 if (!m_data_ptr && m_content_length > 0)
00151 {
00152 m_data_ptr = new unsigned char[m_content_length];
00153 m_data_size = m_content_length;
00154 }
00155
00156
00157 if (m_content_length_is_set && m_content_length == 0)
00158 {
00159 EndConnection();
00160 }
00161 }
00162
00163
00164 void HttpClientSocket::EndConnection()
00165 {
00166 if (m_fil)
00167 {
00168 m_fil -> fclose();
00169 delete m_fil;
00170 m_fil = NULL;
00171 }
00172 m_b_complete = true;
00173 OnContent();
00174 if (m_b_close_when_complete)
00175 {
00176 SetCloseAndDelete();
00177 }
00178 }
00179
00180
00181 void HttpClientSocket::OnData(const char *buf,size_t len)
00182 {
00183 if (m_fil)
00184 {
00185 m_fil -> fwrite(buf, 1, len);
00186 }
00187 if (m_data_ptr)
00188 {
00189 size_t left = m_data_size - m_content_ptr;
00190 size_t sz = len < left ? len : left;
00191 if (sz > 0)
00192 memcpy(m_data_ptr + m_content_ptr, buf, sz);
00193 m_content_ptr += sz;
00194 if (len > left)
00195 {
00196 Handler().LogError(this, "OnData", -1, "content buffer overflow", LOG_LEVEL_ERROR);
00197 }
00198 }
00199 if (m_content_ptr == m_content_length && m_content_length)
00200 {
00201 EndConnection();
00202 }
00203 }
00204
00205
00206 void HttpClientSocket::OnDelete()
00207 {
00208 if (!m_b_complete)
00209 {
00210 if (m_fil)
00211 {
00212 m_fil -> fclose();
00213 delete m_fil;
00214 m_fil = NULL;
00215 }
00216 m_b_complete = true;
00217 OnContent();
00218 }
00219 }
00220
00221
00222 void HttpClientSocket::SetFilename(const std::string& x)
00223 {
00224 m_filename = x;
00225 }
00226
00227
00228 void HttpClientSocket::SetDataPtr(unsigned char *buf,size_t len)
00229 {
00230 m_data_ptr = buf;
00231 m_data_size = len;
00232 m_data_ptr_set = true;
00233 }
00234
00235
00236 const std::string& HttpClientSocket::GetContent()
00237 {
00238 return m_content;
00239 }
00240
00241
00242 size_t HttpClientSocket::GetContentLength()
00243 {
00244 return m_content_length;
00245 }
00246
00247
00248 size_t HttpClientSocket::GetContentPtr()
00249 {
00250 return m_content_ptr;
00251 }
00252
00253
00254 size_t HttpClientSocket::GetPos()
00255 {
00256 return m_content_ptr;
00257 }
00258
00259
00260 bool HttpClientSocket::Complete()
00261 {
00262 return m_b_complete;
00263 }
00264
00265
00266 const unsigned char *HttpClientSocket::GetDataPtr() const
00267 {
00268 return m_data_ptr;
00269 }
00270
00271
00272 void HttpClientSocket::OnContent()
00273 {
00274 }
00275
00276
00277 void HttpClientSocket::SetCloseOnComplete(bool x)
00278 {
00279 m_b_close_when_complete = x;
00280 }
00281
00282
00283 const std::string& HttpClientSocket::GetUrlProtocol()
00284 {
00285 return m_protocol;
00286 }
00287
00288
00289 const std::string& HttpClientSocket::GetUrlHost()
00290 {
00291 return m_host;
00292 }
00293
00294
00295 port_t HttpClientSocket::GetUrlPort()
00296 {
00297 return m_port;
00298 }
00299
00300
00301 const std::string& HttpClientSocket::GetUrlFilename()
00302 {
00303 return m_url_filename;
00304 }
00305
00306
00307 const std::string& HttpClientSocket::GetContentType()
00308 {
00309 return m_content_type;
00310 }
00311
00312
00313 void HttpClientSocket::Url(const std::string& url_in,std::string& host,port_t& port)
00314 {
00315 std::string url;
00316 url_this(url_in, m_protocol, m_host, m_port, url, m_url_filename);
00317 SetUrl(url);
00318 host = GetUrlHost();
00319 port = GetUrlPort();
00320 }
00321
00322
00323 #ifdef SOCKETS_NAMESPACE
00324 }
00325 #endif
00326