initial load of upstream version 1.06.32
[xmlrpc-c] / src / cpp / curl.cpp
diff --git a/src/cpp/curl.cpp b/src/cpp/curl.cpp
new file mode 100644 (file)
index 0000000..65e8cc3
--- /dev/null
@@ -0,0 +1,285 @@
+/*=============================================================================
+                                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