71 #define MAX_THREADS 1024    78 static volatile sig_atomic_t 
run;
    88     for (pos = 0; pos < 
octstr_len(headers); pos++) {
   108     List *headers, *resph, *cgivars;
   110     Octstr *reply_body, *reply_type;
   121         info(0, 
"Request for <%s> from <%s>", 
   124             debug(
"test.http", 0, 
"CGI vars were");
   140                                        "charset=\"UTF-8\"");
   143             reply_type = 
octstr_create(
"Content-Type: text/vnd.wap.wml");
   158                     debug(
"test.http.server", 0, 
"we send a white list");
   169                     debug(
"test.http.server", 0, 
"we send a blacklist");
   178             pid_t pid = getpid();
   187             Octstr *redirect_header, *scheme, *uri, *l;
   188             pid_t pid = getpid();
   196             reply_body = 
octstr_imm(
"Here you got a redirection URL that you should follow.");
   207             pid_t pid = getpid();
   211             reply_type = 
octstr_create(
"Content-Type: application/vnd.wap.mms-message");
   218                 "8b313331373939353434393639383434313731323400"   229             debug(
"test.http", 0, 
"request headers were");
   232                 debug(
"test.http", 0, 
"request body was");
   254     debug(
"test.http", 0, 
"Working thread 'client_thread' terminates");
   259     info(0, 
"Usage: test_http_server [options...]");
   260     info(0, 
"where options are:");
   261     info(0, 
"-t number");
   262     info(0, 
"    set number of working threads to use (default: 1)");
   263     info(0, 
"-v number");
   264     info(0, 
"    set log level for stderr logging (default: 0 - debug)");
   265     info(0, 
"-l logfile");
   266     info(0, 
"    log all output to a file");
   268     info(0, 
"    use a specific file content for the response body");
   269     info(0, 
"-r reply_text");
   270     info(0, 
"    defines which static text to use for replies");
   272     info(0, 
"    provides this usage help information");
   274     info(0, 
"    don't be too verbose with output");
   276     info(0, 
"    bind server to a specific port");
   278     info(0, 
"    be an SSL-enabled server");
   279     info(0, 
"-c ssl_cert");
   280     info(0, 
"    file of the SSL certificate to use");
   281     info(0, 
"-k ssl_key");
   282     info(0, 
"    file of the SSL private key to use");
   283     info(0, 
"-w white_list");
   284     info(0, 
"    file that is used for whitelist");
   285     info(0, 
"-b black_list");
   286     info(0, 
"    file that is used for blacklist");
   287     info(0, 
"-H filename");
   288     info(0, 
"    read HTTP headers from file 'filename' and add them to");
   289     info(0, 
"    the request for url 'url'");
   290     info(0, 
"specific URIs with special functions are:");
   291     info(0, 
"  /quite - shutdown the HTTP server");
   292     info(0, 
"  /whitelist - provides the -w whitelist as response");
   293     info(0, 
"  /blacklist - provides the -b blacklist as response");
   294     info(0, 
"  /save - save a HTTP POST request body to a file /tmp/body.<pid>.<n>");
   295     info(0, 
"    where <pid> is the process id and <n> is the received request number");
   296     info(0, 
"  /redirect/ - respond with HTTP 302 and the location /redirect/<pid>");
   297     info(0, 
"    where <pid> is the process id. if a cgivar loop=<something> is given");
   298     info(0, 
"    then HTTP responses will end up in a loop.");
   299     info(0, 
"  /mmsc - fake a MMSC HTTP interface for M-Send.req PDUs send by a");
   300     info(0, 
"    mobile MMS-capable device, responds with a M-Send.conf PDU and");
   301     info(0, 
"    saves the M-Send.req body to a file /tmp/mms-body.<pid>.<n> in");
   302     info(0, 
"    MMSEncapsulation encoded binary format");
   308     debug(
"test.gwlib", 0, 
"Signal %d received, quitting.", signo);
   311 int main(
int argc, 
char **argv) {
   312     int i, opt, use_threads;
   313     struct sigaction act;
   318     Octstr *ssl_server_cert_file = NULL;
   319     Octstr *ssl_server_key_file = NULL;
   321     char *whitelist_name;
   322     char *blacklist_name;
   331     sigemptyset(&act.sa_mask);
   333     sigaction(SIGTERM, &act, NULL);
   334     sigaction(SIGINT, &act, NULL);
   342     blacklist_name = NULL;
   343     whitelist_name = NULL;
   349     while ((opt = 
getopt(argc, argv, 
"hqv:p:t:f:l:sc:k:b:w:r:H:")) != EOF) {
   368         use_threads = atoi(
optarg);
   404         if (whitelist_name == NULL)
   411         if (blacklist_name == NULL)
   426             panic(0, 
"Cannot open header text file %s", 
optarg);
   429             panic(0, 
"Cannot read header text");
   430         debug(
"", 0, 
"headers are");
   440         error(0, 
"Invalid option %c", opt);
   442         panic(0, 
"Stopping.");
   446     if (log_filename != NULL) {
   452         file_contents = NULL;
   459             panic(0, 
"Cannot read the whitelist");
   465             panic(0, 
"Cannot read the blacklist");
   474         if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) {
   475             conn_use_global_server_certkey_file(ssl_server_cert_file, ssl_server_key_file);
   479             panic(0, 
"certificate and public key need to be given!");
   485         panic(0, 
"http_open_server failed");
   491     for (i = 0; i < use_threads; ++i) 
   495     for (i = 0; i < use_threads; ++i)
   501     debug(
"test.http", 0, 
"Program exiting normally.");
 void error(int err, const char *fmt,...)
 
void info(int err, const char *fmt,...)
 
void octstr_append_from_hex(Octstr *ostr, char *hex)
 
void gwlist_append(List *list, void *item)
 
static void client_thread(void *arg)
 
void gwthread_join(long thread)
 
long gwlist_len(List *list)
 
static void client(int port)
 
void * gwlist_get(List *list, long pos)
 
void http_header_combine(List *old_headers, List *new_headers)
 
int octstr_print(FILE *f, Octstr *ostr)
 
#define octstr_get_cstr(ostr)
 
#define octstr_copy(ostr, from, len)
 
Octstr * http_cgi_variable(List *list, char *name)
 
int getopt(int argc, char **argv, char *opts)
 
void http_destroy_cgiargs(List *args)
 
void http_send_reply(HTTPClient *client, int status, List *headers, Octstr *body)
 
Octstr * octstr_imm(const char *cstr)
 
void log_set_output_level(enum output_level level)
 
static List * extra_headers
 
HTTPClient * http_accept_request(int port, Octstr **client_ip, Octstr **url, List **headers, Octstr **body, List **cgivars)
 
static void sigterm(int signo)
 
#define octstr_duplicate(ostr)
 
#define octstr_dump(ostr, level,...)
 
int main(int argc, char **argv)
 
Octstr * octstr_format(const char *fmt,...)
 
void octstr_destroy(Octstr *ostr)
 
char filename[FILENAME_MAX+1]
 
#define gwthread_create(func, arg)
 
#define octstr_create(cstr)
 
void octstr_destroy_item(void *os)
 
int http_open_port(int port, int ssl)
 
Octstr * octstr_read_file(const char *filename)
 
int log_open(char *filename, int level, enum excl_state excl)
 
void http_close_all_ports(void)
 
Octstr * http_header_value(List *headers, Octstr *name)
 
long octstr_len(const Octstr *ostr)
 
static void split_headers(Octstr *headers, List **split)
 
void debug(const char *place, int err, const char *fmt,...)
 
void gwlib_shutdown(void)
 
static volatile sig_atomic_t run
 
int octstr_get_char(const Octstr *ostr, long pos)
 
void http_header_dump(List *headers)
 
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
 
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)