|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h> |
|
|
#include <cassert> |
|
|
#include <string> |
|
|
#include <vector> |
|
|
|
|
|
#include "xmlrpc-c/girerr.hpp" |
|
|
using girerr::error; |
|
|
using girerr::throwf; |
|
|
#include "xmlrpc-c/girmem.hpp" |
|
|
using girmem::autoObjectPtr; |
|
|
using girmem::autoObject; |
|
|
#include "xmlrpc-c/env_wrap.hpp" |
|
|
#include "xmlrpc-c/util_int.h" |
|
|
#include "xmlrpc-c/base.h" |
|
|
#include "xmlrpc-c/client.h" |
|
|
#include "xmlrpc-c/transport.h" |
|
|
#include "xmlrpc-c/base.hpp" |
|
|
#include "xmlrpc-c/xml.hpp" |
|
|
#include "xmlrpc-c/timeout.hpp" |
|
|
#include "xmlrpc-c/client.hpp" |
|
|
#include "transport_config.h" |
|
|
|
|
|
using namespace std; |
|
|
using namespace xmlrpc_c; |
|
|
|
|
|
|
|
|
namespace { |
|
|
|
|
|
void |
|
|
throwIfError(env_wrap const& env) { |
|
|
|
|
|
if (env.env_c.fault_occurred) |
|
|
throw(error(env.env_c.fault_string)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class memblockStringWrapper { |
|
|
|
|
|
public: |
|
|
memblockStringWrapper(string const value) { |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
this->memblockP = XMLRPC_MEMBLOCK_NEW(char, &env.env_c, 0); |
|
|
throwIfError(env); |
|
|
|
|
|
XMLRPC_MEMBLOCK_APPEND(char, &env.env_c, this->memblockP, |
|
|
value.c_str(), value.size()); |
|
|
throwIfError(env); |
|
|
} |
|
|
|
|
|
memblockStringWrapper(xmlrpc_mem_block * const memblockP) : |
|
|
memblockP(memblockP) {}; |
|
|
|
|
|
~memblockStringWrapper() { |
|
|
XMLRPC_MEMBLOCK_FREE(char, this->memblockP); |
|
|
} |
|
|
|
|
|
xmlrpc_mem_block * memblockP; |
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
namespace xmlrpc_c { |
|
|
|
|
|
struct client_xml_impl { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
clientXmlTransport * transportP; |
|
|
clientXmlTransportPtr transportPtr; |
|
|
xmlrpc_dialect dialect; |
|
|
|
|
|
client_xml_impl(clientXmlTransport * const transportP, |
|
|
xmlrpc_dialect const dialect = xmlrpc_dialect_i8) : |
|
|
transportP(transportP), |
|
|
dialect(dialect) {} |
|
|
|
|
|
client_xml_impl(clientXmlTransportPtr const transportPtr, |
|
|
clientXmlTransport * const transportP, |
|
|
xmlrpc_dialect const dialect = xmlrpc_dialect_i8) : |
|
|
transportP(transportP), |
|
|
transportPtr(transportPtr), |
|
|
dialect(dialect) {} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
carriageParm::carriageParm() {} |
|
|
|
|
|
|
|
|
|
|
|
carriageParm::~carriageParm() {} |
|
|
|
|
|
|
|
|
|
|
|
carriageParmPtr::carriageParmPtr() { |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
carriageParmPtr::carriageParmPtr( |
|
|
carriageParm * const carriageParmP) : autoObjectPtr(carriageParmP) {} |
|
|
|
|
|
|
|
|
|
|
|
carriageParm * |
|
|
carriageParmPtr::operator->() const { |
|
|
|
|
|
autoObject * const p(this->objectP); |
|
|
return dynamic_cast<carriageParm *>(p); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
carriageParm * |
|
|
carriageParmPtr::get() const { |
|
|
return dynamic_cast<carriageParm *>(this->objectP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
carriageParm_http0::carriageParm_http0() : |
|
|
c_serverInfoP(NULL) {} |
|
|
|
|
|
|
|
|
|
|
|
carriageParm_http0::carriageParm_http0(string const serverUrl) { |
|
|
this->c_serverInfoP = NULL; |
|
|
|
|
|
this->instantiate(serverUrl); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
carriageParm_http0::~carriageParm_http0() { |
|
|
|
|
|
if (this->c_serverInfoP) |
|
|
xmlrpc_server_info_free(this->c_serverInfoP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
carriageParm_http0::instantiate(string const serverUrl) { |
|
|
|
|
|
if (c_serverInfoP) |
|
|
throw(error("object already instantiated")); |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
this->c_serverInfoP = |
|
|
xmlrpc_server_info_new(&env.env_c, serverUrl.c_str()); |
|
|
throwIfError(env); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
carriageParm_http0::setUser(string const userid, |
|
|
string const password) { |
|
|
|
|
|
if (!this->c_serverInfoP) |
|
|
throw(error("object not instantiated")); |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
xmlrpc_server_info_set_user( |
|
|
&env.env_c, this->c_serverInfoP, userid.c_str(), password.c_str()); |
|
|
|
|
|
if (env.env_c.fault_occurred) |
|
|
throw(error(env.env_c.fault_string)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
carriageParm_http0::allowAuthBasic() { |
|
|
|
|
|
if (!this->c_serverInfoP) |
|
|
throw(error("object not instantiated")); |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
xmlrpc_server_info_allow_auth_basic(&env.env_c, this->c_serverInfoP); |
|
|
|
|
|
if (env.env_c.fault_occurred) |
|
|
throw(error(env.env_c.fault_string)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
carriageParm_http0::disallowAuthBasic() { |
|
|
|
|
|
if (!this->c_serverInfoP) |
|
|
throw(error("object not instantiated")); |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
xmlrpc_server_info_disallow_auth_basic(&env.env_c, this->c_serverInfoP); |
|
|
|
|
|
if (env.env_c.fault_occurred) |
|
|
throw(error(env.env_c.fault_string)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
carriageParm_http0::allowAuthDigest() { |
|
|
|
|
|
if (!this->c_serverInfoP) |
|
|
throw(error("object not instantiated")); |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
xmlrpc_server_info_allow_auth_digest(&env.env_c, this->c_serverInfoP); |
|
|
|
|
|
if (env.env_c.fault_occurred) |
|
|
throw(error(env.env_c.fault_string)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
carriageParm_http0::disallowAuthDigest() { |
|
|
|
|
|
if (!this->c_serverInfoP) |
|
|
throw(error("object not instantiated")); |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
xmlrpc_server_info_disallow_auth_digest(&env.env_c, this->c_serverInfoP); |
|
|
|
|
|
if (env.env_c.fault_occurred) |
|
|
throw(error(env.env_c.fault_string)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
carriageParm_http0::allowAuthNegotiate() { |
|
|
|
|
|
if (!this->c_serverInfoP) |
|
|
throw(error("object not instantiated")); |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
xmlrpc_server_info_allow_auth_negotiate(&env.env_c, this->c_serverInfoP); |
|
|
|
|
|
if (env.env_c.fault_occurred) |
|
|
throw(error(env.env_c.fault_string)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
carriageParm_http0::disallowAuthNegotiate() { |
|
|
|
|
|
if (!this->c_serverInfoP) |
|
|
throw(error("object not instantiated")); |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
xmlrpc_server_info_disallow_auth_negotiate( |
|
|
&env.env_c, this->c_serverInfoP); |
|
|
|
|
|
if (env.env_c.fault_occurred) |
|
|
throw(error(env.env_c.fault_string)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
carriageParm_http0::allowAuthNtlm() { |
|
|
|
|
|
if (!this->c_serverInfoP) |
|
|
throw(error("object not instantiated")); |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
xmlrpc_server_info_allow_auth_ntlm(&env.env_c, this->c_serverInfoP); |
|
|
|
|
|
if (env.env_c.fault_occurred) |
|
|
throw(error(env.env_c.fault_string)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
carriageParm_http0::disallowAuthNtlm() { |
|
|
|
|
|
if (!this->c_serverInfoP) |
|
|
throw(error("object not instantiated")); |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
xmlrpc_server_info_disallow_auth_ntlm(&env.env_c, this->c_serverInfoP); |
|
|
|
|
|
if (env.env_c.fault_occurred) |
|
|
throw(error(env.env_c.fault_string)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
carriageParm_http0::setBasicAuth(string const username, |
|
|
string const password) { |
|
|
|
|
|
if (!this->c_serverInfoP) |
|
|
throw(error("object not instantiated")); |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
xmlrpc_server_info_set_basic_auth( |
|
|
&env.env_c, this->c_serverInfoP, username.c_str(), password.c_str()); |
|
|
throwIfError(env); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
carriageParm_http0Ptr::carriageParm_http0Ptr() { |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
carriageParm_http0Ptr::carriageParm_http0Ptr( |
|
|
carriageParm_http0 * const carriageParmP) : |
|
|
carriageParmPtr(carriageParmP) {} |
|
|
|
|
|
|
|
|
|
|
|
carriageParm_http0 * |
|
|
carriageParm_http0Ptr::operator->() const { |
|
|
|
|
|
autoObject * const p(this->objectP); |
|
|
return dynamic_cast<carriageParm_http0 *>(p); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
xmlTransaction::xmlTransaction() {} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
xmlTransaction::finish(string const& responseXml) const { |
|
|
|
|
|
xml::trace("XML-RPC RESPONSE", responseXml); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
xmlTransaction::finishErr(error const&) const { |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
xmlTransaction::progress(struct xmlrpc_progress_data const&) const { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
xmlTransactionPtr::xmlTransactionPtr() {} |
|
|
|
|
|
|
|
|
|
|
|
xmlTransactionPtr::xmlTransactionPtr(xmlTransaction * xmlTransP) : |
|
|
autoObjectPtr(xmlTransP) {} |
|
|
|
|
|
|
|
|
|
|
|
xmlTransaction * |
|
|
xmlTransactionPtr::operator->() const { |
|
|
autoObject * const p(this->objectP); |
|
|
return dynamic_cast<xmlTransaction *>(p); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
struct xmlTranCtl { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xmlTranCtl(xmlTransactionPtr const& xmlTranP, |
|
|
string const& callXml) : |
|
|
|
|
|
xmlTranP(xmlTranP) { |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
this->callXmlP = XMLRPC_MEMBLOCK_NEW(char, &env.env_c, 0); |
|
|
throwIfError(env); |
|
|
|
|
|
XMLRPC_MEMBLOCK_APPEND(char, &env.env_c, this->callXmlP, |
|
|
callXml.c_str(), callXml.size()); |
|
|
throwIfError(env); |
|
|
} |
|
|
|
|
|
~xmlTranCtl() { |
|
|
XMLRPC_MEMBLOCK_FREE(char, this->callXmlP); |
|
|
} |
|
|
|
|
|
xmlTransactionPtr const xmlTranP; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xmlrpc_mem_block * callXmlP; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
clientXmlTransport::~clientXmlTransport() {} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
clientXmlTransport::start(carriageParm * const carriageParmP, |
|
|
string const& callXml, |
|
|
xmlTransactionPtr const& xmlTranP) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string responseXml; |
|
|
|
|
|
this->call(carriageParmP, callXml, &responseXml); |
|
|
|
|
|
xmlTranP->finish(responseXml); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
clientXmlTransport::finishAsync(xmlrpc_c::timeout) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
clientXmlTransport::asyncComplete( |
|
|
struct xmlrpc_call_info * const callInfoP, |
|
|
xmlrpc_mem_block * const responseXmlMP, |
|
|
xmlrpc_env const transportEnv) { |
|
|
|
|
|
xmlTranCtl * const xmlTranCtlP = reinterpret_cast<xmlTranCtl *>(callInfoP); |
|
|
|
|
|
try { |
|
|
if (transportEnv.fault_occurred) { |
|
|
xmlTranCtlP->xmlTranP->finishErr(error(transportEnv.fault_string)); |
|
|
} else { |
|
|
string const responseXml( |
|
|
XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlMP), |
|
|
XMLRPC_MEMBLOCK_SIZE(char, responseXmlMP)); |
|
|
xmlTranCtlP->xmlTranP->finish(responseXml); |
|
|
} |
|
|
} catch(exception const&) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(false); |
|
|
} |
|
|
delete(xmlTranCtlP); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
clientXmlTransport::progress( |
|
|
struct xmlrpc_call_info * const callInfoP, |
|
|
struct xmlrpc_progress_data const progressData) { |
|
|
|
|
|
xmlTranCtl * const xmlTranCtlP = reinterpret_cast<xmlTranCtl *>(callInfoP); |
|
|
|
|
|
xmlTranCtlP->xmlTranP->progress(progressData); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
clientXmlTransport::setInterrupt(int *) { |
|
|
|
|
|
throwf("The client XML transport is not interruptible"); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
clientXmlTransportPtr::clientXmlTransportPtr() { |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
clientXmlTransportPtr::clientXmlTransportPtr( |
|
|
clientXmlTransport * const transportP) : autoObjectPtr(transportP) {} |
|
|
|
|
|
|
|
|
|
|
|
clientXmlTransport * |
|
|
clientXmlTransportPtr::get() const { |
|
|
return dynamic_cast<clientXmlTransport *>(objectP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
clientXmlTransport * |
|
|
clientXmlTransportPtr::operator->() const { |
|
|
|
|
|
autoObject * const p(this->objectP); |
|
|
return dynamic_cast<clientXmlTransport *>(p); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
clientXmlTransport_http::~clientXmlTransport_http() {} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
clientXmlTransport_http::call( |
|
|
carriageParm * const carriageParmP, |
|
|
string const& callXml, |
|
|
string * const responseXmlP) { |
|
|
|
|
|
carriageParm_http0 * const carriageParmHttpP = |
|
|
dynamic_cast<carriageParm_http0 *>(carriageParmP); |
|
|
|
|
|
if (carriageParmHttpP == NULL) |
|
|
throw(error("HTTP client XML transport called with carriage " |
|
|
"parameter object not of class carriageParm_http")); |
|
|
|
|
|
memblockStringWrapper callXmlM(callXml); |
|
|
|
|
|
xmlrpc_mem_block * responseXmlMP; |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
this->c_transportOpsP->call(&env.env_c, |
|
|
this->c_transportP, |
|
|
carriageParmHttpP->c_serverInfoP, |
|
|
callXmlM.memblockP, |
|
|
&responseXmlMP); |
|
|
|
|
|
throwIfError(env); |
|
|
|
|
|
memblockStringWrapper responseHolder(responseXmlMP); |
|
|
|
|
|
|
|
|
*responseXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlMP), |
|
|
XMLRPC_MEMBLOCK_SIZE(char, responseXmlMP)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
clientXmlTransport_http::start( |
|
|
carriageParm * const carriageParmP, |
|
|
string const& callXml, |
|
|
xmlTransactionPtr const& xmlTranP) { |
|
|
|
|
|
env_wrap env; |
|
|
|
|
|
carriageParm_http0 * const carriageParmHttpP = |
|
|
dynamic_cast<carriageParm_http0 *>(carriageParmP); |
|
|
|
|
|
if (carriageParmHttpP == NULL) |
|
|
throw(error("HTTP client XML transport called with carriage " |
|
|
"parameter object not of type carriageParm_http")); |
|
|
|
|
|
xmlTranCtl * const tranCtlP(new xmlTranCtl(xmlTranP, callXml)); |
|
|
|
|
|
try { |
|
|
this->c_transportOpsP->send_request( |
|
|
&env.env_c, |
|
|
this->c_transportP, |
|
|
carriageParmHttpP->c_serverInfoP, |
|
|
tranCtlP->callXmlP, |
|
|
&this->asyncComplete, &this->progress, |
|
|
reinterpret_cast<xmlrpc_call_info *>(tranCtlP)); |
|
|
|
|
|
throwIfError(env); |
|
|
} catch (...) { |
|
|
delete tranCtlP; |
|
|
throw; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
clientXmlTransport_http::finishAsync(xmlrpc_c::timeout const timeout) { |
|
|
|
|
|
xmlrpc_timeoutType const c_timeoutType( |
|
|
timeout.finite ? timeout_yes : timeout_no); |
|
|
xmlrpc_timeout const c_timeout(timeout.duration); |
|
|
|
|
|
this->c_transportOpsP->finish_asynch( |
|
|
this->c_transportP, c_timeoutType, c_timeout); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
clientXmlTransport_http::setInterrupt(int * const interruptP) { |
|
|
|
|
|
if (this->c_transportOpsP->set_interrupt) |
|
|
this->c_transportOpsP->set_interrupt(this->c_transportP, interruptP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool const haveCurl( |
|
|
#if MUST_BUILD_CURL_CLIENT |
|
|
true |
|
|
#else |
|
|
false |
|
|
#endif |
|
|
); |
|
|
|
|
|
bool const haveLibwww( |
|
|
#if MUST_BUILD_LIBWWW_CLIENT |
|
|
true |
|
|
#else |
|
|
false |
|
|
#endif |
|
|
); |
|
|
|
|
|
bool const haveWininet( |
|
|
#if MUST_BUILD_WININET_CLIENT |
|
|
true |
|
|
#else |
|
|
false |
|
|
#endif |
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
vector<string> |
|
|
clientXmlTransport_http::availableTypes() { |
|
|
|
|
|
vector<string> retval; |
|
|
|
|
|
if (haveCurl) |
|
|
retval.push_back("curl"); |
|
|
|
|
|
if (haveLibwww) |
|
|
retval.push_back("libwww"); |
|
|
|
|
|
if (haveWininet) |
|
|
retval.push_back("wininet"); |
|
|
|
|
|
return retval; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
clientXmlTransportPtr |
|
|
clientXmlTransport_http::create() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (haveCurl) |
|
|
return clientXmlTransportPtr(new clientXmlTransport_curl()); |
|
|
else if (haveLibwww) |
|
|
return clientXmlTransportPtr(new clientXmlTransport_libwww()); |
|
|
else if (haveWininet) |
|
|
return clientXmlTransportPtr(new clientXmlTransport_wininet()); |
|
|
else |
|
|
throwf("This XML-RPC client library contains no HTTP XML transports"); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
clientTransaction::clientTransaction() {} |
|
|
|
|
|
|
|
|
|
|
|
clientTransactionPtr::clientTransactionPtr() {} |
|
|
|
|
|
|
|
|
|
|
|
clientTransactionPtr::clientTransactionPtr( |
|
|
clientTransaction * const transP) : autoObjectPtr(transP) {} |
|
|
|
|
|
|
|
|
|
|
|
clientTransactionPtr::~clientTransactionPtr() {} |
|
|
|
|
|
|
|
|
|
|
|
clientTransaction * |
|
|
clientTransactionPtr::operator->() const { |
|
|
autoObject * const p(this->objectP); |
|
|
return dynamic_cast<clientTransaction *>(p); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
client::~client() {} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
client::start(carriageParm * const carriageParmP, |
|
|
string const& methodName, |
|
|
paramList const& paramList, |
|
|
clientTransactionPtr const& tranP) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rpcOutcome outcome; |
|
|
|
|
|
this->call(carriageParmP, methodName, paramList, &outcome); |
|
|
|
|
|
tranP->finish(outcome); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
client::finishAsync(xmlrpc_c::timeout) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
client::setInterrupt(int *) { |
|
|
|
|
|
throwf("Clients of this type are not interruptible"); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
clientPtr::clientPtr() { |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
clientPtr::clientPtr( |
|
|
client * const clientP) : autoObjectPtr(clientP) {} |
|
|
|
|
|
|
|
|
|
|
|
client * |
|
|
clientPtr::operator->() const { |
|
|
|
|
|
autoObject * const p(this->objectP); |
|
|
return dynamic_cast<client *>(p); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
client * |
|
|
clientPtr::get() const { |
|
|
return dynamic_cast<client *>(objectP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
client_xml::client_xml(clientXmlTransport * const transportP) { |
|
|
|
|
|
this->implP = new client_xml_impl(transportP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
client_xml::client_xml(clientXmlTransportPtr const transportPtr) { |
|
|
|
|
|
this->implP = new client_xml_impl(transportPtr, transportPtr.get()); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
client_xml::client_xml(clientXmlTransport * const transportP, |
|
|
xmlrpc_dialect const dialect) { |
|
|
|
|
|
this->implP = new client_xml_impl(transportP, dialect); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
client_xml::client_xml(clientXmlTransportPtr const transportPtr, |
|
|
xmlrpc_dialect const dialect) { |
|
|
|
|
|
this->implP = new client_xml_impl(transportPtr, transportPtr.get(), |
|
|
dialect); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
client_xml::~client_xml() { |
|
|
|
|
|
delete(this->implP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
client_xml::call(carriageParm * const carriageParmP, |
|
|
string const& methodName, |
|
|
paramList const& paramList, |
|
|
rpcOutcome * const outcomeP) { |
|
|
|
|
|
string callXml; |
|
|
string responseXml; |
|
|
|
|
|
xml::generateCall(methodName, paramList, this->implP->dialect, &callXml); |
|
|
|
|
|
xml::trace("XML-RPC CALL", callXml); |
|
|
|
|
|
try { |
|
|
this->implP->transportP->call(carriageParmP, callXml, &responseXml); |
|
|
} catch (exception const& e) { |
|
|
throwf("Unable to transport XML to server and " |
|
|
"get XML response back. %s", e.what()); |
|
|
} |
|
|
xml::trace("XML-RPC RESPONSE", responseXml); |
|
|
|
|
|
try { |
|
|
xml::parseResponse(responseXml, outcomeP); |
|
|
} catch (exception const& e) { |
|
|
throwf("Response XML from server is not valid XML-RPC response. %s", |
|
|
e.what()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
client_xml::start(carriageParm * const carriageParmP, |
|
|
string const& methodName, |
|
|
paramList const& paramList, |
|
|
clientTransactionPtr const& tranP) { |
|
|
|
|
|
string callXml; |
|
|
|
|
|
xml::generateCall(methodName, paramList, this->implP->dialect, &callXml); |
|
|
|
|
|
xml::trace("XML-RPC CALL", callXml); |
|
|
|
|
|
xmlTransaction_clientPtr const xmlTranP(tranP); |
|
|
|
|
|
this->implP->transportP->start(carriageParmP, callXml, xmlTranP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
client_xml::finishAsync(xmlrpc_c::timeout const timeout) { |
|
|
|
|
|
this->implP->transportP->finishAsync(timeout); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
client_xml::setInterrupt(int * const interruptP) { |
|
|
|
|
|
this->implP->transportP->setInterrupt(interruptP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
serverAccessor::serverAccessor(clientPtr const clientP, |
|
|
carriageParmPtr const carriageParmP) : |
|
|
|
|
|
clientP(clientP), carriageParmP(carriageParmP) {}; |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
serverAccessor::call(std::string const& methodName, |
|
|
xmlrpc_c::paramList const& paramList, |
|
|
xmlrpc_c::rpcOutcome * const outcomeP) const { |
|
|
|
|
|
this->clientP->call(this->carriageParmP.get(), |
|
|
methodName, |
|
|
paramList, |
|
|
outcomeP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
serverAccessorPtr::serverAccessorPtr() { |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
serverAccessorPtr::serverAccessorPtr( |
|
|
serverAccessor * const serverAccessorParmP) : |
|
|
autoObjectPtr(serverAccessorParmP) {} |
|
|
|
|
|
|
|
|
|
|
|
serverAccessor * |
|
|
serverAccessorPtr::operator->() const { |
|
|
|
|
|
autoObject * const p(this->objectP); |
|
|
return dynamic_cast<serverAccessor *>(p); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
serverAccessor * |
|
|
serverAccessorPtr::get() const { |
|
|
return dynamic_cast<serverAccessor *>(objectP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
connection::connection(client * const clientP, |
|
|
carriageParm * const carriageParmP) : |
|
|
clientP(clientP), carriageParmP(carriageParmP) {} |
|
|
|
|
|
|
|
|
|
|
|
connection::~connection() {} |
|
|
|
|
|
|
|
|
|
|
|
struct rpc_impl { |
|
|
enum state { |
|
|
STATE_UNFINISHED, |
|
|
STATE_ERROR, |
|
|
STATE_FAILED, |
|
|
STATE_SUCCEEDED |
|
|
}; |
|
|
enum state state; |
|
|
girerr::error * errorP; |
|
|
rpcOutcome outcome; |
|
|
|
|
|
string methodName; |
|
|
xmlrpc_c::paramList paramList; |
|
|
|
|
|
rpc_impl(string const& methodName, |
|
|
xmlrpc_c::paramList const& paramList) : |
|
|
state(STATE_UNFINISHED), |
|
|
methodName(methodName), |
|
|
paramList(paramList) {} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
rpc::rpc(string const methodName, |
|
|
paramList const& paramList) { |
|
|
|
|
|
this->implP = new rpc_impl(methodName, paramList); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rpc::~rpc() { |
|
|
|
|
|
if (this->implP->state == rpc_impl::STATE_ERROR) |
|
|
delete(this->implP->errorP); |
|
|
|
|
|
delete(this->implP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
rpc::call(client * const clientP, |
|
|
carriageParm * const carriageParmP) { |
|
|
|
|
|
if (this->implP->state != rpc_impl::STATE_UNFINISHED) |
|
|
throw(error("Attempt to execute an RPC that has already been " |
|
|
"executed")); |
|
|
|
|
|
clientP->call(carriageParmP, |
|
|
this->implP->methodName, |
|
|
this->implP->paramList, |
|
|
&this->implP->outcome); |
|
|
|
|
|
this->implP->state = this->implP->outcome.succeeded() ? |
|
|
rpc_impl::STATE_SUCCEEDED : rpc_impl::STATE_FAILED; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
rpc::call(connection const& connection) { |
|
|
|
|
|
this->call(connection.clientP, connection.carriageParmP); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
rpc::start(client * const clientP, |
|
|
carriageParm * const carriageParmP) { |
|
|
|
|
|
if (this->implP->state != rpc_impl::STATE_UNFINISHED) |
|
|
throw(error("Attempt to execute an RPC that has already been " |
|
|
"executed")); |
|
|
|
|
|
clientP->start(carriageParmP, |
|
|
this->implP->methodName, |
|
|
this->implP->paramList, |
|
|
rpcPtr(this)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
rpc::start(xmlrpc_c::connection const& connection) { |
|
|
|
|
|
this->start(connection.clientP, connection.carriageParmP); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
rpc::finish(rpcOutcome const& outcome) { |
|
|
|
|
|
this->implP->state = |
|
|
outcome.succeeded() ? |
|
|
rpc_impl::STATE_SUCCEEDED : rpc_impl::STATE_FAILED; |
|
|
|
|
|
this->implP->outcome = outcome; |
|
|
|
|
|
this->notifyComplete(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
rpc::finishErr(error const& error) { |
|
|
|
|
|
this->implP->state = rpc_impl::STATE_ERROR; |
|
|
this->implP->errorP = new girerr::error(error); |
|
|
this->notifyComplete(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
rpc::notifyComplete() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
rpc::progress(struct xmlrpc_progress_data const&) const { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
value |
|
|
rpc::getResult() const { |
|
|
|
|
|
switch (this->implP->state) { |
|
|
case rpc_impl::STATE_UNFINISHED: |
|
|
throw(error("Attempt to get result of RPC that is not finished.")); |
|
|
break; |
|
|
case rpc_impl::STATE_ERROR: |
|
|
throw(*this->implP->errorP); |
|
|
break; |
|
|
case rpc_impl::STATE_FAILED: |
|
|
throw(error("RPC response indicates failure. " + |
|
|
this->implP->outcome.getFault().getDescription())); |
|
|
break; |
|
|
case rpc_impl::STATE_SUCCEEDED: { |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
return this->implP->outcome.getResult(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fault |
|
|
rpc::getFault() const { |
|
|
|
|
|
switch (this->implP->state) { |
|
|
case rpc_impl::STATE_UNFINISHED: |
|
|
throw(error("Attempt to get fault from RPC that is not finished")); |
|
|
break; |
|
|
case rpc_impl::STATE_ERROR: |
|
|
throw(*this->implP->errorP); |
|
|
break; |
|
|
case rpc_impl::STATE_SUCCEEDED: |
|
|
throw(error("Attempt to get fault from an RPC that succeeded")); |
|
|
break; |
|
|
case rpc_impl::STATE_FAILED: { |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
return this->implP->outcome.getFault(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
rpc::isFinished() const { |
|
|
return (this->implP->state != rpc_impl::STATE_UNFINISHED); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
rpc::isSuccessful() const { |
|
|
return (this->implP->state == rpc_impl::STATE_SUCCEEDED); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rpcPtr::rpcPtr() {} |
|
|
|
|
|
|
|
|
|
|
|
rpcPtr::rpcPtr(rpc * const rpcP) : clientTransactionPtr(rpcP) {} |
|
|
|
|
|
|
|
|
|
|
|
rpcPtr::rpcPtr(string const methodName, |
|
|
xmlrpc_c::paramList const& paramList) : |
|
|
clientTransactionPtr(new rpc(methodName, paramList)) {} |
|
|
|
|
|
|
|
|
|
|
|
rpc * |
|
|
rpcPtr::operator->() const { |
|
|
|
|
|
autoObject * const p(this->objectP); |
|
|
return dynamic_cast<rpc *>(p); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
xmlTransaction_client::xmlTransaction_client( |
|
|
clientTransactionPtr const& tranP) : |
|
|
tranP(tranP) {} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
xmlTransaction_client::finish(string const& responseXml) const { |
|
|
|
|
|
xml::trace("XML-RPC RESPONSE", responseXml); |
|
|
|
|
|
try { |
|
|
rpcOutcome outcome; |
|
|
|
|
|
xml::parseResponse(responseXml, &outcome); |
|
|
|
|
|
this->tranP->finish(outcome); |
|
|
} catch (error const& error) { |
|
|
this->tranP->finishErr(error); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
xmlTransaction_client::finishErr(error const& error) const { |
|
|
|
|
|
this->tranP->finishErr(error); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
xmlTransaction_client::progress( |
|
|
struct xmlrpc_progress_data const& progressData) const { |
|
|
|
|
|
this->tranP->progress(progressData); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
xmlTransaction_clientPtr::xmlTransaction_clientPtr() {} |
|
|
|
|
|
|
|
|
|
|
|
xmlTransaction_clientPtr::xmlTransaction_clientPtr( |
|
|
clientTransactionPtr const& tranP) : |
|
|
xmlTransactionPtr(new xmlTransaction_client(tranP)) {} |
|
|
|
|
|
|
|
|
|
|
|
xmlTransaction_client * |
|
|
xmlTransaction_clientPtr::operator->() const { |
|
|
autoObject * const p(this->objectP); |
|
|
return dynamic_cast<xmlTransaction_client *>(p); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|