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