test_http.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:11k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * test_http.c - a simple program to test the new http library
  3.  *
  4.  * Lars Wirzenius
  5.  */
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9. #include <stdio.h>
  10. #include "gwlib/gwlib.h"
  11. #include "gwlib/http.h"
  12. #define MAX_THREADS 1024
  13. #define MAX_IN_QUEUE 128
  14. static Counter *counter = NULL;
  15. static long max_requests = 1;
  16. static int method = HTTP_METHOD_GET;
  17. static char **urls = NULL;
  18. static int num_urls = 0;
  19. static int verbose = 1;
  20. static Octstr *auth_username = NULL;
  21. static Octstr *auth_password = NULL;
  22. static Octstr *msg_text = NULL;
  23. static Octstr *ssl_client_certkey_file = NULL;
  24. static Octstr *extra_headers = NULL;
  25. static Octstr *content_file = NULL; /* if set use POST method */
  26. static Octstr *method_name = NULL;
  27. static int file = 0;
  28. static List *split = NULL;
  29. static Octstr *post_content_create(void)
  30. {
  31.     Octstr *content;
  32.     if ((content = octstr_read_file(octstr_get_cstr(content_file))) == NULL)
  33.         panic(0, "Cannot read content text");
  34.     debug("", 0, "body content is");
  35.     octstr_dump(content, 0);
  36.     return content;
  37. }
  38. static void start_request(HTTPCaller *caller, List *reqh, long i)
  39. {
  40.     Octstr *url, *content = NULL;
  41.     long *id;
  42.     if ((i % 1000) == 0)
  43. info(0, "Starting fetch %ld", i);
  44.     id = gw_malloc(sizeof(long));
  45.     *id = i;
  46.     url = octstr_create(urls[i % num_urls]);
  47.     if (file) {
  48.         octstr_append(url, octstr_imm("&text="));
  49.         octstr_append(url, msg_text);
  50.     }
  51.     /* add the extra headers that have been read from the file */
  52.     if (split != NULL)
  53.         http_header_combine(reqh, split);
  54.     /* 
  55.      * if a body content file has been specified, then
  56.      * we assume this should be a POST
  57.      */
  58.     if (content_file != NULL) {
  59.         content = post_content_create();
  60.         method = HTTP_METHOD_POST;
  61.     }
  62.                                 
  63.     /*
  64.      * if this is a POST request then pass the required content as body to
  65.      * the HTTP server, otherwise skip the body, the arguments will be
  66.      * urlencoded in the URL itself.
  67.      */
  68.     http_start_request(caller, method,
  69.                        url, reqh, content, 0, id, ssl_client_certkey_file);
  70.     debug("", 0, "Started request %ld with url:", *id);
  71.     octstr_url_decode(url);
  72.     octstr_dump(url, 0);
  73.     octstr_destroy(url);
  74.     octstr_destroy(msg_text);
  75.     octstr_destroy(content);
  76. }
  77. static int receive_reply(HTTPCaller *caller)
  78. {
  79.     void *id;
  80.     int ret;
  81.     Octstr *final_url;
  82.     List *replyh;
  83.     Octstr *replyb;
  84.     Octstr *type;
  85.     Octstr *charset;
  86.     Octstr *os;
  87.     id = http_receive_result(caller, &ret, &final_url, &replyh, &replyb);
  88.     octstr_destroy(final_url);
  89.     if (id == NULL || ret == -1) {
  90. error(0, "http GET failed");
  91. return -1;
  92.     }
  93.     debug("", 0, "Done with request %ld", *(long *) id);
  94.     gw_free(id);
  95.     http_header_get_content_type(replyh, &type, &charset);
  96.     debug("", 0, "Content-type is <%s>, charset is <%s>",
  97.   octstr_get_cstr(type), 
  98.   octstr_get_cstr(charset));
  99.     octstr_destroy(type);
  100.     octstr_destroy(charset);
  101.     if (verbose)
  102.         debug("", 0, "Reply headers:");
  103.     while ((os = list_extract_first(replyh)) != NULL) {
  104.         if (verbose)
  105.     octstr_dump(os, 1);
  106. octstr_destroy(os);
  107.     }
  108.     list_destroy(replyh, NULL);
  109.     if (verbose) {
  110.         debug("", 0, "Reply body:");
  111.         octstr_dump(replyb, 1);
  112.     }
  113.     octstr_destroy(replyb);
  114.     return 0;
  115. }
  116. static void client_thread(void *arg) 
  117. {
  118.     List *reqh;
  119.     unsigned long i;
  120.     long succeeded, failed;
  121.     HTTPCaller *caller;
  122.     char buf[1024];
  123.     long in_queue;
  124.     caller = arg;
  125.     succeeded = 0;
  126.     failed = 0;
  127.     reqh = list_create();
  128.     sprintf(buf, "%ld", (long) gwthread_self());
  129.     http_header_add(reqh, "X-Thread", buf);
  130.     if (auth_username != NULL && auth_password != NULL)
  131. http_add_basic_auth(reqh, auth_username, auth_password);
  132.     in_queue = 0;
  133.     
  134.     for (;;) {
  135. while (in_queue < MAX_IN_QUEUE) {
  136.     i = counter_increase(counter);
  137.     if (i >= max_requests)
  138.      goto receive_rest;
  139.     start_request(caller, reqh, i);
  140. #if 0
  141.     gwthread_sleep(0.1);
  142. #endif
  143.     ++in_queue;
  144. }
  145. while (in_queue >= MAX_IN_QUEUE) {
  146.     if (receive_reply(caller) == -1)
  147.      ++failed;
  148.          else
  149.      ++succeeded;
  150.     --in_queue;
  151. }
  152.     }
  153.     
  154. receive_rest:
  155.     while (in_queue > 0) {
  156. if (receive_reply(caller) == -1)
  157.     ++failed;
  158. else
  159.     ++succeeded;
  160.      --in_queue;
  161.     }
  162.     http_destroy_headers(reqh);
  163.     http_caller_destroy(caller);
  164.     info(0, "This thread: %ld succeeded, %ld failed.", succeeded, failed);
  165. }
  166. static void split_headers(Octstr *headers, List **split)
  167. {
  168.     long start;
  169.     long pos;
  170.     *split = list_create();
  171.     start = 0;
  172.     for (pos = 0; pos < octstr_len(headers); pos++) {
  173.         if (octstr_get_char(headers, pos) == 'n') {
  174.             Octstr *line;
  175.             if (pos == start) {
  176.                 /* Skip empty lines */
  177.                 start = pos + 1;
  178.                 continue;
  179.             }
  180.             line = octstr_copy(headers, start, pos - start);
  181.             start = pos + 1;
  182.             list_append(*split, line);
  183.         }
  184.     }
  185. }
  186. static void help(void) 
  187. {
  188.     info(0, "Usage: test_http [options] url ...");
  189.     info(0, "where options are:");
  190.     info(0, "-v number");
  191.     info(0, "    set log level for stderr logging");
  192.     info(0, "-q");
  193.     info(0, "    don't print the body or headers of the HTTP response");
  194.     info(0, "-r number");
  195.     info(0, "    make `number' requests, repeating URLs as necessary");
  196.     info(0, "-p domain.name");
  197.     info(0, "    use `domain.name' as a proxy");
  198.     info(0, "-P portnumber");
  199.     info(0, "    connect to proxy at port `portnumber'");
  200.     info(0, "-e domain1:domain2:...");
  201.     info(0, "    set exception list for proxy use");
  202.     info(0, "-u filename");
  203.     info(0, "    read request's &text= string from file 'filename'. It is"); 
  204.     info(0, "    url encoded before it is added to the request");
  205.     info(0, "-H filename");
  206.     info(0, "    read HTTP headers from file 'filename' and add them to");
  207.     info(0, "    the request for url 'url'");
  208.     info(0, "-B filename");
  209.     info(0, "    read content from file 'filename' and send it as body");
  210.     info(0, "    of a POST method request (default: GET if no -B is set)");
  211.     info(0, "-m method");
  212.     info(0, "    use a specific HTTP method for request to server");
  213.     info(0, "-s");
  214.     info(0, "    use HTTPS scheme to access SSL-enabled HTTP server");
  215.     info(0, "-c ssl_client_cert_key_file");
  216.     info(0, "    use this file as the SSL certificate and key file");
  217. }
  218. int main(int argc, char **argv) 
  219. {
  220.     int i, opt, num_threads;
  221.     Octstr *proxy;
  222.     List *exceptions;
  223.     long proxy_port;
  224.     Octstr *proxy_username;
  225.     Octstr *proxy_password;
  226.     char *p;
  227.     long threads[MAX_THREADS];
  228.     time_t start, end;
  229.     double run_time;
  230.     FILE *fp;
  231.     int ssl = 0;
  232.     
  233.     gwlib_init();
  234.     
  235.     proxy = NULL;
  236.     proxy_port = -1;
  237.     exceptions = list_create();
  238.     proxy_username = NULL;
  239.     proxy_password = NULL;
  240.     num_threads = 0;
  241.     file = 0;
  242.     fp = NULL;
  243.     
  244.     while ((opt = getopt(argc, argv, "hv:qr:p:P:e:t:a:u:sc:H:B:m:")) != EOF) {
  245. switch (opt) {
  246. case 'v':
  247.     log_set_output_level(atoi(optarg));
  248.     break;
  249. case 'q':
  250.     verbose = 0;
  251.     break;
  252. case 'r':
  253.     max_requests = atoi(optarg);
  254.     break;
  255. case 't':
  256.     num_threads = atoi(optarg);
  257.     if (num_threads > MAX_THREADS)
  258. num_threads = MAX_THREADS;
  259.     break;
  260.     case 'u':
  261.         file = 1;
  262.         fp = fopen(optarg, "a");
  263.         if (fp == NULL)
  264.             panic(0, "Cannot open message text file %s", optarg);
  265.         msg_text = octstr_read_file(optarg);
  266.         if (msg_text == NULL)
  267.             panic(0, "Cannot read message text");
  268.         debug("", 0, "message text is");
  269.         octstr_dump(msg_text, 0);
  270.         octstr_url_encode(msg_text);
  271.         fclose(fp);
  272.         break;
  273. case 'h':
  274.     help();
  275.     exit(0);
  276. case 'p':
  277.     proxy = octstr_create(optarg);
  278.     break;
  279. case 'P':
  280.     proxy_port = atoi(optarg);
  281.     break;
  282. case 'e':
  283.     p = strtok(optarg, ":");
  284.     while (p != NULL) {
  285. list_append(exceptions, octstr_create(p));
  286. p = strtok(NULL, ":");
  287.     }
  288.     break;
  289. case 'a':
  290.     p = strtok(optarg, ":");
  291.     if (p != NULL) {
  292. auth_username = octstr_create(p);
  293. p = strtok(NULL, "");
  294. if (p != NULL)
  295.     auth_password = octstr_create(p);
  296.     }
  297.     break;
  298.     case 's':
  299.         ssl = 1;
  300.         break;
  301.     case 'c':
  302.     octstr_destroy(ssl_client_certkey_file);
  303.     ssl_client_certkey_file = octstr_create(optarg);
  304.         break;
  305.     case 'H':
  306.         fp = fopen(optarg, "a");
  307.         if (fp == NULL)
  308.             panic(0, "Cannot open header text file %s", optarg);
  309.         extra_headers = octstr_read_file(optarg);
  310.         if (extra_headers == NULL)
  311.             panic(0, "Cannot read header text");
  312.         debug("", 0, "headers are");
  313.         octstr_dump(extra_headers, 0);
  314.         split_headers(extra_headers, &split);
  315.         fclose(fp);
  316.         break;
  317.     case 'B':
  318.         content_file = octstr_create(optarg);
  319.         break;
  320. case 'm':
  321.     method_name = octstr_create(optarg);
  322.     break;
  323. case '?':
  324. default:
  325.     error(0, "Invalid option %c", opt);
  326.     help();
  327.     panic(0, "Stopping.");
  328. }
  329.     }
  330.     
  331.     if (optind == argc) {
  332.         help();
  333.         exit(0);
  334.     }
  335. #ifdef HAVE_LIBSSL
  336.     /*
  337.      * check if we are doing a SSL-enabled client version here
  338.      * load the required cert and key file
  339.      */
  340.     if (ssl) {
  341.         if (ssl_client_certkey_file != NULL) {
  342.             use_global_client_certkey_file(ssl_client_certkey_file);
  343.         } else {
  344.             panic(0, "client certkey file need to be given!");
  345.         }
  346.     }
  347. #endif
  348.     if (method_name != NULL) {
  349.         method = http_name2method(method_name);
  350.     }
  351.     
  352.     if (proxy != NULL && proxy_port > 0) {
  353.         http_use_proxy(proxy, proxy_port, exceptions,
  354.         proxy_username, proxy_password);
  355.     }
  356.     octstr_destroy(proxy);
  357.     octstr_destroy(proxy_username);
  358.     octstr_destroy(proxy_password);
  359.     list_destroy(exceptions, octstr_destroy_item);
  360.     
  361.     counter = counter_create();
  362.     urls = argv + optind;
  363.     num_urls = argc - optind;
  364.     
  365.     time(&start);
  366.     if (num_threads == 0)
  367.         client_thread(http_caller_create());
  368.     else {
  369.         for (i = 0; i < num_threads; ++i)
  370.             threads[i] = gwthread_create(client_thread, http_caller_create());
  371.         for (i = 0; i < num_threads; ++i)
  372.             gwthread_join(threads[i]);
  373.     }
  374.     time(&end);
  375.     
  376.     counter_destroy(counter);
  377.     
  378.     run_time = difftime(end, start);
  379.     info(0, "%ld requests in %f seconds, %f requests/s.",
  380.          max_requests, run_time, max_requests / run_time);
  381.     
  382.     octstr_destroy(auth_username);
  383.     octstr_destroy(auth_password);
  384.     octstr_destroy(ssl_client_certkey_file);
  385.     octstr_destroy(extra_headers);
  386.     octstr_destroy(content_file);
  387.     list_destroy(split, octstr_destroy_item);
  388.     
  389.     gwlib_shutdown();
  390.     
  391.     return 0;
  392. }