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)