XmlRpc::XmlRpcClient Class Reference

#include <XmlRpcClient.h>

Inheritance diagram for XmlRpc::XmlRpcClient:

XmlRpc::XmlRpcSource List of all members.

Detailed Description

A class to send XML RPC requests to a server and return the results.


Public Member Functions

 XmlRpcClient (const char *host, int port, const char *uri=0)
 Construct a client to connect to the server at the specified host:port address.
 XmlRpcClient (const char *host, int port, const char *uri=0, bool ssl=false)
 XmlRpcClient (const char *host, int port, const char *login, const char *password, const char *uri=0)
 Construct a client to connect to the server at the specified host:port address including HTTP authentication.
 XmlRpcClient (const char *host, int port, const char *login, const char *password, const char *uri=0, bool ssl=false)
virtual ~XmlRpcClient ()
 Destructor.
bool execute (const char *method, XmlRpcValue const &params, XmlRpcValue &result)
 Execute the named procedure on the remote server.
bool isFault () const
 Returns true if the result of the last execute() was a fault response.
const char *const host () const
 Return the host name of the server.
int port () const
 Return the port.
const char *const uri () const
 Return the URI.
virtual void close ()
 Close the connection.
virtual unsigned handleEvent (unsigned eventType)
 Handle server responses.

Static Public Attributes

static const char REQUEST_BEGIN []
static const char REQUEST_END_METHODNAME []
static const char PARAMS_TAG []
static const char PARAMS_ETAG []
static const char PARAM_TAG []
static const char PARAM_ETAG []
static const char REQUEST_END []
static const char METHODRESPONSE_TAG []
static const char FAULT_TAG []

Protected Types

enum  ClientConnectionState {
  NO_CONNECTION, CONNECTING, WRITE_REQUEST, READ_HEADER,
  READ_RESPONSE, IDLE
}

Protected Member Functions

virtual bool doConnect ()
virtual bool setupConnection ()
virtual bool generateRequest (const char *method, XmlRpcValue const &params)
virtual std::string generateHeader (std::string const &body)
virtual bool writeRequest ()
virtual bool readHeader ()
virtual bool readResponse ()
virtual bool parseResponse (XmlRpcValue &result)

Protected Attributes

ClientConnectionState _connectionState
std::string _host
std::string _uri
int _port
std::string _login
std::string _password
std::string _request
std::string _header
std::string _response
int _sendAttempts
int _bytesWritten
bool _executing
bool _eof
bool _isFault
int _contentLength
XmlRpcDispatch _disp


Member Enumeration Documentation

enum XmlRpc::XmlRpcClient::ClientConnectionState [protected]

Enumerator:
NO_CONNECTION 
CONNECTING 
WRITE_REQUEST 
READ_HEADER 
READ_RESPONSE 
IDLE 


Constructor & Destructor Documentation

XmlRpcClient::XmlRpcClient ( const char *  host,
int  port,
const char *  uri = 0 
)

Construct a client to connect to the server at the specified host:port address.

Parameters:
host The name of the remote machine hosting the server, eg "myserver.mycompany.com"
port The port on the remote machine where the server is listening
uri An optional string to be sent as the URI in the HTTP GET header Note that the host is not a URL, do not prepend "http://" or other protocol specifiers.
00032 {
00033   XmlRpcUtil::log(1, "XmlRpcClient new client: host %s, port %d.", host, port);
00034 
00035   _host = host;
00036   _port = port;
00037   if (uri && *uri)
00038     _uri = uri;
00039   else
00040     _uri = "/RPC2";
00041   _connectionState = NO_CONNECTION;
00042   _executing = false;
00043   _eof = false;
00044   _ssl = false; _ssl_ssl = (SSL *) NULL;
00045 
00046   // Default to keeping the connection open until an explicit close is done
00047   setKeepOpen();
00048 }

XmlRpcClient::XmlRpcClient ( const char *  host,
int  port,
const char *  uri = 0,
bool  ssl = false 
)

00050 {
00051   XmlRpcUtil::log(1, "XmlRpcClient new client: host %s, port %d.", host, port);
00052 
00053   _host = host;
00054   _port = port;
00055   if (uri && *uri)
00056     _uri = uri;
00057   else
00058     _uri = "/RPC2";
00059   _connectionState = NO_CONNECTION;
00060   _executing = false;
00061   _eof = false;
00062   _ssl = ssl;
00063   if (!_ssl) { _ssl_ssl = (SSL *) NULL; }
00064 
00065   // Default to keeping the connection open until an explicit close is done
00066   setKeepOpen();
00067 }

XmlRpcClient::XmlRpcClient ( const char *  host,
int  port,
const char *  login,
const char *  password,
const char *  uri = 0 
)

Construct a client to connect to the server at the specified host:port address including HTTP authentication.

Parameters:
host The name of the remote machine hosting the server
port The port on the remote machine where the server is listening
login The username passed to the server
pass The password passed to the server
uri An optional string to be sent as the URI in the HTTP GET header
00072 {
00073   XmlRpcUtil::log(1, "XmlRpcClient new client: host %s, port %d, login %s.", host, port, login);
00074 
00075   _host = host;
00076   _port = port;
00077   if (uri)
00078     _uri = uri;
00079   else
00080     _uri = "/RPC2";
00081 
00082   _login = login;
00083   _password = password;
00084 
00085   _connectionState = NO_CONNECTION;
00086   _executing = false;
00087   _eof = false;
00088 
00089   // Default to keeping the connection open until an explicit close is done
00090   setKeepOpen();
00091 }

XmlRpcClient::XmlRpcClient ( const char *  host,
int  port,
const char *  login,
const char *  password,
const char *  uri = 0,
bool  ssl = false 
)

00096 {
00097   XmlRpcUtil::log(1, "XmlRpcClient new client: host %s, port %d, login %s.", host, port, login);
00098 
00099   _host = host;
00100   _port = port;
00101   if (uri)
00102     _uri = uri;
00103   else
00104     _uri = "/RPC2";
00105 
00106   _login = login;
00107   _password = password;
00108 
00109   _connectionState = NO_CONNECTION;
00110   _executing = false;
00111   _eof = false;
00112   _ssl = ssl;
00113   if (!_ssl) { _ssl_ssl = (SSL *) NULL; }
00114 
00115   // Default to keeping the connection open until an explicit close is done
00116   setKeepOpen();
00117 }

XmlRpcClient::~XmlRpcClient (  )  [virtual]

Destructor.

00121 {
00122   XmlRpcUtil::log(1, "XmlRpcClient dtor client: host %s, port %d.", _host.c_str(), _port);
00123   if (_connectionState != NO_CONNECTION) close();
00124 }


Member Function Documentation

bool XmlRpcClient::execute ( const char *  method,
XmlRpcValue const &  params,
XmlRpcValue result 
)

Execute the named procedure on the remote server.

Parameters:
method The name of the remote procedure to execute
params An array of the arguments for the method
result The result value to be returned to the client
Returns:
true if the request was sent and a result received (although the result might be a fault).
Currently this is a synchronous (blocking) implementation (execute does not return until it receives a response or an error). Use isFault() to determine whether the result is a fault response.
00166 {
00167   XmlRpcUtil::log(1, "XmlRpcClient::execute: method %s (_connectionState %d).", method, _connectionState);
00168 
00169   // This is not a thread-safe operation, if you want to do multithreading, use separate
00170   // clients for each thread. If you want to protect yourself from multiple threads
00171   // accessing the same client, replace this code with a real mutex.
00172   if (_executing)
00173     return false;
00174 
00175   _executing = true;
00176   ClearFlagOnExit cf(_executing);
00177 
00178   _sendAttempts = 0;
00179   _isFault = false;
00180 
00181   if ( ! setupConnection())
00182     return false;
00183 
00184   if ( ! generateRequest(method, params))
00185     return false;
00186 
00187   result.clear();
00188   double msTime = -1.0;   // Process until exit is called
00189   _disp.work(msTime);
00190 
00191   if (_connectionState != IDLE || ! parseResponse(result))
00192     return false;
00193 
00194   XmlRpcUtil::log(1, "XmlRpcClient::execute: method %s completed.", method);
00195   _response = "";
00196   return true;
00197 }

bool XmlRpc::XmlRpcClient::isFault (  )  const [inline]

Returns true if the result of the last execute() was a fault response.

00072 { return _isFault; }

const char* const XmlRpc::XmlRpcClient::host (  )  const [inline]

Return the host name of the server.

00075 { return _host.c_str(); }

int XmlRpc::XmlRpcClient::port (  )  const [inline]

Return the port.

00078 { return _port; }

const char* const XmlRpc::XmlRpcClient::uri (  )  const [inline]

Return the URI.

00081 { return _uri.c_str(); }

void XmlRpcClient::close (  )  [virtual]

Close the connection.

Reimplemented from XmlRpc::XmlRpcSource.

00130 {
00131   XmlRpcUtil::log(4, "XmlRpcClient::close: fd %d.", getfd());
00132   _connectionState = NO_CONNECTION;
00133   _disp.exit();
00134   _disp.removeSource(this);
00135   if (_ssl) {
00136     // Pre-socket shutdown
00137     XmlRpcUtil::log(4, "XmlRpcClient::close: before SSL_shutdown");
00138     SSL_shutdown(_ssl_ssl);
00139     XmlRpcUtil::log(4, "XmlRpcClient::close: after SSL_shutdown");
00140   }
00141   XmlRpcSource::close();
00142   if (_ssl) {
00143     // Post-socket shutdown
00144     XmlRpcUtil::log(4, "XmlRpcClient::close: before SSL_free(_ssl_ssl)");
00145     SSL_free(_ssl_ssl);
00146     XmlRpcUtil::log(4, "XmlRpcClient::close: before SSL_CTX_free(_ssl_ctx)");
00147     SSL_CTX_free(_ssl_ctx);
00148     XmlRpcUtil::log(4, "XmlRpcClient::close: SSL shutdown successful!");
00149   }
00150 }

unsigned XmlRpcClient::handleEvent ( unsigned  eventType  )  [virtual]

Handle server responses.

Called by the event dispatcher during execute.

Parameters:
eventType The type of event that occurred.
See also:
XmlRpcDispatch::EventType

Implements XmlRpc::XmlRpcSource.

00203 {
00204   if (eventType == XmlRpcDispatch::Exception)
00205   {
00206     //if (XmlRpcSocket::nonFatalError())
00207     //  return (_connectionState == WRITE_REQUEST) 
00208     //        ? XmlRpcDispatch::WritableEvent : XmlRpcDispatch::ReadableEvent;
00209 
00210     if (_connectionState == WRITE_REQUEST && _bytesWritten == 0)
00211       XmlRpcUtil::error("Error in XmlRpcClient::handleEvent: could not connect to server (%s).", 
00212                        XmlRpcSocket::getErrorMsg().c_str());
00213     else
00214       XmlRpcUtil::error("Error in XmlRpcClient::handleEvent (state %d): %s.", 
00215                         _connectionState, XmlRpcSocket::getErrorMsg().c_str());
00216     return 0;
00217   }
00218 
00219   if (_connectionState == WRITE_REQUEST)
00220     if ( ! writeRequest()) return 0;
00221 
00222   if (_connectionState == READ_HEADER)
00223     if ( ! readHeader()) return 0;
00224 
00225   if (_connectionState == READ_RESPONSE)
00226     if ( ! readResponse()) return 0;
00227 
00228   // This should probably always ask for Exception events too
00229   return (_connectionState == WRITE_REQUEST) 
00230         ? XmlRpcDispatch::WritableEvent : XmlRpcDispatch::ReadableEvent;
00231 }

bool XmlRpcClient::doConnect (  )  [protected, virtual]

00262 {
00263   int fd = XmlRpcSocket::socket();
00264   if (fd < 0)
00265   {
00266     XmlRpcUtil::error("Error in XmlRpcClient::doConnect: Could not create socket (%s).", XmlRpcSocket::getErrorMsg().c_str());
00267     return false;
00268   }
00269 
00270   XmlRpcUtil::log(3, "XmlRpcClient::doConnect: fd %d.", fd);
00271   this->setfd(fd);
00272 
00273   // Don't block on connect/reads/writes
00274   if ( ! XmlRpcSocket::setNonBlocking(fd))
00275   {
00276     this->close();
00277     XmlRpcUtil::error("Error in XmlRpcClient::doConnect: Could not set socket to non-blocking IO mode (%s).", XmlRpcSocket::getErrorMsg().c_str());
00278     return false;
00279   }
00280 
00281   if ( ! XmlRpcSocket::connect(fd, _host, _port))
00282   {
00283     this->close();
00284     XmlRpcUtil::error("Error in XmlRpcClient::doConnect: Could not connect to server (%s).", XmlRpcSocket::getErrorMsg().c_str());
00285     return false;
00286   }
00287 
00288 #ifdef USE_SSL
00289   // Perform SSL if needed
00290   if (_ssl) {
00291     SSLeay_add_ssl_algorithms();
00292     _ssl_meth = SSLv23_client_method();
00293     SSL_load_error_strings();
00294     _ssl_ctx = SSL_CTX_new (_ssl_meth);
00295     _ssl_ssl = SSL_new (_ssl_ctx);
00296     SSL_set_fd (_ssl_ssl, fd);
00297     int err = SSL_connect (_ssl_ssl);
00298   }
00299 #endif  
00300   
00301 
00302   return true;
00303 }

bool XmlRpcClient::setupConnection (  )  [protected, virtual]

00237 {
00238   // If an error occurred last time through, or if the server closed the connection, close our end
00239   if ((_connectionState != NO_CONNECTION && _connectionState != IDLE) || _eof)
00240     close();
00241 
00242   _eof = false;
00243   if (_connectionState == NO_CONNECTION)
00244     if (! doConnect()) 
00245       return false;
00246 
00247   // Prepare to write the request
00248   _connectionState = WRITE_REQUEST;
00249   _bytesWritten = 0;
00250 
00251   // Notify the dispatcher to listen on this source (calls handleEvent when the socket is writable)
00252   _disp.removeSource(this);       // Make sure nothing is left over
00253   _disp.addSource(this, XmlRpcDispatch::WritableEvent | XmlRpcDispatch::Exception);
00254 
00255   return true;
00256 }

bool XmlRpcClient::generateRequest ( const char *  method,
XmlRpcValue const &  params 
) [protected, virtual]

00308 {
00309   std::string body = REQUEST_BEGIN;
00310   body += methodName;
00311   body += REQUEST_END_METHODNAME;
00312 
00313   // If params is an array, each element is a separate parameter
00314   if (params.valid()) {
00315     body += PARAMS_TAG;
00316     if (params.getType() == XmlRpcValue::TypeArray)
00317     {
00318       for (int i=0; i<params.size(); ++i) {
00319         body += PARAM_TAG;
00320         body += params[i].toXml();
00321         body += PARAM_ETAG;
00322       }
00323     }
00324     else
00325     {
00326       body += PARAM_TAG;
00327       body += params.toXml();
00328       body += PARAM_ETAG;
00329     }
00330       
00331     body += PARAMS_ETAG;
00332   }
00333   body += REQUEST_END;
00334 
00335   std::string header = generateHeader(body);
00336   XmlRpcUtil::log(4, "XmlRpcClient::generateRequest: header is %d bytes, content-length is %d.", 
00337                   header.length(), body.length());
00338 
00339   _request = header + body;
00340   return true;
00341 }

std::string XmlRpcClient::generateHeader ( std::string const &  body  )  [protected, virtual]

00346 {
00347   std::string header = 
00348     "POST " + _uri + " HTTP/1.1\r\n"
00349     "User-Agent: ";
00350   header += XMLRPC_VERSION;
00351   header += "\r\nHost: ";
00352   header += _host;
00353 
00354   char buff[40];
00355   sprintf(buff,":%d\r\n", _port);
00356 
00357   header += buff;
00358 
00359   if (_login.length() != 0)
00360   {
00361     // convert to base64
00362     std::vector<char> base64data;
00363     int iostatus = 0;
00364     base64<char> encoder;
00365     std::back_insert_iterator<std::vector<char> > ins =
00366       std::back_inserter(base64data);
00367 
00368     std::string authBuf = _login + ":" + _password;
00369 
00370     encoder.put(authBuf.begin(), authBuf.end(), ins, iostatus,
00371                 base64<>::crlf());
00372 
00373     header += "Authorization: Basic ";
00374     std::string authEnc(base64data.begin(), base64data.end());
00375     // handle pesky linefeed characters
00376     string::size_type lf;
00377     while ( (lf = authEnc.find("\r")) != string::npos ) {
00378       authEnc.erase(lf, 1);
00379     }
00380     while ( (lf = authEnc.find("\n")) != string::npos ) {
00381       authEnc.erase(lf, 1);
00382     }
00383     header += authEnc;
00384     header += "\r\n";
00385   }
00386 
00387   header += "Content-Type: text/xml\r\nContent-length: ";
00388 
00389   sprintf(buff,"%d\r\n\r\n", body.size());
00390 
00391   return header + buff;
00392 }

bool XmlRpcClient::writeRequest (  )  [protected, virtual]

00396 {
00397   if (_bytesWritten == 0)
00398     XmlRpcUtil::log(5, "XmlRpcClient::writeRequest (attempt %d):\n%s\n", _sendAttempts+1, _request.c_str());
00399 
00400   // Try to write the request
00401   if ( ! XmlRpcSocket::nbWrite(this->getfd(), _request, &_bytesWritten, _ssl_ssl)) {
00402     XmlRpcUtil::error("Error in XmlRpcClient::writeRequest: write error (%s).",XmlRpcSocket::getErrorMsg().c_str());
00403     return false;
00404   }
00405     
00406   XmlRpcUtil::log(3, "XmlRpcClient::writeRequest: wrote %d of %d bytes.", _bytesWritten, _request.length());
00407 
00408   // Wait for the result
00409   if (_bytesWritten == int(_request.length())) {
00410     _header = "";
00411     _response = "";
00412     _connectionState = READ_HEADER;
00413   }
00414   return true;
00415 }

bool XmlRpcClient::readHeader (  )  [protected, virtual]

00421 {
00422   // Read available data
00423   if ( ! XmlRpcSocket::nbRead(this->getfd(), _header, &_eof, _ssl_ssl) ||
00424        (_eof && _header.length() == 0)) {
00425 
00426     // If we haven't read any data yet and this is a keep-alive connection, the server may
00427     // have timed out, so we try one more time.
00428     if (getKeepOpen() && _header.length() == 0 && _sendAttempts++ == 0) {
00429       XmlRpcUtil::log(4, "XmlRpcClient::readHeader: re-trying connection");
00430       XmlRpcSource::close();
00431       _connectionState = NO_CONNECTION;
00432       _eof = false;
00433       return setupConnection();
00434     }
00435 
00436     XmlRpcUtil::error("Error in XmlRpcClient::readHeader: error while reading header (%s) on fd %d.",
00437                       XmlRpcSocket::getErrorMsg().c_str(), getfd());
00438     return false;
00439   }
00440 
00441   XmlRpcUtil::log(4, "XmlRpcClient::readHeader: client has read %d bytes", _header.length());
00442 
00443   char *hp = (char*)_header.c_str();  // Start of header
00444   char *ep = hp + _header.length();   // End of string
00445   char *bp = 0;                       // Start of body
00446   char *lp = 0;                       // Start of content-length value
00447 
00448   for (char *cp = hp; (bp == 0) && (cp < ep); ++cp) {
00449     if ((ep - cp > 16) && (strncasecmp(cp, "Content-length: ", 16) == 0))
00450       lp = cp + 16;
00451     else if ((ep - cp > 4) && (strncmp(cp, "\r\n\r\n", 4) == 0))
00452       bp = cp + 4;
00453     else if ((ep - cp > 2) && (strncmp(cp, "\n\n", 2) == 0))
00454       bp = cp + 2;
00455   }
00456 
00457   // If we haven't gotten the entire header yet, return (keep reading)
00458   if (bp == 0) {
00459     if (_eof)          // EOF in the middle of a response is an error
00460     {
00461       XmlRpcUtil::error("Error in XmlRpcClient::readHeader: EOF while reading header");
00462       return false;   // Close the connection
00463     }
00464     
00465     return true;  // Keep reading
00466   }
00467 
00468   // Decode content length
00469   if (lp == 0) {
00470     XmlRpcUtil::error("Error XmlRpcClient::readHeader: No Content-length specified");
00471     return false;   // We could try to figure it out by parsing as we read, but for now...
00472   }
00473 
00474   _contentLength = atoi(lp);
00475   if (_contentLength <= 0) {
00476     XmlRpcUtil::error("Error in XmlRpcClient::readHeader: Invalid Content-length specified (%d).", _contentLength);
00477     return false;
00478   }
00479         
00480   XmlRpcUtil::log(4, "client read content length: %d", _contentLength);
00481 
00482   // Otherwise copy non-header data to response buffer and set state to read response.
00483   _response = bp;
00484   _header = "";   // should parse out any interesting bits from the header (connection, etc)...
00485   _connectionState = READ_RESPONSE;
00486   return true;    // Continue monitoring this source
00487 }

bool XmlRpcClient::readResponse (  )  [protected, virtual]

00492 {
00493   // If we dont have the entire response yet, read available data
00494   if (int(_response.length()) < _contentLength) {
00495     if ( ! XmlRpcSocket::nbRead(this->getfd(), _response, &_eof, _ssl_ssl)) {
00496       XmlRpcUtil::error("Error in XmlRpcClient::readResponse: read error (%s).",XmlRpcSocket::getErrorMsg().c_str());
00497       return false;
00498     }
00499 
00500     // If we haven't gotten the entire _response yet, return (keep reading)
00501     if (int(_response.length()) < _contentLength) {
00502       if (_eof) {
00503         XmlRpcUtil::error("Error in XmlRpcClient::readResponse: EOF while reading response");
00504         return false;
00505       }
00506       return true;
00507     }
00508   }
00509 
00510   // Otherwise, parse and return the result
00511   XmlRpcUtil::log(3, "XmlRpcClient::readResponse (read %d bytes)", _response.length());
00512   XmlRpcUtil::log(5, "response:\n%s", _response.c_str());
00513 
00514   _connectionState = IDLE;
00515 
00516   return false;    // Stop monitoring this source (causes return from work)
00517 }

bool XmlRpcClient::parseResponse ( XmlRpcValue result  )  [protected, virtual]

00523 {
00524   // Parse response xml into result
00525   int offset = 0;
00526   if ( ! XmlRpcUtil::findTag(METHODRESPONSE_TAG,_response,&offset)) {
00527     XmlRpcUtil::error("Error in XmlRpcClient::parseResponse: Invalid response - no methodResponse. Response:\n%s", _response.c_str());
00528     return false;
00529   }
00530 
00531   // Expect either <params><param>... or <fault>...
00532   if ((XmlRpcUtil::nextTagIs(PARAMS_TAG,_response,&offset) &&
00533        XmlRpcUtil::nextTagIs(PARAM_TAG,_response,&offset)) ||
00534       XmlRpcUtil::nextTagIs(FAULT_TAG,_response,&offset) && (_isFault = true))
00535   {
00536     if ( ! result.fromXml(_response, &offset)) {
00537       XmlRpcUtil::error("Error in XmlRpcClient::parseResponse: Invalid response value. Response:\n%s", _response.c_str());
00538       _response = "";
00539       return false;
00540     }
00541   } else {
00542     XmlRpcUtil::error("Error in XmlRpcClient::parseResponse: Invalid response - no param or fault tag. Response:\n%s", _response.c_str());
00543     _response = "";
00544     return false;
00545   }
00546       
00547   _response = "";
00548   return result.valid();
00549 }


Member Data Documentation

const char XmlRpcClient::REQUEST_BEGIN [static]

const char XmlRpcClient::REQUEST_END_METHODNAME [static]

const char XmlRpcClient::PARAMS_TAG [static]

const char XmlRpcClient::PARAMS_ETAG [static]

const char XmlRpcClient::PARAM_TAG [static]

const char XmlRpcClient::PARAM_ETAG [static]

const char XmlRpcClient::REQUEST_END [static]

const char XmlRpcClient::METHODRESPONSE_TAG [static]

const char XmlRpcClient::FAULT_TAG [static]

ClientConnectionState XmlRpc::XmlRpcClient::_connectionState [protected]

std::string XmlRpc::XmlRpcClient::_host [protected]

std::string XmlRpc::XmlRpcClient::_uri [protected]

int XmlRpc::XmlRpcClient::_port [protected]

std::string XmlRpc::XmlRpcClient::_login [protected]

std::string XmlRpc::XmlRpcClient::_password [protected]

std::string XmlRpc::XmlRpcClient::_request [protected]

std::string XmlRpc::XmlRpcClient::_header [protected]

std::string XmlRpc::XmlRpcClient::_response [protected]

int XmlRpc::XmlRpcClient::_sendAttempts [protected]

int XmlRpc::XmlRpcClient::_bytesWritten [protected]

bool XmlRpc::XmlRpcClient::_executing [protected]

bool XmlRpc::XmlRpcClient::_eof [protected]

bool XmlRpc::XmlRpcClient::_isFault [protected]

int XmlRpc::XmlRpcClient::_contentLength [protected]

XmlRpcDispatch XmlRpc::XmlRpcClient::_disp [protected]


The documentation for this class was generated from the following files:
Generated on Tue Jul 24 16:51:19 2007 for ITM OverSim by  doxygen 1.5.1