19 using namespace XmlRpc;
 
   24   "<?xml version=\"1.0\"?>\r\n" 
   25   "<methodCall><methodName>";
 
   39   XmlRpcUtil::log(1, 
"XmlRpcClient new client: host %s, port %d.", host, port);
 
   47   _connectionState = NO_CONNECTION;
 
   50   _ssl = 
false; _ssl_ssl = (
SSL *) NULL;
 
   57   XmlRpcUtil::log(1, 
"XmlRpcClient new client: host %s, port %d.", host, port);
 
   65   _connectionState = NO_CONNECTION;
 
   69   if (!_ssl) { _ssl_ssl = (
SSL *) NULL; }
 
   77                            const char* login, 
const char* password, 
const char* uri)
 
   79   XmlRpcUtil::log(1, 
"XmlRpcClient new client: host %s, port %d, login %s.", host, port, login);
 
   91   _connectionState = NO_CONNECTION;
 
  100                            const char* login, 
const char* password,
 
  101                            const char* uri, 
bool ssl)
 
  103   XmlRpcUtil::log(1, 
"XmlRpcClient new client: host %s, port %d, login %s.", host, port, login);
 
  113   _password = password;
 
  115   _connectionState = NO_CONNECTION;
 
  119   if (!_ssl) { _ssl_ssl = (
SSL *) NULL; }
 
  128   XmlRpcUtil::log(1, 
"XmlRpcClient dtor client: host %s, port %d.", _host.c_str(), _port);
 
  129   if (_connectionState != NO_CONNECTION) close();
 
  138   _connectionState = NO_CONNECTION;
 
  140   _disp.removeSource(
this);
 
  152     XmlRpcUtil::log(4, 
"XmlRpcClient::close: before SSL_CTX_free(_ssl_ctx)");
 
  173   XmlRpcUtil::log(1, 
"XmlRpcClient::execute: method %s (_connectionState %d).", method, _connectionState);
 
  187   if ( ! setupConnection())
 
  190   if ( ! generateRequest(method, params))
 
  194   double msTime = -1.0;   
 
  197   if (_connectionState != IDLE || ! parseResponse(result))
 
  200   XmlRpcUtil::log(1, 
"XmlRpcClient::execute: method %s completed.", method);
 
  216     if (_connectionState == WRITE_REQUEST && _bytesWritten == 0)
 
  217       XmlRpcUtil::error(
"Error in XmlRpcClient::handleEvent: could not connect to server (%s).",
 
  225   if (_connectionState == WRITE_REQUEST)
 
  226     if ( ! writeRequest()) 
return 0;
 
  228   if (_connectionState == READ_HEADER)
 
  229     if ( ! readHeader()) 
return 0;
 
  231   if (_connectionState == READ_RESPONSE)
 
  232     if ( ! readResponse()) 
return 0;
 
  235   return (_connectionState == WRITE_REQUEST)
 
  245   if ((_connectionState != NO_CONNECTION && _connectionState != IDLE) || _eof)
 
  249   if (_connectionState == NO_CONNECTION)
 
  254   _connectionState = WRITE_REQUEST;
 
  258   _disp.removeSource(
this);       
 
  315   std::string body = REQUEST_BEGIN;
 
  317   body += REQUEST_END_METHODNAME;
 
  324       for (
int i=0; i<params.
size(); ++i) {
 
  326         body += params[i].
toXml();
 
  333       body += params.
toXml();
 
  341   std::string header = generateHeader(body);
 
  342   XmlRpcUtil::log(4, 
"XmlRpcClient::generateRequest: header is %d bytes, content-length is %d.",
 
  343                   header.length(), body.length());
 
  345   _request = header + body;
 
  354     "POST " + _uri + 
" HTTP/1.1\r\n" 
  357   header += 
"\r\nHost: ";
 
  361   sprintf(buff,
":%d\r\n", _port);
 
  365   if (_login.length() != 0)
 
  368     std::vector<char> base64data;
 
  371     std::back_insert_iterator<std::vector<char> > ins =
 
  372       std::back_inserter(base64data);
 
  374     std::string authBuf = _login + 
":" + _password;
 
  376     encoder.
put(authBuf.begin(), authBuf.end(), ins, iostatus,
 
  379     header += 
"Authorization: Basic ";
 
  380     std::string authEnc(base64data.begin(), base64data.end());
 
  382     string::size_type lf;
 
  383     while ( (lf = authEnc.find(
"\r")) != string::npos ) {
 
  384       authEnc.erase(lf, 1);
 
  386     while ( (lf = authEnc.find(
"\n")) != string::npos ) {
 
  387       authEnc.erase(lf, 1);
 
  393   header += 
"Content-Type: text/xml\r\nContent-length: ";
 
  395   sprintf(buff,
"%zu\r\n\r\n", body.size());
 
  397   return header + buff;
 
  403   if (_bytesWritten == 0)
 
  404     XmlRpcUtil::log(5, 
"XmlRpcClient::writeRequest (attempt %d):\n%s\n", _sendAttempts+1, _request.c_str());
 
  412   XmlRpcUtil::log(3, 
"XmlRpcClient::writeRequest: wrote %d of %d bytes.", _bytesWritten, _request.length());
 
  415   if (_bytesWritten == 
int(_request.length())) {
 
  418     _connectionState = READ_HEADER;
 
  430        (_eof && _header.length() == 0)) {
 
  434     if (getKeepOpen() && _header.length() == 0 && _sendAttempts++ == 0) {
 
  437       _connectionState = NO_CONNECTION;
 
  439       return setupConnection();
 
  442     XmlRpcUtil::error(
"Error in XmlRpcClient::readHeader: error while reading header (%s) on fd %d.",
 
  447   XmlRpcUtil::log(4, 
"XmlRpcClient::readHeader: client has read %d bytes", _header.length());
 
  449   char *hp = (
char*)_header.c_str();  
 
  450   char *ep = hp + _header.length();   
 
  454   for (
char *cp = hp; (bp == 0) && (cp < ep); ++cp) {
 
  455     if ((ep - cp > 16) && (strncasecmp(cp, 
"Content-length: ", 16) == 0))
 
  457     else if ((ep - cp > 4) && (strncmp(cp, 
"\r\n\r\n", 4) == 0))
 
  459     else if ((ep - cp > 2) && (strncmp(cp, 
"\n\n", 2) == 0))
 
  467       XmlRpcUtil::error(
"Error in XmlRpcClient::readHeader: EOF while reading header");
 
  476     XmlRpcUtil::error(
"Error XmlRpcClient::readHeader: No Content-length specified");
 
  480   _contentLength = atoi(lp);
 
  481   if (_contentLength <= 0) {
 
  482     XmlRpcUtil::error(
"Error in XmlRpcClient::readHeader: Invalid Content-length specified (%d).", _contentLength);
 
  491   _connectionState = READ_RESPONSE;
 
  500   if (
int(_response.length()) < _contentLength) {
 
  507     if (
int(_response.length()) < _contentLength) {
 
  509         XmlRpcUtil::error(
"Error in XmlRpcClient::readResponse: EOF while reading response");
 
  517   XmlRpcUtil::log(3, 
"XmlRpcClient::readResponse (read %d bytes)", _response.length());
 
  520   _connectionState = IDLE;
 
  533     XmlRpcUtil::error(
"Error in XmlRpcClient::parseResponse: Invalid response - no methodResponse. Response:\n%s", _response.c_str());
 
  542     if ( ! result.
fromXml(_response, &offset)) {
 
  543       XmlRpcUtil::error(
"Error in XmlRpcClient::parseResponse: Invalid response value. Response:\n%s", _response.c_str());
 
  548     XmlRpcUtil::error(
"Error in XmlRpcClient::parseResponse: Invalid response - no param or fault tag. Response:\n%s", _response.c_str());