mirror of
https://github.com/lxsang/ant-http
synced 2024-11-17 17:08:20 +01:00
Allow specific configuration for plugins
This commit is contained in:
parent
5d7a0f8b49
commit
4e1c220b39
@ -30,6 +30,8 @@ ssl.cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA
|
||||
; enable compression
|
||||
gzip_enable = 1
|
||||
gzip_types = text\/.*,.*\/css,.*\/json,.*\/javascript
|
||||
debug_enable = 1
|
||||
; 0 to disable
|
||||
|
||||
; a configuration each port
|
||||
|
||||
@ -106,11 +108,14 @@ lua = lua
|
||||
; handled by the cgi plugin
|
||||
; php = cgi
|
||||
|
||||
|
||||
; This enable some plugins to be initialised at server startup
|
||||
; this section shall always at the end of the
|
||||
; configuration file
|
||||
[AUTOSTART]
|
||||
; to start a plugin at server statup use:
|
||||
;plugin = plugin_name_1
|
||||
;plugin = plugin_name_2, etc
|
||||
; Example of plugin configurations
|
||||
[PLUGIN:php]
|
||||
; theses configurations is understandable by the server
|
||||
; the name of the plugin in plugin dir
|
||||
name = fastcgi
|
||||
; run this plugin at startup
|
||||
autoload = true
|
||||
; pluggin specific configurations here, for example
|
||||
socket = /var/php.sock
|
||||
bin = /usr/bin/phpfcgi
|
||||
; etc
|
@ -58,6 +58,7 @@ config_t *config()
|
||||
}
|
||||
void destroy_config()
|
||||
{
|
||||
chain_t it;
|
||||
freedict(server_config.handlers);
|
||||
if (server_config.plugins_dir)
|
||||
free(server_config.plugins_dir);
|
||||
@ -75,9 +76,16 @@ void destroy_config()
|
||||
freedict(server_config.mimes);
|
||||
if (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)
|
||||
{
|
||||
chain_t it;
|
||||
port_config_t *cnf;
|
||||
for_each_assoc(it, server_config.ports)
|
||||
{
|
||||
@ -102,7 +110,8 @@ static int config_handler(void *conf, const char *section, const char *name,
|
||||
const char *value)
|
||||
{
|
||||
config_t *pconfig = (config_t *)conf;
|
||||
regmatch_t port_matches[2];
|
||||
regmatch_t regex_matches[2];
|
||||
char buf[255];
|
||||
char * tmp;
|
||||
struct stat st;
|
||||
// trim(section, ' ');
|
||||
@ -237,21 +246,14 @@ static int config_handler(void *conf, const char *section, const char *name,
|
||||
{
|
||||
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)
|
||||
{
|
||||
dput(pconfig->mimes, name, strdup(value));
|
||||
}
|
||||
else if (regex_match("PORT:\\s*([0-9]+)", section, 2, port_matches))
|
||||
else if (regex_match("PORT:\\s*([0-9]+)", section, 2, regex_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);
|
||||
memcpy(buf, section + regex_matches[1].rm_so, regex_matches[1].rm_eo - regex_matches[1].rm_so);
|
||||
port_config_t *p = dvalue(pconfig->ports, buf);
|
||||
if (!p)
|
||||
{
|
||||
@ -291,6 +293,19 @@ static int config_handler(void *conf, const char *section, const char *name,
|
||||
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
|
||||
{
|
||||
return 0; /* unknown section/name, error */
|
||||
@ -298,9 +313,35 @@ static int config_handler(void *conf, const char *section, const char *name,
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
server_config.ports = dict();
|
||||
server_config.plugins = dict();
|
||||
server_config.plugins_dir = strdup("plugins/");
|
||||
server_config.plugins_ext = strdup(".so");
|
||||
server_config.db_path = strdup("databases/");
|
||||
@ -345,6 +386,8 @@ void load_config(const char *file)
|
||||
#endif
|
||||
}
|
||||
LOG("%d mimes entries found", server_config.mimes->size);
|
||||
// Init plugins if necessary
|
||||
init_plugins();
|
||||
}
|
||||
|
||||
void *accept_request(void *data)
|
||||
@ -1632,16 +1675,13 @@ void *execute_plugin(void *data, const char *pname)
|
||||
// LOG("Plugin name '%s'", pname);
|
||||
rq->client->state = ANTD_CLIENT_PLUGIN_EXEC;
|
||||
// load the plugin
|
||||
if ((plugin = plugin_lookup((char *)pname)) == NULL)
|
||||
pthread_mutex_lock(&server_mux);
|
||||
plugin = plugin_load((char *)pname, dvalue(server_config.plugins, pname));
|
||||
pthread_mutex_unlock(&server_mux);
|
||||
if (plugin == NULL)
|
||||
{
|
||||
pthread_mutex_lock(&server_mux);
|
||||
plugin = plugin_load((char *)pname);
|
||||
pthread_mutex_unlock(&server_mux);
|
||||
if (plugin == NULL)
|
||||
{
|
||||
antd_error(rq->client, 503, "Requested service not found");
|
||||
return task;
|
||||
}
|
||||
antd_error(rq->client, 503, "Requested service not found");
|
||||
return task;
|
||||
}
|
||||
// check if the plugin want rawbody or decoded body
|
||||
metafn = (plugin_header_t * (*)()) dlsym(plugin->handle, "meta");
|
||||
@ -1675,17 +1715,17 @@ dictionary_t mimes_list()
|
||||
return server_config.mimes;
|
||||
}
|
||||
|
||||
void dbdir(char *dest)
|
||||
void dbdir(char **dest)
|
||||
{
|
||||
strncpy(dest, server_config.db_path, 512);
|
||||
*dest = server_config.db_path;
|
||||
}
|
||||
void tmpdir(char *dest)
|
||||
void tmpdir(char **dest)
|
||||
{
|
||||
strncpy(dest, server_config.tmpdir, 512);
|
||||
*dest = server_config.tmpdir;
|
||||
}
|
||||
void plugindir(char *dest)
|
||||
void plugindir(char **dest)
|
||||
{
|
||||
strncpy(dest, server_config.plugins_dir, 512);
|
||||
*dest =server_config.plugins_dir;
|
||||
}
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
|
@ -115,15 +115,15 @@ void htdocs(antd_request_t *rq, char *dest)
|
||||
strcpy(dest, www);
|
||||
}
|
||||
}
|
||||
void dbdir(char *dest)
|
||||
void dbdir(char **dest)
|
||||
{
|
||||
UNUSED(dest);
|
||||
}
|
||||
void tmpdir(char *dest)
|
||||
void tmpdir(char **dest)
|
||||
{
|
||||
UNUSED(dest);
|
||||
}
|
||||
void plugindir(char *dest)
|
||||
void plugindir(char **dest)
|
||||
{
|
||||
UNUSED(dest);
|
||||
}
|
||||
|
14
lib/handle.h
14
lib/handle.h
@ -98,23 +98,25 @@ typedef struct
|
||||
list_t gzip_types;
|
||||
dictionary_t mimes;
|
||||
dictionary_t ports;
|
||||
dictionary_t plugins;
|
||||
// #endif
|
||||
} config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[128];
|
||||
char dbpath[512];
|
||||
char tmpdir[512];
|
||||
char pdir[512];
|
||||
char* dbpath;
|
||||
char* tmpdir;
|
||||
char* pdir;
|
||||
dictionary_t config;
|
||||
int raw_body;
|
||||
} plugin_header_t;
|
||||
|
||||
int __attribute__((weak)) require_plugin(const char *);
|
||||
void __attribute__((weak)) htdocs(antd_request_t *rq, char *dest);
|
||||
void __attribute__((weak)) dbdir(char *dest);
|
||||
void __attribute__((weak)) tmpdir(char *dest);
|
||||
void __attribute__((weak)) plugindir(char *dest);
|
||||
void __attribute__((weak)) dbdir(char **dest);
|
||||
void __attribute__((weak)) tmpdir(char **dest);
|
||||
void __attribute__((weak)) plugindir(char **dest);
|
||||
|
||||
int __attribute__((weak)) compressable(char *ctype);
|
||||
|
||||
|
@ -35,11 +35,12 @@ STATIC PART, should be included in any plugin
|
||||
#ifdef PLUGIN_IMPLEMENT
|
||||
static plugin_header_t __plugin__;
|
||||
// private function
|
||||
void __init_plugin__(const char* pl){
|
||||
void __init_plugin__(const char* pl, dictionary_t* conf){
|
||||
strcpy(__plugin__.name,pl);
|
||||
dbdir(__plugin__.dbpath);
|
||||
plugindir(__plugin__.pdir);
|
||||
tmpdir(__plugin__.tmpdir);
|
||||
dbdir(&__plugin__.dbpath);
|
||||
plugindir(&__plugin__.pdir);
|
||||
tmpdir(&__plugin__.tmpdir);
|
||||
__plugin__.config = conf;
|
||||
__plugin__.raw_body = 0;
|
||||
init();
|
||||
};
|
||||
|
@ -4,6 +4,10 @@
|
||||
#include "lib/utils.h"
|
||||
#include "lib/handle.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
|
||||
*/
|
||||
@ -25,7 +29,7 @@ struct plugin_entry *plugin_lookup(char *s)
|
||||
|
||||
int require_plugin(const char* name)
|
||||
{
|
||||
struct plugin_entry* ptr = plugin_load((char*)name);
|
||||
struct plugin_entry* ptr = plugin_load((char*)name, NULL);
|
||||
return ptr != NULL;
|
||||
}
|
||||
|
||||
@ -33,13 +37,24 @@ int require_plugin(const char* name)
|
||||
* Load a plugin to the plugin table
|
||||
* Only load when not available in the plugin table
|
||||
* @param name plugin name
|
||||
* @param config: plugin configuration
|
||||
* @return pointer to the loaded plugin
|
||||
*/
|
||||
struct plugin_entry *plugin_load(char *name)
|
||||
struct plugin_entry *plugin_load(char *name, dictionary_t config)
|
||||
{
|
||||
char* pname = NULL;
|
||||
struct plugin_entry *np;
|
||||
unsigned hashval;
|
||||
if(config)
|
||||
{
|
||||
pname = dvalue(config, "name");
|
||||
}
|
||||
if(!pname)
|
||||
{
|
||||
pname = name;
|
||||
}
|
||||
if ((np = plugin_lookup(name)) == NULL) { /* not found */
|
||||
LOG("Loading plugin: %s -> %s", name, pname);
|
||||
np = (struct plugin_entry *) malloc(sizeof(*np));
|
||||
if (np == NULL || name == NULL)
|
||||
{
|
||||
@ -47,7 +62,7 @@ struct plugin_entry *plugin_load(char *name)
|
||||
return NULL;
|
||||
}
|
||||
np->pname = strdup(name);
|
||||
if ((np->handle = plugin_from_file(name)) == NULL)
|
||||
if ((np->handle = plugin_from_file(pname,config)) == NULL)
|
||||
{
|
||||
if(np->pname) free(np->pname);
|
||||
if(np) free(np);
|
||||
@ -68,12 +83,12 @@ struct plugin_entry *plugin_load(char *name)
|
||||
* @param name Name of the plugin
|
||||
* @return
|
||||
*/
|
||||
void * plugin_from_file(char* name)
|
||||
static void * plugin_from_file(char* name, dictionary_t conf)
|
||||
{
|
||||
void *lib_handle;
|
||||
void *lib_handle;
|
||||
char* error;
|
||||
char* path = __s("%s/%s%s",config()->plugins_dir,name,config()->plugins_ext);
|
||||
void (*fn)(const char*);
|
||||
void (*fn)(const char*, dictionary_t);
|
||||
lib_handle = dlopen(path, RTLD_LAZY);
|
||||
if (!lib_handle)
|
||||
{
|
||||
@ -83,11 +98,11 @@ void * plugin_from_file(char* name)
|
||||
return NULL;
|
||||
}
|
||||
// set database path
|
||||
fn = (void (*)(const char *))dlsym(lib_handle, "__init_plugin__");
|
||||
fn = (void (*)(const char*, dictionary_t))dlsym(lib_handle, "__init_plugin__");
|
||||
if ((error = dlerror()) != NULL)
|
||||
ERROR("Problem when finding plugin init function for %s : %s", name,error);
|
||||
else
|
||||
(*fn)(name);
|
||||
(*fn)(name, conf);
|
||||
if(path)
|
||||
free(path);
|
||||
return lib_handle;
|
||||
|
@ -1,5 +1,8 @@
|
||||
#ifndef PLUGIN_MANAGER_H
|
||||
#define PLUGIN_MANAGER_H
|
||||
|
||||
#include "lib/dictionary.h"
|
||||
|
||||
struct plugin_entry {
|
||||
struct plugin_entry *next;
|
||||
char *pname;
|
||||
@ -8,10 +11,7 @@ struct plugin_entry {
|
||||
/* lookup: look for s in hashtab */
|
||||
struct plugin_entry *plugin_lookup(char *s);
|
||||
/* install: put (name, defn) in hashtab */
|
||||
struct plugin_entry *plugin_load(char *name);
|
||||
struct plugin_entry *plugin_load(char *name, dictionary_t config);
|
||||
void unload_all_plugin();
|
||||
void unload_plugin(struct plugin_entry*);
|
||||
void unload_plugin_by_name(const char*);
|
||||
void * plugin_from_file(char* name);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user