1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <errno.h>
5 
6 #include "xmlrpc_config.h"
7 #include "transport_config.h"
8 
9 #include "xmlrpc-c/base.h"
10 #include "xmlrpc-c/client.h"
11 #include "xmlrpc-c/transport.h"
12 
13 #include "bool.h"
14 #include "testtool.h"
15 #include "client.h"
16 
17 
18 
19 static void
testVersion(void)20 testVersion(void) {
21 
22     unsigned int major, minor, point;
23 
24     xmlrpc_client_version(&major, &minor, &point);
25 
26 #ifndef WIN32
27     /* xmlrpc_client_version_major, etc. are not exported from a Windows DLL */
28 
29     TEST(major = xmlrpc_client_version_major);
30     TEST(minor = xmlrpc_client_version_minor);
31     TEST(point = xmlrpc_client_version_point);
32 #endif
33 }
34 
35 
36 
37 static void
testGlobalConst(void)38 testGlobalConst(void) {
39 
40     xmlrpc_env env;
41     xmlrpc_env_init(&env);
42 
43     xmlrpc_client_setup_global_const(&env);
44     TEST_NO_FAULT(&env);
45 
46     xmlrpc_client_teardown_global_const();
47 
48     xmlrpc_client_setup_global_const(&env);
49     TEST_NO_FAULT(&env);
50     xmlrpc_client_setup_global_const(&env);
51     TEST_NO_FAULT(&env);
52 
53     xmlrpc_client_teardown_global_const();
54     xmlrpc_client_teardown_global_const();
55 
56     xmlrpc_env_clean(&env);
57 }
58 
59 
60 
61 static xmlrpc_progress_fn myProgress;
62 
63 static void
myProgress(void * const userHandle,struct xmlrpc_progress_data const data)64 myProgress(void *                      const userHandle,
65            struct xmlrpc_progress_data const data) {
66 
67     printf("Progress of %p: %f, %f, %f, %f\n",
68            userHandle,
69            data.call.total,
70            data.call.now,
71            data.response.total,
72            data.response.now);
73 }
74 
75 
76 
77 static void
testCreateCurlParms(void)78 testCreateCurlParms(void) {
79 
80 #if MUST_BUILD_CURL_CLIENT
81 
82     xmlrpc_env env;
83     xmlrpc_client * clientP;
84     struct xmlrpc_clientparms clientParms1;
85     struct xmlrpc_curl_xportparms curlTransportParms1;
86 
87     xmlrpc_env_init(&env);
88 
89     clientParms1.transport = "curl";
90     clientParms1.transportparmsP = &curlTransportParms1;
91 
92     curlTransportParms1.network_interface = "eth0";
93     clientParms1.transportparm_size = XMLRPC_CXPSIZE(network_interface);
94     xmlrpc_client_create(&env, 0, "testprog", "1.0",
95                          &clientParms1, XMLRPC_CPSIZE(transportparm_size),
96                          &clientP);
97     TEST_NO_FAULT(&env);
98     xmlrpc_client_destroy(clientP);
99 
100     curlTransportParms1.no_ssl_verifypeer = 1;
101     curlTransportParms1.no_ssl_verifyhost = 1;
102     clientParms1.transportparm_size = XMLRPC_CXPSIZE(no_ssl_verifyhost);
103     xmlrpc_client_create(&env, 0, "testprog", "1.0",
104                          &clientParms1, XMLRPC_CPSIZE(transportparm_size),
105                          &clientP);
106     TEST_NO_FAULT(&env);
107     xmlrpc_client_destroy(clientP);
108 
109     curlTransportParms1.user_agent = "testprog/1.0";
110     clientParms1.transportparm_size = XMLRPC_CXPSIZE(user_agent);
111     xmlrpc_client_create(&env, 0, "testprog", "1.0",
112                          &clientParms1, XMLRPC_CPSIZE(transportparm_size),
113                          &clientP);
114     TEST_NO_FAULT(&env);
115     xmlrpc_client_destroy(clientP);
116 
117     curlTransportParms1.ssl_cert          = NULL;
118     curlTransportParms1.sslcerttype       = NULL;
119     curlTransportParms1.sslcertpasswd     = NULL;
120     curlTransportParms1.sslkey            = NULL;
121     curlTransportParms1.sslkeytype        = NULL;
122     curlTransportParms1.sslkeypasswd      = NULL;
123     curlTransportParms1.sslengine         = NULL;
124     curlTransportParms1.sslengine_default = false;
125     curlTransportParms1.sslversion        = XMLRPC_SSLVERSION_DEFAULT;
126     curlTransportParms1.cainfo            = NULL;
127     curlTransportParms1.capath            = NULL;
128     curlTransportParms1.randomfile        = NULL;
129     curlTransportParms1.egdsocket         = NULL;
130     curlTransportParms1.ssl_cipher_list   = NULL;
131     curlTransportParms1.timeout           = 0;
132     curlTransportParms1.dont_advertise    = 1;
133     curlTransportParms1.proxy             = NULL;
134     curlTransportParms1.proxy_port        = 0;
135     curlTransportParms1.proxy_type        = XMLRPC_HTTPPROXY_HTTP;
136     curlTransportParms1.proxy_auth        = XMLRPC_HTTPAUTH_NONE;
137     clientParms1.transportparm_size = XMLRPC_CXPSIZE(proxy_auth);
138     xmlrpc_client_create(&env, 0, "testprog", "1.0",
139                          &clientParms1, XMLRPC_CPSIZE(transportparm_size),
140                          &clientP);
141     TEST_NO_FAULT(&env);
142     xmlrpc_client_destroy(clientP);
143 
144     xmlrpc_env_clean(&env);
145 #endif  /* MUST_BUILD_CURL_CLIENT */
146 }
147 
148 
149 
150 static void
testCreateSeparateXport(void)151 testCreateSeparateXport(void) {
152 
153 #if MUST_BUILD_CURL_CLIENT
154     xmlrpc_env env;
155     xmlrpc_client * clientP;
156     struct xmlrpc_clientparms clientParms1;
157     struct xmlrpc_curl_xportparms curlTransportParms1;
158     struct xmlrpc_client_transport * transportP;
159 
160     xmlrpc_env_init(&env);
161 
162     xmlrpc_curl_transport_ops.create(
163         &env, 0, "", "", &curlTransportParms1, 0,
164         &transportP);
165 
166     TEST_NO_FAULT(&env);
167 
168     clientParms1.transport          = NULL;
169     clientParms1.transportparmsP    = NULL;
170     clientParms1.transportparm_size = 0;
171     clientParms1.transportOpsP      = NULL;
172     clientParms1.transportP         = NULL;
173 
174     xmlrpc_client_create(&env, 0, "", "",
175                          &clientParms1, XMLRPC_CPSIZE(transportP),
176                          &clientP);
177     TEST_NO_FAULT(&env);
178 
179     xmlrpc_client_destroy(clientP);
180 
181     clientParms1.transport = "curl";
182     clientParms1.transportparmsP = &curlTransportParms1;
183     clientParms1.transportparm_size = 0;
184     clientParms1.transportOpsP = NULL;
185     clientParms1.transportP = NULL;
186 
187     xmlrpc_client_create(&env, 0, "", "",
188                          &clientParms1, XMLRPC_CPSIZE(transportP),
189                          &clientP);
190     TEST_NO_FAULT(&env);
191 
192     xmlrpc_client_destroy(clientP);
193 
194     clientParms1.transportP = transportP;
195     xmlrpc_client_create(&env, 0, "", "",
196                          &clientParms1, XMLRPC_CPSIZE(transportP),
197                          &clientP);
198     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
199         /* Both transportP and transport specified */
200 
201     clientParms1.transport          = NULL;
202     clientParms1.transportparmsP    = NULL;
203     clientParms1.transportparm_size = 0;
204     clientParms1.transportOpsP      = &xmlrpc_curl_transport_ops;
205     clientParms1.transportP         = transportP;
206 
207     xmlrpc_client_create(&env, 0, "", "",
208                          &clientParms1, XMLRPC_CPSIZE(transportOpsP),
209                          &clientP);
210 
211     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
212         /* transportOpsP but no transportP */
213 
214     xmlrpc_client_create(&env, 0, "", "",
215                          &clientParms1, XMLRPC_CPSIZE(transportP),
216                          &clientP);
217 
218     TEST_NO_FAULT(&env);
219 
220     xmlrpc_client_destroy(clientP);
221 
222     xmlrpc_curl_transport_ops.destroy(transportP);
223 
224     xmlrpc_env_clean(&env);
225 
226 #endif  /* MUST_BUILD_CURL_CLIENT */
227 }
228 
229 
230 
231 static void
testCreateDestroy(void)232 testCreateDestroy(void) {
233 
234     xmlrpc_env env;
235     xmlrpc_client * clientP;
236     struct xmlrpc_clientparms clientParms1;
237     struct xmlrpc_curl_xportparms curlTransportParms1;
238     int interrupt;
239 
240     xmlrpc_env_init(&env);
241 
242     xmlrpc_client_create(&env, 0, "testprog", "1.0", NULL, 0, &clientP);
243     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
244         /* Didn't set up global const */
245 
246     xmlrpc_client_setup_global_const(&env);
247     TEST_NO_FAULT(&env);
248 
249     xmlrpc_client_create(&env, 0, "testprog", "1.0", NULL, 0, &clientP);
250     TEST_NO_FAULT(&env);
251     xmlrpc_client_destroy(clientP);
252 
253     xmlrpc_client_create(&env, 0, "testprog", "1.0", &clientParms1, 0,
254                          &clientP);
255     TEST_NO_FAULT(&env);
256     xmlrpc_client_destroy(clientP);
257 
258     clientParms1.transport = "curl";
259     xmlrpc_client_create(&env, 0, "testprog", "1.0",
260                         &clientParms1, XMLRPC_CPSIZE(transport), &clientP);
261     TEST_NO_FAULT(&env);
262     xmlrpc_client_destroy(clientP);
263 
264     clientParms1.transportparmsP = NULL;
265     xmlrpc_client_create(&env, 0, "testprog", "1.0",
266                          &clientParms1, XMLRPC_CPSIZE(transportparmsP),
267                          &clientP);
268     TEST_NO_FAULT(&env);
269     xmlrpc_client_destroy(clientP);
270 
271     clientParms1.transportOpsP = NULL;
272     clientParms1.transportP    = NULL;
273     clientParms1.dialect       = xmlrpc_dialect_apache;
274     clientParms1.progressFn    = &myProgress;
275     xmlrpc_client_create(&env, 0, "testprog", "1.0",
276                          &clientParms1, XMLRPC_CPSIZE(progressFn),
277                          &clientP);
278     TEST_NO_FAULT(&env);
279     xmlrpc_client_destroy(clientP);
280 
281     clientParms1.transportparmsP = &curlTransportParms1;
282 
283     xmlrpc_client_create(&env, 0, "testprog", "1.0",
284                          &clientParms1, XMLRPC_CPSIZE(transportparmsP),
285                          &clientP);
286     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
287 
288     clientParms1.transportparm_size = 0;
289     xmlrpc_client_create(&env, 0, "testprog", "1.0",
290                          &clientParms1, XMLRPC_CPSIZE(transportparm_size),
291                          &clientP);
292     TEST_NO_FAULT(&env);
293 
294     xmlrpc_client_set_interrupt(clientP, &interrupt);
295     xmlrpc_client_set_interrupt(clientP, NULL);
296 
297     xmlrpc_client_destroy(clientP);
298 
299     testCreateCurlParms();
300 
301     testCreateSeparateXport();
302 
303     xmlrpc_client_teardown_global_const();
304 
305     xmlrpc_env_clean(&env);
306 }
307 
308 
309 
310 static void
testSynchCall(void)311 testSynchCall(void) {
312 
313     xmlrpc_env env;
314     xmlrpc_client * clientP;
315     xmlrpc_value * resultP;
316     xmlrpc_value * emptyArrayP;
317     xmlrpc_server_info * noSuchServerInfoP;
318 
319     xmlrpc_env_init(&env);
320 
321     emptyArrayP = xmlrpc_array_new(&env);
322     TEST_NO_FAULT(&env);
323 
324     xmlrpc_client_setup_global_const(&env);
325     TEST_NO_FAULT(&env);
326 
327     xmlrpc_client_create(&env, 0, "testprog", "1.0", NULL, 0, &clientP);
328     TEST_NO_FAULT(&env);
329 
330     noSuchServerInfoP = xmlrpc_server_info_new(&env, "nosuchserver");
331     TEST_NO_FAULT(&env);
332 
333     xmlrpc_client_call2(&env, clientP, noSuchServerInfoP, "nosuchmethod",
334                         emptyArrayP, &resultP);
335     TEST_FAULT(&env, XMLRPC_NETWORK_ERROR);  /* No such server */
336 
337     xmlrpc_client_call2f(&env, clientP, "nosuchserver", "nosuchmethod",
338                           &resultP, "(i)", 7);
339     TEST_FAULT(&env, XMLRPC_NETWORK_ERROR);  /* No such server */
340 
341     xmlrpc_server_info_free(noSuchServerInfoP);
342 
343     xmlrpc_client_destroy(clientP);
344 
345     xmlrpc_DECREF(emptyArrayP);
346 
347     xmlrpc_client_teardown_global_const();
348 
349     xmlrpc_env_clean(&env);
350 }
351 
352 
353 
354 static void
testInitCleanup(void)355 testInitCleanup(void) {
356 
357     xmlrpc_env env;
358     struct xmlrpc_clientparms clientParms1;
359     struct xmlrpc_curl_xportparms curlTransportParms1;
360 
361     xmlrpc_env_init(&env);
362 
363     xmlrpc_client_init2(&env, 0, "testprog", "1.0", NULL, 0);
364     TEST_NO_FAULT(&env);
365     xmlrpc_client_cleanup();
366 
367     xmlrpc_client_init2(&env, 0, "testprog", "1.0", &clientParms1, 0);
368     TEST_NO_FAULT(&env);
369     xmlrpc_client_cleanup();
370 
371     clientParms1.transport = "curl";
372     xmlrpc_client_init2(&env, 0, "testprog", "1.0",
373                         &clientParms1, XMLRPC_CPSIZE(transport));
374     TEST_NO_FAULT(&env);
375     xmlrpc_client_cleanup();
376 
377     clientParms1.transportparmsP = NULL;
378     xmlrpc_client_init2(&env, 0, "testprog", "1.0",
379                         &clientParms1, XMLRPC_CPSIZE(transportparmsP));
380     TEST_NO_FAULT(&env);
381     xmlrpc_client_cleanup();
382 
383     clientParms1.transportparmsP = &curlTransportParms1;
384 
385     /* Fails because we didn't include transportparm_size: */
386     xmlrpc_client_init2(&env, 0, "testprog", "1.0",
387                         &clientParms1, XMLRPC_CPSIZE(transportparmsP));
388     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
389 
390     clientParms1.transportparm_size = 0;
391     xmlrpc_client_init2(&env, 0, "testprog", "1.0",
392                         &clientParms1, XMLRPC_CPSIZE(transportparm_size));
393     TEST_NO_FAULT(&env);
394     xmlrpc_client_cleanup();
395 
396     curlTransportParms1.network_interface = "eth0";
397     clientParms1.transportparm_size = XMLRPC_CXPSIZE(network_interface);
398     xmlrpc_client_init2(&env, 0, "testprog", "1.0",
399                         &clientParms1, XMLRPC_CPSIZE(transportparm_size));
400     TEST_NO_FAULT(&env);
401     xmlrpc_client_cleanup();
402 
403     curlTransportParms1.no_ssl_verifypeer = 1;
404     curlTransportParms1.no_ssl_verifyhost = 1;
405     clientParms1.transportparm_size = XMLRPC_CXPSIZE(no_ssl_verifyhost);
406     xmlrpc_client_init2(&env, 0, "testprog", "1.0",
407                         &clientParms1, XMLRPC_CPSIZE(transportparm_size));
408     TEST_NO_FAULT(&env);
409     xmlrpc_client_cleanup();
410 
411     curlTransportParms1.user_agent = "testprog/1.0";
412     clientParms1.transportparm_size = XMLRPC_CXPSIZE(user_agent);
413     xmlrpc_client_init2(&env, 0, "testprog", "1.0",
414                         &clientParms1, XMLRPC_CPSIZE(transportparm_size));
415     TEST_NO_FAULT(&env);
416     xmlrpc_client_cleanup();
417 
418     xmlrpc_client_init(0, "testprog", "1.0");
419     TEST_NO_FAULT(&env);
420     xmlrpc_client_cleanup();
421 
422     xmlrpc_env_clean(&env);
423 }
424 
425 
426 
427 static void
testServerInfo(void)428 testServerInfo(void) {
429 
430     xmlrpc_env env;
431     xmlrpc_server_info * serverInfoP;
432     xmlrpc_server_info * serverInfo2P;
433 
434     printf("  Running serverInfo tests...\n");
435 
436     xmlrpc_env_init(&env);
437 
438     serverInfoP = xmlrpc_server_info_new(&env, "testurl");
439     TEST_NO_FAULT(&env);
440 
441     serverInfo2P = xmlrpc_server_info_copy(&env, serverInfoP);
442     TEST_NO_FAULT(&env);
443 
444     xmlrpc_server_info_free(serverInfo2P);
445 
446     /* Fails because we haven't set user/password yet: */
447     xmlrpc_server_info_allow_auth_basic(&env, serverInfoP);
448     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
449 
450     xmlrpc_server_info_set_basic_auth(&env, serverInfoP,
451                                       "username", "password");
452     TEST_NO_FAULT(&env);
453 
454     xmlrpc_server_info_set_user(&env, serverInfoP, "username", "password");
455     TEST_NO_FAULT(&env);
456 
457     xmlrpc_server_info_allow_auth_basic(&env, serverInfoP);
458     TEST_NO_FAULT(&env);
459 
460     xmlrpc_server_info_disallow_auth_basic(&env, serverInfoP);
461     TEST_NO_FAULT(&env);
462 
463     xmlrpc_server_info_allow_auth_digest(&env, serverInfoP);
464     TEST_NO_FAULT(&env);
465 
466     xmlrpc_server_info_disallow_auth_digest(&env, serverInfoP);
467     TEST_NO_FAULT(&env);
468 
469     xmlrpc_server_info_allow_auth_negotiate(&env, serverInfoP);
470     TEST_NO_FAULT(&env);
471 
472     xmlrpc_server_info_disallow_auth_negotiate(&env, serverInfoP);
473     TEST_NO_FAULT(&env);
474 
475     xmlrpc_server_info_allow_auth_ntlm(&env, serverInfoP);
476     TEST_NO_FAULT(&env);
477 
478     xmlrpc_server_info_disallow_auth_ntlm(&env, serverInfoP);
479     TEST_NO_FAULT(&env);
480 
481     xmlrpc_server_info_free(serverInfoP);
482 
483     xmlrpc_env_clean(&env);
484 }
485 
486 
487 
488 void
test_client(void)489 test_client(void) {
490 
491     printf("Running client tests.");
492 
493     testVersion();
494     testGlobalConst();
495     testCreateDestroy();
496     testInitCleanup();
497     printf("\n");
498     testServerInfo();
499     testSynchCall();
500 
501     printf("\n");
502     printf("Client tests done.\n");
503 }
504