1 /*=============================================================================
3 ===============================================================================
4 This is the Curl XML transport of the C++ XML-RPC client library for
7 Note that unlike most of Xmlprc-c's C++ API, this is _not_ based on the
8 C client library. This code is independent of the C client library, and
9 is based directly on the client XML transport libraries (with a little
10 help from internal C utility libraries).
11 =============================================================================*/
17 #include "xmlrpc-c/girerr.hpp"
20 #include "xmlrpc-c/girmem.hpp"
21 using girmem::autoObjectPtr;
22 using girmem::autoObject;
23 #include "env_wrap.hpp"
24 #include "xmlrpc-c/base.h"
25 #include "xmlrpc-c/client.h"
26 #include "xmlrpc-c/transport.h"
27 #include "xmlrpc-c/base_int.h"
29 #include "xmlrpc_curl_transport.h"
31 /* transport_config.h defines MUST_BUILD_CURL_CLIENT */
32 #include "transport_config.h"
34 #include "xmlrpc-c/client_transport.hpp"
38 using namespace xmlrpc_c;
44 class globalConstant {
52 globalConstant::globalConstant() {
56 xmlrpc_transport_setup setupFn;
58 #if MUST_BUILD_CURL_CLIENT
59 setupFn = xmlrpc_curl_transport_ops.setup_global_const;
66 setupFn(&env.env_c); // Not thread safe
68 if (env.env_c.fault_occurred)
69 throwf("Failed to do global initialization "
70 "of Curl transport code. %s", env.env_c.fault_string);
76 globalConstant::~globalConstant() {
80 xmlrpc_transport_teardown teardownFn;
82 #if MUST_BUILD_CURL_CLIENT
83 teardownFn = xmlrpc_curl_transport_ops.teardown_global_const;
88 teardownFn(); // not thread safe
91 globalConstant globalConst;
92 // This object is never accessed. Its whole purpose to to be born and
93 // to die, which it does automatically as part of C++ program
94 // program initialization and termination.
101 carriageParm_curl0::carriageParm_curl0(
102 string const serverUrl
105 this->instantiate(serverUrl);
110 carriageParm_curl0Ptr::carriageParm_curl0Ptr() {
111 // Base class constructor will construct pointer that points to nothing
116 carriageParm_curl0Ptr::carriageParm_curl0Ptr(
117 carriageParm_curl0 * const carriageParmP) {
118 this->point(carriageParmP);
124 carriageParm_curl0Ptr::operator->() const {
126 autoObject * const p(this->objectP);
127 return dynamic_cast<carriageParm_curl0 *>(p);
132 clientXmlTransport_curl::constrOpt::constrOpt() {
134 present.network_interface = false;
135 present.no_ssl_verifypeer = false;
136 present.no_ssl_verifyhost = false;
137 present.user_agent = false;
138 present.ssl_cert = false;
139 present.sslcerttype = false;
140 present.sslcertpasswd = false;
141 present.sslkey = false;
142 present.sslkeytype = false;
143 present.sslkeypasswd = false;
144 present.sslengine = false;
145 present.sslengine_default = false;
146 present.sslversion = false;
147 present.cainfo = false;
148 present.capath = false;
149 present.randomfile = false;
150 present.egdsocket = false;
151 present.ssl_cipher_list = false;
156 #define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \
157 clientXmlTransport_curl::constrOpt & \
158 clientXmlTransport_curl::constrOpt::OPTION_NAME(TYPE const& arg) { \
159 this->value.OPTION_NAME = arg; \
160 this->present.OPTION_NAME = true; \
164 DEFINE_OPTION_SETTER(network_interface, string);
165 DEFINE_OPTION_SETTER(no_ssl_verifypeer, bool);
166 DEFINE_OPTION_SETTER(no_ssl_verifyhost, bool);
167 DEFINE_OPTION_SETTER(user_agent, string);
168 DEFINE_OPTION_SETTER(ssl_cert, string);
169 DEFINE_OPTION_SETTER(sslcerttype, string);
170 DEFINE_OPTION_SETTER(sslcertpasswd, string);
171 DEFINE_OPTION_SETTER(sslkey, string);
172 DEFINE_OPTION_SETTER(sslkeytype, string);
173 DEFINE_OPTION_SETTER(sslkeypasswd, string);
174 DEFINE_OPTION_SETTER(sslengine, string);
175 DEFINE_OPTION_SETTER(sslengine_default, bool);
176 DEFINE_OPTION_SETTER(sslversion, xmlrpc_sslversion);
177 DEFINE_OPTION_SETTER(cainfo, string);
178 DEFINE_OPTION_SETTER(capath, string);
179 DEFINE_OPTION_SETTER(randomfile, string);
180 DEFINE_OPTION_SETTER(egdsocket, string);
181 DEFINE_OPTION_SETTER(ssl_cipher_list, string);
183 #undef DEFINE_OPTION_SETTER
185 #if MUST_BUILD_CURL_CLIENT
188 clientXmlTransport_curl::initialize(constrOpt const& opt) {
189 struct xmlrpc_curl_xportparms transportParms;
191 transportParms.network_interface = opt.present.network_interface ?
192 opt.value.network_interface.c_str() : NULL;
193 transportParms.no_ssl_verifypeer = opt.present.no_ssl_verifypeer ?
194 opt.value.no_ssl_verifypeer : false;
195 transportParms.no_ssl_verifyhost = opt.present.no_ssl_verifyhost ?
196 opt.value.no_ssl_verifyhost : false;
197 transportParms.user_agent = opt.present.user_agent ?
198 opt.value.user_agent.c_str() : NULL;
199 transportParms.ssl_cert = opt.present.ssl_cert ?
200 opt.value.ssl_cert.c_str() : NULL;
201 transportParms.sslcerttype = opt.present.sslcerttype ?
202 opt.value.sslcerttype.c_str() : NULL;
203 transportParms.sslcertpasswd = opt.present.sslcertpasswd ?
204 opt.value.sslcertpasswd.c_str() : NULL;
205 transportParms.sslkey = opt.present.sslkey ?
206 opt.value.sslkey.c_str() : NULL;
207 transportParms.sslkeytype = opt.present.sslkeytype ?
208 opt.value.sslkeytype.c_str() : NULL;
209 transportParms.sslkeypasswd = opt.present.sslkeypasswd ?
210 opt.value.sslkeypasswd.c_str() : NULL;
211 transportParms.sslengine = opt.present.sslengine ?
212 opt.value.sslengine.c_str() : NULL;
213 transportParms.sslengine_default = opt.present.sslengine_default ?
214 opt.value.sslengine_default : false;
215 transportParms.sslversion = opt.present.sslversion ?
216 opt.value.sslversion : XMLRPC_SSLVERSION_DEFAULT;
217 transportParms.cainfo = opt.present.cainfo ?
218 opt.value.cainfo.c_str() : NULL;
219 transportParms.capath = opt.present.capath ?
220 opt.value.capath.c_str() : NULL;
221 transportParms.randomfile = opt.present.randomfile ?
222 opt.value.randomfile.c_str() : NULL;
223 transportParms.egdsocket = opt.present.egdsocket ?
224 opt.value.egdsocket.c_str() : NULL;
225 transportParms.ssl_cipher_list = opt.present.ssl_cipher_list ?
226 opt.value.ssl_cipher_list.c_str() : NULL;
228 this->c_transportOpsP = &xmlrpc_curl_transport_ops;
232 xmlrpc_curl_transport_ops.create(
233 &env.env_c, 0, "", "", (xmlrpc_xportparms *)&transportParms,
234 XMLRPC_CXPSIZE(ssl_cipher_list),
235 &this->c_transportP);
237 if (env.env_c.fault_occurred)
238 throw(error(env.env_c.fault_string));
241 #else // MUST_BUILD_CURL_CLIENT
244 clientXmlTransport_curl::initialize(constrOpt const& opt) {
246 throw(error("There is no Curl client XML transport in this XML-RPC client "
252 clientXmlTransport_curl::clientXmlTransport_curl(constrOpt const& opt) {
254 this->initialize(opt);
259 clientXmlTransport_curl::clientXmlTransport_curl(
260 string const networkInterface,
261 bool const noSslVerifyPeer,
262 bool const noSslVerifyHost,
263 string const userAgent) {
265 clientXmlTransport_curl::constrOpt opt;
267 if (networkInterface.size() > 0)
268 opt.network_interface(networkInterface);
269 opt.no_ssl_verifypeer(noSslVerifyPeer);
270 opt.no_ssl_verifyhost(noSslVerifyHost);
271 if (userAgent.size() > 0)
272 opt.user_agent(userAgent);
274 this->initialize(opt);
279 clientXmlTransport_curl::~clientXmlTransport_curl() {
281 this->c_transportOpsP->destroy(this->c_transportP);