00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #include <string.h>
00065 #include <stdlib.h>
00066 #include <unistd.h>
00067 #include <stdio.h>
00068
00069 #include "gwlib/gwlib.h"
00070 #include "gwlib/http.h"
00071 #include "gwlib/xmlrpc.h"
00072
00073 #define MAX_THREADS 1024
00074 #define MAX_IN_QUEUE 128
00075
00076 static Counter *counter = NULL;
00077 static long max_requests = 1;
00078
00079 static Octstr *auth_username = NULL;
00080 static Octstr *auth_password = NULL;
00081 static Octstr *ssl_client_certkey_file = NULL;
00082 static Octstr *extra_headers = NULL;
00083 static Octstr *content_file = NULL;
00084 static Octstr *url = NULL;
00085 static int file = 0;
00086 static XMLRPCDocument *msg;
00087
00088
00089 static void start_request(HTTPCaller *caller, List *reqh, long i)
00090 {
00091 long *id;
00092 int ret;
00093
00094 if ((i % 1000) == 0)
00095 info(0, "Starting fetch %ld", i);
00096 id = gw_malloc(sizeof(long));
00097 *id = i;
00098
00099
00100
00101
00102
00103 ret = xmlrpc_send_call(msg, caller, url, reqh, id);
00104
00105 debug("", 0, "Started request %ld.", *id);
00106
00107
00108
00109
00110
00111 }
00112
00113
00114 static int receive_reply(HTTPCaller *caller)
00115 {
00116 void *id;
00117 int ret;
00118 Octstr *final_url;
00119 List *replyh;
00120 Octstr *replyb;
00121 Octstr *output;
00122 XMLRPCDocument *xrdoc;
00123
00124
00125
00126
00127
00128 id = http_receive_result(caller, &ret, &final_url, &replyh, &replyb);
00129 octstr_destroy(final_url);
00130 if (id == NULL || ret == -1) {
00131 error(0, "http POST failed");
00132 gw_free(id);
00133 return -1;
00134 }
00135 debug("", 0, "Done with request %ld", *(long *) id);
00136 gw_free(id);
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 xrdoc = xmlrpc_parse_response(replyb);
00157 debug("", 0, "Parsed xmlrpc");
00158
00159 if ((xmlrpc_parse_status(xrdoc) != XMLRPC_COMPILE_OK) &&
00160 ((output = xmlrpc_parse_error(xrdoc)) != NULL)) {
00161
00162 error(0, "%s", octstr_get_cstr(output));
00163 octstr_destroy(output);
00164 return -1;
00165 } else {
00166
00167 if (xmlrpc_is_fault(xrdoc)) {
00168 Octstr *fstring = xmlrpc_get_faultstring(xrdoc);
00169 debug("xr", 0, "Got fault response with code:%ld and description: %s",
00170 xmlrpc_get_faultcode(xrdoc),
00171 octstr_get_cstr(fstring));
00172 octstr_destroy(fstring);
00173 http_destroy_headers(replyh);
00174 octstr_destroy(replyb);
00175 return -1;
00176 }
00177
00178
00179
00180
00181
00182 }
00183 http_destroy_headers(replyh);
00184 octstr_destroy(replyb);
00185 return 0;
00186 }
00187
00188
00189 static void client_thread(void *arg)
00190 {
00191 List *reqh;
00192 long i, succeeded, failed;
00193 HTTPCaller *caller;
00194 char buf[1024];
00195 long in_queue;
00196
00197 caller = arg;
00198 succeeded = 0;
00199 failed = 0;
00200 reqh = gwlist_create();
00201
00202 sprintf(buf, "%ld", (long) gwthread_self());
00203 http_header_add(reqh, "X-Thread", buf);
00204 if (auth_username != NULL && auth_password != NULL)
00205 http_add_basic_auth(reqh, auth_username, auth_password);
00206
00207 in_queue = 0;
00208
00209 for (;;) {
00210 while (in_queue < MAX_IN_QUEUE) {
00211 i = counter_increase(counter);
00212 if (i >= max_requests)
00213 goto receive_rest;
00214 start_request(caller, reqh, i);
00215 #if 1
00216 gwthread_sleep(0.1);
00217 #endif
00218 ++in_queue;
00219 }
00220 while (in_queue >= MAX_IN_QUEUE) {
00221 if (receive_reply(caller) == -1)
00222 ++failed;
00223 else
00224 ++succeeded;
00225 --in_queue;
00226 }
00227 }
00228
00229 receive_rest:
00230 while (in_queue > 0) {
00231 if (receive_reply(caller) == -1)
00232 ++failed;
00233 else
00234 ++succeeded;
00235 --in_queue;
00236 }
00237
00238 http_caller_destroy(caller);
00239 info(0, "This thread: %ld succeeded, %ld failed.", succeeded, failed);
00240 }
00241
00242
00243 static void help(void)
00244 {
00245 info(0, "Usage: test_xmlrpc [options] xml_source");
00246 info(0, "where options are:");
00247 info(0, "-u URL");
00248 info(0, " send XML-RPC source as POST HTTP request to URL");
00249 info(0, "-v number");
00250 info(0, " set log level for stderr logging");
00251 info(0, "-q");
00252 info(0, " don't print the body or headers of the HTTP response");
00253 info(0, "-r number");
00254 info(0, " make `number' requests, repeating URLs as necessary");
00255 info(0, "-p domain.name");
00256 info(0, " use `domain.name' as a proxy");
00257 info(0, "-P portnumber");
00258 info(0, " connect to proxy at port `portnumber'");
00259 info(0, "-S");
00260 info(0, " use HTTPS scheme to access SSL-enabled proxy server");
00261 info(0, "-e domain1:domain2:...");
00262 info(0, " set exception list for proxy use");
00263 info(0, "-s");
00264 info(0, " use HTTPS scheme to access SSL-enabled HTTP server");
00265 info(0, "-c ssl_client_cert_key_file");
00266 info(0, " use this file as the SSL certificate and key file");
00267 }
00268
00269
00270 int main(int argc, char **argv)
00271 {
00272 int i, opt, num_threads;
00273 Octstr *proxy;
00274 List *exceptions;
00275 long proxy_port;
00276 int proxy_ssl = 0;
00277 Octstr *proxy_username;
00278 Octstr *proxy_password;
00279 Octstr *exceptions_regex;
00280 char *p;
00281 long threads[MAX_THREADS];
00282 time_t start, end;
00283 double run_time;
00284 FILE *fp;
00285 Octstr *output, *xml_doc;
00286 int ssl = 0;
00287
00288 gwlib_init();
00289
00290 proxy = NULL;
00291 proxy_port = -1;
00292 exceptions = gwlist_create();
00293 proxy_username = NULL;
00294 proxy_password = NULL;
00295 exceptions_regex = NULL;
00296 num_threads = 0;
00297 file = 0;
00298 fp = NULL;
00299
00300 while ((opt = getopt(argc, argv, "hvr:t:p:u:P:Se:a:sc:")) != EOF) {
00301 switch (opt) {
00302 case 'h':
00303 help();
00304 exit(1);
00305 break;
00306
00307 case 'v':
00308 log_set_output_level(atoi(optarg));
00309 break;
00310
00311 case 'r':
00312 max_requests = atoi(optarg);
00313 break;
00314
00315 case 't':
00316 num_threads = atoi(optarg);
00317 if (num_threads > MAX_THREADS)
00318 num_threads = MAX_THREADS;
00319 break;
00320
00321 case 'p':
00322 proxy = octstr_create(optarg);
00323 break;
00324
00325 case 'u':
00326 url = octstr_create(optarg);
00327 break;
00328
00329 case 'P':
00330 proxy_port = atoi(optarg);
00331 break;
00332
00333 case 'S':
00334 proxy_ssl = 1;
00335 break;
00336
00337 case 'e':
00338 p = strtok(optarg, ":");
00339 while (p != NULL) {
00340 gwlist_append(exceptions, octstr_create(p));
00341 p = strtok(NULL, ":");
00342 }
00343 break;
00344
00345 case 'E':
00346 exceptions_regex = octstr_create(optarg);
00347 break;
00348
00349 case 'a':
00350 p = strtok(optarg, ":");
00351 if (p != NULL) {
00352 auth_username = octstr_create(p);
00353 p = strtok(NULL, "");
00354 if (p != NULL)
00355 auth_password = octstr_create(p);
00356 }
00357 break;
00358
00359 case 's':
00360 ssl = 1;
00361 break;
00362
00363 case 'c':
00364 octstr_destroy(ssl_client_certkey_file);
00365 ssl_client_certkey_file = octstr_create(optarg);
00366 break;
00367
00368 case '?':
00369 default:
00370 error(0, "Invalid option %c", opt);
00371 help();
00372 panic(0, "Stopping");
00373 break;
00374 }
00375 }
00376
00377 if (optind >= argc) {
00378 error(0, "Missing arguments");
00379 help();
00380 panic(0, "Stopping");
00381 }
00382
00383 #ifdef HAVE_LIBSSL
00384
00385
00386
00387
00388 if (ssl || proxy_ssl) {
00389 if (ssl_client_certkey_file != NULL) {
00390 use_global_client_certkey_file(ssl_client_certkey_file);
00391 } else {
00392 panic(0, "client certkey file need to be given!");
00393 }
00394 }
00395 #endif
00396
00397 if (proxy != NULL && proxy_port > 0) {
00398 http_use_proxy(proxy, proxy_port, proxy_ssl, exceptions,
00399 proxy_username, proxy_password,
00400 exceptions_regex);
00401 }
00402 octstr_destroy(proxy);
00403 octstr_destroy(proxy_username);
00404 octstr_destroy(proxy_password);
00405 octstr_destroy(exceptions_regex);
00406 gwlist_destroy(exceptions, octstr_destroy_item);
00407
00408 counter = counter_create();
00409
00410 xml_doc = octstr_read_file(argv[optind]);
00411 if (xml_doc == NULL)
00412 panic(0, "Cannot read the XML document");
00413
00414
00415
00416
00417 msg = xmlrpc_parse_call(xml_doc);
00418
00419 if ((xmlrpc_parse_status(msg) != XMLRPC_COMPILE_OK) &&
00420 ((output = xmlrpc_parse_error(msg)) != NULL)) {
00421
00422 error(0, "%s", octstr_get_cstr(output));
00423 octstr_destroy(output);
00424 }
00425
00426
00427
00428
00429 if (url != NULL) {
00430
00431 time(&start);
00432 if (num_threads == 0)
00433 client_thread(http_caller_create());
00434 else {
00435 for (i = 0; i < num_threads; ++i)
00436 threads[i] = gwthread_create(client_thread, http_caller_create());
00437 for (i = 0; i < num_threads; ++i)
00438 gwthread_join(threads[i]);
00439 }
00440 time(&end);
00441
00442
00443 run_time = difftime(end, start);
00444 info(0, "%ld requests in %f seconds, %f requests/s.",
00445 max_requests, run_time, max_requests / run_time);
00446
00447 octstr_destroy(url);
00448
00449 } else {
00450 output = xmlrpc_print_call(msg);
00451 if (output != NULL) {
00452 octstr_print(stderr, output);
00453 octstr_destroy(output);
00454 }
00455 }
00456
00457 counter_destroy(counter);
00458 octstr_destroy(auth_username);
00459 octstr_destroy(auth_password);
00460 octstr_destroy(ssl_client_certkey_file);
00461 octstr_destroy(extra_headers);
00462 octstr_destroy(content_file);
00463
00464
00465 xmlrpc_destroy_call(msg);
00466 octstr_destroy(xml_doc);
00467
00468 gwlib_shutdown();
00469
00470 return 0;
00471 }
00472
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.