mirror of
https://github.com/lxsang/ant-http
synced 2024-11-18 01:08:21 +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
|
; 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
|
||||||
|
|
||||||
@ -106,11 +108,14 @@ lua = lua
|
|||||||
; handled by the cgi plugin
|
; handled by the cgi plugin
|
||||||
; php = cgi
|
; php = cgi
|
||||||
|
|
||||||
|
; Example of plugin configurations
|
||||||
; This enable some plugins to be initialised at server startup
|
[PLUGIN:php]
|
||||||
; this section shall always at the end of the
|
; theses configurations is understandable by the server
|
||||||
; configuration file
|
; the name of the plugin in plugin dir
|
||||||
[AUTOSTART]
|
name = fastcgi
|
||||||
; to start a plugin at server statup use:
|
; run this plugin at startup
|
||||||
;plugin = plugin_name_1
|
autoload = true
|
||||||
;plugin = plugin_name_2, etc
|
; 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()
|
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);
|
||||||
@ -75,9 +76,16 @@ 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)
|
||||||
{
|
{
|
||||||
@ -102,7 +110,8 @@ 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];
|
regmatch_t regex_matches[2];
|
||||||
|
char buf[255];
|
||||||
char * tmp;
|
char * tmp;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
// trim(section, ' ');
|
// trim(section, ' ');
|
||||||
@ -237,21 +246,14 @@ static int config_handler(void *conf, const char *section, const char *name,
|
|||||||
{
|
{
|
||||||
dput(pconfig->handlers, name, strdup(value));
|
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, port_matches))
|
else if (regex_match("PORT:\\s*([0-9]+)", section, 2, regex_matches))
|
||||||
{
|
{
|
||||||
char buf[20];
|
|
||||||
memset(buf, '\0', sizeof(buf));
|
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);
|
port_config_t *p = dvalue(pconfig->ports, buf);
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
@ -291,6 +293,19 @@ 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 */
|
||||||
@ -298,9 +313,35 @@ 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);
|
||||||
|
}
|
||||||
|
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/");
|
||||||
@ -345,6 +386,8 @@ 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)
|
||||||
@ -1632,16 +1675,13 @@ void *execute_plugin(void *data, const char *pname)
|
|||||||
// 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
|
||||||
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);
|
antd_error(rq->client, 503, "Requested service not found");
|
||||||
plugin = plugin_load((char *)pname);
|
return task;
|
||||||
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");
|
||||||
@ -1675,17 +1715,17 @@ dictionary_t mimes_list()
|
|||||||
return server_config.mimes;
|
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
|
#ifdef USE_ZLIB
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
14
lib/handle.h
14
lib/handle.h
@ -98,23 +98,25 @@ 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[512];
|
char* dbpath;
|
||||||
char tmpdir[512];
|
char* tmpdir;
|
||||||
char pdir[512];
|
char* pdir;
|
||||||
|
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);
|
||||||
|
|
||||||
|
@ -35,11 +35,12 @@ 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){
|
void __init_plugin__(const char* pl, dictionary_t* conf){
|
||||||
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();
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
#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
|
||||||
*/
|
*/
|
||||||
@ -25,7 +29,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);
|
struct plugin_entry* ptr = plugin_load((char*)name, NULL);
|
||||||
return ptr != NULL;
|
return ptr != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,13 +37,24 @@ 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)
|
struct plugin_entry *plugin_load(char *name, dictionary_t config)
|
||||||
{
|
{
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
@ -47,7 +62,7 @@ struct plugin_entry *plugin_load(char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
np->pname = strdup(name);
|
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->pname) free(np->pname);
|
||||||
if(np) free(np);
|
if(np) free(np);
|
||||||
@ -68,12 +83,12 @@ struct plugin_entry *plugin_load(char *name)
|
|||||||
* @param name Name of the plugin
|
* @param name Name of the plugin
|
||||||
* @return
|
* @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* 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*);
|
void (*fn)(const char*, dictionary_t);
|
||||||
lib_handle = dlopen(path, RTLD_LAZY);
|
lib_handle = dlopen(path, RTLD_LAZY);
|
||||||
if (!lib_handle)
|
if (!lib_handle)
|
||||||
{
|
{
|
||||||
@ -83,11 +98,11 @@ void * plugin_from_file(char* name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// set database path
|
// 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)
|
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);
|
(*fn)(name, conf);
|
||||||
if(path)
|
if(path)
|
||||||
free(path);
|
free(path);
|
||||||
return lib_handle;
|
return lib_handle;
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#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;
|
||||||
@ -8,10 +11,7 @@ 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);
|
struct plugin_entry *plugin_load(char *name, dictionary_t config);
|
||||||
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
|
Loading…
Reference in New Issue
Block a user