1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2001-2003, Ximian, Inc.
9 #include <libsoup/soup.h>
10 #include <libsoup/soup-date.h>
11 #include <libsoup/soup-md5-utils.h>
12 #include <libsoup/soup-xmlrpc-message.h>
13 #include <libsoup/soup-xmlrpc-response.h>
15 #include "apache-wrapper.h"
18 static const char *uri = "http://localhost:47524/xmlrpc-server.php";
21 static const char *const value_type[] = {
33 static SoupXmlrpcValue *
34 do_xmlrpc (SoupXmlrpcMessage *xmsg, SoupXmlrpcValueType type)
36 SoupMessage *msg = SOUP_MESSAGE (xmsg);
37 SoupXmlrpcResponse *response;
38 SoupXmlrpcValue *value;
41 soup_xmlrpc_message_persist (xmsg);
42 status = soup_session_send_message (session, msg);
45 printf ("\n%.*s\n%d %s\n%.*s\n",
46 msg->request.length, msg->request.body,
47 msg->status_code, msg->reason_phrase,
48 msg->response.length, msg->response.body);
51 if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
52 printf ("ERROR: %d %s\n", status, msg->reason_phrase);
56 response = soup_xmlrpc_message_parse_response (xmsg);
57 if (!response || soup_xmlrpc_response_is_fault (response)) {
59 printf ("ERROR: no response\n");
61 printf ("ERROR: fault\n");
65 value = soup_xmlrpc_response_get_value (response);
67 printf ("ERROR: no value?\n");
69 } else if (soup_xmlrpc_value_get_type (value) != type) {
70 printf ("ERROR: wrong value type; expected %s, got %s\n",
71 value_type[type], value_type[soup_xmlrpc_value_get_type (value)]);
81 SoupXmlrpcMessage *msg;
82 SoupXmlrpcValue *value;
86 printf ("sum (array of int -> int): ");
88 msg = soup_xmlrpc_message_new (uri);
89 soup_xmlrpc_message_start_call (msg, "sum");
90 soup_xmlrpc_message_start_param (msg);
91 soup_xmlrpc_message_start_array (msg);
92 for (i = sum = 0; i < 10; i++) {
95 printf ("%s%d", i == 0 ? "[" : ", ", val);
96 soup_xmlrpc_message_write_int (msg, val);
101 soup_xmlrpc_message_end_array (msg);
102 soup_xmlrpc_message_end_param (msg);
103 soup_xmlrpc_message_end_call (msg);
105 value = do_xmlrpc (msg, SOUP_XMLRPC_VALUE_TYPE_INT);
109 if (!soup_xmlrpc_value_get_int (value, &result)) {
110 printf ("wrong type?\n");
115 printf ("%ld: ", result);
116 printf ("%s\n", result == sum ? "OK!" : "WRONG!");
117 return result == sum;
121 test_countBools (void)
123 SoupXmlrpcMessage *msg;
124 SoupXmlrpcValue *value;
125 int i, trues, falses;
126 long ret_trues, ret_falses;
130 printf ("countBools (array of boolean -> struct of ints): ");
132 msg = soup_xmlrpc_message_new (uri);
133 soup_xmlrpc_message_start_call (msg, "countBools");
134 soup_xmlrpc_message_start_param (msg);
135 soup_xmlrpc_message_start_array (msg);
136 for (i = trues = falses = 0; i < 10; i++) {
137 val = rand () > (RAND_MAX / 2);
139 printf ("%s%c", i == 0 ? "[" : ", ", val ? 'T' : 'F');
140 soup_xmlrpc_message_write_boolean (msg, val);
148 soup_xmlrpc_message_end_array (msg);
149 soup_xmlrpc_message_end_param (msg);
150 soup_xmlrpc_message_end_call (msg);
152 value = do_xmlrpc (msg, SOUP_XMLRPC_VALUE_TYPE_STRUCT);
156 if (!soup_xmlrpc_value_get_struct (value, &result)) {
157 printf ("wrong type?\n");
161 if (!soup_xmlrpc_value_get_int (g_hash_table_lookup (result, "true"), &ret_trues)) {
162 printf ("NO 'true' value in response\n");
165 if (!soup_xmlrpc_value_get_int (g_hash_table_lookup (result, "false"), &ret_falses)) {
166 printf ("NO 'false' value in response\n");
171 printf ("{ true: %ld, false: %ld } ", ret_trues, ret_falses);
172 ok = (trues == ret_trues) && (falses == ret_falses);
173 printf ("%s\n", ok ? "OK!" : "WRONG!");
180 SoupXmlrpcMessage *msg;
181 SoupXmlrpcValue *value;
189 printf ("md5sum (base64 -> base64): ");
191 msg = soup_xmlrpc_message_new (uri);
192 soup_xmlrpc_message_start_call (msg, "md5sum");
193 soup_xmlrpc_message_start_param (msg);
194 for (i = 0; i < sizeof (data); i++)
195 data[i] = (char)(rand () & 0xFF);
196 soup_xmlrpc_message_write_base64 (msg, data, sizeof (data));
197 soup_xmlrpc_message_end_param (msg);
198 soup_xmlrpc_message_end_call (msg);
200 value = do_xmlrpc (msg, SOUP_XMLRPC_VALUE_TYPE_BASE64);
204 if (!soup_xmlrpc_value_get_base64 (value, &result)) {
205 printf ("wrong type?\n");
209 if (result->len != 16) {
210 printf ("result has WRONG length (%d)\n", result->len);
211 g_byte_array_free (result, TRUE);
215 soup_md5_init (&md5);
216 soup_md5_update (&md5, data, sizeof (data));
217 soup_md5_final (&md5, digest);
219 ok = (memcmp (digest, result->data, 16) == 0);
220 printf ("%s\n", ok ? "OK!" : "WRONG!");
221 g_byte_array_free (result, TRUE);
226 test_dateChange (void)
228 SoupXmlrpcMessage *msg;
229 SoupXmlrpcValue *value;
234 printf ("dateChange (struct of time and ints -> time): ");
236 msg = soup_xmlrpc_message_new (uri);
237 soup_xmlrpc_message_start_call (msg, "dateChange");
238 soup_xmlrpc_message_start_param (msg);
239 soup_xmlrpc_message_start_struct (msg);
241 soup_xmlrpc_message_start_member (msg, "date");
242 memset (&tm, 0, sizeof (tm));
243 tm.tm_year = 70 + (rand () % 50);
244 tm.tm_mon = rand () % 12;
245 tm.tm_mday = 1 + (rand () % 28);
246 tm.tm_hour = rand () % 24;
247 tm.tm_min = rand () % 60;
248 tm.tm_sec = rand () % 60;
249 when = soup_mktime_utc (&tm);
250 soup_xmlrpc_message_write_datetime (msg, when);
251 soup_xmlrpc_message_end_member (msg);
254 strftime (timestamp, sizeof (timestamp),
255 "%Y-%m-%dT%H:%M:%S", &tm);
256 printf ("{ date: %s", timestamp);
260 tm.tm_year = 70 + (rand () % 50);
262 printf (", tm_year: %d", tm.tm_year);
263 soup_xmlrpc_message_start_member (msg, "tm_year");
264 soup_xmlrpc_message_write_int (msg, tm.tm_year);
265 soup_xmlrpc_message_end_member (msg);
268 tm.tm_mon = rand () % 12;
270 printf (", tm_mon: %d", tm.tm_mon);
271 soup_xmlrpc_message_start_member (msg, "tm_mon");
272 soup_xmlrpc_message_write_int (msg, tm.tm_mon);
273 soup_xmlrpc_message_end_member (msg);
276 tm.tm_mday = 1 + (rand () % 28);
278 printf (", tm_mday: %d", tm.tm_mday);
279 soup_xmlrpc_message_start_member (msg, "tm_mday");
280 soup_xmlrpc_message_write_int (msg, tm.tm_mday);
281 soup_xmlrpc_message_end_member (msg);
284 tm.tm_hour = rand () % 24;
286 printf (", tm_hour: %d", tm.tm_hour);
287 soup_xmlrpc_message_start_member (msg, "tm_hour");
288 soup_xmlrpc_message_write_int (msg, tm.tm_hour);
289 soup_xmlrpc_message_end_member (msg);
292 tm.tm_min = rand () % 60;
294 printf (", tm_min: %d", tm.tm_min);
295 soup_xmlrpc_message_start_member (msg, "tm_min");
296 soup_xmlrpc_message_write_int (msg, tm.tm_min);
297 soup_xmlrpc_message_end_member (msg);
300 tm.tm_sec = rand () % 60;
302 printf (", tm_sec: %d", tm.tm_sec);
303 soup_xmlrpc_message_start_member (msg, "tm_sec");
304 soup_xmlrpc_message_write_int (msg, tm.tm_sec);
305 soup_xmlrpc_message_end_member (msg);
307 when = soup_mktime_utc (&tm);
312 soup_xmlrpc_message_end_struct (msg);
313 soup_xmlrpc_message_end_param (msg);
314 soup_xmlrpc_message_end_call (msg);
316 value = do_xmlrpc (msg, SOUP_XMLRPC_VALUE_TYPE_DATETIME);
320 if (!soup_xmlrpc_value_get_datetime (value, &result)) {
321 printf ("wrong type?\n");
326 memset (&tm, 0, sizeof (tm));
327 soup_gmtime (&result, &tm);
328 strftime (timestamp, sizeof (timestamp),
329 "%Y-%m-%dT%H:%M:%S", &tm);
330 printf ("%s: ", timestamp);
333 printf ("%s\n", (when == result) ? "OK!" : "WRONG!");
334 return (when == result);
337 static const char *const echo_strings[] = {
341 "& so is <this>"
343 #define N_ECHO_STRINGS G_N_ELEMENTS (echo_strings)
348 SoupXmlrpcMessage *msg;
349 SoupXmlrpcValue *value, *elt;
350 SoupXmlrpcValueArrayIterator *iter;
354 printf ("echo (array of string -> array of string): ");
356 msg = soup_xmlrpc_message_new (uri);
357 soup_xmlrpc_message_start_call (msg, "echo");
358 soup_xmlrpc_message_start_param (msg);
359 soup_xmlrpc_message_start_array (msg);
360 for (i = 0; i < N_ECHO_STRINGS; i++) {
362 printf ("%s\"%s\"", i == 0 ? "[" : ", ", echo_strings[i]);
363 soup_xmlrpc_message_write_string (msg, echo_strings[i]);
367 soup_xmlrpc_message_end_array (msg);
368 soup_xmlrpc_message_end_param (msg);
369 soup_xmlrpc_message_end_call (msg);
371 value = do_xmlrpc (msg, SOUP_XMLRPC_VALUE_TYPE_ARRAY);
375 if (!soup_xmlrpc_value_array_get_iterator (value, &iter)) {
376 printf ("wrong type?\n");
381 if (!soup_xmlrpc_value_array_iterator_get_value (iter, &elt)) {
382 printf (" WRONG! Can't get result element %d\n", i + 1);
385 if (!soup_xmlrpc_value_get_string (elt, &echo)) {
386 printf (" WRONG! Result element %d is not a string", i + 1);
390 printf ("%s\"%s\"", i == 0 ? "[" : ", ", echo);
391 if (strcmp (echo_strings[i], echo) != 0) {
392 printf (" WRONG! Mismatch at %d\n", i + 1);
396 iter = soup_xmlrpc_value_array_iterator_next (iter);
402 printf ("%s\n", i == N_ECHO_STRINGS ? "OK!" : "WRONG! Too few results");
403 return i == N_ECHO_STRINGS;
409 fprintf (stderr, "Usage: xmlrpc-test [-d] [-d]\n");
414 main (int argc, char **argv)
419 g_thread_init (NULL);
421 while ((opt = getopt (argc, argv, "d")) != -1) {
435 if (!apache_init ()) {
436 fprintf (stderr, "Could not start apache\n");
440 session = soup_session_sync_new ();
444 if (!test_countBools ())
448 if (!test_dateChange ())
455 printf ("\n%d errors\n", errors);