#include <string.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include "gwlib/gwlib.h"#include "gwlib/http.h"Include dependency graph for test_http_server.c:

Go to the source code of this file.
Defines | |
| #define | MAX_THREADS 1024 |
Functions | |
| void | client_thread (void *arg) |
| void | help (void) |
| void | sigterm (int signo) |
| int | main (int argc, char **argv) |
Variables | |
| Octstr * | whitelist |
| Octstr * | blacklist |
| Octstr * | reply_text = NULL |
| int | verbose |
| int | run |
| int | port |
| int | ssl = 0 |
|
|
Definition at line 71 of file test_http_server.c. |
|
|
Definition at line 79 of file test_http_server.c. References blacklist, debug(), gwlist_append(), gwlist_create, gwlist_destroy(), gwlist_get(), gwlist_len(), http_accept_request(), http_cgi_variable(), http_close_all_ports(), http_destroy_cgiargs(), http_header_dump(), http_header_value(), http_send_reply(), info(), HTTPCGIVar::name, octstr_append_from_hex(), octstr_compare(), octstr_create, octstr_destroy(), octstr_destroy_item(), octstr_dump, octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_imm(), octstr_print(), port, reply_text, run, ssl, HTTPCGIVar::value, and whitelist. Referenced by main(). 00080 {
00081 HTTPClient *client;
00082 Octstr *body, *url, *ip;
00083 List *headers, *resph, *cgivars;
00084 HTTPCGIVar *v;
00085 Octstr *reply_body, *reply_type;
00086 unsigned long n = 0;
00087 int status, i;
00088
00089 while (run) {
00090 client = http_accept_request(port, &ip, &url, &headers, &body, &cgivars);
00091
00092 n++;
00093 if (client == NULL)
00094 break;
00095
00096 info(0, "Request for <%s> from <%s>",
00097 octstr_get_cstr(url), octstr_get_cstr(ip));
00098 if (verbose)
00099 debug("test.http", 0, "CGI vars were");
00100
00101 /*
00102 * Don't use gwlist_extract() here, otherwise we don't have a chance
00103 * to re-use the cgivars later on.
00104 */
00105 for (i = 0; i < gwlist_len(cgivars); i++) {
00106 if ((v = gwlist_get(cgivars, i)) != NULL && verbose) {
00107 octstr_dump(v->name, 0);
00108 octstr_dump(v->value, 0);
00109 }
00110 }
00111
00112 if (arg == NULL) {
00113 reply_body = octstr_duplicate(reply_text);
00114 reply_type = octstr_create("Content-Type: text/plain; "
00115 "charset=\"UTF-8\"");
00116 } else {
00117 reply_body = octstr_duplicate(arg);
00118 reply_type = octstr_create("Content-Type: text/vnd.wap.wml");
00119 }
00120
00121 resph = gwlist_create();
00122 gwlist_append(resph, reply_type);
00123
00124 status = HTTP_OK;
00125
00126 /* check for special URIs and handle those */
00127 if (octstr_compare(url, octstr_imm("/quit")) == 0) {
00128 run = 0;
00129 } else if (octstr_compare(url, octstr_imm("/whitelist")) == 0) {
00130 octstr_destroy(reply_body);
00131 if (whitelist != NULL) {
00132 if (verbose) {
00133 debug("test.http.server", 0, "we send a white list");
00134 octstr_dump(whitelist, 0);
00135 }
00136 reply_body = octstr_duplicate(whitelist);
00137 } else {
00138 reply_body = octstr_imm("");
00139 }
00140 } else if (octstr_compare(url, octstr_imm("/blacklist")) == 0) {
00141 octstr_destroy(reply_body);
00142 if (blacklist != NULL) {
00143 if (verbose) {
00144 debug("test.http.server", 0, "we send a blacklist");
00145 octstr_dump(blacklist, 0);
00146 }
00147 reply_body = octstr_duplicate(blacklist);
00148 } else {
00149 reply_body = octstr_imm("");
00150 }
00151 } else if (octstr_compare(url, octstr_imm("/save")) == 0) {
00152 /* safe the body into a temporary file */
00153 pid_t pid = getpid();
00154 FILE *f = fopen(octstr_get_cstr(octstr_format("/tmp/body.%ld.%ld", pid, n)), "w");
00155 octstr_print(f, body);
00156 fclose(f);
00157 } else if (octstr_compare(url, octstr_imm("/redirect/")) == 0) {
00158 /* provide us with a HTTP 302 redirection response
00159 * will return /redirect/<pid> for the location header
00160 * and will return /redirect/ if cgivar loop is set to allow looping
00161 */
00162 Octstr *redirect_header, *scheme, *uri, *l;
00163 pid_t pid = getpid();
00164
00165 uri = ((l = http_cgi_variable(cgivars, "loop")) != NULL) ?
00166 octstr_format("%s?loop=%s", octstr_get_cstr(url),
00167 octstr_get_cstr(l)) :
00168 octstr_format("%s%ld", octstr_get_cstr(url), pid);
00169
00170 octstr_destroy(reply_body);
00171 reply_body = octstr_imm("Here you got a redirection URL that you should follow.");
00172 scheme = ssl ? octstr_imm("https://") : octstr_imm("http://");
00173 redirect_header = octstr_format("Location: %s%s%s",
00174 octstr_get_cstr(scheme),
00175 octstr_get_cstr(http_header_value(headers, octstr_imm("Host"))),
00176 octstr_get_cstr(uri));
00177 gwlist_append(resph, redirect_header);
00178 status = HTTP_FOUND; /* will provide 302 */
00179 octstr_destroy(uri);
00180 } else if (octstr_compare(url, octstr_imm("/mmsc")) == 0) {
00181 /* fake a M-Send.conf PDU which is using MMSEncapsulation as body */
00182 pid_t pid = getpid();
00183 FILE *f;
00184 gwlist_destroy(resph, octstr_destroy_item);
00185 octstr_destroy(reply_body);
00186 reply_type = octstr_create("Content-Type: application/vnd.wap.mms-message");
00187 reply_body = octstr_create("");
00188 octstr_append_from_hex(reply_body,
00189 "8c81" /* X-Mms-Message-Type: m-send-conf */
00190 "98632d3862343300" /* X-Mms-Transaction-ID: c-8b43 */
00191 "8d90" /* X-Mms-MMS-Version: 1.0 */
00192 "9280" /* Response-status: Ok */
00193 "8b313331373939353434393639383434313731323400"
00194 ); /* Message-Id: 13179954496984417124 */
00195 resph = gwlist_create();
00196 gwlist_append(resph, reply_type);
00197 /* safe the M-Send.req body into a temporary file */
00198 f = fopen(octstr_get_cstr(octstr_format("/tmp/mms-body.%ld.%ld", pid, n)), "w");
00199 octstr_print(f, body);
00200 fclose(f);
00201 }
00202
00203 if (verbose) {
00204 debug("test.http", 0, "request headers were");
00205 http_header_dump(headers);
00206 if (body != NULL) {
00207 debug("test.http", 0, "request body was");
00208 octstr_dump(body, 0);
00209 }
00210 }
00211
00212 /* return response to client */
00213 http_send_reply(client, status, resph, reply_body);
00214
00215 octstr_destroy(ip);
00216 octstr_destroy(url);
00217 octstr_destroy(body);
00218 octstr_destroy(reply_body);
00219 http_destroy_cgiargs(cgivars);
00220 gwlist_destroy(headers, octstr_destroy_item);
00221 gwlist_destroy(resph, octstr_destroy_item);
00222 }
00223
00224 octstr_destroy(whitelist);
00225 octstr_destroy(blacklist);
00226 debug("test.http", 0, "Working thread 'client_thread' terminates");
00227 http_close_all_ports();
00228 }
|
Here is the call graph for this function:

|
|
Definition at line 230 of file test_http_server.c. References info(). 00230 {
00231 info(0, "Usage: test_http_server [options...]");
00232 info(0, "where options are:");
00233 info(0, "-t number");
00234 info(0, " set number of working threads to use (default: 1)");
00235 info(0, "-v number");
00236 info(0, " set log level for stderr logging (default: 0 - debug)");
00237 info(0, "-l logfile");
00238 info(0, " log all output to a file");
00239 info(0, "-f file");
00240 info(0, " use a specific file content for the response body");
00241 info(0, "-r reply_text");
00242 info(0, " defines which static text to use for replies");
00243 info(0, "-h");
00244 info(0, " provides this usage help information");
00245 info(0, "-q");
00246 info(0, " don't be too verbose with output");
00247 info(0, "-p port");
00248 info(0, " bind server to a specific port");
00249 info(0, "-s");
00250 info(0, " be an SSL-enabled server");
00251 info(0, "-c ssl_cert");
00252 info(0, " file of the SSL certificate to use");
00253 info(0, "-k ssl_key");
00254 info(0, " file of the SSL private key to use");
00255 info(0, "-w white_list");
00256 info(0, " file that is used for whitelist");
00257 info(0, "-b black_list");
00258 info(0, " file that is used for blacklist");
00259 info(0, "specific URIs with special functions are:");
00260 info(0, " /quite - shutdown the HTTP server");
00261 info(0, " /whitelist - provides the -w whitelist as response");
00262 info(0, " /blacklist - provides the -b blacklist as response");
00263 info(0, " /save - save a HTTP POST request body to a file /tmp/body.<pid>.<n>");
00264 info(0, " where <pid> is the process id and <n> is the received request number");
00265 info(0, " /redirect/ - respond with HTTP 302 and the location /redirect/<pid>");
00266 info(0, " where <pid> is the process id. if a cgivar loop=<something> is given");
00267 info(0, " then HTTP reponses will end up in a loop.");
00268 info(0, " /mmsc - fake a MMSC HTTP interface for M-Send.req PDUs send by a");
00269 info(0, " mobile MMS-capable device, responds with a M-Send.conf PDU and");
00270 info(0, " saves the M-Send.req body to a file /tmp/mms-body.<pid>.<n> in");
00271 info(0, " MMSEncapsulation encoded binary format");
00272
00273 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 281 of file test_http_server.c. References blacklist, client_thread(), debug(), error(), filename, getopt(), GW_DEBUG, GW_NON_EXCL, gwlib_init(), gwlib_shutdown(), gwthread_create, gwthread_join(), help(), http_open_port(), log_open(), log_set_output_level(), octstr_create, octstr_destroy(), octstr_get_cstr, octstr_read_file(), optarg, panic, port, reply_text, run, ssl, threads, use_global_server_certkey_file(), verbose, and whitelist. 00281 {
00282 int i, opt, use_threads;
00283 struct sigaction act;
00284 char *filename;
00285 Octstr *log_filename;
00286 Octstr *file_contents;
00287 #ifdef HAVE_LIBSSL
00288 Octstr *ssl_server_cert_file = NULL;
00289 Octstr *ssl_server_key_file = NULL;
00290 #endif
00291 char *whitelist_name;
00292 char *blacklist_name;
00293 int white_asked,
00294 black_asked;
00295 long threads[MAX_THREADS];
00296
00297 gwlib_init();
00298
00299 act.sa_handler = sigterm;
00300 sigemptyset(&act.sa_mask);
00301 act.sa_flags = 0;
00302 sigaction(SIGTERM, &act, NULL);
00303
00304 port = 8080;
00305 use_threads = 1;
00306 verbose = 1;
00307 run = 1;
00308 filename = NULL;
00309 log_filename = NULL;
00310 blacklist_name = NULL;
00311 whitelist_name = NULL;
00312 white_asked = 0;
00313 black_asked = 0;
00314
00315 reply_text = octstr_create("Sent.");
00316
00317 while ((opt = getopt(argc, argv, "hqv:p:t:f:l:sc:k:b:w:r:")) != EOF) {
00318 switch (opt) {
00319 case 'v':
00320 log_set_output_level(atoi(optarg));
00321 break;
00322
00323 case 'q':
00324 verbose = 0;
00325 break;
00326
00327 case 'h':
00328 help();
00329 exit(0);
00330
00331 case 'p':
00332 port = atoi(optarg);
00333 break;
00334
00335 case 't':
00336 use_threads = atoi(optarg);
00337 if (use_threads > MAX_THREADS)
00338 use_threads = MAX_THREADS;
00339 break;
00340
00341 case 'c':
00342 #ifdef HAVE_LIBSSL
00343 octstr_destroy(ssl_server_cert_file);
00344 ssl_server_cert_file = octstr_create(optarg);
00345 #endif
00346 break;
00347
00348 case 'k':
00349 #ifdef HAVE_LIBSSL
00350 octstr_destroy(ssl_server_key_file);
00351 ssl_server_key_file = octstr_create(optarg);
00352 #endif
00353 break;
00354
00355 case 's':
00356 #ifdef HAVE_LIBSSL
00357 ssl = 1;
00358 #endif
00359 break;
00360
00361 case 'f':
00362 filename = optarg;
00363 break;
00364
00365 case 'l':
00366 octstr_destroy(log_filename);
00367 log_filename = octstr_create(optarg);
00368 break;
00369
00370 case 'w':
00371 whitelist_name = optarg;
00372 if (whitelist_name == NULL)
00373 whitelist_name = "";
00374 white_asked = 1;
00375 break;
00376
00377 case 'b':
00378 blacklist_name = optarg;
00379 if (blacklist_name == NULL)
00380 blacklist_name = "";
00381 black_asked = 1;
00382 break;
00383
00384 case 'r':
00385 octstr_destroy(reply_text);
00386 reply_text = octstr_create(optarg);
00387 break;
00388
00389 case '?':
00390 default:
00391 error(0, "Invalid option %c", opt);
00392 help();
00393 panic(0, "Stopping.");
00394 }
00395 }
00396
00397 if (log_filename != NULL) {
00398 log_open(octstr_get_cstr(log_filename), GW_DEBUG, GW_NON_EXCL);
00399 octstr_destroy(log_filename);
00400 }
00401
00402 if (filename == NULL)
00403 file_contents = NULL;
00404 else
00405 file_contents = octstr_read_file(filename);
00406
00407 if (white_asked) {
00408 whitelist = octstr_read_file(whitelist_name);
00409 if (whitelist == NULL)
00410 panic(0, "Cannot read the whitelist");
00411 }
00412
00413 if (black_asked) {
00414 blacklist = octstr_read_file(blacklist_name);
00415 if (blacklist == NULL)
00416 panic(0, "Cannot read the blacklist");
00417 }
00418
00419 #ifdef HAVE_LIBSSL
00420 /*
00421 * check if we are doing a SSL-enabled server version here
00422 * load the required cert and key file
00423 */
00424 if (ssl) {
00425 if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) {
00426 use_global_server_certkey_file(ssl_server_cert_file, ssl_server_key_file);
00427 octstr_destroy(ssl_server_cert_file);
00428 octstr_destroy(ssl_server_key_file);
00429 } else {
00430 panic(0, "certificate and public key need to be given!");
00431 }
00432 }
00433 #endif
00434
00435 if (http_open_port(port, ssl) == -1)
00436 panic(0, "http_open_server failed");
00437
00438 /*
00439 * Do the real work in a separate thread so that the main
00440 * thread can catch signals safely.
00441 */
00442 for (i = 0; i < use_threads; ++i)
00443 threads[i] = gwthread_create(client_thread, file_contents);
00444
00445 /* wait for all working threads */
00446 for (i = 0; i < use_threads; ++i)
00447 gwthread_join(threads[i]);
00448
00449 debug("test.http", 0, "Program exiting normally.");
00450 gwlib_shutdown();
00451 return 0;
00452 }
|
Here is the call graph for this function:

|
|
Definition at line 275 of file test_http_server.c. References debug(), http_close_all_ports(), and run. 00275 {
00276 run = 0;
00277 http_close_all_ports();
00278 debug("test.gwlib", 0, "Signal %d received, quitting.", signo);
00279 }
|
Here is the call graph for this function:

|
|
Definition at line 73 of file test_http_server.c. Referenced by client_thread(), and main(). |
|
|
Definition at line 76 of file test_http_server.c. |
|
|
Definition at line 74 of file test_http_server.c. Referenced by client_thread(), and main(). |
|
|
Definition at line 76 of file test_http_server.c. Referenced by client_thread(), main(), and sigterm(). |
|
|
Definition at line 77 of file test_http_server.c. Referenced by accept_boxc(), boxc_create(), client_thread(), conn_pool_get(), conn_pool_key(), conn_pool_put(), connect_to_bearerbox(), get_connection(), http_open_port(), httpadmin_start(), httpd_emu_create(), init_smsbox(), main(), server_thread(), smsc_http_create(), SSL_smart_shutdown(), start_http_thread(), and wait_for_connections(). |
|
|
Definition at line 76 of file test_http_server.c. |
|
|
Definition at line 73 of file test_http_server.c. Referenced by client_thread(), and main(). |