From 3435733ac21180613b5948c345caa6f15a2837ef Mon Sep 17 00:00:00 2001 From: lxsang Date: Fri, 20 Dec 2019 16:49:41 +0100 Subject: [PATCH] add multiport support --- antd-config.ini | 36 +++++++-- http_server.c | 145 +++++++++++++++++++++++------------- http_server.h | 3 - httpd.c | 189 ++++++++++++++++++++++++++++++----------------- lib/handle.c | 35 ++------- lib/handle.h | 32 ++++---- lib/ini.h | 2 +- lib/plugin.h | 30 ++------ lib/scheduler.c | 3 +- lib/utils.c | 48 +++++++++++- lib/utils.h | 11 ++- plugin_manager.c | 2 +- 12 files changed, 336 insertions(+), 200 deletions(-) diff --git a/antd-config.ini b/antd-config.ini index 817ad5b..0f8ad95 100644 --- a/antd-config.ini +++ b/antd-config.ini @@ -9,8 +9,6 @@ plugins=/opt/www/lib/ plugins_ext=.so ; SQLITE database path database=/opt/www/database/ -; Website store here -htdocs=/opt/www/htdocs ; tmp dir tmpdir=/opt/www/tmp/ ; server log @@ -19,13 +17,35 @@ server_log = /var/log/antd.log error_log = /var/log/antd_error.log ; server backlocg backlog=5000 -; eable or disalbe SSL -ssl.enable=0 -; if SSL is enable, one should specify +; number of workers +workers = 4 +; if SSL is enable on one port, one should specify ; the SSL cert and key files -; ssl.cert=fullchain.pem -; ssl.key=privkey.pem -; ssl.cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 +;Example: self signed key +; openssl genrsa -des3 -passout pass:1234 -out keypair.key 2048 +; openssl rsa -passin pass:1234 -in keypair.key -out server.key +; openssl req -new -key server.key -out server.csr +; openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt +ssl.cert=/opt/www/server.crt +ssl.key=/opt/www/server.key +ssl.cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + +; a configuration each port + +[PORT:443] +; Website store here +htdocs=/opt/www/htdocs +; enable or disalbe SSL +ssl.enable=1 + + +[PORT:80] +; Website store here +htdocs=/opt/www/htdocs +; enable or disalbe SSL +ssl.enable=0 + + ; This enable some plugins to be initialised at server startup [AUTOSTART] ; to start a plugin at server statup use: diff --git a/http_server.c b/http_server.c index f6d718e..30a188d 100644 --- a/http_server.c +++ b/http_server.c @@ -82,8 +82,6 @@ void destroy_config() free(server_config.plugins_ext); if (server_config.db_path) free(server_config.db_path); - if (server_config.htdocs) - free(server_config.htdocs); if (server_config.tmpdir) free(server_config.tmpdir); if(server_config.ssl_cipher) @@ -100,19 +98,35 @@ void destroy_config() #endif if(server_config.mimes) freedict(server_config.mimes); + if(server_config.ports) + { + chain_t it; + port_config_t* cnf; + for_each_assoc(it, server_config.ports) + { + cnf = (port_config_t*)it->value; + if(cnf && cnf->htdocs) + free(cnf->htdocs); + if(cnf->sock > 0) + { + close(cnf->sock); + } + } + freedict(server_config.ports); + } LOG("Unclosed connection: %d", server_config.connection); } static int config_handler(void *conf, const char *section, const char *name, - const char *value) + const char *value) { config_t *pconfig = (config_t *)conf; + regmatch_t port_matches[2]; + //trim(section, ' '); + //trim(value,' '); + //trim(name,' '); //char * ppath = NULL; - if (MATCH("SERVER", "port")) - { - pconfig->port = atoi(value); - } - else if (MATCH("SERVER", "plugins")) + if (MATCH("SERVER", "plugins")) { pconfig->plugins_dir = strdup(value); } @@ -124,10 +138,6 @@ static int config_handler(void *conf, const char *section, const char *name, { pconfig->db_path = strdup(value); } - else if (MATCH("SERVER", "htdocs")) - { - pconfig->htdocs = strdup(value); - } else if (MATCH("SERVER", "tmpdir")) { pconfig->tmpdir = strdup(value); @@ -155,10 +165,6 @@ static int config_handler(void *conf, const char *section, const char *name, } #endif #ifdef USE_OPENSSL - else if (MATCH("SERVER", "ssl.enable")) - { - pconfig->usessl = atoi(value); - } else if (MATCH("SERVER", "ssl.cert")) { pconfig->sslcert = strdup(value); @@ -191,6 +197,31 @@ static int config_handler(void *conf, const char *section, const char *name, { dput(pconfig->mimes,name,strdup(value)); } + else if( regex_match("PORT:\\s*([0-9]+)", section, 2, port_matches) ) + { + char buf[20]; + memset(buf, '\0', sizeof(buf)); + memcpy(buf, section + port_matches[1].rm_so, port_matches[1].rm_eo - port_matches[1].rm_so); + port_config_t* p = dvalue(pconfig->ports,buf); + if(!p) + { + p = (port_config_t*) malloc( sizeof(port_config_t)); + p->htdocs = NULL; + p->sock = -1; + dput(pconfig->ports,buf, p); + p->port = atoi(buf); + } + if(strcmp(name, "htdocs") == 0) + { + p->htdocs = strdup(value); + } + else if(strcmp(name, "ssl.enable") == 0) + { + p->usessl = atoi(value); + if(p->usessl) + pconfig->enable_ssl = 1; + } + } else { return 0; /* unknown section/name, error */ @@ -200,14 +231,23 @@ static int config_handler(void *conf, const char *section, const char *name, void init_file_system() { struct stat st; + port_config_t* pcnf; + chain_t it; if (stat(server_config.plugins_dir, &st) == -1) - mkdir(server_config.plugins_dir, 0755); + mkdirp(server_config.plugins_dir, 0755); if (stat(server_config.db_path, &st) == -1) - mkdir(server_config.db_path, 0755); - if (stat(server_config.htdocs, &st) == -1) - mkdir(server_config.htdocs, 0755); + mkdirp(server_config.db_path, 0755); + for_each_assoc(it, server_config.ports) + { + pcnf = (port_config_t*) it->value; + if (stat(pcnf->htdocs, &st) == -1) + { + mkdirp(pcnf->htdocs, 0755); + } + + } if (stat(server_config.tmpdir, &st) == -1) - mkdir(server_config.tmpdir, 0755); + mkdirp(server_config.tmpdir, 0755); else { removeAll(server_config.tmpdir, 0); @@ -215,22 +255,22 @@ void init_file_system() } void load_config(const char *file) { - server_config.port = 8888; + server_config.ports = dict(); server_config.plugins_dir = "plugins/"; server_config.plugins_ext = ".dylib"; server_config.db_path = "databases/"; - server_config.htdocs = "htdocs/"; + //server_config.htdocs = "htdocs/"; server_config.tmpdir = "tmp/"; server_config.n_workers = 4; - server_config.backlog = 100; + server_config.backlog = 1000; server_config.rules = list_init(); server_config.handlers = dict(); - server_config.maxcon = 1000; + server_config.maxcon = 100; server_config.connection = 0; server_config.errorfp = NULL; server_config.logfp = NULL; server_config.mimes = dict(); - server_config.usessl = 0; + server_config.enable_ssl = 0; server_config.sslcert = "cert.pem"; server_config.sslkey = "key.pem"; server_config.ssl_cipher = NULL; @@ -247,7 +287,7 @@ void load_config(const char *file) { LOG("Using configuration : %s", file); #ifdef USE_OPENSSL - LOG("SSL enable %d", server_config.usessl); + LOG("SSL enable %d", server_config.enable_ssl); LOG("SSL cert %s", server_config.sslcert); LOG("SSL key %s", server_config.sslkey); /*if(!server_config.ssl_cipher) @@ -257,6 +297,7 @@ void load_config(const char *file) #endif } LOG("%d mimes entries found", server_config.mimes->size); + init_file_system(); } void *accept_request(void *data) @@ -303,7 +344,7 @@ void *accept_request(void *data) // perform the ssl handshake if enabled #ifdef USE_OPENSSL int ret = -1, stat; - if (server_config.usessl == 1 && client->status == 0) + if (client->port_config->usessl == 1 && client->status == 0) { //LOG("Atttempt %d\n", client->attempt); if (SSL_accept((SSL *)client->ssl) == -1) @@ -327,10 +368,10 @@ void *accept_request(void *data) task->handle = accept_request; return task; default: - ERROR("Error performing SSL handshake %d %d %lu", stat, ret, ERR_get_error()); + ERROR("Error performing SSL handshake %d %d %s", stat, ret, ERR_error_string(ERR_get_error(), NULL)); + antd_error(rq->client, 400, "Invalid SSL request"); //server_config.connection++; ERR_print_errors_fp(stderr); - antd_error(rq->client, 400, "Invalid SSL request"); return task; } } @@ -405,7 +446,7 @@ void *resolve_request(void *data) char *newurl = NULL; char *rqp = NULL; char *oldrqp = NULL; - strcpy(path, server_config.htdocs); + strcpy(path, rq->client->port_config->htdocs); strcat(path, url); //LOG("Path is : %s", path); //if (path[strlen(path) - 1] == '/') @@ -438,7 +479,7 @@ void *resolve_request(void *data) { newurl = __s("%s/index.%s", url, it->key); memset(path, 0, sizeof(path)); - strcat(path, server_config.htdocs); + strcat(path, rq->client->port_config->htdocs); strcat(path, newurl); if (stat(path, &st) != 0) { @@ -578,11 +619,6 @@ int rule_check(const char *k, const char *v, const char *host, const char *_url, return 1; } -static void error_die(const char *sc) -{ - perror(sc); - exit(1); -} void *serve_file(void *data) { antd_request_t *rq = (antd_request_t *)data; @@ -626,23 +662,35 @@ int startup(unsigned *port) httpd = socket(PF_INET, SOCK_STREAM, 0); if (httpd == -1) - error_die("socket"); + { + ERROR("Port %d - socket: %s", *port, strerror(errno)); + return -1; + } memset(&name, 0, sizeof(name)); name.sin_family = AF_INET; name.sin_port = htons(*port); name.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(httpd, (struct sockaddr *)&name, sizeof(name)) < 0) - error_die("bind"); + { + ERROR("Port %d -bind: %s", *port, strerror(errno)); + return -1; + } if (*port == 0) /* if dynamically allocating a port */ { socklen_t namelen = sizeof(name); if (getsockname(httpd, (struct sockaddr *)&name, &namelen) == -1) - error_die("getsockname"); + { + ERROR("Port %d - getsockname: %s", *port, strerror(errno)); + return -1; + } *port = ntohs(name.sin_port); } - //LOG("back log is %d", server_config.backlog); + LOG("back log is %d", server_config.backlog); if (listen(httpd, server_config.backlog) < 0) - error_die("listen"); + { + ERROR("Port %d - listen: %s", *port, strerror(errno)); + return -1; + } return (httpd); } @@ -703,7 +751,7 @@ void *decode_request_header(void *data) // this for check if web socket is enabled // ip address dput(xheader, "REMOTE_ADDR", (void *)strdup(((antd_client_t *)rq->client)->ip)); - dput(xheader, "SERVER_PORT", (void *)__s("%d", server_config.port)); + dput(xheader, "SERVER_PORT", (void *)__s("%d", ((antd_client_t *)rq->client)->port_config->port)); //while((line = read_line(client)) && strcmp("\r\n",line)) while ((read_buf(rq->client, buf, sizeof(buf))) && strcmp("\r\n", buf)) { @@ -728,9 +776,9 @@ void *decode_request_header(void *data) //if(line) free(line); memset(buf, 0, sizeof(buf)); strcat(buf, url); - //LOG("Original query: %s", url); + LOG("Original query: %s", url); query = apply_rules(host, buf); - //LOG("Processed query: %s", query); + LOG("Processed query: %s", query); dput(rq->request, "RESOURCE_PATH", url_decode(buf)); if (query) { @@ -1242,13 +1290,6 @@ void *execute_plugin(void *data, const char *pname) return task; } -#ifdef USE_OPENSSL -int usessl() -{ - return server_config.usessl; -} -#endif - dictionary_t mimes_list() { return server_config.mimes; diff --git a/http_server.h b/http_server.h index 134bff4..29c91cc 100644 --- a/http_server.h +++ b/http_server.h @@ -27,11 +27,8 @@ void* finish_request(void*); void cat(void*, FILE *); void cannot_execute(void*); //int get_line(int, char *, int); -void not_found(void*); void* serve_file(void*); int startup(unsigned *); -void unimplemented(void*); -void badrequest(void*); int rule_check(const char*, const char*, const char* , const char* , const char* , char*); void ws_confirm_request(void*, const char*); char* post_url_decode(void* client,int len); diff --git a/httpd.c b/httpd.c index d5d4f5b..4e3ab5b 100644 --- a/httpd.c +++ b/httpd.c @@ -4,7 +4,6 @@ #include "lib/ini.h" static antd_scheduler_t scheduler; -static int server_sock = -1; #ifdef USE_OPENSSL @@ -63,23 +62,26 @@ void configure_context(SSL_CTX *ctx) LOG("Cirpher suit used: %s", suit); if (SSL_CTX_set_cipher_list(ctx, suit) != 1) { + ERROR("Fail to set ssl cirpher suit: %s", suit); ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } /* Set the key and cert */ /* use the full chain bundle of certificate */ //if (SSL_CTX_use_certificate_file(ctx, server_config->sslcert, SSL_FILETYPE_PEM) <= 0) { - if (SSL_CTX_use_certificate_chain_file(ctx, config()->sslcert) <= 0) { + if (SSL_CTX_use_certificate_chain_file(ctx, cnf->sslcert) <= 0) { + ERROR("Fail to read SSL certificate chain file: %s", cnf->sslcert); ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } - if (SSL_CTX_use_PrivateKey_file(ctx, config()->sslkey, SSL_FILETYPE_PEM) <= 0 ) { + if (SSL_CTX_use_PrivateKey_file(ctx, cnf->sslkey, SSL_FILETYPE_PEM) <= 0 ) { + ERROR("Fail to read SSL private file: %s", cnf->sslkey); ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } if (!SSL_CTX_check_private_key(ctx)) { - ERROR("Failed to validate cert"); + ERROR("Failed to validate SSL certificate"); ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } @@ -111,8 +113,6 @@ void stop_serve(int dummy) { // DEPRECATED: ERR_remove_state(0); ERR_free_strings(); #endif - if(server_sock != -1) - close(server_sock); destroy_config(); sigprocmask(SIG_UNBLOCK, &mask, NULL); } @@ -124,7 +124,6 @@ int main(int argc, char* argv[]) load_config(CONFIG_FILE); else load_config(argv[1]); - unsigned port = config()->port; int client_sock = -1; struct sockaddr_in client_name; socklen_t client_name_len = sizeof(client_name); @@ -135,8 +134,10 @@ int main(int argc, char* argv[]) signal(SIGABRT, SIG_IGN); signal(SIGINT, stop_serve); + config_t* conf = config(); + #ifdef USE_OPENSSL - if( config()->usessl == 1 ) + if( conf->enable_ssl == 1 ) { init_openssl(); ctx = create_context(); @@ -145,10 +146,36 @@ int main(int argc, char* argv[]) } #endif - server_sock = startup(&port); - LOG("httpd running on port %d", port); + // startup port + chain_t it; + port_config_t * pcnf; + int nlisten = 0; + for_each_assoc(it, conf->ports) + { + pcnf = (port_config_t*)it->value; + if(pcnf) + { + pcnf->sock = startup(&pcnf->port); + if(pcnf->sock>0) + { + nlisten++; + set_nonblock(pcnf->sock); + LOG("Listening on port %d", pcnf->port); + } + else + { + ERROR("Port %d is disabled", pcnf->port); + } + } + } + if(nlisten == 0) + { + ERROR("No port is listenned, quit!!"); + stop_serve(0); + exit(1); + } // default to 4 workers - antd_scheduler_init(&scheduler, config()->n_workers); + antd_scheduler_init(&scheduler, conf->n_workers); scheduler.validate_data = 1; scheduler.destroy_data = finish_request; // use blocking server_sock @@ -169,69 +196,99 @@ int main(int argc, char* argv[]) 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) { - client_sock = accept(server_sock,(struct sockaddr *)&client_name,&client_name_len); - if (client_sock == -1) + if(conf->connection > conf->maxcon) { + //ERROR("Reach max connection %d", conf->connection); + timeout.tv_sec = 0; + timeout.tv_usec = 5000; // 5 ms + select(0, NULL, NULL, NULL, &timeout); continue; } - // 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(); - /* - get the remote IP - */ - client->ip = NULL; - if (client_name.sin_family == AF_INET) + for_each_assoc(it, conf->ports) { - client_ip = inet_ntoa(client_name.sin_addr); - client->ip = strdup(client_ip); - LOG("Client IP: %s", client_ip); - //LOG("socket: %d\n", client_sock); + 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 = 5000; // 5 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->port_config = pcnf; + /* + get the remote IP + */ + client->ip = NULL; + if (client_name.sin_family == AF_INET) + { + client_ip = inet_ntoa(client_name.sin_addr); + client->ip = strdup(client_ip); + LOG("Connect to client IP: %s on port:%d", client_ip, pcnf->port); + //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); + #ifdef USE_OPENSSL + client->ssl = NULL; + 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); + + /*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); + } + } + } } - - // 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); -#ifdef USE_OPENSSL - client->ssl = NULL; - client->status = 0; - if(config()->usessl == 1) - { - client->ssl = (void*)SSL_new(ctx); - if(!client->ssl) continue; - SSL_set_fd((SSL*)client->ssl, client->sock); - - /*if (SSL_accept((SSL*)client->ssl) <= 0) { - LOG("EROOR accept\n"); - ERR_print_errors_fp(stderr); - antd_close(client); - continue; - }*/ - } -#endif - config()->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); } - close(server_sock); - + stop_serve(0); return(0); } diff --git a/lib/handle.c b/lib/handle.c index c7a3255..922fb87 100644 --- a/lib/handle.c +++ b/lib/handle.c @@ -1,6 +1,5 @@ #include "handle.h" #define HTML_TPL "%s

%s

" -#ifdef USE_OPENSSL static const char* S_100 = "Continue"; static const char* S_101 = "Switching Protocols"; @@ -70,24 +69,6 @@ static const char* S_510 = "Not Extended"; static const char* S_511 = "Network Authentication Required"; static const char* S_UNOF = "Unofficial Status"; -int usessl() -{ - return 0; -} -#endif - -void error_log(const char* fmt, ...) -{ - UNUSED(fmt); - return; -} -#ifdef DEBUG -void server_log(const char* fmt, ...) -{ - UNUSED(fmt); - return; -} -#endif const char* get_status_str(int stat) { @@ -210,7 +191,7 @@ int antd_send(void *src, const void* data, int len) int writelen = 0; int count; #ifdef USE_OPENSSL - if(usessl()) + if(source->port_config->usessl) { //LOG("SSL WRITE\n"); //ret = SSL_write((SSL*) source->ssl, data, len); @@ -246,7 +227,7 @@ int antd_send(void *src, const void* data, int len) case SSL_ERROR_ZERO_RETURN: { // peer disconnected... - ERROR("SSLWRITE: SSL_ERROR_ZERO_RETURN: peer disconected: %d", source->sock); + // ERROR("SSLWRITE: SSL_ERROR_ZERO_RETURN: peer disconected: %d", source->sock); break; } @@ -324,7 +305,7 @@ int antd_send(void *src, const void* data, int len) { if(written == 0) written = count; - //ERROR("Error while writing: %s", strerror(errno)); + ERROR("Error while writing: %s", strerror(errno)); break; //return written; } @@ -349,7 +330,7 @@ int antd_recv(void *src, void* data, int len) int readlen=0; antd_client_t * source = (antd_client_t *) src; #ifdef USE_OPENSSL - if(usessl()) + if(source->port_config->usessl) { ptr = (char* )data; readlen = len > BUFFLEN?BUFFLEN:len; @@ -435,7 +416,7 @@ int antd_recv(void *src, void* data, int len) break; } } - if(read = 0) + if(read == 0) read = received; break; } @@ -478,7 +459,7 @@ int antd_recv(void *src, void* data, int len) } else if(errno != EAGAIN && errno != EWOULDBLOCK) { - ERROR("Error while writing: %s", strerror(errno)); + ERROR("Error while reading: %s", strerror(errno)); if(read ==0) read = received; break; @@ -515,7 +496,7 @@ int antd_close(void* src) if(!src) return -1; antd_client_t * source = (antd_client_t *) src; #ifdef USE_OPENSSL - if(source->ssl && usessl()){ + if(source->port_config->usessl && source->ssl){ //printf("SSL:Shutdown ssl\n"); //SSL_shutdown((SSL*) source->ssl); SSL_set_shutdown((SSL*) source->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); @@ -727,7 +708,7 @@ void destroy_request(void *data) if (!data) return; antd_request_t *rq = (antd_request_t *)data; - LOG("Close request %d", rq->client->sock); + //LOG("Close request %d", rq->client->sock); // free all other thing if (rq->request) { diff --git a/lib/handle.h b/lib/handle.h index 1fa1e82..2bd5677 100644 --- a/lib/handle.h +++ b/lib/handle.h @@ -29,22 +29,26 @@ #define FORM_URL_ENCODE "application/x-www-form-urlencoded" #define FORM_MULTI_PART "multipart/form-data" #define MAX_WAIT_S 2 // 1/3 minute -#ifdef USE_OPENSSL -int __attribute__((weak)) usessl(); -#endif -void __attribute__((weak)) error_log(const char*, ...); -#ifdef DEBUG -void __attribute__((weak)) server_log(const char*, ...); -#endif + //extern config_t server_config; + +typedef struct { + unsigned int port; + int usessl; + char* htdocs; + int sock; +} port_config_t; + typedef struct{ int sock; void* ssl; char* ip; + int port; //#ifdef USE_OPENSSL int status; //#endif time_t last_io; + port_config_t* port_config; } antd_client_t; typedef struct { @@ -61,12 +65,13 @@ typedef struct } antd_response_header_t; + typedef struct { - int port; + //int port; char *plugins_dir; char *plugins_ext; char *db_path; - char* htdocs; + //char* htdocs; char* tmpdir; list_t rules; dictionary_t handlers; @@ -79,24 +84,21 @@ typedef struct { FILE* logfp; // #endif // #ifdef USE_OPENSSL - int usessl; + int enable_ssl; char* sslcert; char* sslkey; char* ssl_cipher; dictionary_t mimes; + dictionary_t ports; // #endif }config_t; typedef struct { char *name; char *dbpath; - char * htdocs; + char *tmpdir; char*pdir; - int sport; int raw_body; -//#ifdef USE_OPENSSL - int usessl; -//#endif } plugin_header_t; void set_nonblock(int socket); diff --git a/lib/ini.h b/lib/ini.h index 9442bec..273615e 100644 --- a/lib/ini.h +++ b/lib/ini.h @@ -67,7 +67,7 @@ int ini_parse_file(FILE* file, /* Maximum line length for any line in INI file. */ #ifndef INI_MAX_LINE -#define INI_MAX_LINE 200 +#define INI_MAX_LINE 512 #endif #ifdef __cplusplus diff --git a/lib/plugin.h b/lib/plugin.h index 1321f05..5799c12 100644 --- a/lib/plugin.h +++ b/lib/plugin.h @@ -39,13 +39,9 @@ static plugin_header_t __plugin__; // private function void __init_plugin__(const char* pl,config_t* conf){ __plugin__.name = strdup(pl); - __plugin__.dbpath= strdup(conf->db_path); - __plugin__.htdocs = strdup(conf->htdocs); - __plugin__.pdir = strdup(conf->plugins_dir); - __plugin__.sport = conf->port; -#ifdef USE_OPENSSL - __plugin__.usessl = conf->usessl; -#endif + __plugin__.dbpath= conf->db_path; + __plugin__.pdir = conf->plugins_dir; + __plugin__.tmpdir = = sconf->tmpdir; __plugin__.raw_body = 0; init(); }; @@ -72,13 +68,6 @@ sqldb getdb() } #endif -/*#ifdef USE_OPENSSL -int usessl() - { - LOG("CALLED from plugin \n"); - return __plugin__.usessl; - } - #endif*/ plugin_header_t* meta() { return &__plugin__; @@ -99,12 +88,9 @@ char* route(const char* repath) return path; } -char* htdocs(const char* repath) +const char* tmpdir() { - if(repath != NULL) - return __s("%s/%s",__plugin__.htdocs,repath); - else - return __s("%s",__plugin__.htdocs); + return (const char*) __plugin__.tmpdir; } char* config_dir() @@ -121,9 +107,9 @@ void __release__() destroy(); LOG("Releasing plugin\n"); if(__plugin__.name) free(__plugin__.name); - if(__plugin__.dbpath) free(__plugin__.dbpath); - if(__plugin__.htdocs) free(__plugin__.htdocs); - if(__plugin__.pdir) free(__plugin__.pdir); + //if(__plugin__.dbpath) free(__plugin__.dbpath); + //if(__plugin__.htdocs) free(__plugin__.htdocs); + //if(__plugin__.pdir) free(__plugin__.pdir); } #endif #endif diff --git a/lib/scheduler.c b/lib/scheduler.c index 9c8f5cd..85e45a7 100644 --- a/lib/scheduler.c +++ b/lib/scheduler.c @@ -25,7 +25,8 @@ static void stop(antd_scheduler_t* scheduler) // unlock all idle workers if any for (int i = 0; i < scheduler->n_workers; i++) sem_post(scheduler->worker_sem); - sem_post(scheduler->scheduler_sem); + if(scheduler->scheduler_sem) + sem_post(scheduler->scheduler_sem); for (int i = 0; i < scheduler->n_workers; i++) if(scheduler->workers[i].id != -1) pthread_join(scheduler->workers[i].tid, NULL); diff --git a/lib/utils.c b/lib/utils.c index 617c596..8630178 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -23,6 +23,22 @@ THE SOFTWARE. */ #include "utils.h" + +void error_log(const char* fmt, ...) +{ + UNUSED(fmt); + return; +} +#ifdef DEBUG +void server_log(const char* fmt, ...) +{ + UNUSED(fmt); + return; +} +#endif + + + /** * Trim a string by a character on both ends * @param str The target string @@ -197,8 +213,8 @@ int regex_match(const char* expr,const char* search, int msize, regmatch_t* matc if( reti ){ //ERROR("Could not compile regex: %s",expr); regerror(reti, ®ex, msgbuf, sizeof(msgbuf)); - //ERROR("Regex match failed: %s", msgbuf); - return 0; + ERROR("Regex match failed: %s", msgbuf); + //return 0; } /* Execute regular expression */ @@ -457,4 +473,32 @@ char* __s(const char* fstring,...) return data; } else return ""; +} + +int mkdirp(const char* path, mode_t mode) +{ + char tmp[BUFFLEN]; + if(strlen(path) > BUFFLEN) + { + ERROR("mkdirp: Path is too long %s", path); + return -1; + } + char *p = NULL; + size_t len; + int stat; + snprintf(tmp, sizeof(tmp),"%s",path); + len = strlen(tmp); + if(tmp[len - 1] == '/') + tmp[len - 1] = 0; + for(p = tmp + 1; *p; p++) + { + if(*p == '/') { + *p = 0; + stat = mkdir(tmp, mode); + if(stat == -1 && errno != EEXIST) + return stat; + *p = '/'; + } + } + return mkdir(path, mode); } \ No newline at end of file diff --git a/lib/utils.h b/lib/utils.h index 0323234..c1f32de 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -54,13 +54,14 @@ THE SOFTWARE. #define DIR_SEP "/" #define true 1 #define false 0 + #ifdef DEBUG - #define LOG(a,...) server_log("[%s: %d]: " a "\n", __FILE__, \ + #define LOG(a,...) server_log("%s: [%s: %d]: " a "\n",server_time(), __FILE__, \ __LINE__, ##__VA_ARGS__) #else #define LOG(a,...) do{}while(0) #endif -#define ERROR(a,...) error_log("[%s: %d]: " a "\n", __FILE__, \ +#define ERROR(a,...) error_log("%s: [%s: %d]: " a "\n", server_time() , __FILE__, \ __LINE__, ##__VA_ARGS__) // add this to the utils #define UNUSED(x) (void)(x) @@ -73,6 +74,11 @@ typedef struct{ const char* ext; } mime_t; + +void __attribute__((weak)) error_log(const char*, ...); +#ifdef DEBUG +void __attribute__((weak)) server_log(const char*, ...); +#endif dictionary_t __attribute__((weak)) mimes_list(); char* __s(const char*,...); void trim(char*,const char); @@ -84,6 +90,7 @@ char* mime(const char*); int match_int(const char*); int match_float(const char*); int regex_match(const char*,const char*, int, regmatch_t*); +int mkdirp(const char* path,mode_t mode); char *url_decode(const char *str); char *url_encode(const char *str); char from_hex(char ch); diff --git a/plugin_manager.c b/plugin_manager.c index 4b17f7d..be3a59c 100644 --- a/plugin_manager.c +++ b/plugin_manager.c @@ -113,7 +113,7 @@ void unload_plugin_by_name(const char* name) } else { - for (np ; np != NULL; np = np->next) + for (np = plugin_table[hasval] ; np != NULL; np = np->next) { if (np->next != NULL && strcmp(name, np->next->pname) == 0) {