--- /dev/null
+/*=============================================================================
+ curl.cpp
+===============================================================================
+ This is the Curl XML transport of the C++ XML-RPC client library for
+ Xmlrpc-c.
+
+ Note that unlike most of Xmlprc-c's C++ API, this is _not_ based on the
+ C client library. This code is independent of the C client library, and
+ is based directly on the client XML transport libraries (with a little
+ help from internal C utility libraries).
+=============================================================================*/
+
+#include <stdlib.h>
+#include <cassert>
+#include <string>
+
+#include "xmlrpc-c/girerr.hpp"
+using girerr::error;
+using girerr::throwf;
+#include "xmlrpc-c/girmem.hpp"
+using girmem::autoObjectPtr;
+using girmem::autoObject;
+#include "env_wrap.hpp"
+#include "xmlrpc-c/base.h"
+#include "xmlrpc-c/client.h"
+#include "xmlrpc-c/transport.h"
+#include "xmlrpc-c/base_int.h"
+
+#include "xmlrpc_curl_transport.h"
+
+/* transport_config.h defines MUST_BUILD_CURL_CLIENT */
+#include "transport_config.h"
+
+#include "xmlrpc-c/client_transport.hpp"
+
+
+using namespace std;
+using namespace xmlrpc_c;
+
+
+
+namespace {
+
+class globalConstant {
+public:
+ globalConstant();
+ ~globalConstant();
+};
+
+
+
+globalConstant::globalConstant() {
+
+ // Not thread safe
+
+ xmlrpc_transport_setup setupFn;
+
+#if MUST_BUILD_CURL_CLIENT
+ setupFn = xmlrpc_curl_transport_ops.setup_global_const;
+#else
+ setupFn = NULL;
+#endif
+ if (setupFn) {
+ env_wrap env;
+
+ setupFn(&env.env_c); // Not thread safe
+
+ if (env.env_c.fault_occurred)
+ throwf("Failed to do global initialization "
+ "of Curl transport code. %s", env.env_c.fault_string);
+ }
+}
+
+
+
+globalConstant::~globalConstant() {
+
+ // Not thread safe
+
+ xmlrpc_transport_teardown teardownFn;
+
+#if MUST_BUILD_CURL_CLIENT
+ teardownFn = xmlrpc_curl_transport_ops.teardown_global_const;
+#else
+ teardownFn = NULL;
+#endif
+ if (teardownFn)
+ teardownFn(); // not thread safe
+}
+
+globalConstant globalConst;
+ // This object is never accessed. Its whole purpose to to be born and
+ // to die, which it does automatically as part of C++ program
+ // program initialization and termination.
+
+} // namespace
+
+
+namespace xmlrpc_c {
+
+carriageParm_curl0::carriageParm_curl0(
+ string const serverUrl
+ ) {
+
+ this->instantiate(serverUrl);
+}
+
+
+
+carriageParm_curl0Ptr::carriageParm_curl0Ptr() {
+ // Base class constructor will construct pointer that points to nothing
+}
+
+
+
+carriageParm_curl0Ptr::carriageParm_curl0Ptr(
+ carriageParm_curl0 * const carriageParmP) {
+ this->point(carriageParmP);
+}
+
+
+
+carriageParm_curl0 *
+carriageParm_curl0Ptr::operator->() const {
+
+ autoObject * const p(this->objectP);
+ return dynamic_cast<carriageParm_curl0 *>(p);
+}
+
+
+
+clientXmlTransport_curl::constrOpt::constrOpt() {
+
+ present.network_interface = false;
+ present.no_ssl_verifypeer = false;
+ present.no_ssl_verifyhost = false;
+ present.user_agent = false;
+ present.ssl_cert = false;
+ present.sslcerttype = false;
+ present.sslcertpasswd = false;
+ present.sslkey = false;
+ present.sslkeytype = false;
+ present.sslkeypasswd = false;
+ present.sslengine = false;
+ present.sslengine_default = false;
+ present.sslversion = false;
+ present.cainfo = false;
+ present.capath = false;
+ present.randomfile = false;
+ present.egdsocket = false;
+ present.ssl_cipher_list = false;
+}
+
+
+
+#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \
+clientXmlTransport_curl::constrOpt & \
+clientXmlTransport_curl::constrOpt::OPTION_NAME(TYPE const& arg) { \
+ this->value.OPTION_NAME = arg; \
+ this->present.OPTION_NAME = true; \
+ return *this; \
+}
+
+DEFINE_OPTION_SETTER(network_interface, string);
+DEFINE_OPTION_SETTER(no_ssl_verifypeer, bool);
+DEFINE_OPTION_SETTER(no_ssl_verifyhost, bool);
+DEFINE_OPTION_SETTER(user_agent, string);
+DEFINE_OPTION_SETTER(ssl_cert, string);
+DEFINE_OPTION_SETTER(sslcerttype, string);
+DEFINE_OPTION_SETTER(sslcertpasswd, string);
+DEFINE_OPTION_SETTER(sslkey, string);
+DEFINE_OPTION_SETTER(sslkeytype, string);
+DEFINE_OPTION_SETTER(sslkeypasswd, string);
+DEFINE_OPTION_SETTER(sslengine, string);
+DEFINE_OPTION_SETTER(sslengine_default, bool);
+DEFINE_OPTION_SETTER(sslversion, xmlrpc_sslversion);
+DEFINE_OPTION_SETTER(cainfo, string);
+DEFINE_OPTION_SETTER(capath, string);
+DEFINE_OPTION_SETTER(randomfile, string);
+DEFINE_OPTION_SETTER(egdsocket, string);
+DEFINE_OPTION_SETTER(ssl_cipher_list, string);
+
+#undef DEFINE_OPTION_SETTER
+
+#if MUST_BUILD_CURL_CLIENT
+
+void
+clientXmlTransport_curl::initialize(constrOpt const& opt) {
+ struct xmlrpc_curl_xportparms transportParms;
+
+ transportParms.network_interface = opt.present.network_interface ?
+ opt.value.network_interface.c_str() : NULL;
+ transportParms.no_ssl_verifypeer = opt.present.no_ssl_verifypeer ?
+ opt.value.no_ssl_verifypeer : false;
+ transportParms.no_ssl_verifyhost = opt.present.no_ssl_verifyhost ?
+ opt.value.no_ssl_verifyhost : false;
+ transportParms.user_agent = opt.present.user_agent ?
+ opt.value.user_agent.c_str() : NULL;
+ transportParms.ssl_cert = opt.present.ssl_cert ?
+ opt.value.ssl_cert.c_str() : NULL;
+ transportParms.sslcerttype = opt.present.sslcerttype ?
+ opt.value.sslcerttype.c_str() : NULL;
+ transportParms.sslcertpasswd = opt.present.sslcertpasswd ?
+ opt.value.sslcertpasswd.c_str() : NULL;
+ transportParms.sslkey = opt.present.sslkey ?
+ opt.value.sslkey.c_str() : NULL;
+ transportParms.sslkeytype = opt.present.sslkeytype ?
+ opt.value.sslkeytype.c_str() : NULL;
+ transportParms.sslkeypasswd = opt.present.sslkeypasswd ?
+ opt.value.sslkeypasswd.c_str() : NULL;
+ transportParms.sslengine = opt.present.sslengine ?
+ opt.value.sslengine.c_str() : NULL;
+ transportParms.sslengine_default = opt.present.sslengine_default ?
+ opt.value.sslengine_default : false;
+ transportParms.sslversion = opt.present.sslversion ?
+ opt.value.sslversion : XMLRPC_SSLVERSION_DEFAULT;
+ transportParms.cainfo = opt.present.cainfo ?
+ opt.value.cainfo.c_str() : NULL;
+ transportParms.capath = opt.present.capath ?
+ opt.value.capath.c_str() : NULL;
+ transportParms.randomfile = opt.present.randomfile ?
+ opt.value.randomfile.c_str() : NULL;
+ transportParms.egdsocket = opt.present.egdsocket ?
+ opt.value.egdsocket.c_str() : NULL;
+ transportParms.ssl_cipher_list = opt.present.ssl_cipher_list ?
+ opt.value.ssl_cipher_list.c_str() : NULL;
+
+ this->c_transportOpsP = &xmlrpc_curl_transport_ops;
+
+ env_wrap env;
+
+ xmlrpc_curl_transport_ops.create(
+ &env.env_c, 0, "", "", (xmlrpc_xportparms *)&transportParms,
+ XMLRPC_CXPSIZE(ssl_cipher_list),
+ &this->c_transportP);
+
+ if (env.env_c.fault_occurred)
+ throw(error(env.env_c.fault_string));
+}
+
+#else // MUST_BUILD_CURL_CLIENT
+
+void
+clientXmlTransport_curl::initialize(constrOpt const& opt) {
+
+ throw(error("There is no Curl client XML transport in this XML-RPC client "
+ "library"));
+}
+
+#endif
+
+clientXmlTransport_curl::clientXmlTransport_curl(constrOpt const& opt) {
+
+ this->initialize(opt);
+}
+
+
+
+clientXmlTransport_curl::clientXmlTransport_curl(
+ string const networkInterface,
+ bool const noSslVerifyPeer,
+ bool const noSslVerifyHost,
+ string const userAgent) {
+
+ clientXmlTransport_curl::constrOpt opt;
+
+ if (networkInterface.size() > 0)
+ opt.network_interface(networkInterface);
+ opt.no_ssl_verifypeer(noSslVerifyPeer);
+ opt.no_ssl_verifyhost(noSslVerifyHost);
+ if (userAgent.size() > 0)
+ opt.user_agent(userAgent);
+
+ this->initialize(opt);
+}
+
+
+
+clientXmlTransport_curl::~clientXmlTransport_curl() {
+
+ this->c_transportOpsP->destroy(this->c_transportP);
+}
+
+
+} // namespace