Compare commits

..

No commits in common. "a78815c3b6f8aa727cdccc7baace02fee95f429c" and "5d7a0f8b4991754f3088e7284dc4f16ddb13c5da" have entirely different histories.

7 changed files with 73 additions and 165 deletions

View File

@ -30,8 +30,6 @@ ssl.cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA
; enable compression ; enable compression
gzip_enable = 1 gzip_enable = 1
gzip_types = text\/.*,.*\/css,.*\/json,.*\/javascript gzip_types = text\/.*,.*\/css,.*\/json,.*\/javascript
debug_enable = 1
; 0 to disable
; a configuration each port ; a configuration each port
@ -54,8 +52,6 @@ ssl.enable=0
[PORT:80] [PORT:80]
htdocs=/opt/www/htdocs htdocs=/opt/www/htdocs
; enable specific plugin
plugins=lua,tunnel
; enable or disable SSL ; enable or disable SSL
ssl.enable=0 ssl.enable=0
; ^\/os\/+(.*)$ = /proxy/http://localhost:443/test.html?<query> ; ^\/os\/+(.*)$ = /proxy/http://localhost:443/test.html?<query>
@ -99,17 +95,22 @@ application/x-font-woff=woff,woff2
application/x-font-otf=otf application/x-font-otf=otf
audio/mpeg=mp3,mpeg audio/mpeg=mp3,mpeg
[FILEHANDLER]
; specify a plugin for handling
; a file type
; lua page script
ls = lua
; pure lua script
lua = lua
; php and o ther scripting languages can be
; handled by the cgi plugin
; php = cgi
; Example of plugin configurations
[PLUGIN:php] ; This enable some plugins to be initialised at server startup
; theses configurations is understandable by the server ; this section shall always at the end of the
; the name of the plugin in plugin dir ; configuration file
name = fastcgi [AUTOSTART]
; run this plugin at startup ; to start a plugin at server statup use:
autoload = true ;plugin = plugin_name_1
; file handle ;plugin = plugin_name_2, etc
file_type = php,pp
; pluggin specific configurations here, for example
socket = /var/php.sock
bin = /usr/bin/phpfcgi
; etc

View File

@ -58,7 +58,6 @@ config_t *config()
} }
void destroy_config() void destroy_config()
{ {
chain_t it;
freedict(server_config.handlers); freedict(server_config.handlers);
if (server_config.plugins_dir) if (server_config.plugins_dir)
free(server_config.plugins_dir); free(server_config.plugins_dir);
@ -76,16 +75,9 @@ void destroy_config()
freedict(server_config.mimes); freedict(server_config.mimes);
if (server_config.stat_fifo_path) if (server_config.stat_fifo_path)
free(server_config.stat_fifo_path); free(server_config.stat_fifo_path);
if(server_config.plugins)
{
for_each_assoc(it, server_config.plugins)
{
freedict((dictionary_t) it->value);
}
freedict(server_config.plugins);
}
if (server_config.ports) if (server_config.ports)
{ {
chain_t it;
port_config_t *cnf; port_config_t *cnf;
for_each_assoc(it, server_config.ports) for_each_assoc(it, server_config.ports)
{ {
@ -94,8 +86,6 @@ void destroy_config()
{ {
if (cnf->htdocs != NULL) if (cnf->htdocs != NULL)
free(cnf->htdocs); free(cnf->htdocs);
if(cnf->plugins)
free(cnf->plugins);
if (cnf->sock > 0) if (cnf->sock > 0)
{ {
close(cnf->sock); close(cnf->sock);
@ -112,8 +102,7 @@ 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 regex_matches[2]; regmatch_t port_matches[2];
char buf[255];
char * tmp; char * tmp;
struct stat st; struct stat st;
// trim(section, ' '); // trim(section, ' ');
@ -244,20 +233,30 @@ static int config_handler(void *conf, const char *section, const char *name,
pconfig->ssl_cipher = strdup(value); pconfig->ssl_cipher = strdup(value);
} }
#endif #endif
else if (strcmp(section, "FILEHANDLER") == 0)
{
dput(pconfig->handlers, name, strdup(value));
}
else if (strcmp(section, "AUTOSTART") == 0 || strcmp(section, "AUTOLOAD") == 0)
{
// The server section must be added before the autostart section
// auto start plugin
plugin_load((char *)value);
}
else if (strcmp(section, "MIMES") == 0) else if (strcmp(section, "MIMES") == 0)
{ {
dput(pconfig->mimes, name, strdup(value)); dput(pconfig->mimes, name, strdup(value));
} }
else if (regex_match("PORT:\\s*([0-9]+)", section, 2, regex_matches)) else if (regex_match("PORT:\\s*([0-9]+)", section, 2, port_matches))
{ {
char buf[20];
memset(buf, '\0', sizeof(buf)); memset(buf, '\0', sizeof(buf));
memcpy(buf, section + regex_matches[1].rm_so, regex_matches[1].rm_eo - regex_matches[1].rm_so); 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); port_config_t *p = dvalue(pconfig->ports, buf);
if (!p) if (!p)
{ {
p = (port_config_t *)malloc(sizeof(port_config_t)); p = (port_config_t *)malloc(sizeof(port_config_t));
p->htdocs = NULL; p->htdocs = NULL;
p->plugins = NULL;
p->sock = -1; p->sock = -1;
p->rules = dict_n(1); p->rules = dict_n(1);
dput(pconfig->ports, buf, p); dput(pconfig->ports, buf, p);
@ -280,10 +279,6 @@ static int config_handler(void *conf, const char *section, const char *name,
LOG("Server root is %s", p->htdocs); LOG("Server root is %s", p->htdocs);
} }
} }
else if(strcmp(name, "plugins") == 0)
{
p->plugins = strdup(value);
}
else if (strcmp(name, "ssl.enable") == 0) else if (strcmp(name, "ssl.enable") == 0)
{ {
p->usessl = atoi(value); p->usessl = atoi(value);
@ -296,19 +291,6 @@ static int config_handler(void *conf, const char *section, const char *name,
dput(p->rules, name, strdup(value)); dput(p->rules, name, strdup(value));
} }
} }
// plugin configuration
else if (regex_match("PLUGIN:\\s*(.*)", section, 2, regex_matches))
{
memset(buf, '\0', sizeof(buf));
memcpy(buf, section + regex_matches[1].rm_so, regex_matches[1].rm_eo - regex_matches[1].rm_so);
dictionary_t p = dvalue(pconfig->plugins, buf);
if (!p)
{
p = dict();
dput(pconfig->plugins, buf, p);
}
dput(p, name, strdup(value));
}
else else
{ {
return 0; /* unknown section/name, error */ return 0; /* unknown section/name, error */
@ -316,51 +298,9 @@ static int config_handler(void *conf, const char *section, const char *name,
return 1; return 1;
} }
static void init_plugins()
{
chain_t it, it2;
dictionary_t config;
const char* value;
for_each_assoc(it, server_config.plugins)
{
config = (dictionary_t) it -> value;
if(config)
{
for_each_assoc(it2, config)
{
LOG("Plugin %s: [%s] -> [%s]", it->key, it2->key, (char*) it2->value);
if(strncmp(it2->key, "file_type", 9) == 0 && it2->value)
{
char* file_type = strdup((char*) it2->value);
char* token;
char *stringp = file_type;
while((token = strsep(&stringp,",")))
{
trim(token, ' ');
if(strlen(token) > 0)
{
dput(server_config.handlers,token, strdup((char*)it->key));
LOG("Plugin %s: support %s file", it->key, token);
}
}
free(file_type);
}
}
value = (char*)dvalue(config,"autoload");
if( value && (strncmp(value,"1", 1) == 0 || strncmp(value, "true", 3) == 0 ) )
{
// load the plugin
LOG("Plugin %s: autoloading...", it->key);
plugin_load(it->key, config);
}
}
}
}
void load_config(const char *file) void load_config(const char *file)
{ {
server_config.ports = dict(); server_config.ports = dict();
server_config.plugins = dict();
server_config.plugins_dir = strdup("plugins/"); server_config.plugins_dir = strdup("plugins/");
server_config.plugins_ext = strdup(".so"); server_config.plugins_ext = strdup(".so");
server_config.db_path = strdup("databases/"); server_config.db_path = strdup("databases/");
@ -405,8 +345,6 @@ 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 plugins if necessary
init_plugins();
} }
void *accept_request(void *data) void *accept_request(void *data)
@ -1688,34 +1626,22 @@ void *execute_plugin(void *data, const char *pname)
plugin_header_t *meta = NULL; plugin_header_t *meta = NULL;
struct plugin_entry *plugin; struct plugin_entry *plugin;
char *error; char *error;
char pattern[256];
antd_request_t *rq = (antd_request_t *)data; antd_request_t *rq = (antd_request_t *)data;
antd_task_t *task = antd_create_task(NULL, (void *)rq, NULL, rq->client->last_io); antd_task_t *task = antd_create_task(NULL, (void *)rq, NULL, rq->client->last_io);
antd_task_bind_event(task, rq->client->sock, 0, TASK_EVT_ON_WRITABLE | TASK_EVT_ON_READABLE); antd_task_bind_event(task, rq->client->sock, 0, TASK_EVT_ON_WRITABLE | TASK_EVT_ON_READABLE);
snprintf(pattern, sizeof(pattern), "\\b%s\\b", pname);
char *port_s = (char *)dvalue(rq->request, "SERVER_PORT");
port_config_t *pcnf = (port_config_t *)dvalue(server_config.ports, port_s);
// check if plugin is enabled on this port
if(!pcnf->plugins || !regex_match(pattern, pcnf->plugins , 0,NULL))
{
LOG("No plugin matched in [%s] using pattern [%s]", pcnf->plugins, pattern);
antd_error(rq->client, 403, "Access forbidden");
return task;
}
// LOG("Plugin name '%s'", pname); // LOG("Plugin name '%s'", pname);
rq->client->state = ANTD_CLIENT_PLUGIN_EXEC; rq->client->state = ANTD_CLIENT_PLUGIN_EXEC;
// load the plugin // load the plugin
pthread_mutex_lock(&server_mux); if ((plugin = plugin_lookup((char *)pname)) == NULL)
plugin = plugin_load((char *)pname, dvalue(server_config.plugins, pname));
pthread_mutex_unlock(&server_mux);
if (plugin == NULL)
{ {
antd_error(rq->client, 503, "Requested service not found"); pthread_mutex_lock(&server_mux);
return task; plugin = plugin_load((char *)pname);
pthread_mutex_unlock(&server_mux);
if (plugin == NULL)
{
antd_error(rq->client, 503, "Requested service not found");
return task;
}
} }
// check if the plugin want rawbody or decoded body // check if the plugin want rawbody or decoded body
metafn = (plugin_header_t * (*)()) dlsym(plugin->handle, "meta"); metafn = (plugin_header_t * (*)()) dlsym(plugin->handle, "meta");
@ -1749,17 +1675,17 @@ dictionary_t mimes_list()
return server_config.mimes; return server_config.mimes;
} }
void dbdir(char **dest) void dbdir(char *dest)
{ {
*dest = server_config.db_path; strncpy(dest, server_config.db_path, 512);
} }
void tmpdir(char **dest) void tmpdir(char *dest)
{ {
*dest = server_config.tmpdir; strncpy(dest, server_config.tmpdir, 512);
} }
void plugindir(char **dest) void plugindir(char *dest)
{ {
*dest =server_config.plugins_dir; strncpy(dest, server_config.plugins_dir, 512);
} }
#ifdef USE_ZLIB #ifdef USE_ZLIB

View File

@ -115,15 +115,15 @@ void htdocs(antd_request_t *rq, char *dest)
strcpy(dest, www); strcpy(dest, www);
} }
} }
void dbdir(char **dest) void dbdir(char *dest)
{ {
UNUSED(dest); UNUSED(dest);
} }
void tmpdir(char **dest) void tmpdir(char *dest)
{ {
UNUSED(dest); UNUSED(dest);
} }
void plugindir(char **dest) void plugindir(char *dest)
{ {
UNUSED(dest); UNUSED(dest);
} }

View File

@ -42,7 +42,6 @@ typedef struct
unsigned int port; unsigned int port;
int usessl; int usessl;
char *htdocs; char *htdocs;
char* plugins;
int sock; int sock;
dictionary_t rules; dictionary_t rules;
} port_config_t; } port_config_t;
@ -99,25 +98,23 @@ typedef struct
list_t gzip_types; list_t gzip_types;
dictionary_t mimes; dictionary_t mimes;
dictionary_t ports; dictionary_t ports;
dictionary_t plugins;
// #endif // #endif
} config_t; } config_t;
typedef struct typedef struct
{ {
char name[128]; char name[128];
char* dbpath; char dbpath[512];
char* tmpdir; char tmpdir[512];
char* pdir; char pdir[512];
dictionary_t config;
int raw_body; int raw_body;
} plugin_header_t; } plugin_header_t;
int __attribute__((weak)) require_plugin(const char *); int __attribute__((weak)) require_plugin(const char *);
void __attribute__((weak)) htdocs(antd_request_t *rq, char *dest); void __attribute__((weak)) htdocs(antd_request_t *rq, char *dest);
void __attribute__((weak)) dbdir(char **dest); void __attribute__((weak)) dbdir(char *dest);
void __attribute__((weak)) tmpdir(char **dest); void __attribute__((weak)) tmpdir(char *dest);
void __attribute__((weak)) plugindir(char **dest); void __attribute__((weak)) plugindir(char *dest);
int __attribute__((weak)) compressable(char *ctype); int __attribute__((weak)) compressable(char *ctype);

View File

@ -35,12 +35,11 @@ STATIC PART, should be included in any plugin
#ifdef PLUGIN_IMPLEMENT #ifdef PLUGIN_IMPLEMENT
static plugin_header_t __plugin__; static plugin_header_t __plugin__;
// private function // private function
void __init_plugin__(const char* pl, dictionary_t* conf){ void __init_plugin__(const char* pl){
strcpy(__plugin__.name,pl); strcpy(__plugin__.name,pl);
dbdir(&__plugin__.dbpath); dbdir(__plugin__.dbpath);
plugindir(&__plugin__.pdir); plugindir(__plugin__.pdir);
tmpdir(&__plugin__.tmpdir); tmpdir(__plugin__.tmpdir);
__plugin__.config = conf;
__plugin__.raw_body = 0; __plugin__.raw_body = 0;
init(); init();
}; };

View File

@ -4,10 +4,6 @@
#include "lib/utils.h" #include "lib/utils.h"
#include "lib/handle.h" #include "lib/handle.h"
#include "http_server.h" #include "http_server.h"
static void unload_plugin_by_name(const char*);
static void * plugin_from_file(char* name, dictionary_t conf);
/** /**
* Plugin table to store the loaded plugin * Plugin table to store the loaded plugin
*/ */
@ -29,7 +25,7 @@ struct plugin_entry *plugin_lookup(char *s)
int require_plugin(const char* name) int require_plugin(const char* name)
{ {
struct plugin_entry* ptr = plugin_load((char*)name, NULL); struct plugin_entry* ptr = plugin_load((char*)name);
return ptr != NULL; return ptr != NULL;
} }
@ -37,24 +33,13 @@ int require_plugin(const char* name)
* Load a plugin to the plugin table * Load a plugin to the plugin table
* Only load when not available in the plugin table * Only load when not available in the plugin table
* @param name plugin name * @param name plugin name
* @param config: plugin configuration
* @return pointer to the loaded plugin * @return pointer to the loaded plugin
*/ */
struct plugin_entry *plugin_load(char *name, dictionary_t config) struct plugin_entry *plugin_load(char *name)
{ {
char* pname = NULL;
struct plugin_entry *np; struct plugin_entry *np;
unsigned hashval; unsigned hashval;
if(config)
{
pname = dvalue(config, "name");
}
if(!pname)
{
pname = name;
}
if ((np = plugin_lookup(name)) == NULL) { /* not found */ if ((np = plugin_lookup(name)) == NULL) { /* not found */
LOG("Loading plugin: %s -> %s", name, pname);
np = (struct plugin_entry *) malloc(sizeof(*np)); np = (struct plugin_entry *) malloc(sizeof(*np));
if (np == NULL || name == NULL) if (np == NULL || name == NULL)
{ {
@ -62,7 +47,7 @@ struct plugin_entry *plugin_load(char *name, dictionary_t config)
return NULL; return NULL;
} }
np->pname = strdup(name); np->pname = strdup(name);
if ((np->handle = plugin_from_file(pname,config)) == NULL) if ((np->handle = plugin_from_file(name)) == NULL)
{ {
if(np->pname) free(np->pname); if(np->pname) free(np->pname);
if(np) free(np); if(np) free(np);
@ -83,12 +68,12 @@ struct plugin_entry *plugin_load(char *name, dictionary_t config)
* @param name Name of the plugin * @param name Name of the plugin
* @return * @return
*/ */
static void * plugin_from_file(char* name, dictionary_t conf) void * plugin_from_file(char* name)
{ {
void *lib_handle; void *lib_handle;
char* error; char* error;
char* path = __s("%s/%s%s",config()->plugins_dir,name,config()->plugins_ext); char* path = __s("%s/%s%s",config()->plugins_dir,name,config()->plugins_ext);
void (*fn)(const char*, dictionary_t); void (*fn)(const char*);
lib_handle = dlopen(path, RTLD_LAZY); lib_handle = dlopen(path, RTLD_LAZY);
if (!lib_handle) if (!lib_handle)
{ {
@ -98,11 +83,11 @@ static void * plugin_from_file(char* name, dictionary_t conf)
return NULL; return NULL;
} }
// set database path // set database path
fn = (void (*)(const char*, dictionary_t))dlsym(lib_handle, "__init_plugin__"); fn = (void (*)(const char *))dlsym(lib_handle, "__init_plugin__");
if ((error = dlerror()) != NULL) if ((error = dlerror()) != NULL)
ERROR("Problem when finding plugin init function for %s : %s", name,error); ERROR("Problem when finding plugin init function for %s : %s", name,error);
else else
(*fn)(name, conf); (*fn)(name);
if(path) if(path)
free(path); free(path);
return lib_handle; return lib_handle;

View File

@ -1,8 +1,5 @@
#ifndef PLUGIN_MANAGER_H #ifndef PLUGIN_MANAGER_H
#define PLUGIN_MANAGER_H #define PLUGIN_MANAGER_H
#include "lib/dictionary.h"
struct plugin_entry { struct plugin_entry {
struct plugin_entry *next; struct plugin_entry *next;
char *pname; char *pname;
@ -11,7 +8,10 @@ struct plugin_entry {
/* lookup: look for s in hashtab */ /* lookup: look for s in hashtab */
struct plugin_entry *plugin_lookup(char *s); struct plugin_entry *plugin_lookup(char *s);
/* install: put (name, defn) in hashtab */ /* install: put (name, defn) in hashtab */
struct plugin_entry *plugin_load(char *name, dictionary_t config); struct plugin_entry *plugin_load(char *name);
void unload_all_plugin(); void unload_all_plugin();
void unload_plugin(struct plugin_entry*); void unload_plugin(struct plugin_entry*);
void unload_plugin_by_name(const char*);
void * plugin_from_file(char* name);
#endif #endif