diff --git a/antd b/antd deleted file mode 100755 index ddb69bf..0000000 --- a/antd +++ /dev/null @@ -1,210 +0,0 @@ -#! /bin/bash - -# antd - temporary wrapper script for .libs/antd -# Generated by libtool (GNU libtool) 2.4.6 Debian-2.4.6-14 -# -# The antd program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='s|\([`"$\\]\)|\\\1|g' - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -relink_command="" - -# This environment variable determines our operation mode. -if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then - # install mode needs the following variables: - generated_by_libtool_version='2.4.6' - notinst_deplibs=' libantd.la' -else - # When we are sourced in execute mode, $file and $ECHO are already set. - if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then - file="$0" - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' -} - ECHO="printf %s\\n" - fi - -# Very basic option parsing. These options are (a) specific to -# the libtool wrapper, (b) are identical between the wrapper -# /script/ and the wrapper /executable/ that is used only on -# windows platforms, and (c) all begin with the string --lt- -# (application programs are unlikely to have options that match -# this pattern). -# -# There are only two supported options: --lt-debug and -# --lt-dump-script. There is, deliberately, no --lt-help. -# -# The first argument to this parsing function should be the -# script's ./libtool value, followed by no. -lt_option_debug= -func_parse_lt_options () -{ - lt_script_arg0=$0 - shift - for lt_opt - do - case "$lt_opt" in - --lt-debug) lt_option_debug=1 ;; - --lt-dump-script) - lt_dump_D=`$ECHO "X$lt_script_arg0" | /usr/bin/sed -e 's/^X//' -e 's%/[^/]*$%%'` - test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=. - lt_dump_F=`$ECHO "X$lt_script_arg0" | /usr/bin/sed -e 's/^X//' -e 's%^.*/%%'` - cat "$lt_dump_D/$lt_dump_F" - exit 0 - ;; - --lt-*) - $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2 - exit 1 - ;; - esac - done - - # Print the debug banner immediately: - if test -n "$lt_option_debug"; then - echo "antd:antd:$LINENO: libtool wrapper (GNU libtool) 2.4.6 Debian-2.4.6-14" 1>&2 - fi -} - -# Used when --lt-debug. Prints its arguments to stdout -# (redirection is the responsibility of the caller) -func_lt_dump_args () -{ - lt_dump_args_N=1; - for lt_arg - do - $ECHO "antd:antd:$LINENO: newargv[$lt_dump_args_N]: $lt_arg" - lt_dump_args_N=`expr $lt_dump_args_N + 1` - done -} - -# Core function for launching the target application -func_exec_program_core () -{ - - if test -n "$lt_option_debug"; then - $ECHO "antd:antd:$LINENO: newargv[0]: $progdir/$program" 1>&2 - func_lt_dump_args ${1+"$@"} 1>&2 - fi - exec "$progdir/$program" ${1+"$@"} - - $ECHO "$0: cannot exec $program $*" 1>&2 - exit 1 -} - -# A function to encapsulate launching the target application -# Strips options in the --lt-* namespace from $@ and -# launches target application with the remaining arguments. -func_exec_program () -{ - case " $* " in - *\ --lt-*) - for lt_wr_arg - do - case $lt_wr_arg in - --lt-*) ;; - *) set x "$@" "$lt_wr_arg"; shift;; - esac - shift - done ;; - esac - func_exec_program_core ${1+"$@"} -} - - # Parse options - func_parse_lt_options "$0" ${1+"$@"} - - # Find the directory that this script lives in. - thisdir=`$ECHO "$file" | /usr/bin/sed 's%/[^/]*$%%'` - test "x$thisdir" = "x$file" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=`ls -ld "$file" | /usr/bin/sed -n 's/.*-> //p'` - while test -n "$file"; do - destdir=`$ECHO "$file" | /usr/bin/sed 's%/[^/]*$%%'` - - # If there was a directory component, then change thisdir. - if test "x$destdir" != "x$file"; then - case "$destdir" in - [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;; - *) thisdir="$thisdir/$destdir" ;; - esac - fi - - file=`$ECHO "$file" | /usr/bin/sed 's%^.*/%%'` - file=`ls -ld "$thisdir/$file" | /usr/bin/sed -n 's/.*-> //p'` - done - - # Usually 'no', except on cygwin/mingw when embedded into - # the cwrapper. - WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no - if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then - # special case for '.' - if test "$thisdir" = "."; then - thisdir=`pwd` - fi - # remove .libs from thisdir - case "$thisdir" in - *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /usr/bin/sed 's%[\\/][^\\/]*$%%'` ;; - .libs ) thisdir=. ;; - esac - fi - - # Try to get the absolute directory name. - absdir=`cd "$thisdir" && pwd` - test -n "$absdir" && thisdir="$absdir" - - program='antd' - progdir="$thisdir/.libs" - - - if test -f "$progdir/$program"; then - # Add our own library path to LD_LIBRARY_PATH - LD_LIBRARY_PATH="/home/mrsang/workspace/ant-http/.libs:/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH" - - # Some systems cannot cope with colon-terminated LD_LIBRARY_PATH - # The second colon is a workaround for a bug in BeOS R4 sed - LD_LIBRARY_PATH=`$ECHO "$LD_LIBRARY_PATH" | /usr/bin/sed 's/::*$//'` - - export LD_LIBRARY_PATH - - if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then - # Run the actual program with our arguments. - func_exec_program ${1+"$@"} - fi - else - # The program doesn't exist. - $ECHO "$0: error: '$progdir/$program' does not exist" 1>&2 - $ECHO "This script is just a wrapper for $program." 1>&2 - $ECHO "See the libtool documentation for more information." 1>&2 - exit 1 - fi -fi diff --git a/dist/antd-1.0.4b.tar.gz b/dist/antd-1.0.4b.tar.gz index 03a9209..3a81462 100644 Binary files a/dist/antd-1.0.4b.tar.gz and b/dist/antd-1.0.4b.tar.gz differ diff --git a/http_server.c b/http_server.c index 6c6edf0..984abb5 100644 --- a/http_server.c +++ b/http_server.c @@ -937,7 +937,7 @@ void ws_confirm_request(void *client, const char *key) char rkey[128]; char sha_d[20]; char base64[64]; - strcpy(rkey, key); + strncpy(rkey, key, 128); strcat(rkey, WS_MAGIC_STRING); //printf("RESPONDKEY '%s'\n", rkey); #ifdef USE_OPENSSL @@ -1307,15 +1307,15 @@ dictionary_t mimes_list() void dbdir(char* dest) { - strcpy(dest,server_config.db_path); + strncpy(dest,server_config.db_path, 512); } void tmpdir(char* dest) { - strcpy(dest, server_config.tmpdir); + strncpy(dest, server_config.tmpdir, 512); } void plugindir(char* dest) { - strcpy(dest, server_config.plugins_dir); + strncpy(dest, server_config.plugins_dir, 512); } #ifdef USE_ZLIB diff --git a/httpd.c b/httpd.c index c142f59..a530f0b 100644 --- a/httpd.c +++ b/httpd.c @@ -150,6 +150,96 @@ void stop_serve(int dummy) { sigprocmask(SIG_UNBLOCK, &mask, NULL); } +static void* antd_monitor(port_config_t* pcnf) +{ + antd_task_t* task = NULL; + struct timeval timeout; + int client_sock = -1; + struct sockaddr_in client_name; + socklen_t client_name_len = sizeof(client_name); + char* client_ip = NULL; + config_t* conf = config(); + LOG("Listening on port %d", pcnf->port); + while (scheduler.status) + { + if(conf->connection > conf->maxcon) + { + //ERROR("Reach max connection %d", conf->connection); + timeout.tv_sec = 0; + timeout.tv_usec = 10000; // 5 ms + select(0, NULL, NULL, NULL, &timeout); + continue; + } + if(pcnf->sock > 0) + { + client_sock = accept(pcnf->sock,(struct sockaddr *)&client_name,&client_name_len); + if (client_sock > 0) + { + // just dump the scheduler when we have a connection + antd_client_t* client = (antd_client_t*)malloc(sizeof(antd_client_t)); + antd_request_t* request = (antd_request_t*)malloc(sizeof(*request)); + request->client = client; + request->request = dict(); + client->zstream = NULL; + client->z_level = ANTD_CNONE; + + dictionary_t xheader = dict(); + dput(request->request, "REQUEST_HEADER", xheader); + dput(request->request, "REQUEST_DATA", dict()); + dput(xheader, "SERVER_PORT", (void *)__s("%d", pcnf->port)); + dput(xheader, "SERVER_WWW_ROOT", (void*)strdup(pcnf->htdocs)); + /* + get the remote IP + */ + if (client_name.sin_family == AF_INET) + { + client_ip = inet_ntoa(client_name.sin_addr); + LOG("Connect to client IP: %s on port:%d", client_ip, pcnf->port); + // ip address + dput(xheader, "REMOTE_ADDR", (void *)strdup(client_ip)); + //LOG("socket: %d\n", client_sock); + } + + // set timeout to socket + set_nonblock(client_sock); + + client->sock = client_sock; + time(&client->last_io); + client->ssl = NULL; +#ifdef USE_OPENSSL + client->status = 0; + if(pcnf->usessl == 1) + { + client->ssl = (void*)SSL_new(ctx); + if(!client->ssl) continue; + SSL_set_fd((SSL*)client->ssl, client->sock); + // this can be used in the protocol select callback to + // set the protocol selected by the server + if(!SSL_set_ex_data((SSL*)client->ssl, client->sock, client)) + { + ERROR("Cannot set ex data to ssl client:%d", client->sock); + } + /*if (SSL_accept((SSL*)client->ssl) <= 0) { + LOG("EROOR accept\n"); + ERR_print_errors_fp(stderr); + antd_close(client); + continue; + }*/ + } +#endif + pthread_mutex_lock(&scheduler.scheduler_lock); + conf->connection++; + pthread_mutex_unlock(&scheduler.scheduler_lock); + // create callback for the server + task = antd_create_task(accept_request,(void*)request, finish_request, client->last_io); + //task->type = LIGHT; + antd_add_task(&scheduler, task); + } + } + } + return NULL; +} + int main(int argc, char* argv[]) { // load the config first @@ -157,10 +247,6 @@ int main(int argc, char* argv[]) load_config(CONFIG_FILE); else load_config(argv[1]); - int client_sock = -1; - struct sockaddr_in client_name; - socklen_t client_name_len = sizeof(client_name); - char* client_ip = NULL; // ignore the broken PIPE error when writing //or reading to/from a closed socked connection signal(SIGPIPE, SIG_IGN); @@ -182,6 +268,12 @@ int main(int argc, char* argv[]) } #endif + // enable scheduler + // default to 4 workers + scheduler.validate_data = 1; + scheduler.destroy_data = finish_request; + antd_scheduler_init(&scheduler, conf->n_workers); + pthread_t monitor_th; // startup port chain_t it; port_config_t * pcnf; @@ -194,9 +286,18 @@ int main(int argc, char* argv[]) pcnf->sock = startup(&pcnf->port); if(pcnf->sock>0) { + if (pthread_create(&monitor_th, NULL,(void *(*)(void *))antd_monitor, (void*)pcnf) != 0) + { + ERROR("pthread_create: cannot create worker"); + stop_serve(0); + exit(1); + } + else + { + // reclaim data when exit + pthread_detach(monitor_th); + } nlisten++; - set_nonblock(pcnf->sock); - LOG("Listening on port %d", pcnf->port); } else { @@ -210,133 +311,7 @@ int main(int argc, char* argv[]) stop_serve(0); exit(1); } - // default to 4 workers - antd_scheduler_init(&scheduler, conf->n_workers); - scheduler.validate_data = 1; - scheduler.destroy_data = finish_request; - // use blocking server_sock - // make the scheduler wait for event on another thread - // this allow to ged rid of high cpu usage on - // endless loop without doing anything - // set_nonblock(server_sock); - pthread_t scheduler_th; - if (pthread_create(&scheduler_th, NULL,(void *(*)(void *))antd_wait, (void*)&scheduler) != 0) - { - ERROR("pthread_create: cannot create worker"); - stop_serve(0); - exit(1); - } - else - { - // reclaim data when exit - pthread_detach(scheduler_th); - } - antd_task_t* task = NULL; - - fd_set read_flags, write_flags; - // first verify if the socket is ready - struct timeval timeout; - // select - - while (scheduler.status) - { - if(conf->connection > conf->maxcon) - { - //ERROR("Reach max connection %d", conf->connection); - timeout.tv_sec = 0; - timeout.tv_usec = 10000; // 5 ms - select(0, NULL, NULL, NULL, &timeout); - continue; - } - for_each_assoc(it, conf->ports) - { - pcnf = (port_config_t*) it->value; - if(pcnf->sock > 0) - { - FD_ZERO(&read_flags); - FD_SET(pcnf->sock, &read_flags); - FD_ZERO(&write_flags); - FD_SET(pcnf->sock, &write_flags); - timeout.tv_sec = 0; - timeout.tv_usec = 10000; // 10 ms - int sel = select(pcnf->sock + 1, &read_flags, &write_flags, (fd_set *)0, &timeout); - if(sel > 0 && (FD_ISSET(pcnf->sock, &read_flags) || FD_ISSET(pcnf->sock, &write_flags))) - { - client_sock = accept(pcnf->sock,(struct sockaddr *)&client_name,&client_name_len); - if (client_sock > 0) - { - // just dump the scheduler when we have a connection - antd_client_t* client = (antd_client_t*)malloc(sizeof(antd_client_t)); - antd_request_t* request = (antd_request_t*)malloc(sizeof(*request)); - request->client = client; - request->request = dict(); - client->zstream = NULL; - client->z_level = ANTD_CNONE; - - dictionary_t xheader = dict(); - dput(request->request, "REQUEST_HEADER", xheader); - dput(request->request, "REQUEST_DATA", dict()); - dput(xheader, "SERVER_PORT", (void *)__s("%d", pcnf->port)); - dput(xheader, "SERVER_WWW_ROOT", (void*)strdup(pcnf->htdocs)); - /* - get the remote IP - */ - if (client_name.sin_family == AF_INET) - { - client_ip = inet_ntoa(client_name.sin_addr); - LOG("Connect to client IP: %s on port:%d", client_ip, pcnf->port); - // ip address - dput(xheader, "REMOTE_ADDR", (void *)strdup(client_ip)); - //LOG("socket: %d\n", client_sock); - } - - // set timeout to socket - set_nonblock(client_sock); - /*struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 5000; - - if (setsockopt (client_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,sizeof(timeout)) < 0) - perror("setsockopt failed\n"); - - if (setsockopt (client_sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,sizeof(timeout)) < 0) - perror("setsockopt failed\n"); - */ - client->sock = client_sock; - time(&client->last_io); - client->ssl = NULL; - #ifdef USE_OPENSSL - client->status = 0; - if(pcnf->usessl == 1) - { - client->ssl = (void*)SSL_new(ctx); - if(!client->ssl) continue; - SSL_set_fd((SSL*)client->ssl, client->sock); - // this can be used in the protocol select callback to - // set the protocol selected by the server - if(!SSL_set_ex_data((SSL*)client->ssl, client->sock, client)) - { - ERROR("Cannot set ex data to ssl client:%d", client->sock); - } - /*if (SSL_accept((SSL*)client->ssl) <= 0) { - LOG("EROOR accept\n"); - ERR_print_errors_fp(stderr); - antd_close(client); - continue; - }*/ - } - #endif - conf->connection++; - // create callback for the server - task = antd_create_task(accept_request,(void*)request, finish_request, client->last_io); - //task->type = LIGHT; - antd_add_task(&scheduler, task); - } - } - } - } - } - + antd_wait(&scheduler); stop_serve(0); return(0); }