mirror of
				https://github.com/lxsang/ant-http
				synced 2025-10-31 10:25:55 +01:00 
			
		
		
		
	Allow specific configuration for plugins
This commit is contained in:
		| @@ -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 | ||||
		Reference in New Issue
	
	Block a user