00001
00002
00003
00004
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
00031
00032
00033
00034
00035
00036
00037 #include "httpclnt.h"
00038
00039 #pragma comment(lib, "wininet")
00040
00041
00042 namespace XMLRPC {
00043
00044
00045 XMLRPCClient::XMLRPCClient(LPCTSTR url, LPCTSTR agent)
00046 : _extensions(false),
00047 _parsed_url(url),
00048 #ifdef USE_WININET
00049 _inet_lib(agent),
00050 _connection(_inet_lib._hinet, _parsed_url)
00051 #else
00052 _connection(agent, _parsed_url)
00053 #endif
00054 {
00055
00056 _addr.resolve(_parsed_url._hostname.c_str(), _parsed_url._port.c_str(), 0);
00057 }
00058
00059
00060 #ifdef USE_WININET
00061
00062
00063 string XMLRPCClient::request_post(const string& in)
00064 {
00065 HTTPRequest request(_connection, _parsed_url.get_path(), "POST");
00066
00067 return request.send(in.c_str(), in.length());
00068 }
00069
00070 string HTTPRequest::send(const void* data, size_t len)
00071 {
00072 if (!HttpSendRequest(_hRequest, NULL, 0, (void*)data, len))
00073 throw LIE();
00074
00075 string ret;
00076
00077
00078 char bufQuery[32];
00079 DWORD dwLengthBufQuery = sizeof(bufQuery);
00080
00081 if (HttpQueryInfo(_hRequest, HTTP_QUERY_CONTENT_LENGTH, bufQuery, &dwLengthBufQuery, NULL)) {
00082
00083 DWORD content_length = (DWORD) atol(bufQuery);
00084
00085 ret.resize(content_length);
00086
00087 DWORD read;
00088
00089 if (!InternetReadFile(_hRequest, &ret.at(0), content_length, &read))
00090 throw LIE();
00091 } else {
00092
00093 TCHAR buffer[BUFFER_LEN];
00094 DWORD read;
00095
00096 for(;;) {
00097 if (!InternetReadFile(_hRequest, buffer, sizeof(buffer), &read))
00098 throw LIE();
00099
00100 if (!read)
00101 break;
00102
00103 ret.append(buffer, read);
00104 }
00105 }
00106
00107 return ret;
00108 }
00109
00110 #else
00111
00112
00113 string XMLRPCClient::request_post(const string& in)
00114 {
00115 return _connection.send_request(_parsed_url, _addr, "POST", in.c_str(), in.length(), !_extensions);
00116 }
00117
00118
00119 HTTPConnection::HTTPConnection(const char* agent, const URL& url)
00120 : _agent(agent),
00121 _url(url),
00122 _pConnect(NULL)
00123 {
00124 }
00125
00126 Socket& HTTPConnection::get_socket(const AddressList& addr)
00127 {
00128 if (!_pConnect)
00129 _pConnect = new INConnect(addr);
00130
00131 return *_pConnect;
00132 }
00133
00134 void HTTPConnection::close()
00135 {
00136 if (_pConnect) {
00137 delete _pConnect;
00138 _pConnect = NULL;
00139 }
00140 }
00141
00142
00143 string HTTPConnection::send_request(const URL& url, const AddressList& addr, const char* verb, const char* data, size_t len, bool close_connection)
00144 {
00145 Socket& socket = get_socket(addr);
00146
00147
00148 ostringstream buffer;
00149
00150 buffer << verb << " " << url._path << " HTTP/1.1\r\n";
00151 buffer << "User-Agent: " << _agent << "\r\n";
00152 buffer << "Host: " << url._hostname << ":" << url._port << "\r\n";
00153 buffer << "Content-length: " << len << "\r\n";
00154 buffer << "Content-type: text/xml\r\n";
00155
00156 buffer << "\r\n";
00157
00158 const string& header = buffer.str();
00159 socket.send(header.c_str(), header.length());
00160
00161
00162 socket.send(data, len);
00163
00164
00165
00166 SocketReader reader(socket);
00167
00168 char line[BUFFER_LEN];
00169
00170 if (reader.read_line(line, BUFFER_LEN) <= 0)
00171 throw Exception("missing HTML server response");
00172
00173 char version[12];
00174 int code;
00175 char msg[BUFFER_LEN];
00176
00177 #ifdef __STDC_WANT_SECURE_LIB__
00178 if (sscanf_s(line, "%s %d %s", version, _countof(version), &code, msg, _countof(msg)) != 3)
00179 #else
00180 if (sscanf(line, "%s %d %s", version, &code, msg) != 3)
00181 #endif
00182 throw Exception("invalid HTML server response");
00183
00184 if (code != 200)
00185 throw Exception(line);
00186
00187
00188
00189 int content_length = 0;
00190 string content_type;
00191
00192 for(;;) {
00193 if (reader.read_line(line, BUFFER_LEN) <= 0)
00194 break;
00195
00196 if (!_strnicmp(line, "Content-length:", 15))
00197 content_length = atoi(line+15);
00198 else if (!_strnicmp(line, "Content-type:", 13))
00199 content_type = line+14;
00200 else if (!_stricmp(line, "Connection: close"))
00201 close_connection = true;
00202 }
00203
00204 if (!content_type.empty() && _strnicmp(content_type.c_str(),"text/xml",8)) {
00205 char b[BUFFER_LEN];
00206 sprintf(b, "illegal content type: %s", content_type.c_str());
00207 throw Exception(b);
00208 }
00209
00210
00211
00212 string ret;
00213
00214 if (content_length) {
00215 ret.resize(content_length);
00216 reader.read(&ret.at(0), content_length);
00217 }
00218
00219 if (close_connection)
00220 close();
00221
00222 return ret;
00223 }
00224
00225 #endif
00226
00227
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254