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
00065
00066
00067
00068
00069
00070 #define MAX_THREADS 1024
00071 #define MAX_IN_QUEUE 128
00072
00073 #include <unistd.h>
00074 #include <stdlib.h>
00075 #include <string.h>
00076
00077 #include "gwlib/gwlib.h"
00078 #include "gw/wap_push_pap_compiler.h"
00079
00080 static long max_pushes = 1;
00081 static int verbose = 1,
00082 use_hardcoded = 0,
00083 num_urls = 0,
00084 use_headers = 0,
00085 use_config = 0,
00086 accept_binary = 0,
00087 use_numeric = 0,
00088 use_string = 0,
00089 use_content_header = 0,
00090 add_epilogue = 0,
00091 add_preamble = 0,
00092 use_dlr_mask = 0,
00093 use_dlr_url = 0;
00094 static double wait_seconds = 0.0;
00095 static Counter *counter = NULL;
00096 static char **push_data = NULL;
00097 static char *boundary = NULL;
00098 static Octstr *content_flag = NULL;
00099 static Octstr *appid_flag = NULL;
00100 static Octstr *appid_string = NULL;
00101 static Octstr *content_header = NULL;
00102 static Octstr *content_transfer_encoding = NULL;
00103 static Octstr *connection = NULL;
00104 static Octstr *delimiter = NULL;
00105 static Octstr *initiator_uri = NULL;
00106 static Octstr *dlr_mask = NULL;
00107 static Octstr *dlr_url = NULL;
00108
00109 enum { SSL_CONNECTION_OFF = 0,
00110 DEFAULT_NUMBER_OF_RELOGS = 2};
00111
00112
00113
00114
00115 static int pi_ssl = SSL_CONNECTION_OFF;
00116 static long retries = DEFAULT_NUMBER_OF_RELOGS;
00117 static Octstr *ssl_client_certkey_file = NULL;
00118 static Octstr *push_url = NULL;
00119 static Octstr *pap_file = NULL;
00120 static Octstr *content_file = NULL;
00121 static Octstr *username = NULL;
00122 static Octstr *password = NULL;
00123
00124 static void read_test_ppg_config(Octstr *name)
00125 {
00126 Cfg *cfg;
00127 CfgGroup *grp;
00128
00129 cfg = cfg_create(name);
00130 if (cfg_read(cfg) == -1)
00131 panic(0, "Cannot read a configuration file %s, exiting",
00132 octstr_get_cstr(name));
00133 cfg_dump(cfg);
00134 grp = cfg_get_single_group(cfg, octstr_imm("test-ppg"));
00135 cfg_get_integer(&retries, grp, octstr_imm("retries"));
00136 cfg_get_bool(&pi_ssl, grp, octstr_imm("pi-ssl"));
00137 #ifdef HAVE_LIBSSL
00138 if (pi_ssl) {
00139 ssl_client_certkey_file = cfg_get(grp,
00140 octstr_imm("ssl-client-certkey-file"));
00141 if (ssl_client_certkey_file != NULL) {
00142 use_global_client_certkey_file(ssl_client_certkey_file);
00143 } else {
00144 error(0, "cannot set up SSL without client certkey file");
00145 exit(1);
00146 }
00147 }
00148 #endif
00149
00150 grp = cfg_get_single_group(cfg, octstr_imm("configuration"));
00151 push_url = cfg_get(grp, octstr_imm("push-url"));
00152 pap_file = cfg_get(grp, octstr_imm("pap-file"));
00153 content_file = cfg_get(grp, octstr_imm("content-file"));
00154 if (!use_hardcoded) {
00155 username = cfg_get(grp, octstr_imm("username"));
00156 password = cfg_get(grp, octstr_imm("password"));
00157 }
00158
00159 cfg_destroy(cfg);
00160 }
00161
00162 static void add_delimiter(Octstr **content)
00163 {
00164 if (octstr_compare(delimiter, octstr_imm("crlf")) == 0) {
00165 octstr_format_append(*content, "%c", '\r');
00166 }
00167
00168 octstr_format_append(*content, "%c", '\n');
00169 }
00170
00171 static void add_push_application_id(List **push_headers, Octstr *appid_flag,
00172 int use_string)
00173 {
00174 if (use_string) {
00175 gwlist_append(*push_headers, appid_string);
00176 return;
00177 }
00178
00179 if (octstr_compare(appid_flag, octstr_imm("any")) == 0) {
00180 if (!use_numeric)
00181 http_header_add(*push_headers, "X-WAP-Application-Id",
00182 "http://www.wiral.com:*");
00183 else
00184 http_header_add(*push_headers, "X-WAP-Application-Id", "0");
00185 } else if (octstr_compare(appid_flag, octstr_imm("ua")) == 0) {
00186 if (!use_numeric)
00187 http_header_add(*push_headers, "X-WAP-Application-Id",
00188 "http://www.wiral.com:wml.ua");
00189 else
00190 http_header_add(*push_headers, "X-WAP-Application-Id", "2");
00191 } else if (octstr_compare(appid_flag, octstr_imm("mms")) == 0) {
00192 if (!use_numeric)
00193 http_header_add(*push_headers, "X-WAP-Application-Id",
00194 "mms.ua");
00195 else
00196 http_header_add(*push_headers, "X-WAP-Application-Id", "4");
00197 } else if (octstr_compare(appid_flag, octstr_imm("scrap")) == 0) {
00198 if (!use_numeric)
00199 http_header_add(*push_headers, "X-WAP-Application-Id",
00200 "no appid at all");
00201 else
00202 http_header_add(*push_headers, "X-WAP-Application-Id",
00203 "this is not a numeric header");
00204 }
00205 }
00206
00207 static void add_dlr_mask(List **push_headers, Octstr *value)
00208 {
00209 http_header_add(*push_headers, "X-Kannel-DLR-Mask",
00210 octstr_get_cstr(value));
00211 }
00212
00213 static void add_dlr_url(List **push_headers, Octstr *value)
00214 {
00215 http_header_add(*push_headers, "X-Kannel-DLR-Url",
00216 octstr_get_cstr(value));
00217 }
00218
00219 static void add_part_header(Octstr *content_keader, Octstr **wap_content)
00220 {
00221 if (use_content_header) {
00222 octstr_append(*wap_content, content_header);
00223 }
00224
00225 add_delimiter(wap_content);
00226 }
00227
00228
00229 static void add_content_type(Octstr *content_flag, Octstr **wap_content)
00230 {
00231 if (octstr_compare(content_flag, octstr_imm("wml")) == 0)
00232 *wap_content = octstr_format("%s",
00233 "Content-Type: text/vnd.wap.wml");
00234 else if (octstr_compare(content_flag, octstr_imm("si")) == 0)
00235 *wap_content = octstr_format("%s",
00236 "Content-Type: text/vnd.wap.si");
00237 else if (octstr_compare(content_flag, octstr_imm("sl")) == 0)
00238 *wap_content = octstr_format("%s",
00239 "Content-Type: text/vnd.wap.sl");
00240 else if (octstr_compare(content_flag, octstr_imm("multipart")) == 0)
00241 *wap_content = octstr_format("%s",
00242 "Content-Type: multipart/related; boundary=fsahgwruijkfldsa");
00243 else if (octstr_compare(content_flag, octstr_imm("mms")) == 0)
00244 *wap_content = octstr_format("%s",
00245 "Content-Type: application/vnd.wap.mms-message");
00246 else if (octstr_compare(content_flag, octstr_imm("scrap")) == 0)
00247 *wap_content = octstr_format("%s", "no type at all");
00248 else if (octstr_compare(content_flag, octstr_imm("nil")) == 0)
00249 *wap_content = octstr_create("");
00250 if (octstr_len(*wap_content) > 0)
00251 add_delimiter(wap_content);
00252 }
00253
00254 static void add_content_transfer_encoding_type(Octstr *content_flag,
00255 Octstr *wap_content)
00256 {
00257 if (!content_flag)
00258 return;
00259
00260 if (octstr_compare(content_flag, octstr_imm("base64")) == 0)
00261 octstr_append_cstr(wap_content, "Content-transfer-encoding: base64");
00262
00263 add_delimiter(&wap_content);
00264 }
00265
00266 static void add_connection_header(List **push_headers, Octstr *connection)
00267 {
00268 if (!connection)
00269 return;
00270
00271 if (octstr_compare(connection, octstr_imm("close")) == 0)
00272 http_header_add(*push_headers, "Connection", "close");
00273 else if (octstr_compare(connection, octstr_imm("keep-alive")) == 0)
00274 http_header_add(*push_headers, "Connection", "keep-alive");
00275 }
00276
00277 static void transfer_encode (Octstr *cte, Octstr *content)
00278 {
00279 if (!cte)
00280 return;
00281
00282 if (octstr_compare(cte, octstr_imm("base64")) == 0) {
00283 octstr_binary_to_base64(content);
00284 }
00285 }
00286
00287
00288
00289
00290
00291 static Octstr *make_multipart_value(const char *boundary)
00292 {
00293 Octstr *hos;
00294
00295 hos = octstr_format("%s", "multipart/related; boundary=");
00296 octstr_append(hos, octstr_imm(boundary));
00297 octstr_append(hos, octstr_imm("; type=\"application/xml\""));
00298
00299 return hos;
00300 }
00301
00302 static Octstr *make_part_delimiter(Octstr *boundary)
00303 {
00304 Octstr *part_delimiter;
00305
00306 part_delimiter = octstr_create("");
00307 add_delimiter(&part_delimiter);
00308 octstr_format_append(part_delimiter, "%s", "--");
00309 octstr_append(part_delimiter, boundary);
00310 add_delimiter(&part_delimiter);
00311
00312 return part_delimiter;
00313 }
00314
00315 static Octstr *make_close_delimiter(Octstr *boundary)
00316 {
00317 Octstr *close_delimiter;
00318
00319 close_delimiter = octstr_create("");
00320 add_delimiter(&close_delimiter);
00321 octstr_format_append(close_delimiter, "%s", "--");
00322 octstr_append(close_delimiter, boundary);
00323 octstr_format_append(close_delimiter, "%s", "--");
00324
00325
00326 return close_delimiter;
00327 }
00328
00329 static List *push_headers_create(size_t content_len)
00330 {
00331 List *push_headers;
00332 Octstr *mos;
00333
00334 mos = NULL;
00335 push_headers = http_create_empty_headers();
00336 if (use_hardcoded)
00337 http_header_add(push_headers, "Content-Type", "multipart/related;"
00338 " boundary=asdlfkjiurwgasf; type=\"application/xml\"");
00339 else
00340 http_header_add(push_headers, "Content-Type",
00341 octstr_get_cstr(mos = make_multipart_value(boundary)));
00342 if (use_headers)
00343 http_add_basic_auth(push_headers, username, password);
00344 add_push_application_id(&push_headers, appid_flag, use_string);
00345 add_connection_header(&push_headers, connection);
00346 if (use_dlr_mask)
00347 add_dlr_mask(&push_headers, dlr_mask);
00348 if (use_dlr_url)
00349 add_dlr_url(&push_headers, dlr_url);
00350
00351 octstr_destroy(mos);
00352
00353
00354 if (initiator_uri)
00355 http_header_add(push_headers, "X-Wap-Initiator-URI",
00356 octstr_get_cstr(initiator_uri));
00357
00358 return push_headers;
00359 }
00360
00361 static Octstr *push_content_create(void)
00362 {
00363 Octstr *push_content,
00364 *wap_content;
00365 Octstr *wap_file_content,
00366 *pap_content,
00367 *pap_file_content,
00368 *bpos,
00369 *bcos;
00370
00371 wap_content = NULL;
00372 push_content = NULL;
00373 if (use_hardcoded) {
00374 push_content = octstr_create("\r\n\r\n"
00375 "--asdlfkjiurwgasf\r\n"
00376 "Content-Type: application/xml\r\n\r\n"
00377 "<?xml version=\"1.0\"?>"
00378 "<!DOCTYPE pap PUBLIC \"-//WAPFORUM//DTD PAP//EN\""
00379 " \"http://www.wapforum.org/DTD/pap_1.0.dtd\">"
00380 "<pap>"
00381 "<push-message push-id=\"9fjeo39jf084@pi.com\""
00382 " deliver-before-timestamp=\"2002-11-01T06:45:00Z\""
00383 " deliver-after-timestamp=\"2000-02-27T06:45:00Z\""
00384 " progress-notes-requested=\"false\">"
00385 "<address address-value=\"WAPPUSH=+358408676001/"
00386 "TYPE=PLMN@ppg.carrier.com\">"
00387 "</address>"
00388 "<quality-of-service"
00389 " priority=\"low\""
00390 " delivery-method=\"unconfirmed\""
00391 " network-required=\"true\""
00392 " network=\"GSM\""
00393 " bearer-required=\"true\""
00394 " bearer=\"SMS\">"
00395 "</quality-of-service>"
00396 "</push-message>"
00397 "</pap>\r\n\r\n"
00398 "--asdlfkjiurwgasf\r\n"
00399 "Content-Type: text/vnd.wap.si\r\n\r\n"
00400 "<?xml version=\"1.0\"?>"
00401 "<!DOCTYPE si PUBLIC \"-//WAPFORUM//DTD SI 1.0//EN\" "
00402 " \"http://www.wapforum.org/DTD/si.dtd\">"
00403 "<si>"
00404 "<indication href=\"http://wap.iobox.fi\""
00405 " si-id=\"1@wiral.com\""
00406 " action=\"signal-high\""
00407 " created=\"1999-06-25T15:23:15Z\""
00408 " si-expires=\"2002-12-30T00:00:00Z\">"
00409 "Want to test a fetch?"
00410 "</indication>"
00411 "</si>\r\n\r\n"
00412 "--asdlfkjiurwgasf--\r\n\r\n"
00413 "");
00414 } else {
00415 add_content_type(content_flag, &wap_content);
00416 add_content_transfer_encoding_type(content_transfer_encoding,
00417 wap_content);
00418 add_part_header(content_header, &wap_content);
00419
00420
00421 if ((wap_file_content =
00422 octstr_read_file(octstr_get_cstr(content_file))) == NULL)
00423 panic(0, "Stopping");
00424 if (accept_binary) {
00425 octstr_delete_matching(wap_file_content, octstr_imm(" "));
00426 octstr_delete_matching(wap_file_content, octstr_imm("\n"));
00427 octstr_delete_matching(wap_file_content, octstr_imm("\r"));
00428 if (!octstr_is_all_hex(wap_file_content))
00429 panic(0, "non-hex chars in the content file, cannot continue");
00430 octstr_hex_to_binary(wap_file_content);
00431 }
00432
00433 transfer_encode(content_transfer_encoding, wap_file_content);
00434 octstr_append(wap_content, wap_file_content);
00435 octstr_destroy(wap_file_content);
00436
00437
00438 pap_content = octstr_format("%s", "Content-Type: application/xml");
00439 add_delimiter(&pap_content);
00440 add_delimiter(&pap_content);
00441 if ((pap_file_content =
00442 octstr_read_file(octstr_get_cstr(pap_file))) == NULL)
00443 panic(0, "Stopping");
00444
00445 octstr_append(pap_content, pap_file_content);
00446 octstr_destroy(pap_file_content);
00447
00448 if (wap_content == NULL || pap_content == NULL)
00449 panic(0, "Cannot open the push content files");
00450
00451 push_content = octstr_create("");
00452 if (add_preamble)
00453 octstr_append(push_content, octstr_imm("the parser should discard this"));
00454 octstr_append(push_content,
00455 bpos = make_part_delimiter(octstr_imm(boundary)));
00456
00457
00458 octstr_append(push_content, pap_content);
00459 octstr_append(push_content, bpos);
00460 octstr_destroy(bpos);
00461 octstr_append(push_content, wap_content);
00462 octstr_append(push_content,
00463 bcos = make_close_delimiter(octstr_imm(boundary)));
00464 if (add_epilogue) {
00465 octstr_append(push_content, octstr_imm("\r\n"));
00466 octstr_append(push_content, octstr_imm("the parser should discard this"));
00467 }
00468 octstr_destroy(bcos);
00469 octstr_destroy(pap_content);
00470 octstr_destroy(wap_content);
00471 }
00472
00473 return push_content;
00474 }
00475
00476 static void make_url(Octstr **url)
00477 {
00478 if (use_config && !use_headers) {
00479 octstr_append(*url, octstr_imm("?username="));
00480 octstr_append(*url, username ? username : octstr_imm("default"));
00481 octstr_append(*url, octstr_imm("&password="));
00482 octstr_append(*url, password ? password: octstr_imm("default"));
00483 }
00484 }
00485
00486 static void start_push(HTTPCaller *caller, long i)
00487 {
00488 List *push_headers;
00489 Octstr *push_content;
00490 long *id;
00491
00492 push_content = push_content_create();
00493 push_headers = push_headers_create(octstr_len(push_content));
00494 if (verbose) {
00495 debug("test.ppg", 0, "we have push content");
00496 octstr_dump(push_content, 0);
00497 debug("test.ppg", 0, "and headers");
00498 http_header_dump(push_headers);
00499 }
00500
00501 id = gw_malloc(sizeof(long));
00502 *id = i;
00503 make_url(&push_url);
00504 debug("test.ppg", 0, "TEST_PPG: starting to push job %ld", i);
00505 http_start_request(caller, HTTP_METHOD_POST, push_url, push_headers,
00506 push_content, 0, id, ssl_client_certkey_file);
00507 debug("test.ppg", 0, "push done");
00508 octstr_destroy(push_content);
00509 http_destroy_headers(push_headers);
00510 }
00511
00512
00513
00514
00515
00516 static int receive_push_reply(HTTPCaller *caller)
00517 {
00518 void *id;
00519 long *trid;
00520 int http_status,
00521 tries;
00522 List *reply_headers;
00523 Octstr *final_url,
00524 *auth_url,
00525 *reply_body,
00526 *os,
00527 *push_content,
00528 *auth_reply_body;
00529 WAPEvent *e;
00530 List *retry_headers;
00531
00532 http_status = HTTP_UNAUTHORIZED;
00533 tries = 0;
00534
00535 id = http_receive_result(caller, &http_status, &final_url, &reply_headers,
00536 &reply_body);
00537
00538 if (id == NULL || http_status == -1 || final_url == NULL) {
00539 error(0, "push failed, no reason found");
00540 goto push_failed;
00541 }
00542
00543 while (use_headers && http_status == HTTP_UNAUTHORIZED && tries < retries) {
00544 debug("test.ppg", 0, "try number %d", tries);
00545 debug("test.ppg", 0, "authentication failure, get a challenge");
00546 http_destroy_headers(reply_headers);
00547 push_content = push_content_create();
00548 retry_headers = push_headers_create(octstr_len(push_content));
00549 http_add_basic_auth(retry_headers, username, password);
00550 trid = gw_malloc(sizeof(long));
00551 *trid = tries;
00552 http_start_request(caller, HTTP_METHOD_POST, final_url, retry_headers,
00553 push_content, 0, trid, NULL);
00554 debug("test.ppg ", 0, "TEST_PPG: doing response to %s",
00555 octstr_get_cstr(final_url));
00556
00557 octstr_destroy(push_content);
00558 http_destroy_headers(retry_headers);
00559
00560 trid = http_receive_result(caller, &http_status, &auth_url,
00561 &reply_headers, &auth_reply_body);
00562
00563 if (trid == NULL || http_status == -1 || auth_url == NULL) {
00564 error(0, "unable to send authorisation, no reason found");
00565 goto push_failed;
00566 }
00567
00568 debug("test.ppg", 0, "TEST_PPG: send authentication to %s, retry %ld",
00569 octstr_get_cstr(auth_url), *(long *) trid);
00570 gw_free(trid);
00571 octstr_destroy(auth_reply_body);
00572 octstr_destroy(auth_url);
00573 ++tries;
00574 }
00575
00576 if (http_status == HTTP_NOT_FOUND) {
00577 error(0, "push failed, service not found");
00578 goto push_failed;
00579 }
00580
00581 if (http_status == HTTP_FORBIDDEN) {
00582 error(0, "push failed, service forbidden");
00583 goto push_failed;
00584 }
00585
00586 if (http_status == HTTP_UNAUTHORIZED) {
00587 if (use_headers)
00588 error(0, "tried %ld times, stopping", retries);
00589 else
00590 error(0, "push failed, authorisation failure");
00591 goto push_failed;
00592 }
00593
00594 debug("test.ppg", 0, "TEST_PPG: push %ld done: reply from, %s",
00595 *(long *) id, octstr_get_cstr(final_url));
00596 gw_free(id);
00597 octstr_destroy(final_url);
00598
00599 if (verbose)
00600 debug("test.ppg", 0, "TEST_PPG: reply headers were");
00601
00602 while ((os = gwlist_extract_first(reply_headers)) != NULL) {
00603 if (verbose)
00604 octstr_dump(os, 0);
00605 octstr_destroy(os);
00606 }
00607
00608 if (verbose) {
00609 debug("test.ppg", 0, "TEST_PPG: reply body was");
00610 octstr_dump(reply_body, 0);
00611 }
00612
00613 e = NULL;
00614 if (pap_compile(reply_body, &e) < 0) {
00615 warning(0, "TEST_PPG: receive_push_reply: cannot compile pap message");
00616 goto parse_error;
00617 }
00618
00619 switch (e->type) {
00620 case Push_Response:
00621 debug("test.ppg", 0, "TEST_PPG: and type push response");
00622 break;
00623
00624 case Bad_Message_Response:
00625 debug("test.ppg", 0, "TEST_PPG: and type bad message response");
00626 break;
00627
00628 default:
00629 warning(0, "TEST_PPG: unknown event received from %s",
00630 octstr_get_cstr(final_url));
00631 break;
00632 }
00633
00634 octstr_destroy(reply_body);
00635 wap_event_destroy(e);
00636 http_destroy_headers(reply_headers);
00637 return 0;
00638
00639 push_failed:
00640 gw_free(id);
00641 octstr_destroy(final_url);
00642 octstr_destroy(reply_body);
00643 http_destroy_headers(reply_headers);
00644 return -1;
00645
00646 parse_error:
00647 octstr_destroy(reply_body);
00648 http_destroy_headers(reply_headers);
00649 wap_event_destroy(e);
00650 return -1;
00651 }
00652
00653 static void push_thread(void *arg)
00654 {
00655 HTTPCaller *caller;
00656 long succeeded, failed, in_queue;
00657 unsigned long i;
00658
00659 caller = arg;
00660 succeeded = 0;
00661 failed = 0;
00662 in_queue = 0;
00663 i = 0;
00664
00665 for (;;) {
00666 while (in_queue < MAX_IN_QUEUE) {
00667 i = counter_increase(counter);
00668 if (i >= max_pushes)
00669 goto receive_rest;
00670 start_push(caller, i);
00671 if (wait_seconds > 0)
00672 gwthread_sleep(wait_seconds);
00673 ++in_queue;
00674 }
00675
00676 while (in_queue >= MAX_IN_QUEUE) {
00677 if (receive_push_reply(caller) == -1)
00678 ++failed;
00679 else
00680 ++succeeded;
00681 --in_queue;
00682 }
00683 }
00684
00685 receive_rest:
00686 while (in_queue > 0) {
00687 if (receive_push_reply(caller) == -1)
00688 ++failed;
00689 else
00690 ++succeeded;
00691 --in_queue;
00692 }
00693
00694 http_caller_destroy(caller);
00695 info(0, "TEST_PPG: In thread %ld %ld succeeded, %ld failed",
00696 (long) gwthread_self(), succeeded, failed);
00697 }
00698
00699 static void help(void)
00700 {
00701 info(0, "Usage: test_ppg [options] push_url [content_file pap_file]");
00702 info(0, " or");
00703 info(0, "Usage: test_ppg [options] [conf_file]");
00704 info(0, "Implements push initiator for wap push. Push services are ");
00705 info(0, "located in push_url, push content in the file content file.");
00706 info(0, "File pap_file contains pap control document that controls");
00707 info(0, "pushing");
00708 info(0, "If option -H is not used, command line has either three or one");
00709 info(0, "arguments:");
00710 info(0, " a) the url of the push proxy gateway");
00711 info(0, " b) a file containing the content to be pushed");
00712 info(0, " c) a pap document controlling pushing");
00713 info(0, " or");
00714 info(0, " a) a test configuration file, containing all these");
00715 info(0, "Option -H cannot be used with a configuration file. If it is");
00716 info(0, "used, the push url is the only argument.");
00717 info(0, "Options are:");
00718 info(0, "-h");
00719 info(0, "print this info");
00720 info(0, "-c content qualifier");
00721 info(0, "Define content type of the push content. Wml, multipart, nil,");
00722 info(0, "scrap, sl, and si accepted. Si is default, nil (no content");
00723 info(0, " type at all) and scrap (random string) are used for debugging");
00724 info(0, "-a application id");
00725 info(0, "Define the client application that will handle the push. Any,");
00726 info(0, "ua, mms, nil and scrap accepted, default ua.");
00727 info(0, "-n");
00728 info(0, "if set, use numeric appid values instead of string ones. For");
00729 info(0, "instance, '4' instead of 'mms.ua'. Default is off.");
00730 info(0, "-s string");
00731 info(0, "supply a message header as a plain string. For instance");
00732 info(0, "-s x-wap-application-id:mms.ua equals -a ua. Default is");
00733 info(0, "x-wap-application-id:mms.ua.");
00734 info(0, "-I string");
00735 info(0, "supply an initiator header as a plain string. For instance");
00736 info(0, "-I x-wap-application-id:http://foo.bar equals -I http://foo.bar");
00737 info(0, "-S string");
00738 info(0, "supply an additional part header (for push content) as a string.");
00739 info(0, "For instance, -S Content-Language: en. Default no additional part");
00740 info(0, "headers.");
00741 info(0, "-b");
00742 info(0, "If true, send username/password in headers. Default false");
00743 info(0, "-v number");
00744 info(0, " Set log level for stderr logging. Default 0 (debug)");
00745 info(0, "-q");
00746 info(0, " Do not print debugging information");
00747 info(0, "Default: print it");
00748 info(0, "-r number");
00749 info(0, " Make `number' requests. Default one request");
00750 info(0, "-i seconds");
00751 info(0, " Wait 'seconds' seconds between pushes. Default: do not wait");
00752 info(0, "-e transfer encoding");
00753 info(0, " use transfer encoding to send push contents.");
00754 info(0, " Currently supported is base64.");
00755 info(0, "-k connection header");
00756 info(0, "Use the connection header. Keep-alive and close accepted,");
00757 info(0, "default close");
00758 info(0, "-H");
00759 info(0, "Use hardcoded MIME message, containing a pap control document.");
00760 info(0, "In addition, use hardcoded username/password in headers (if ");
00761 info(0, "flag -b is set, too");
00762 info(0, "Default: read components from files");
00763 info(0, "-t");
00764 info(0, "number of threads, maximum 1024, default 1");
00765 info(0, "-B");
00766 info(0, "accept binary push content. Default: off.");
00767 info(0, "Binary content consist of hex numbers. In addition, crs, lfs and");
00768 info(0, "spaces are accepted, and ignored.");
00769 info(0, "-d value");
00770 info(0, "set delimiter to be used. Accepted values crlf and lf. Default crlf.");
00771 info(0, "-E");
00772 info(0, "If set, add a hardcoded epilogue (epilogue is to be discarded anyway).");
00773 info(0, "Default off.");
00774 info(0, "-p");
00775 info(0, "If set, add hardcoded preamble. Default is off.");
00776 info(0, "-m value");
00777 info(0, "If set, add push header X-Kannel-DLR-Mask: value");
00778 info(0, "Default off.");
00779 info(0, "-u value");
00780 info(0, "If set, add push header X-Kannel-DLR-Url: value");
00781 info(0, "Default off.");
00782 }
00783
00784 int main(int argc, char **argv)
00785 {
00786 int opt,
00787 num_threads;
00788 time_t start,
00789 end;
00790 double run_time;
00791 long threads[MAX_THREADS];
00792 long i;
00793 Octstr *fos;
00794
00795 gwlib_init();
00796 num_threads = 1;
00797
00798 while ((opt = getopt(argc, argv, "HhBbnEpv:qr:t:c:a:i:e:k:d:s:S:I:m:u:")) != EOF) {
00799 switch(opt) {
00800 case 'v':
00801 log_set_output_level(atoi(optarg));
00802 break;
00803
00804 case 'q':
00805 verbose = 0;
00806 break;
00807
00808 case 'r':
00809 max_pushes = atoi(optarg);
00810 break;
00811
00812 case 'i':
00813 wait_seconds = atof(optarg);
00814 break;
00815
00816 case 't':
00817 num_threads = atoi(optarg);
00818 if (num_threads > MAX_THREADS)
00819 num_threads = MAX_THREADS;
00820 break;
00821
00822 case 'H':
00823 use_hardcoded = 1;
00824 break;
00825
00826 case 'c':
00827 content_flag = octstr_create(optarg);
00828 if (octstr_compare(content_flag, octstr_imm("wml")) != 0 &&
00829 octstr_compare(content_flag, octstr_imm("si")) != 0 &&
00830 octstr_compare(content_flag, octstr_imm("sl")) != 0 &&
00831 octstr_compare(content_flag, octstr_imm("nil")) != 0 &&
00832 octstr_compare(content_flag, octstr_imm("mms")) != 0 &&
00833 octstr_compare(content_flag, octstr_imm("scrap")) != 0 &&
00834 octstr_compare(content_flag, octstr_imm("multipart")) != 0) {
00835 octstr_destroy(content_flag);
00836 error(0, "TEST_PPG: Content type not known");
00837 help();
00838 exit(1);
00839 }
00840 break;
00841
00842 case 'a':
00843 appid_flag = octstr_create(optarg);
00844 if (octstr_compare(appid_flag, octstr_imm("any")) != 0 &&
00845 octstr_compare(appid_flag, octstr_imm("ua")) != 0 &&
00846 octstr_compare(appid_flag, octstr_imm("mms")) != 0 &&
00847 octstr_compare(appid_flag, octstr_imm("nil")) != 0 &&
00848 octstr_compare(appid_flag, octstr_imm("scrap")) != 0) {
00849 octstr_destroy(appid_flag);
00850 error(0, "TEST_PPG: Push application id not known");
00851 help();
00852 exit(1);
00853 }
00854 break;
00855
00856 case 'n':
00857 use_numeric = 1;
00858 break;
00859
00860 case 's':
00861 appid_string = octstr_create(optarg);
00862 use_string = 1;
00863 break;
00864
00865 case 'S':
00866 content_header = octstr_create(optarg);
00867 use_content_header = 1;
00868 break;
00869
00870 case 'e':
00871 content_transfer_encoding = octstr_create(optarg);
00872 if (octstr_compare(content_transfer_encoding, octstr_imm("base64")) != 0) {
00873 octstr_destroy(content_transfer_encoding);
00874 error(0, "TEST_PPG: unknown content transfer"
00875 " encoding \"%s\"", octstr_get_cstr(content_transfer_encoding));
00876 help();
00877 exit(1);
00878 }
00879 break;
00880
00881 case 'k':
00882 connection = octstr_create(optarg);
00883 if (octstr_compare(connection, octstr_imm("close")) != 0 &&
00884 octstr_compare(connection, octstr_imm("keep-alive")) != 0) {
00885 octstr_destroy(connection);
00886 error(0, "TEST_PPG: Connection-header unacceptable");
00887 help();
00888 exit(1);
00889 }
00890 break;
00891
00892 case 'h':
00893 help();
00894 exit(1);
00895
00896 case 'b':
00897 use_headers = 1;
00898 break;
00899
00900 case 'B':
00901 accept_binary = 1;
00902 break;
00903
00904 case 'd':
00905 delimiter = octstr_create(optarg);
00906 if (octstr_compare(delimiter, octstr_imm("crlf")) != 0 &&
00907 octstr_compare(delimiter, octstr_imm("lf")) != 0) {
00908 octstr_destroy(delimiter);
00909 error(0, "illegal d value");
00910 help();
00911 exit(1);
00912 }
00913 break;
00914
00915 case 'E':
00916 add_epilogue = 1;
00917 break;
00918
00919 case 'p':
00920 add_preamble = 1;
00921 break;
00922
00923 case 'I':
00924 initiator_uri = octstr_create(optarg);
00925 break;
00926
00927 case 'm':
00928 use_dlr_mask = 1;
00929 dlr_mask = octstr_create(optarg);
00930 break;
00931
00932 case 'u':
00933 use_dlr_url = 1;
00934 dlr_url = octstr_create(optarg);
00935 break;
00936
00937 case '?':
00938 default:
00939 error(0, "TEST_PPG: Invalid option %c", opt);
00940 help();
00941 error(0, "Stopping");
00942 exit(1);
00943 }
00944 }
00945
00946 if (optind == argc) {
00947 help();
00948 exit(1);
00949 }
00950
00951 push_data = argv + optind;
00952 num_urls = argc - optind;
00953
00954 if (content_flag == NULL)
00955 content_flag = octstr_imm("si");
00956
00957 if (appid_flag == NULL)
00958 appid_flag = octstr_imm("ua");
00959
00960 if (appid_string == NULL)
00961 appid_string = octstr_imm("x-wap-application-id: wml.ua");
00962
00963 if (content_header == NULL)
00964 use_content_header = 0;
00965
00966 if (dlr_mask == NULL)
00967 use_dlr_mask = 0;
00968
00969 if (dlr_url == NULL)
00970 use_dlr_url = 0;
00971
00972 if (delimiter == NULL)
00973 delimiter = octstr_imm("crlf");
00974
00975 if (use_hardcoded) {
00976 username = octstr_imm("troo");
00977 password = octstr_imm("far");
00978 }
00979
00980 if (push_data[0] == NULL) {
00981 error(0, "No ppg address or config file, stopping");
00982 exit(1);
00983 }
00984
00985 use_config = 0;
00986 if (!use_hardcoded) {
00987 if (push_data[1] == NULL) {
00988 info(0, "a configuration file input assumed");
00989 read_test_ppg_config(fos = octstr_format("%s", push_data[0]));
00990 octstr_destroy(fos);
00991 use_config = 1;
00992 }
00993 }
00994
00995 if (!use_config)
00996 push_url = octstr_format("%s", push_data[0]);
00997
00998 if (!use_hardcoded && !use_config && push_data[1] != NULL) {
00999 if (push_data[2] == NULL) {
01000 error(0, "no pap control document, stopping");
01001 exit(1);
01002 } else {
01003 info(0, "an input without a configuration file assumed");
01004 content_file = octstr_create(push_data[1]);
01005 pap_file = octstr_create(push_data[2]);
01006 debug("test.ppg", 0, "using %s as a content file", push_data[1]);
01007 debug("test.ppg", 0, "using %s as a control file", push_data[2]);
01008 }
01009 }
01010
01011 boundary = "asdlfkjiurwghasf";
01012 counter = counter_create();
01013
01014 time(&start);
01015 if (num_threads == 0)
01016 push_thread(http_caller_create());
01017 else {
01018 for (i = 0; i < num_threads; ++i)
01019 threads[i] = gwthread_create(push_thread, http_caller_create());
01020 for (i = 0; i < num_threads; ++i)
01021 gwthread_join(threads[i]);
01022 }
01023 time(&end);
01024 run_time = difftime(end, start);
01025 info(0, "TEST_PPG: %ld requests in %f seconds, %f requests per second",
01026 max_pushes, run_time, max_pushes / run_time);
01027
01028 octstr_destroy(content_flag);
01029 octstr_destroy(appid_flag);
01030 octstr_destroy(content_header);
01031 octstr_destroy(content_file);
01032 octstr_destroy(pap_file);
01033 octstr_destroy(ssl_client_certkey_file);
01034 octstr_destroy(username);
01035 octstr_destroy(password);
01036 octstr_destroy(push_url);
01037 octstr_destroy(connection);
01038 octstr_destroy(delimiter);
01039 octstr_destroy(dlr_mask);
01040 octstr_destroy(dlr_url);
01041 counter_destroy(counter);
01042 gwlib_shutdown();
01043
01044 exit(0);
01045 }
01046
01047
01048
01049
01050
01051
01052
01053
01054
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.