Skip to content
Snippets Groups Projects
Commit cae57ad9 authored by Andy Green's avatar Andy Green
Browse files

plugins_dir convert to array


If OOT lws plugins will be packaged as separate projects,
they're going to want to install their plugins somewhere
that makes sense for the package instead of one big lws
plugin dir.

This patch changes info to have a const char ** to a NULL
terminated array of directories it should search for
plugins.  lwsws knows about this and you can add to the
dir array using config fragments like

{
  "global": {
   "plugin-dir": "/usr/local/share/coherent-timeline/plugins"
  }
}

if the config fragment in /etc/lwsws/conf.d/ is also managed by the
package with the plugin, it can very cleanly add and remove itself
from lwsws based on package install status.

Signed-off-by: default avatarAndy Green <andy@warmcat.com>
parent 4d5ac9c9
Branches
Tags
No related merge requests found
......@@ -284,6 +284,19 @@ To help that happen conveniently, there are some new apis
dumb increment, mirror and status protocol plugins are provided as examples.
Additional plugin search paths
------------------------------
Packages that have their own lws plugins can install them in their own
preferred dir and ask lwsws to scan there by using a config fragment
like this, in its own conf.d/ file managed by the other package
{
"global": {
"plugin-dir": "/usr/local/share/coherent-timeline/plugins"
}
}
lws-server-status plugin
------------------------
......
......@@ -416,7 +416,7 @@ lws_libuv_closehandle(struct lws *wsi)
#if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0)
LWS_VISIBLE int
lws_plat_plugins_init(struct lws_context * context, const char *d)
lws_plat_plugins_init(struct lws_context * context, const char * const *d)
{
struct lws_plugin_capability lcaps;
struct lws_plugin *plugin;
......@@ -434,20 +434,24 @@ lws_plat_plugins_init(struct lws_context * context, const char *d)
uv_loop_init(&loop);
if (!uv_fs_scandir(&loop, &req, d, 0, NULL)) {
lwsl_err("Scandir on %s failed\n", d);
lwsl_notice(" Plugins:\n");
while (d && *d) {
lwsl_notice(" Scanning %s\n", *d);
m =uv_fs_scandir(&loop, &req, *d, 0, NULL);
if (m < 1) {
lwsl_err("Scandir on %s failed\n", *d);
return 1;
}
lwsl_notice(" Plugins:\n");
while (uv_fs_scandir_next(&req, &dent) != UV_EOF) {
if (strlen(dent.name) < 7)
continue;
lwsl_notice(" %s\n", dent.name);
snprintf(path, sizeof(path) - 1, "%s/%s", d, dent.name);
snprintf(path, sizeof(path) - 1, "%s/%s", *d, dent.name);
if (uv_dlopen(path, &lib)) {
uv_dlerror(&lib);
lwsl_err("Error loading DSO: %s\n", lib.errmsg);
......@@ -490,9 +494,11 @@ lws_plat_plugins_init(struct lws_context * context, const char *d)
skip:
uv_dlclose(&lib);
}
bail:
uv_fs_req_cleanup(&req);
d++;
}
uv_loop_close(&loop);
return ret;
......
......@@ -1478,8 +1478,8 @@ struct lws_http_mount {
* @vhost_name: VHOST: name of vhost, must match external DNS name used to
* access the site, like "warmcat.com" as it's used to match
* Host: header and / or SNI name for SSL.
* @plugins_dir: CONTEXT: directory to scan for lws protocol plugins at
* context creation time
* @plugin_dirs: CONTEXT: NULL, or NULL-terminated array of directories to
* scan for lws protocol plugins at context creation time
* @pvo: VHOST: pointer to optional linked list of per-vhost
* options made accessible to protocols
* @keepalive_timeout: VHOST: (default = 0 = 60s) seconds to allow remote
......@@ -1525,7 +1525,7 @@ struct lws_context_creation_info {
unsigned int timeout_secs; /* VH */
const char *ecdh_curve; /* VH */
const char *vhost_name; /* VH */
const char *plugins_dir; /* context */
const char * const *plugin_dirs; /* context */
const struct lws_protocol_vhost_options *pvo; /* VH */
int keepalive_timeout; /* VH */
const char *log_filepath; /* VH */
......
......@@ -306,7 +306,7 @@ static int filter(const struct dirent *ent)
}
LWS_VISIBLE int
lws_plat_plugins_init(struct lws_context * context, const char *d)
lws_plat_plugins_init(struct lws_context * context, const char * const *d)
{
struct lws_plugin_capability lcaps;
struct lws_plugin *plugin;
......@@ -316,22 +316,22 @@ lws_plat_plugins_init(struct lws_context * context, const char *d)
char path[256];
void *l;
lwsl_notice(" Plugins:\n");
n = scandir(d, &namelist, filter, alphasort);
while (d && *d) {
n = scandir(*d, &namelist, filter, alphasort);
if (n < 0) {
lwsl_err("Scandir on %s failed\n", d);
lwsl_err("Scandir on %s failed\n", *d);
return 1;
}
lwsl_notice(" Plugins:\n");
for (i = 0; i < n; i++) {
if (strlen(namelist[i]->d_name) < 7)
goto inval;
lwsl_notice(" %s\n", namelist[i]->d_name);
snprintf(path, sizeof(path) - 1, "%s/%s", d,
snprintf(path, sizeof(path) - 1, "%s/%s", *d,
namelist[i]->d_name);
l = dlopen(path, RTLD_NOW);
if (!l) {
......@@ -381,6 +381,9 @@ skip:
inval:
free(namelist[i]);
}
free(namelist);
d++;
}
bail:
free(namelist);
......@@ -707,8 +710,8 @@ lws_plat_init(struct lws_context *context,
context->fops.write = _lws_plat_file_write;
#ifdef LWS_WITH_PLUGINS
if (info->plugins_dir)
lws_plat_plugins_init(context, info->plugins_dir);
if (info->plugin_dirs)
lws_plat_plugins_init(context, info->plugin_dirs);
#endif
return 0;
......
......@@ -770,7 +770,7 @@ LWS_EXTERN void
lws_libuv_closehandle(struct lws *wsi);
LWS_VISIBLE LWS_EXTERN int
lws_plat_plugins_init(struct lws_context * context, const char *d);
lws_plat_plugins_init(struct lws_context * context, const char * const *d);
LWS_VISIBLE LWS_EXTERN int
lws_plat_plugins_destroy(struct lws_context * context);
......
......@@ -27,6 +27,7 @@ static const char * const paths_global[] = {
"global.count-threads",
"global.init-ssl",
"global.server-string",
"global.plugin-dir"
};
enum lejp_global_paths {
......@@ -35,6 +36,7 @@ enum lejp_global_paths {
LEJPGP_COUNT_THREADS,
LWJPGP_INIT_SSL,
LEJPGP_SERVER_STRING,
LEJPGP_PLUGIN_DIR
};
static const char * const paths_vhosts[] = {
......@@ -91,6 +93,8 @@ enum lejp_vhost_paths {
LEJPVP_KEEPALIVE_TIMEOUT,
};
#define MAX_PLUGIN_DIRS 10
struct jpargs {
struct lws_context_creation_info *info;
struct lws_context *context;
......@@ -101,6 +105,8 @@ struct jpargs {
struct lws_protocol_vhost_options *pvo;
struct lws_http_mount m;
const char **plugin_dirs;
int count_plugin_dirs;
};
static void *
......@@ -154,6 +160,13 @@ lejp_globals_cb(struct lejp_ctx *ctx, char reason)
case LEJPGP_SERVER_STRING:
a->info->server_string = a->p;
break;
case LEJPGP_PLUGIN_DIR:
if (a->count_plugin_dirs == MAX_PLUGIN_DIRS - 1) {
lwsl_err("Too many plugin dirs\n");
return -1;
}
a->plugin_dirs[a->count_plugin_dirs++] = a->p;
break;
default:
return 0;
......@@ -537,12 +550,27 @@ lwsws_get_config_globals(struct lws_context_creation_info *info, const char *d,
char **cs, int *len)
{
struct jpargs a;
const char * const *old = info->plugin_dirs;
memset(&a, 0, sizeof(a));
a.info = info;
a.p = *cs;
a.end = (a.p + *len) - 1;
a.valid = 0;
lwsws_align(&a);
info->plugin_dirs = (void *)a.p;
a.plugin_dirs = (void *)a.p; /* writeable version */
a.p += MAX_PLUGIN_DIRS * sizeof(void *);
/* copy any default paths */
while (old && *old) {
a.plugin_dirs[a.count_plugin_dirs++] = *old;
old++;
}
if (lwsws_get_config(&a, "/etc/lwsws/conf", paths_global,
ARRAY_SIZE(paths_global), lejp_globals_cb) > 1)
return 1;
......@@ -550,6 +578,8 @@ lwsws_get_config_globals(struct lws_context_creation_info *info, const char *d,
ARRAY_SIZE(paths_global), lejp_globals_cb) > 1)
return 1;
a.plugin_dirs[a.count_plugin_dirs] = NULL;
*cs = a.p;
*len = a.end - a.p;
......@@ -563,6 +593,8 @@ lwsws_get_config_vhosts(struct lws_context *context,
{
struct jpargs a;
memset(&a, 0, sizeof(a));
a.info = info;
a.p = *cs;
a.end = a.p + *len;
......
......@@ -80,6 +80,11 @@ static const struct lws_extension exts[] = {
{ NULL, NULL, NULL /* terminator */ }
};
static const char * const plugin_dirs[] = {
INSTALL_DATADIR"/libwebsockets-test-server/plugins/",
NULL
};
static struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "debug", required_argument, NULL, 'd' },
......@@ -107,6 +112,8 @@ void signal_cb(uv_signal_t *watcher, int signum)
}
#endif
int main(int argc, char **argv)
{
struct lws_context_creation_info info;
......@@ -184,8 +191,7 @@ int main(int argc, char **argv)
LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
LWS_SERVER_OPTION_LIBUV;
info.plugins_dir = INSTALL_DATADIR"/libwebsockets-test-server/plugins/";
info.plugin_dirs = plugin_dirs;
lwsl_notice("Using config dir: \"%s\"\n", config_dir);
/*
......
......@@ -155,6 +155,11 @@ static const struct option options[] = {
{ NULL, 0, 0, 0 }
};
static const char * const plugin_dirs[] = {
INSTALL_DATADIR"/libwebsockets-test-server/plugins/",
NULL
};
int main(int argc, char **argv)
{
struct lws_context_creation_info info;
......@@ -344,7 +349,7 @@ int main(int argc, char **argv)
"!AES256-SHA256";
/* tell lws to look for protocol plugins here */
info.plugins_dir = INSTALL_DATADIR"/libwebsockets-test-server/plugins/";
info.plugin_dirs = plugin_dirs;
/* tell lws about our mount we want */
info.mounts = &mount;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment