70 #define MAX_THREADS 1024    71 #define MAX_IN_QUEUE 128   131         panic(0, 
"Cannot read a configuration file %s, exiting",
   144             error(0, 
"cannot set up SSL without client certkey file");
   299     return part_delimiter;
   313     return close_delimiter;
   325                         " boundary=asdlfkjiurwgasf; type=\"application/xml\"");
   361                   "--asdlfkjiurwgasf\r\n"   362                   "Content-Type: application/xml\r\n\r\n"   363                   "<?xml version=\"1.0\"?>"   364                   "<!DOCTYPE pap PUBLIC \"-//WAPFORUM//DTD PAP//EN\""   365                              " \"http://www.wapforum.org/DTD/pap_1.0.dtd\">"   367                         "<push-message push-id=\"9fjeo39jf084@pi.com\""   368                           " deliver-before-timestamp=\"2002-11-01T06:45:00Z\""   369                           " deliver-after-timestamp=\"2000-02-27T06:45:00Z\""   370                           " progress-notes-requested=\"false\">"   371                  "<address address-value=\"WAPPUSH=+358408676001/"   372                 "TYPE=PLMN@ppg.carrier.com\">"   374                              "<quality-of-service"   376                                " delivery-method=\"unconfirmed\""   377                                " network-required=\"true\""   379                                " bearer-required=\"true\""   381                              "</quality-of-service>"   384                   "--asdlfkjiurwgasf\r\n"   385                   "Content-Type: text/vnd.wap.si\r\n\r\n"   386                   "<?xml version=\"1.0\"?>"   387                   "<!DOCTYPE si PUBLIC \"-//WAPFORUM//DTD SI 1.0//EN\" "   388                     " \"http://www.wapforum.org/DTD/si.dtd\">"   390                       "<indication href=\"http://wap.iobox.fi\""   391                           " si-id=\"1@wiral.com\""   392                           " action=\"signal-high\""   393                           " created=\"1999-06-25T15:23:15Z\""   394                           " si-expires=\"2002-12-30T00:00:00Z\">"   395                           "Want to test a fetch?"   398                  "--asdlfkjiurwgasf--\r\n\r\n"   408         if ((wap_file_content = 
   410              panic(0, 
"Stopping");
   416                 panic(0, 
"non-hex chars in the content file, cannot continue");
   425         pap_content = 
octstr_format(
"%s", 
"Content-Type: application/xml");
   428         if ((pap_file_content = 
   430             panic(0, 
"Stopping");
   435         if (wap_content == NULL || pap_content == NULL)
   436             panic(0, 
"Cannot open the push content files");
   482        debug(
"test.ppg", 0, 
"we have push content");
   484        debug(
"test.ppg", 0, 
"and headers");
   488     id = gw_malloc(
sizeof(
long));
   491     debug(
"test.ppg", 0, 
"TEST_PPG: starting to push job %ld", i);
   494     debug(
"test.ppg", 0, 
"push done");
   525     if (
id == NULL || http_status == -1 || final_url == NULL) {
   526         error(0, 
"push failed, no reason found");
   531         debug(
"test.ppg", 0, 
"try number %d", tries);
   532         debug(
"test.ppg", 0, 
"authentication failure, get a challenge");
   537         trid = gw_malloc(
sizeof(
long));
   540                            push_content, 0, trid, NULL);
   541         debug(
"test.ppg ", 0, 
"TEST_PPG: doing response to %s", 
   548                                    &reply_headers, &auth_reply_body);
   550         if (trid == NULL || http_status == -1 || auth_url == NULL) {
   551             error(0, 
"unable to send authorisation, no reason found");
   555         debug(
"test.ppg", 0, 
"TEST_PPG: send authentication to %s, retry %ld", 
   564         error(0, 
"push failed, service not found");
   569         error(0, 
"push failed, service forbidden");
   577             error(0, 
"push failed, authorisation failure");
   581     debug(
"test.ppg", 0, 
"TEST_PPG: push %ld done: reply from,  %s", 
   587         debug(
"test.ppg", 0, 
"TEST_PPG: reply headers were");
   596         debug(
"test.ppg", 0, 
"TEST_PPG: reply body was");
   602         warning(0, 
"TEST_PPG: receive_push_reply: cannot compile pap message");
   608             debug(
"test.ppg", 0, 
"TEST_PPG: and type push response");
   611         case Bad_Message_Response:
   612             debug(
"test.ppg", 0, 
"TEST_PPG: and type bad message response");
   616             warning(0, 
"TEST_PPG: unknown event received from %s", 
   643     long succeeded, failed, in_queue;
   673     while (in_queue > 0) {
   682     info(0, 
"TEST_PPG: In thread %ld %ld succeeded, %ld failed", 
   688     info(0, 
"Usage: test_ppg [options] push_url [content_file pap_file]");
   690     info(0, 
"Usage: test_ppg [options] [conf_file]");
   691     info(0, 
"Implements push initiator for wap push. Push services are ");
   692     info(0, 
"located in push_url, push content in the file content file.");
   693     info(0, 
"File pap_file contains pap control document that controls");
   695     info(0, 
"If option -H is not used, command line has either three or one");
   696     info(0, 
"arguments:");
   697     info(0, 
"      a) the url of the push proxy gateway");
   698     info(0, 
"      b) a file containing the content to be pushed");
   699     info(0, 
"      c) a pap document controlling pushing");
   701     info(0, 
"      a) a test configuration file, containing all these");
   702     info(0, 
"Option -H cannot be used with a configuration file. If it is");
   703     info(0, 
"used, the push url is the only argument.");
   704     info(0, 
"Options are:");
   706     info(0, 
"print this info");
   707     info(0, 
"-c content qualifier");
   708     info(0, 
"Define content type of the push content. Wml, multipart, nil,"); 
   709     info(0, 
"scrap, sl, and si accepted. Si is default, nil (no content"); 
   710     info(0, 
" type at all) and scrap (random string) are used for debugging");
   711     info(0, 
"-a application id");
   712     info(0, 
"Define the client application that will handle the push. Any,"); 
   713     info(0, 
"ua, mms, nil and scrap accepted, default ua.");
   715     info(0, 
"if set, use numeric appid values instead of string ones. For");
   716     info(0, 
"instance, '4' instead of 'mms.ua'. Default is off.");
   717     info(0, 
"-s string");
   718     info(0, 
"supply a message header as a plain string. For instance"); 
   719     info(0, 
"-s x-wap-application-id:mms.ua equals -a ua. Default is");
   720     info(0, 
"x-wap-application-id:mms.ua.");
   721     info(0, 
"-I string");
   722     info(0, 
"supply an initiator header as a plain string. For instance"); 
   723     info(0, 
"-I x-wap-application-id:http://foo.bar equals -I http://foo.bar");
   724     info(0, 
"-S string");
   725     info(0, 
"supply an additional part header (for push content) as a string."); 
   726     info(0, 
"For instance, -S Content-Language: en. Default no additional part");
   729     info(0, 
"If true, send username/password in headers. Default false");
   730     info(0, 
"-v number");
   731     info(0, 
"    Set log level for stderr logging. Default 0 (debug)");
   733     info(0, 
"    Do not print debugging information");
   734     info(0, 
"Default: print it");
   735     info(0, 
"-r number");
   736     info(0, 
"    Make `number' requests. Default one request");
   737     info(0, 
"-i seconds");
   738     info(0, 
"    Wait 'seconds' seconds between pushes. Default: do not wait");
   739     info(0, 
"-e transfer encoding");
   740     info(0, 
"    use transfer encoding to send push contents.");
   741     info(0, 
"    Currently supported is base64.");
   742     info(0, 
"-k connection header");
   743     info(0, 
"Use the connection header. Keep-alive and close accepted,");
   744     info(0, 
"default close");
   746     info(0, 
"Use hardcoded MIME message, containing a pap control document.");
   747     info(0, 
"In addition, use hardcoded username/password in headers (if ");
   748     info(0, 
"flag -b is set, too");
   749     info(0, 
"Default: read components from files");
   751     info(0, 
"number of threads, maximum 1024, default 1");
   753     info(0, 
"accept binary push content. Default: off.");
   754     info(0, 
"Binary content consist of hex numbers. In addition, crs, lfs and");
   755     info(0, 
"spaces are accepted, and ignored.");
   757     info(0, 
"set delimiter to be used. Accepted values crlf and lf. Default crlf.");
   759     info(0, 
"If set, add a hardcoded epilogue (epilogue is to be discarded anyway).");
   760     info(0, 
"Default off.");
   762     info(0, 
"If set, add hardcoded preamble. Default is off.");
   764     info(0, 
"If set, add push header X-Kannel-DLR-Mask: value");
   765     info(0, 
"Default off.");
   767     info(0, 
"If set, add push header X-Kannel-DLR-Url: value");
   768     info(0, 
"Default off.");
   771 int main(
int argc, 
char **argv)
   785     while ((opt = 
getopt(argc, argv, 
"HhBbnEpv:qr:t:c:a:i:e:k:d:s:S:I:m:u:")) != EOF) {
   804             num_threads = atoi(
optarg);
   823                 error(0, 
"TEST_PPG: Content type not known");
   837         error(0, 
"TEST_PPG: Push application id not known");
   861             error(0, 
"TEST_PPG: unknown content transfer"    873             error(0, 
"TEST_PPG: Connection-header unacceptable");
   896                     error(0, 
"illegal d value");
   926             error(0, 
"TEST_PPG: Invalid option %c", opt);
   928             error(0, 
"Stopping");
   968         error(0, 
"No ppg address or config file, stopping");
   975             info(0, 
"a configuration file input assumed");
   987             error(0, 
"no pap control document, stopping");
   990            info(0, 
"an input without a configuration file assumed");
  1002     if (num_threads == 0)
  1005         for (i = 0; i < num_threads; ++i)
  1007         for (i = 0; i < num_threads; ++i)
  1011     run_time = difftime(end, 
start);
  1012     info(0, 
"TEST_PPG: %ld requests in %f seconds, %f requests per second",
 
static void add_part_header(Octstr *content_keader, Octstr **wap_content)
 
void error(int err, const char *fmt,...)
 
static Octstr * delimiter
 
void info(int err, const char *fmt,...)
 
static void push_thread(void *arg)
 
static Octstr * initiator_uri
 
void http_header_add(List *headers, char *name, char *contents)
 
void counter_destroy(Counter *counter)
 
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
 
static double wait_seconds
 
void gwthread_join(long thread)
 
static HTTPCaller * caller
 
static Octstr * connection
 
static void make_url(Octstr **url)
 
void http_add_basic_auth(List *headers, Octstr *username, Octstr *password)
 
#define cfg_get(grp, varname)
 
void octstr_binary_to_base64(Octstr *ostr)
 
static void add_content_transfer_encoding_type(Octstr *content_flag, Octstr *wap_content)
 
static Octstr * ssl_client_certkey_file
 
static Octstr * push_content_create(void)
 
void octstr_append_cstr(Octstr *ostr, const char *cstr)
 
int main(int argc, char **argv)
 
#define octstr_get_cstr(ostr)
 
unsigned long counter_increase(Counter *counter)
 
static void add_push_application_id(Octstr *appid_flag, Octstr **content, int use_string)
 
static Octstr * appid_flag
 
static void add_dlr_url(List **push_headers, Octstr *value)
 
static void read_test_ppg_config(Octstr *name)
 
Cfg * cfg_create(Octstr *filename)
 
static Octstr * content_transfer_encoding
 
void http_destroy_headers(List *headers)
 
static void add_dlr_mask(List **push_headers, Octstr *value)
 
static Octstr * content_header
 
int getopt(int argc, char **argv, char *opts)
 
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
 
Octstr * octstr_imm(const char *cstr)
 
Counter * counter_create(void)
 
void cfg_destroy(Cfg *cfg)
 
void * gwlist_extract_first(List *list)
 
void log_set_output_level(enum output_level level)
 
List * http_create_empty_headers(void)
 
#define octstr_dump(ostr, level,...)
 
static int receive_push_reply(HTTPCaller *caller)
 
void warning(int err, const char *fmt,...)
 
static void add_delimiter(Octstr **content)
 
Octstr * octstr_format(const char *fmt,...)
 
void octstr_destroy(Octstr *ostr)
 
#define gwthread_create(func, arg)
 
#define octstr_create(cstr)
 
static Octstr * content_flag
 
static Octstr * appid_string
 
void gwthread_sleep(double seconds)
 
static Octstr * content_file
 
int octstr_is_all_hex(Octstr *os)
 
#define http_receive_result(caller, status, final_url, headers, body)
 
Octstr * octstr_read_file(const char *filename)
 
static List * push_headers_create(size_t content_len)
 
long octstr_len(const Octstr *ostr)
 
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
 
void debug(const char *place, int err, const char *fmt,...)
 
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
 
int octstr_hex_to_binary(Octstr *ostr)
 
static void add_content_type(Octstr *content_flag, Octstr **content)
 
HTTPCaller * http_caller_create(void)
 
void octstr_format_append(Octstr *os, const char *fmt,...)
 
void gwlib_shutdown(void)
 
static Octstr * make_multipart_value(const char *boundary)
 
static Octstr * make_close_delimiter(Octstr *boundary)
 
static void start_push(HTTPCaller *caller, long i)
 
void http_caller_destroy(HTTPCaller *caller)
 
int parse_error(ParseContext *context)
 
static void add_connection_header(List **push_headers, Octstr *connection)
 
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
 
static void transfer_encode(Octstr *cte, Octstr *content)
 
static int use_content_header
 
int pap_compile(Octstr *pap_content, WAPEvent **e)
 
void http_header_dump(List *headers)
 
static Octstr * make_part_delimiter(Octstr *boundary)
 
void wap_event_destroy(WAPEvent *event)
 
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
 
void octstr_delete_matching(Octstr *haystack, Octstr *needle)