add multiport support

This commit is contained in:
lxsang 2019-12-20 16:49:41 +01:00
parent d04d29fe6b
commit 3435733ac2
12 changed files with 336 additions and 200 deletions

View File

@ -9,8 +9,6 @@ plugins=/opt/www/lib/
plugins_ext=.so plugins_ext=.so
; SQLITE database path ; SQLITE database path
database=/opt/www/database/ database=/opt/www/database/
; Website store here
htdocs=/opt/www/htdocs
; tmp dir ; tmp dir
tmpdir=/opt/www/tmp/ tmpdir=/opt/www/tmp/
; server log ; server log
@ -19,13 +17,35 @@ server_log = /var/log/antd.log
error_log = /var/log/antd_error.log error_log = /var/log/antd_error.log
; server backlocg ; server backlocg
backlog=5000 backlog=5000
; eable or disalbe SSL ; number of workers
ssl.enable=0 workers = 4
; if SSL is enable, one should specify ; if SSL is enable on one port, one should specify
; the SSL cert and key files ; the SSL cert and key files
; ssl.cert=fullchain.pem ;Example: self signed key
; ssl.key=privkey.pem ; openssl genrsa -des3 -passout pass:1234 -out keypair.key 2048
; 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 ; 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 ; This enable some plugins to be initialised at server startup
[AUTOSTART] [AUTOSTART]
; to start a plugin at server statup use: ; to start a plugin at server statup use:

View File

@ -82,8 +82,6 @@ void destroy_config()
free(server_config.plugins_ext); free(server_config.plugins_ext);
if (server_config.db_path) if (server_config.db_path)
free(server_config.db_path); free(server_config.db_path);
if (server_config.htdocs)
free(server_config.htdocs);
if (server_config.tmpdir) if (server_config.tmpdir)
free(server_config.tmpdir); free(server_config.tmpdir);
if(server_config.ssl_cipher) if(server_config.ssl_cipher)
@ -100,6 +98,22 @@ void destroy_config()
#endif #endif
if(server_config.mimes) if(server_config.mimes)
freedict(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); LOG("Unclosed connection: %d", server_config.connection);
} }
@ -107,12 +121,12 @@ static int config_handler(void *conf, const char *section, const char *name,
const char *value) const char *value)
{ {
config_t *pconfig = (config_t *)conf; config_t *pconfig = (config_t *)conf;
regmatch_t port_matches[2];
//trim(section, ' ');
//trim(value,' ');
//trim(name,' ');
//char * ppath = NULL; //char * ppath = NULL;
if (MATCH("SERVER", "port")) if (MATCH("SERVER", "plugins"))
{
pconfig->port = atoi(value);
}
else if (MATCH("SERVER", "plugins"))
{ {
pconfig->plugins_dir = strdup(value); 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); pconfig->db_path = strdup(value);
} }
else if (MATCH("SERVER", "htdocs"))
{
pconfig->htdocs = strdup(value);
}
else if (MATCH("SERVER", "tmpdir")) else if (MATCH("SERVER", "tmpdir"))
{ {
pconfig->tmpdir = strdup(value); pconfig->tmpdir = strdup(value);
@ -155,10 +165,6 @@ static int config_handler(void *conf, const char *section, const char *name,
} }
#endif #endif
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
else if (MATCH("SERVER", "ssl.enable"))
{
pconfig->usessl = atoi(value);
}
else if (MATCH("SERVER", "ssl.cert")) else if (MATCH("SERVER", "ssl.cert"))
{ {
pconfig->sslcert = strdup(value); 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)); 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 else
{ {
return 0; /* unknown section/name, error */ 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() void init_file_system()
{ {
struct stat st; struct stat st;
port_config_t* pcnf;
chain_t it;
if (stat(server_config.plugins_dir, &st) == -1) 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) if (stat(server_config.db_path, &st) == -1)
mkdir(server_config.db_path, 0755); mkdirp(server_config.db_path, 0755);
if (stat(server_config.htdocs, &st) == -1) for_each_assoc(it, server_config.ports)
mkdir(server_config.htdocs, 0755); {
pcnf = (port_config_t*) it->value;
if (stat(pcnf->htdocs, &st) == -1)
{
mkdirp(pcnf->htdocs, 0755);
}
}
if (stat(server_config.tmpdir, &st) == -1) if (stat(server_config.tmpdir, &st) == -1)
mkdir(server_config.tmpdir, 0755); mkdirp(server_config.tmpdir, 0755);
else else
{ {
removeAll(server_config.tmpdir, 0); removeAll(server_config.tmpdir, 0);
@ -215,22 +255,22 @@ void init_file_system()
} }
void load_config(const char *file) void load_config(const char *file)
{ {
server_config.port = 8888; server_config.ports = dict();
server_config.plugins_dir = "plugins/"; server_config.plugins_dir = "plugins/";
server_config.plugins_ext = ".dylib"; server_config.plugins_ext = ".dylib";
server_config.db_path = "databases/"; server_config.db_path = "databases/";
server_config.htdocs = "htdocs/"; //server_config.htdocs = "htdocs/";
server_config.tmpdir = "tmp/"; server_config.tmpdir = "tmp/";
server_config.n_workers = 4; server_config.n_workers = 4;
server_config.backlog = 100; server_config.backlog = 1000;
server_config.rules = list_init(); server_config.rules = list_init();
server_config.handlers = dict(); server_config.handlers = dict();
server_config.maxcon = 1000; server_config.maxcon = 100;
server_config.connection = 0; server_config.connection = 0;
server_config.errorfp = NULL; server_config.errorfp = NULL;
server_config.logfp = NULL; server_config.logfp = NULL;
server_config.mimes = dict(); server_config.mimes = dict();
server_config.usessl = 0; server_config.enable_ssl = 0;
server_config.sslcert = "cert.pem"; server_config.sslcert = "cert.pem";
server_config.sslkey = "key.pem"; server_config.sslkey = "key.pem";
server_config.ssl_cipher = NULL; server_config.ssl_cipher = NULL;
@ -247,7 +287,7 @@ void load_config(const char *file)
{ {
LOG("Using configuration : %s", file); LOG("Using configuration : %s", file);
#ifdef USE_OPENSSL #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 cert %s", server_config.sslcert);
LOG("SSL key %s", server_config.sslkey); LOG("SSL key %s", server_config.sslkey);
/*if(!server_config.ssl_cipher) /*if(!server_config.ssl_cipher)
@ -257,6 +297,7 @@ void load_config(const char *file)
#endif #endif
} }
LOG("%d mimes entries found", server_config.mimes->size); LOG("%d mimes entries found", server_config.mimes->size);
init_file_system();
} }
void *accept_request(void *data) void *accept_request(void *data)
@ -303,7 +344,7 @@ void *accept_request(void *data)
// perform the ssl handshake if enabled // perform the ssl handshake if enabled
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
int ret = -1, stat; 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); //LOG("Atttempt %d\n", client->attempt);
if (SSL_accept((SSL *)client->ssl) == -1) if (SSL_accept((SSL *)client->ssl) == -1)
@ -327,10 +368,10 @@ void *accept_request(void *data)
task->handle = accept_request; task->handle = accept_request;
return task; return task;
default: 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++; //server_config.connection++;
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
antd_error(rq->client, 400, "Invalid SSL request");
return task; return task;
} }
} }
@ -405,7 +446,7 @@ void *resolve_request(void *data)
char *newurl = NULL; char *newurl = NULL;
char *rqp = NULL; char *rqp = NULL;
char *oldrqp = NULL; char *oldrqp = NULL;
strcpy(path, server_config.htdocs); strcpy(path, rq->client->port_config->htdocs);
strcat(path, url); strcat(path, url);
//LOG("Path is : %s", path); //LOG("Path is : %s", path);
//if (path[strlen(path) - 1] == '/') //if (path[strlen(path) - 1] == '/')
@ -438,7 +479,7 @@ void *resolve_request(void *data)
{ {
newurl = __s("%s/index.%s", url, it->key); newurl = __s("%s/index.%s", url, it->key);
memset(path, 0, sizeof(path)); memset(path, 0, sizeof(path));
strcat(path, server_config.htdocs); strcat(path, rq->client->port_config->htdocs);
strcat(path, newurl); strcat(path, newurl);
if (stat(path, &st) != 0) 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; return 1;
} }
static void error_die(const char *sc)
{
perror(sc);
exit(1);
}
void *serve_file(void *data) void *serve_file(void *data)
{ {
antd_request_t *rq = (antd_request_t *)data; antd_request_t *rq = (antd_request_t *)data;
@ -626,23 +662,35 @@ int startup(unsigned *port)
httpd = socket(PF_INET, SOCK_STREAM, 0); httpd = socket(PF_INET, SOCK_STREAM, 0);
if (httpd == -1) if (httpd == -1)
error_die("socket"); {
ERROR("Port %d - socket: %s", *port, strerror(errno));
return -1;
}
memset(&name, 0, sizeof(name)); memset(&name, 0, sizeof(name));
name.sin_family = AF_INET; name.sin_family = AF_INET;
name.sin_port = htons(*port); name.sin_port = htons(*port);
name.sin_addr.s_addr = htonl(INADDR_ANY); name.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(httpd, (struct sockaddr *)&name, sizeof(name)) < 0) 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 */ if (*port == 0) /* if dynamically allocating a port */
{ {
socklen_t namelen = sizeof(name); socklen_t namelen = sizeof(name);
if (getsockname(httpd, (struct sockaddr *)&name, &namelen) == -1) 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); *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) if (listen(httpd, server_config.backlog) < 0)
error_die("listen"); {
ERROR("Port %d - listen: %s", *port, strerror(errno));
return -1;
}
return (httpd); return (httpd);
} }
@ -703,7 +751,7 @@ void *decode_request_header(void *data)
// this for check if web socket is enabled // this for check if web socket is enabled
// ip address // ip address
dput(xheader, "REMOTE_ADDR", (void *)strdup(((antd_client_t *)rq->client)->ip)); 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((line = read_line(client)) && strcmp("\r\n",line))
while ((read_buf(rq->client, buf, sizeof(buf))) && strcmp("\r\n", buf)) 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); //if(line) free(line);
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
strcat(buf, url); strcat(buf, url);
//LOG("Original query: %s", url); LOG("Original query: %s", url);
query = apply_rules(host, buf); query = apply_rules(host, buf);
//LOG("Processed query: %s", query); LOG("Processed query: %s", query);
dput(rq->request, "RESOURCE_PATH", url_decode(buf)); dput(rq->request, "RESOURCE_PATH", url_decode(buf));
if (query) if (query)
{ {
@ -1242,13 +1290,6 @@ void *execute_plugin(void *data, const char *pname)
return task; return task;
} }
#ifdef USE_OPENSSL
int usessl()
{
return server_config.usessl;
}
#endif
dictionary_t mimes_list() dictionary_t mimes_list()
{ {
return server_config.mimes; return server_config.mimes;

View File

@ -27,11 +27,8 @@ void* finish_request(void*);
void cat(void*, FILE *); void cat(void*, FILE *);
void cannot_execute(void*); void cannot_execute(void*);
//int get_line(int, char *, int); //int get_line(int, char *, int);
void not_found(void*);
void* serve_file(void*); void* serve_file(void*);
int startup(unsigned *); int startup(unsigned *);
void unimplemented(void*);
void badrequest(void*);
int rule_check(const char*, const char*, const char* , const char* , const char* , char*); int rule_check(const char*, const char*, const char* , const char* , const char* , char*);
void ws_confirm_request(void*, const char*); void ws_confirm_request(void*, const char*);
char* post_url_decode(void* client,int len); char* post_url_decode(void* client,int len);

93
httpd.c
View File

@ -4,7 +4,6 @@
#include "lib/ini.h" #include "lib/ini.h"
static antd_scheduler_t scheduler; static antd_scheduler_t scheduler;
static int server_sock = -1;
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
@ -63,23 +62,26 @@ void configure_context(SSL_CTX *ctx)
LOG("Cirpher suit used: %s", suit); LOG("Cirpher suit used: %s", suit);
if (SSL_CTX_set_cipher_list(ctx, suit) != 1) if (SSL_CTX_set_cipher_list(ctx, suit) != 1)
{ {
ERROR("Fail to set ssl cirpher suit: %s", suit);
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
/* Set the key and cert */ /* Set the key and cert */
/* use the full chain bundle of certificate */ /* 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_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); ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE); 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); ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (!SSL_CTX_check_private_key(ctx)) { if (!SSL_CTX_check_private_key(ctx)) {
ERROR("Failed to validate cert"); ERROR("Failed to validate SSL certificate");
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -111,8 +113,6 @@ void stop_serve(int dummy) {
// DEPRECATED: ERR_remove_state(0); // DEPRECATED: ERR_remove_state(0);
ERR_free_strings(); ERR_free_strings();
#endif #endif
if(server_sock != -1)
close(server_sock);
destroy_config(); destroy_config();
sigprocmask(SIG_UNBLOCK, &mask, NULL); sigprocmask(SIG_UNBLOCK, &mask, NULL);
} }
@ -124,7 +124,6 @@ int main(int argc, char* argv[])
load_config(CONFIG_FILE); load_config(CONFIG_FILE);
else else
load_config(argv[1]); load_config(argv[1]);
unsigned port = config()->port;
int client_sock = -1; int client_sock = -1;
struct sockaddr_in client_name; struct sockaddr_in client_name;
socklen_t client_name_len = sizeof(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(SIGABRT, SIG_IGN);
signal(SIGINT, stop_serve); signal(SIGINT, stop_serve);
config_t* conf = config();
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
if( config()->usessl == 1 ) if( conf->enable_ssl == 1 )
{ {
init_openssl(); init_openssl();
ctx = create_context(); ctx = create_context();
@ -145,10 +146,36 @@ int main(int argc, char* argv[])
} }
#endif #endif
server_sock = startup(&port); // startup port
LOG("httpd running on port %d", 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 // default to 4 workers
antd_scheduler_init(&scheduler, config()->n_workers); antd_scheduler_init(&scheduler, conf->n_workers);
scheduler.validate_data = 1; scheduler.validate_data = 1;
scheduler.destroy_data = finish_request; scheduler.destroy_data = finish_request;
// use blocking server_sock // use blocking server_sock
@ -169,18 +196,45 @@ int main(int argc, char* argv[])
pthread_detach(scheduler_th); pthread_detach(scheduler_th);
} }
antd_task_t* task = NULL; 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) while (scheduler.status)
{ {
client_sock = accept(server_sock,(struct sockaddr *)&client_name,&client_name_len); if(conf->connection > conf->maxcon)
if (client_sock == -1)
{ {
//ERROR("Reach max connection %d", conf->connection);
timeout.tv_sec = 0;
timeout.tv_usec = 5000; // 5 ms
select(0, NULL, NULL, NULL, &timeout);
continue; 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 = 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 // just dump the scheduler when we have a connection
antd_client_t* client = (antd_client_t*)malloc(sizeof(antd_client_t)); antd_client_t* client = (antd_client_t*)malloc(sizeof(antd_client_t));
antd_request_t* request = (antd_request_t*)malloc(sizeof(*request)); antd_request_t* request = (antd_request_t*)malloc(sizeof(*request));
request->client = client; request->client = client;
request->request = dict(); request->request = dict();
client->port_config = pcnf;
/* /*
get the remote IP get the remote IP
*/ */
@ -189,7 +243,7 @@ int main(int argc, char* argv[])
{ {
client_ip = inet_ntoa(client_name.sin_addr); client_ip = inet_ntoa(client_name.sin_addr);
client->ip = strdup(client_ip); client->ip = strdup(client_ip);
LOG("Client IP: %s", client_ip); LOG("Connect to client IP: %s on port:%d", client_ip, pcnf->port);
//LOG("socket: %d\n", client_sock); //LOG("socket: %d\n", client_sock);
} }
@ -210,7 +264,7 @@ int main(int argc, char* argv[])
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
client->ssl = NULL; client->ssl = NULL;
client->status = 0; client->status = 0;
if(config()->usessl == 1) if(pcnf->usessl == 1)
{ {
client->ssl = (void*)SSL_new(ctx); client->ssl = (void*)SSL_new(ctx);
if(!client->ssl) continue; if(!client->ssl) continue;
@ -224,14 +278,17 @@ int main(int argc, char* argv[])
}*/ }*/
} }
#endif #endif
config()->connection++; conf->connection++;
// create callback for the server // create callback for the server
task = antd_create_task(accept_request,(void*)request, finish_request, client->last_io); task = antd_create_task(accept_request,(void*)request, finish_request, client->last_io);
//task->type = LIGHT; //task->type = LIGHT;
antd_add_task(&scheduler, task); antd_add_task(&scheduler, task);
} }
}
}
}
}
close(server_sock); stop_serve(0);
return(0); return(0);
} }

View File

@ -1,6 +1,5 @@
#include "handle.h" #include "handle.h"
#define HTML_TPL "<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY><h2>%s</h2></BODY></HTML>" #define HTML_TPL "<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY><h2>%s</h2></BODY></HTML>"
#ifdef USE_OPENSSL
static const char* S_100 = "Continue"; static const char* S_100 = "Continue";
static const char* S_101 = "Switching Protocols"; 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_511 = "Network Authentication Required";
static const char* S_UNOF = "Unofficial Status"; 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) 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 writelen = 0;
int count; int count;
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
if(usessl()) if(source->port_config->usessl)
{ {
//LOG("SSL WRITE\n"); //LOG("SSL WRITE\n");
//ret = SSL_write((SSL*) source->ssl, data, len); //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: case SSL_ERROR_ZERO_RETURN:
{ {
// peer disconnected... // 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; break;
} }
@ -324,7 +305,7 @@ int antd_send(void *src, const void* data, int len)
{ {
if(written == 0) if(written == 0)
written = count; written = count;
//ERROR("Error while writing: %s", strerror(errno)); ERROR("Error while writing: %s", strerror(errno));
break; break;
//return written; //return written;
} }
@ -349,7 +330,7 @@ int antd_recv(void *src, void* data, int len)
int readlen=0; int readlen=0;
antd_client_t * source = (antd_client_t *) src; antd_client_t * source = (antd_client_t *) src;
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
if(usessl()) if(source->port_config->usessl)
{ {
ptr = (char* )data; ptr = (char* )data;
readlen = len > BUFFLEN?BUFFLEN:len; readlen = len > BUFFLEN?BUFFLEN:len;
@ -435,7 +416,7 @@ int antd_recv(void *src, void* data, int len)
break; break;
} }
} }
if(read = 0) if(read == 0)
read = received; read = received;
break; break;
} }
@ -478,7 +459,7 @@ int antd_recv(void *src, void* data, int len)
} }
else if(errno != EAGAIN && errno != EWOULDBLOCK) else if(errno != EAGAIN && errno != EWOULDBLOCK)
{ {
ERROR("Error while writing: %s", strerror(errno)); ERROR("Error while reading: %s", strerror(errno));
if(read ==0) if(read ==0)
read = received; read = received;
break; break;
@ -515,7 +496,7 @@ int antd_close(void* src)
if(!src) return -1; if(!src) return -1;
antd_client_t * source = (antd_client_t *) src; antd_client_t * source = (antd_client_t *) src;
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
if(source->ssl && usessl()){ if(source->port_config->usessl && source->ssl){
//printf("SSL:Shutdown ssl\n"); //printf("SSL:Shutdown ssl\n");
//SSL_shutdown((SSL*) source->ssl); //SSL_shutdown((SSL*) source->ssl);
SSL_set_shutdown((SSL*) source->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); SSL_set_shutdown((SSL*) source->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
@ -727,7 +708,7 @@ void destroy_request(void *data)
if (!data) if (!data)
return; return;
antd_request_t *rq = (antd_request_t *)data; 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 // free all other thing
if (rq->request) if (rq->request)
{ {

View File

@ -29,22 +29,26 @@
#define FORM_URL_ENCODE "application/x-www-form-urlencoded" #define FORM_URL_ENCODE "application/x-www-form-urlencoded"
#define FORM_MULTI_PART "multipart/form-data" #define FORM_MULTI_PART "multipart/form-data"
#define MAX_WAIT_S 2 // 1/3 minute #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; //extern config_t server_config;
typedef struct {
unsigned int port;
int usessl;
char* htdocs;
int sock;
} port_config_t;
typedef struct{ typedef struct{
int sock; int sock;
void* ssl; void* ssl;
char* ip; char* ip;
int port;
//#ifdef USE_OPENSSL //#ifdef USE_OPENSSL
int status; int status;
//#endif //#endif
time_t last_io; time_t last_io;
port_config_t* port_config;
} antd_client_t; } antd_client_t;
typedef struct { typedef struct {
@ -61,12 +65,13 @@ typedef struct
} antd_response_header_t; } antd_response_header_t;
typedef struct { typedef struct {
int port; //int port;
char *plugins_dir; char *plugins_dir;
char *plugins_ext; char *plugins_ext;
char *db_path; char *db_path;
char* htdocs; //char* htdocs;
char* tmpdir; char* tmpdir;
list_t rules; list_t rules;
dictionary_t handlers; dictionary_t handlers;
@ -79,24 +84,21 @@ typedef struct {
FILE* logfp; FILE* logfp;
// #endif // #endif
// #ifdef USE_OPENSSL // #ifdef USE_OPENSSL
int usessl; int enable_ssl;
char* sslcert; char* sslcert;
char* sslkey; char* sslkey;
char* ssl_cipher; char* ssl_cipher;
dictionary_t mimes; dictionary_t mimes;
dictionary_t ports;
// #endif // #endif
}config_t; }config_t;
typedef struct { typedef struct {
char *name; char *name;
char *dbpath; char *dbpath;
char * htdocs; char *tmpdir;
char*pdir; char*pdir;
int sport;
int raw_body; int raw_body;
//#ifdef USE_OPENSSL
int usessl;
//#endif
} plugin_header_t; } plugin_header_t;
void set_nonblock(int socket); void set_nonblock(int socket);

View File

@ -67,7 +67,7 @@ int ini_parse_file(FILE* file,
/* Maximum line length for any line in INI file. */ /* Maximum line length for any line in INI file. */
#ifndef INI_MAX_LINE #ifndef INI_MAX_LINE
#define INI_MAX_LINE 200 #define INI_MAX_LINE 512
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -39,13 +39,9 @@ static plugin_header_t __plugin__;
// private function // private function
void __init_plugin__(const char* pl,config_t* conf){ void __init_plugin__(const char* pl,config_t* conf){
__plugin__.name = strdup(pl); __plugin__.name = strdup(pl);
__plugin__.dbpath= strdup(conf->db_path); __plugin__.dbpath= conf->db_path;
__plugin__.htdocs = strdup(conf->htdocs); __plugin__.pdir = conf->plugins_dir;
__plugin__.pdir = strdup(conf->plugins_dir); __plugin__.tmpdir = = sconf->tmpdir;
__plugin__.sport = conf->port;
#ifdef USE_OPENSSL
__plugin__.usessl = conf->usessl;
#endif
__plugin__.raw_body = 0; __plugin__.raw_body = 0;
init(); init();
}; };
@ -72,13 +68,6 @@ sqldb getdb()
} }
#endif #endif
/*#ifdef USE_OPENSSL
int usessl()
{
LOG("CALLED from plugin \n");
return __plugin__.usessl;
}
#endif*/
plugin_header_t* meta() plugin_header_t* meta()
{ {
return &__plugin__; return &__plugin__;
@ -99,12 +88,9 @@ char* route(const char* repath)
return path; return path;
} }
char* htdocs(const char* repath) const char* tmpdir()
{ {
if(repath != NULL) return (const char*) __plugin__.tmpdir;
return __s("%s/%s",__plugin__.htdocs,repath);
else
return __s("%s",__plugin__.htdocs);
} }
char* config_dir() char* config_dir()
@ -121,9 +107,9 @@ void __release__()
destroy(); destroy();
LOG("Releasing plugin\n"); LOG("Releasing plugin\n");
if(__plugin__.name) free(__plugin__.name); if(__plugin__.name) free(__plugin__.name);
if(__plugin__.dbpath) free(__plugin__.dbpath); //if(__plugin__.dbpath) free(__plugin__.dbpath);
if(__plugin__.htdocs) free(__plugin__.htdocs); //if(__plugin__.htdocs) free(__plugin__.htdocs);
if(__plugin__.pdir) free(__plugin__.pdir); //if(__plugin__.pdir) free(__plugin__.pdir);
} }
#endif #endif
#endif #endif

View File

@ -25,6 +25,7 @@ static void stop(antd_scheduler_t* scheduler)
// unlock all idle workers if any // unlock all idle workers if any
for (int i = 0; i < scheduler->n_workers; i++) for (int i = 0; i < scheduler->n_workers; i++)
sem_post(scheduler->worker_sem); sem_post(scheduler->worker_sem);
if(scheduler->scheduler_sem)
sem_post(scheduler->scheduler_sem); sem_post(scheduler->scheduler_sem);
for (int i = 0; i < scheduler->n_workers; i++) for (int i = 0; i < scheduler->n_workers; i++)
if(scheduler->workers[i].id != -1) if(scheduler->workers[i].id != -1)

View File

@ -23,6 +23,22 @@ THE SOFTWARE.
*/ */
#include "utils.h" #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 * Trim a string by a character on both ends
* @param str The target string * @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 ){ if( reti ){
//ERROR("Could not compile regex: %s",expr); //ERROR("Could not compile regex: %s",expr);
regerror(reti, &regex, msgbuf, sizeof(msgbuf)); regerror(reti, &regex, msgbuf, sizeof(msgbuf));
//ERROR("Regex match failed: %s", msgbuf); ERROR("Regex match failed: %s", msgbuf);
return 0; //return 0;
} }
/* Execute regular expression */ /* Execute regular expression */
@ -458,3 +474,31 @@ char* __s(const char* fstring,...)
} else } else
return ""; 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);
}

View File

@ -54,13 +54,14 @@ THE SOFTWARE.
#define DIR_SEP "/" #define DIR_SEP "/"
#define true 1 #define true 1
#define false 0 #define false 0
#ifdef DEBUG #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__) __LINE__, ##__VA_ARGS__)
#else #else
#define LOG(a,...) do{}while(0) #define LOG(a,...) do{}while(0)
#endif #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__) __LINE__, ##__VA_ARGS__)
// add this to the utils // add this to the utils
#define UNUSED(x) (void)(x) #define UNUSED(x) (void)(x)
@ -73,6 +74,11 @@ typedef struct{
const char* ext; const char* ext;
} mime_t; } 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(); dictionary_t __attribute__((weak)) mimes_list();
char* __s(const char*,...); char* __s(const char*,...);
void trim(char*,const char); void trim(char*,const char);
@ -84,6 +90,7 @@ char* mime(const char*);
int match_int(const char*); int match_int(const char*);
int match_float(const char*); int match_float(const char*);
int regex_match(const char*,const char*, int, regmatch_t*); 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_decode(const char *str);
char *url_encode(const char *str); char *url_encode(const char *str);
char from_hex(char ch); char from_hex(char ch);

View File

@ -113,7 +113,7 @@ void unload_plugin_by_name(const char* name)
} }
else 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) if (np->next != NULL && strcmp(name, np->next->pname) == 0)
{ {