Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
test_http.c File Reference
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include "gwlib/gwlib.h"
#include "gwlib/http.h"

Go to the source code of this file.

Macros

#define MAX_THREADS   1024
 
#define MAX_IN_QUEUE   128
 

Functions

static Octstrpost_content_create (void)
 
static void start_request (HTTPCaller *caller, List *reqh, long i)
 
static int receive_reply (HTTPCaller *caller)
 
static void client_thread (void *arg)
 
static void split_headers (Octstr *headers, List **split)
 
static void help (void)
 
int main (int argc, char **argv)
 

Variables

static long max_requests = 1
 
static double interval = 0
 
static int method = HTTP_METHOD_GET
 
static char ** urls = NULL
 
static int num_urls = 0
 
static int verbose = 1
 
static Octstrauth_username = NULL
 
static Octstrauth_password = NULL
 
static Octstrmsg_text = NULL
 
static Octstrssl_client_certkey_file = NULL
 
static Octstrextra_headers = NULL
 
static Octstrcontent_file = NULL
 
static Octstrmethod_name = NULL
 
static int file = 0
 
static Listsplit = NULL
 
static int follow_redirect = 1
 

Macro Definition Documentation

#define MAX_IN_QUEUE   128

Definition at line 72 of file test_http.c.

#define MAX_THREADS   1024

Definition at line 71 of file test_http.c.

Referenced by main().

Function Documentation

static void client_thread ( void *  arg)
static

Definition at line 194 of file test_http.c.

References caller, counter, counter_create(), counter_destroy(), counter_increase(), gwlist_create, gwthread_self(), gwthread_sleep(), http_add_basic_auth(), http_caller_destroy(), http_destroy_headers(), http_header_add(), info(), interval, max_requests, receive_reply(), and start_request().

Referenced by main().

195 {
196  List *reqh;
197  unsigned long i;
198  long succeeded, failed;
200  char buf[1024];
201  long in_queue;
202  Counter *counter = NULL;
203 
204  caller = arg;
205  succeeded = 0;
206  failed = 0;
207  reqh = gwlist_create();
208  sprintf(buf, "%ld", (long) gwthread_self());
209  http_header_add(reqh, "X-Thread", buf);
210  if (auth_username != NULL && auth_password != NULL)
212 
213  in_queue = 0;
214  counter = counter_create();
215 
216  for (;;) {
217  i = counter_increase(counter);
218  if (i >= max_requests)
219  goto receive_rest;
220  start_request(caller, reqh, i);
221  if (interval > 0)
223  ++in_queue;
224  if (receive_reply(caller) == -1)
225  ++failed;
226  else
227  ++succeeded;
228  --in_queue;
229  }
230 
231 receive_rest:
232  while (in_queue > 0) {
233  if (receive_reply(caller) == -1)
234  ++failed;
235  else
236  ++succeeded;
237  --in_queue;
238  }
239 
240  counter_destroy(counter);
241  http_destroy_headers(reqh);
242  http_caller_destroy(caller);
243  info(0, "This thread: %ld succeeded, %ld failed.", succeeded, failed);
244 }
void info(int err, const char *fmt,...)
Definition: log.c:636
long gwthread_self(void)
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
void counter_destroy(Counter *counter)
Definition: counter.c:110
static Octstr * auth_password
Definition: test_http.c:81
static HTTPCaller * caller
Definition: smsbox.c:429
void http_add_basic_auth(List *headers, Octstr *username, Octstr *password)
Definition: http.c:3492
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
void http_destroy_headers(List *headers)
Definition: http.c:2856
Counter * counter_create(void)
Definition: counter.c:94
static Octstr * auth_username
Definition: test_http.c:80
static double interval
Definition: test_http.c:75
static int receive_reply(HTTPCaller *caller)
Definition: test_http.c:149
void gwthread_sleep(double seconds)
#define gwlist_create()
Definition: list.h:136
void http_caller_destroy(HTTPCaller *caller)
Definition: http.c:907
static void start_request(HTTPCaller *caller, List *reqh, long i)
Definition: test_http.c:104
static long max_requests
Definition: test_http.c:74
Definition: list.c:102
static Counter * counter
static void help ( void  )
static

Definition at line 271 of file test_http.c.

References info().

Referenced by main().

272 {
273  info(0, "Usage: test_http [options] url ...");
274  info(0, "where options are:");
275  info(0, "-v number");
276  info(0, " set log level for stderr logging");
277  info(0, "-q");
278  info(0, " don't print the body or headers of the HTTP response");
279  info(0, "-r number");
280  info(0, " make `number' requests, repeating URLs as necessary");
281  info(0, "-t number");
282  info(0, " run `number' threads, that make -r `number' requests");
283  info(0, "-i interval");
284  info(0, " make one request in `interval' seconds");
285  info(0, "-p domain.name");
286  info(0, " use `domain.name' as a proxy");
287  info(0, "-P portnumber");
288  info(0, " connect to proxy at port `portnumber'");
289  info(0, "-S");
290  info(0, " use HTTPS scheme to access SSL-enabled proxy server");
291  info(0, "-e domain1:domain2:...");
292  info(0, " set exception list for proxy use");
293  info(0, "-u filename");
294  info(0, " read request's &text= string from file 'filename'. It is");
295  info(0, " url encoded before it is added to the request");
296  info(0, "-H filename");
297  info(0, " read HTTP headers from file 'filename' and add them to");
298  info(0, " the request for url 'url'");
299  info(0, "-B filename");
300  info(0, " read content from file 'filename' and send it as body");
301  info(0, " of a POST method request (default: GET if no -B is set)");
302  info(0, "-m method");
303  info(0, " use a specific HTTP method for request to server");
304  info(0, "-s");
305  info(0, " use HTTPS scheme to access SSL-enabled HTTP server");
306  info(0, "-c ssl_client_cert_key_file");
307  info(0, " use this file as the SSL certificate and key file");
308  info(0, "-C ssl_ca_file");
309  info(0, " use this file as the SSL certificate authority");
310  info(0, "-f");
311  info(0, " don't follow redirects");
312 }
void info(int err, const char *fmt,...)
Definition: log.c:636
int main ( int  argc,
char **  argv 
)

Definition at line 314 of file test_http.c.

References client_thread(), debug(), error(), file, follow_redirect, getopt(), gwlib_init(), gwlib_shutdown(), gwlist_append(), gwlist_create, gwlist_destroy(), gwthread_create, gwthread_join(), help(), http_caller_create(), http_name2method(), http_use_proxy(), info(), interval, log_set_output_level(), max_requests, MAX_THREADS, method, num_urls, octstr_create, octstr_destroy(), octstr_destroy_item(), octstr_dump, octstr_read_file(), octstr_url_encode(), optarg, optind, panic, proxy_password, proxy_port, proxy_ssl, proxy_username, split_headers(), ssl, start, threads, urls, and verbose.

315 {
316  int i, opt, num_threads;
317  Octstr *proxy;
318  List *exceptions;
319  long proxy_port;
320  int proxy_ssl = 0;
323  Octstr *exceptions_regex;
324  char *p;
325  long threads[MAX_THREADS];
326  time_t start, end;
327  double run_time;
328  FILE *fp;
329  int ssl = 0;
330  Octstr *ca_file;
331 
332  gwlib_init();
333 
334  proxy = NULL;
335  proxy_port = -1;
336  exceptions = gwlist_create();
337  proxy_username = NULL;
338  proxy_password = NULL;
339  exceptions_regex = NULL;
340  num_threads = 1;
341  file = 0;
342  fp = NULL;
343 
344  while ((opt = getopt(argc, argv, "hv:qr:p:P:Se:t:i:a:u:sc:H:B:m:fC:")) != EOF) {
345  switch (opt) {
346  case 'v':
348  break;
349 
350  case 'q':
351  verbose = 0;
352  break;
353 
354  case 'r':
355  max_requests = atoi(optarg);
356  break;
357 
358  case 't':
359  num_threads = atoi(optarg);
360  if (num_threads > MAX_THREADS)
361  num_threads = MAX_THREADS;
362  break;
363 
364  case 'i':
365  interval = atof(optarg);
366  break;
367 
368  case 'u':
369  file = 1;
370  fp = fopen(optarg, "a");
371  if (fp == NULL)
372  panic(0, "Cannot open message text file %s", optarg);
374  if (msg_text == NULL)
375  panic(0, "Cannot read message text");
376  debug("", 0, "message text is");
377  octstr_dump(msg_text, 0);
379  fclose(fp);
380  break;
381 
382  case 'h':
383  help();
384  exit(0);
385 
386  case 'p':
387  proxy = octstr_create(optarg);
388  break;
389 
390  case 'P':
391  proxy_port = atoi(optarg);
392  break;
393 
394  case 'S':
395  proxy_ssl = 1;
396  break;
397 
398  case 'e':
399  p = strtok(optarg, ":");
400  while (p != NULL) {
401  gwlist_append(exceptions, octstr_create(p));
402  p = strtok(NULL, ":");
403  }
404  break;
405 
406  case 'E':
407  exceptions_regex = octstr_create(optarg);
408  break;
409 
410  case 'a':
411  p = strtok(optarg, ":");
412  if (p != NULL) {
414  p = strtok(NULL, "");
415  if (p != NULL)
417  }
418  break;
419 
420  case 's':
421  ssl = 1;
422  break;
423 
424  case 'c':
427  break;
428 
429  case 'H':
430  fp = fopen(optarg, "a");
431  if (fp == NULL)
432  panic(0, "Cannot open header text file %s", optarg);
434  if (extra_headers == NULL)
435  panic(0, "Cannot read header text");
436  debug("", 0, "headers are");
439  fclose(fp);
440  break;
441 
442  case 'B':
444  break;
445 
446  case 'm':
448  break;
449 
450  case 'f':
451  follow_redirect = 0;
452  break;
453 
454  case 'C':
455  ca_file = octstr_create(optarg);
456  conn_use_global_trusted_ca_file(ca_file);
457  octstr_destroy(ca_file);
458  break;
459 
460  case '?':
461  default:
462  error(0, "Invalid option %c", opt);
463  help();
464  panic(0, "Stopping.");
465  }
466  }
467 
468  if (optind == argc) {
469  help();
470  exit(0);
471  }
472 
473 #ifdef HAVE_LIBSSL
474  /*
475  * check if we are doing a SSL-enabled client version here
476  * load the required cert and key file
477  */
478  if (ssl || proxy_ssl) {
479  if (ssl_client_certkey_file != NULL) {
480  conn_use_global_client_certkey_file(ssl_client_certkey_file);
481  } else {
482  panic(0, "client certkey file need to be given!");
483  }
484  }
485 #endif
486 
487  if (method_name != NULL) {
489  }
490 
491  if (proxy != NULL && proxy_port > 0) {
492  http_use_proxy(proxy, proxy_port, proxy_ssl, exceptions,
493  proxy_username, proxy_password, exceptions_regex);
494  }
495  octstr_destroy(proxy);
496  octstr_destroy(proxy_username);
497  octstr_destroy(proxy_password);
498  octstr_destroy(exceptions_regex);
499  gwlist_destroy(exceptions, octstr_destroy_item);
500 
501  urls = argv + optind;
502  num_urls = argc - optind;
503 
504  time(&start);
505  if (num_threads == 1)
507  else {
508  for (i = 0; i < num_threads; ++i)
510  for (i = 0; i < num_threads; ++i)
511  gwthread_join(threads[i]);
512  }
513  time(&end);
514 
515  run_time = difftime(end, start);
516  info(0, "%ld requests in %f seconds, %f requests/s.",
517  (max_requests * num_threads), run_time, (max_requests * num_threads) / run_time);
518 
525 
526  gwlib_shutdown();
527 
528  return 0;
529 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
int threads
Definition: fakewap.c:239
static Octstr * method_name
Definition: test_http.c:86
int ssl
static void split_headers(Octstr *headers, List **split)
Definition: test_http.c:247
void gwlist_append(List *list, void *item)
Definition: list.c:179
static Octstr * auth_password
Definition: test_http.c:81
void gwthread_join(long thread)
static void client_thread(void *arg)
Definition: test_http.c:194
static Octstr * extra_headers
Definition: test_http.c:84
int optind
Definition: attgetopt.c:80
static Octstr * msg_text
Definition: test_http.c:82
int http_name2method(Octstr *method)
Definition: http.c:3633
static int proxy_ssl
Definition: http.c:202
static Octstr * ssl_client_certkey_file
Definition: test_http.c:83
static int follow_redirect
Definition: test_http.c:89
int getopt(int argc, char **argv, char *opts)
Definition: attgetopt.c:84
static Octstr * auth_username
Definition: test_http.c:80
void log_set_output_level(enum output_level level)
Definition: log.c:217
static Octstr * content_file
Definition: test_http.c:85
static void help(void)
Definition: test_http.c:271
static double interval
Definition: test_http.c:75
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
static int proxy_port
Definition: http.c:201
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static Octstr * proxy_username
Definition: http.c:203
#define gwthread_create(func, arg)
Definition: gwthread.h:90
static int method
Definition: test_http.c:76
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
static int verbose
Definition: test_http.c:79
Octstr * octstr_read_file(const char *filename)
Definition: octstr.c:1546
static int num_urls
Definition: test_http.c:78
Definition: octstr.c:118
void http_use_proxy(Octstr *hostname, int port, int ssl, List *exceptions, Octstr *username, Octstr *password, Octstr *exceptions_regex)
Definition: http.c:268
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
char * optarg
Definition: attgetopt.c:82
#define panic
Definition: log.h:87
static List * split
Definition: test_http.c:88
HTTPCaller * http_caller_create(void)
Definition: http.c:897
void gwlib_shutdown(void)
Definition: gwlib.c:94
#define gwlist_create()
Definition: list.h:136
void gwlib_init(void)
Definition: gwlib.c:78
static int file
Definition: test_http.c:87
#define MAX_THREADS
Definition: test_http.c:71
static char ** urls
Definition: test_http.c:77
static long max_requests
Definition: test_http.c:74
Definition: list.c:102
static int start
void octstr_url_encode(Octstr *ostr)
Definition: octstr.c:1671
static Octstr * proxy_password
Definition: http.c:204
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static Octstr* post_content_create ( void  )
static

Definition at line 92 of file test_http.c.

References content, debug(), octstr_dump, octstr_get_cstr, octstr_read_file(), and panic.

Referenced by start_request().

93 {
94  Octstr *content;
95 
96  if ((content = octstr_read_file(octstr_get_cstr(content_file))) == NULL)
97  panic(0, "Cannot read content text");
98  debug("", 0, "body content is");
99  octstr_dump(content, 0);
100 
101  return content;
102 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static Octstr * content_file
Definition: test_http.c:85
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
Octstr * octstr_read_file(const char *filename)
Definition: octstr.c:1546
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
#define panic
Definition: log.h:87
static Octstr * content
Definition: mtbatch.c:87
static int receive_reply ( HTTPCaller caller)
static

Definition at line 149 of file test_http.c.

References charset, debug(), error(), gwlist_destroy(), gwlist_extract_first(), http_header_get_content_type(), http_receive_result, octstr_destroy(), octstr_dump, octstr_get_cstr, type, and verbose.

Referenced by client_thread().

150 {
151  void *id;
152  int ret;
153  Octstr *final_url;
154  List *replyh;
155  Octstr *replyb;
156  Octstr *type;
157  Octstr *charset;
158  Octstr *os;
159 
160  id = http_receive_result(caller, &ret, &final_url, &replyh, &replyb);
161  octstr_destroy(final_url);
162  if (id == NULL || ret == -1) {
163  error(0, "http GET failed");
164  gw_free(id);
165  return -1;
166  }
167  debug("", 0, "Done with request %ld", *(long *) id);
168  gw_free(id);
169 
170  http_header_get_content_type(replyh, &type, &charset);
171  debug("", 0, "Content-type is <%s>, charset is <%s>",
172  octstr_get_cstr(type),
173  octstr_get_cstr(charset));
174  octstr_destroy(type);
175  octstr_destroy(charset);
176  if (verbose)
177  debug("", 0, "Reply headers:");
178  while ((os = gwlist_extract_first(replyh)) != NULL) {
179  if (verbose)
180  octstr_dump(os, 1);
181  octstr_destroy(os);
182  }
183  gwlist_destroy(replyh, NULL);
184  if (verbose) {
185  debug("", 0, "Reply body:");
186  octstr_dump(replyb, 1);
187  }
188  octstr_destroy(replyb);
189 
190  return 0;
191 }
void error(int err, const char *fmt,...)
Definition: log.c:612
int type
Definition: smsc_cimd2.c:215
void http_header_get_content_type(List *headers, Octstr **type, Octstr **charset)
Definition: http.c:3202
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * charset
Definition: test_ota.c:68
void * gwlist_extract_first(List *list)
Definition: list.c:305
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static int verbose
Definition: test_http.c:79
#define http_receive_result(caller, status, final_url, headers, body)
Definition: http.h:383
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static void split_headers ( Octstr headers,
List **  split 
)
static

Definition at line 247 of file test_http.c.

References gwlist_append(), gwlist_create, octstr_copy, octstr_get_char(), octstr_len(), and start.

Referenced by main().

248 {
249  long start;
250  long pos;
251 
252  *split = gwlist_create();
253  start = 0;
254  for (pos = 0; pos < octstr_len(headers); pos++) {
255  if (octstr_get_char(headers, pos) == '\n') {
256  Octstr *line;
257 
258  if (pos == start) {
259  /* Skip empty lines */
260  start = pos + 1;
261  continue;
262  }
263  line = octstr_copy(headers, start, pos - start);
264  start = pos + 1;
265  gwlist_append(*split, line);
266  }
267  }
268 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
#define gwlist_create()
Definition: list.h:136
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
static int start
static void start_request ( HTTPCaller caller,
List reqh,
long  i 
)
static

Definition at line 104 of file test_http.c.

References debug(), file, follow_redirect, http_header_combine(), HTTP_METHOD_POST, http_start_request(), info(), method, num_urls, octstr_append(), octstr_create, octstr_destroy(), octstr_dump, octstr_imm(), octstr_url_decode(), post_content_create(), url, and urls.

Referenced by client_thread().

105 {
106  Octstr *url, *content = NULL;
107  long *id;
108 
109  if ((i % 1000) == 0)
110  info(0, "Starting fetch %ld", i);
111  id = gw_malloc(sizeof(long));
112  *id = i;
113  url = octstr_create(urls[i % num_urls]);
114  if (file) {
115  octstr_append(url, octstr_imm("&text="));
116  octstr_append(url, msg_text);
117  }
118 
119  /* add the extra headers that have been read from the file */
120  if (split != NULL)
121  http_header_combine(reqh, split);
122 
123  /*
124  * if a body content file has been specified, then
125  * we assume this should be a POST
126  */
127  if (content_file != NULL) {
128  content = post_content_create();
130  }
131 
132  /*
133  * if this is a POST request then pass the required content as body to
134  * the HTTP server, otherwise skip the body, the arguments will be
135  * urlencoded in the URL itself.
136  */
137  http_start_request(caller, method,
138  url, reqh, content, follow_redirect, id, ssl_client_certkey_file);
139 
140  debug("", 0, "Started request %ld with url:", *id);
141  octstr_url_decode(url);
142  octstr_dump(url, 0);
143  octstr_destroy(url);
145  octstr_destroy(content);
146 }
void info(int err, const char *fmt,...)
Definition: log.c:636
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
void http_header_combine(List *old_headers, List *new_headers)
Definition: http.c:3045
int octstr_url_decode(Octstr *ostr)
Definition: octstr.c:1744
static Octstr * msg_text
Definition: test_http.c:82
static Octstr * ssl_client_certkey_file
Definition: test_http.c:83
static int follow_redirect
Definition: test_http.c:89
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
Definition: http.c:1745
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
static Octstr * content_file
Definition: test_http.c:85
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static int method
Definition: test_http.c:76
#define octstr_create(cstr)
Definition: octstr.h:125
static int num_urls
Definition: test_http.c:78
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static List * split
Definition: test_http.c:88
static Octstr * post_content_create(void)
Definition: test_http.c:92
static int file
Definition: test_http.c:87
static Octstr * url
Definition: test_xmlrpc.c:84
static char ** urls
Definition: test_http.c:77

Variable Documentation

Octstr* auth_password = NULL
static

Definition at line 81 of file test_http.c.

Octstr* auth_username = NULL
static

Definition at line 80 of file test_http.c.

Octstr* content_file = NULL
static

Definition at line 85 of file test_http.c.

Octstr* extra_headers = NULL
static

Definition at line 84 of file test_http.c.

int file = 0
static

Definition at line 87 of file test_http.c.

Referenced by main(), and start_request().

int follow_redirect = 1
static

Definition at line 89 of file test_http.c.

Referenced by main(), and start_request().

double interval = 0
static

Definition at line 75 of file test_http.c.

Referenced by client_thread(), and main().

long max_requests = 1
static

Definition at line 74 of file test_http.c.

Referenced by client_thread(), and main().

Octstr* method_name = NULL
static

Definition at line 86 of file test_http.c.

Referenced by smsbox_xmlrpc_post(), and unpack_datagram().

Octstr* msg_text = NULL
static

Definition at line 82 of file test_http.c.

int num_urls = 0
static

Definition at line 78 of file test_http.c.

Referenced by main(), and start_request().

List* split = NULL
static

Definition at line 88 of file test_http.c.

Referenced by dlr_add(), handle_split(), main(), and smscconn_send().

Octstr* ssl_client_certkey_file = NULL
static

Definition at line 83 of file test_http.c.

char** urls = NULL
static

Definition at line 77 of file test_http.c.

Referenced by main(), and start_request().

int verbose = 1
static

Definition at line 79 of file test_http.c.

Referenced by main(), and receive_reply().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.