mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
lws_plugins
This commit is contained in:
parent
f53db84117
commit
1d05f429dc
8 changed files with 135 additions and 18 deletions
|
@ -390,3 +390,8 @@ endif()
|
|||
if (NOT LWS_WITH_SSL)
|
||||
set(LWS_WITHOUT_BUILTIN_SHA1 OFF)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_PLUGINS OR (LWS_WITH_EVLIB_PLUGINS AND LWS_WITH_EVENT_LIBS))
|
||||
set(LWS_WITH_PLUGINS_API 1)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ option(LWS_WITH_LWSWS "Libwebsockets Webserver" OFF)
|
|||
option(LWS_WITH_CGI "Include CGI (spawn process with network-connected stdin/out/err) APIs" OFF)
|
||||
option(LWS_IPV6 "Compile with support for ipv6" OFF)
|
||||
option(LWS_UNIX_SOCK "Compile with support for UNIX domain socket if OS supports it" ON)
|
||||
option(LWS_WITH_PLUGINS "Support plugins for protocols and extensions" OFF)
|
||||
option(LWS_WITH_PLUGINS "Support plugins for protocols and extensions (implies LWS_WITH_PLUGINS_API)" OFF)
|
||||
option(LWS_WITH_HTTP_PROXY "Support for active HTTP proxying" OFF)
|
||||
option(LWS_WITH_ZIP_FOPS "Support serving pre-zipped files" OFF)
|
||||
option(LWS_WITH_SOCKS5 "Allow use of SOCKS5 proxy on client connections" OFF)
|
||||
|
@ -250,6 +250,7 @@ option(LWS_WITH_FSMOUNT "Overlayfs and fallback mounting apis" OFF)
|
|||
option(LWS_WITH_FANALYZER "Enable gcc -fanalyzer if compiler supports" OFF)
|
||||
option(LWS_HTTP_HEADERS_ALL "Override header reduction optimization and include all like older lws versions" OFF)
|
||||
option(LWS_WITH_SUL_DEBUGGING "Enable zombie lws_sul checking on object deletion" OFF)
|
||||
option(LWS_WITH_PLUGINS_API "Build generic lws_plugins apis (see LWS_WITH_PLUGINS to also build protocol plugins)" OFF)
|
||||
|
||||
#
|
||||
# to use miniz, enable both LWS_WITH_ZLIB and LWS_WITH_MINIZ
|
||||
|
|
105
READMEs/README.lws_plugins.md
Normal file
105
READMEs/README.lws_plugins.md
Normal file
|
@ -0,0 +1,105 @@
|
|||
# lws_plugins
|
||||
|
||||
Lws now offers apis to manage your own user plugins with `LWS_WITH_PLUGINS_API`.
|
||||
Lws uses these apis internally for protocol plugins and event loop plugins
|
||||
if they're selected for build. But they are also exported for user code to
|
||||
use them how you like.
|
||||
|
||||
## Creating your plugin export
|
||||
|
||||
### Specifying your plugin export type
|
||||
|
||||
Lws plugins have a single exported struct with a specified header and a user
|
||||
defined remainder. The public `lws_plugin_header_t` describes the common
|
||||
plugin export header, it's defined via libwebsockets.h as
|
||||
|
||||
```
|
||||
typedef struct lws_plugin_header {
|
||||
const char *name;
|
||||
const char *_class;
|
||||
|
||||
unsigned int api_magic;
|
||||
/* set to LWS_PLUGIN_API_MAGIC at plugin build time */
|
||||
|
||||
/* plugin-class specific superclass data follows */
|
||||
} lws_plugin_header_t;
|
||||
```
|
||||
|
||||
The exported symbol name itself must match the plugin filename, for
|
||||
example if the symbol name is `my_plugin`, then the filename of the
|
||||
plugin might be `libmyapp-my_plugin.so` or similar... the matching
|
||||
part is after the first `-` or `_`, up to the first `.`. The exact
|
||||
details differ by platform but these rules cover the supported
|
||||
platforms. If lws has the filename of the plugin, it can then
|
||||
deduce the symbol export it should look for in the plugin.
|
||||
|
||||
`name` is a freeform human-readable description for the plugin.
|
||||
|
||||
`_class` is shared by your plugins and used to select them from other kinds
|
||||
of plugin that may be in the same dir. So choose a unique name like
|
||||
`"myapp xxx plugin"` or whatever shared by all plugins of that class.
|
||||
|
||||
`api_magic` is set to `LWS_PLUGIN_API_MAGIC` to detect if the plugin is
|
||||
incompatible with the lws plugin apis version.
|
||||
|
||||
So for example your plugin type wrapping the header might look like
|
||||
|
||||
```
|
||||
typedef struct myapp_plugin {
|
||||
lws_plugin_header_t hdr; /* must be first */
|
||||
|
||||
/* optional extra data like function pointers from your plugin */
|
||||
mytype_t mymember;
|
||||
/* ... */
|
||||
} myapp_plugin_t;
|
||||
```
|
||||
|
||||
Typically, you will put function pointers to whatever capability your plugin
|
||||
class offers as the additional members.
|
||||
|
||||
## Building your own plugins
|
||||
|
||||
Plugins are built standalone, cmake is recommended but you can do what you want.
|
||||
|
||||
The only requirement is the single visible export of the plugin name, eg
|
||||
|
||||
```
|
||||
const myapp_plugin_t my_plugin = {
|
||||
.hdr = {
|
||||
"my_plugin",
|
||||
"myapp xxx plugin",
|
||||
LWS_PLUGIN_API_MAGIC
|
||||
},
|
||||
|
||||
.mymember = my_plugin_init,
|
||||
/*...*/
|
||||
};
|
||||
```
|
||||
|
||||
## Bringing in plugins at runtime
|
||||
|
||||
Lws provides an api to import plugins into the process space and another to
|
||||
remove and destroy plugins.
|
||||
|
||||
You can take two approaches depending on what you're doing, either bring in and
|
||||
later destroy a whole class of plugins at once, and walk them via a linked-list,
|
||||
or bring in and later destroy a single specific plugin from the class by filtering
|
||||
on its specific export name.
|
||||
|
||||
See `include/libwebsockets/lws-protocols-plugins.h` for documentation.
|
||||
|
||||
```
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_plugins_init(struct lws_plugin **pplugin, const char * const *d,
|
||||
const char *_class, const char *filter,
|
||||
each_plugin_cb_t each, void *each_user);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_plugins_destroy(struct lws_plugin **pplugin, each_plugin_cb_t each,
|
||||
void *each_user);
|
||||
```
|
||||
|
||||
`struct lws_plugin` is a public struct that contains the linked-list of loaded
|
||||
plugins and a pointer to its exported header object, so you can walk this
|
||||
after loading.
|
||||
|
|
@ -193,4 +193,5 @@
|
|||
#cmakedefine LWS_WITH_EVENT_LIBS
|
||||
#cmakedefine LWS_WITH_EVLIB_PLUGINS
|
||||
#cmakedefine LWS_WITH_LIBUV_INTERNAL
|
||||
#cmakedefine LWS_WITH_PLUGINS_API
|
||||
|
||||
|
|
|
@ -304,15 +304,14 @@ lws_dir_rm_rf_cb(const char *dirpath, void *user, struct lws_dir_entry *lde)
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_PLUGINS) || \
|
||||
(defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS))
|
||||
#if defined(LWS_WITH_PLUGINS_API)
|
||||
|
||||
struct lws_plugins_args {
|
||||
struct lws_plugin **pplugin;
|
||||
const char *_class;
|
||||
const char *filter;
|
||||
each_plugin_cb_t each;
|
||||
void *each_user;
|
||||
struct lws_plugin **pplugin;
|
||||
const char *_class;
|
||||
const char *filter;
|
||||
each_plugin_cb_t each;
|
||||
void *each_user;
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
@ -65,7 +65,7 @@ if (LWS_WITH_NETWORK)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_PLUGINS OR LWS_WITH_EVLIB_PLUGINS)
|
||||
if (LWS_WITH_PLUGINS_API)
|
||||
list(APPEND SOURCES plat/unix/unix-plugins.c)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -29,10 +29,7 @@
|
|||
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#if defined(LWS_WITH_PLUGINS) || defined(LWS_WITH_EVLIB_PLUGINS)
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
const lws_plugin_header_t *
|
||||
lws_plat_dlopen(struct lws_plugin **pplugin, const char *libpath,
|
||||
|
|
|
@ -27,8 +27,11 @@
|
|||
#endif
|
||||
#include "private-lib-core.h"
|
||||
|
||||
#if (defined(LWS_WITH_PLUGINS) || defined(LWS_WITH_EVLIB_PLUGINS)) && \
|
||||
(UV_VERSION_MAJOR > 0)
|
||||
/*
|
||||
* ie, if the plugins api needed at all
|
||||
*/
|
||||
|
||||
#if defined(LWS_WITH_PLUGINS_API) && (UV_VERSION_MAJOR > 0)
|
||||
|
||||
const lws_plugin_header_t *
|
||||
lws_plat_dlopen(struct lws_plugin **pplugin, const char *libpath,
|
||||
|
@ -105,6 +108,14 @@ lws_plat_destroy_dl(struct lws_plugin *p)
|
|||
return uv_dlclose(&p->u.lib);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Specifically for protocol plugins support
|
||||
*/
|
||||
|
||||
#if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0)
|
||||
|
||||
static int
|
||||
protocol_plugin_cb(struct lws_plugin *pin, void *each_user)
|
||||
{
|
||||
|
@ -122,8 +133,7 @@ protocol_plugin_cb(struct lws_plugin *pin, void *each_user)
|
|||
int
|
||||
lws_plat_plugins_init(struct lws_context *context, const char * const *d)
|
||||
{
|
||||
#if (defined(LWS_WITH_PLUGINS) || defined(LWS_WITH_EVLIB_PLUGINS)) && \
|
||||
(UV_VERSION_MAJOR > 0)
|
||||
#if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0)
|
||||
if (info->plugin_dirs) {
|
||||
uv_loop_init(&context->uv.loop);
|
||||
lws_plugins_init(&context->plugin_list, info->plugin_dirs,
|
||||
|
@ -138,8 +148,7 @@ lws_plat_plugins_init(struct lws_context *context, const char * const *d)
|
|||
int
|
||||
lws_plat_plugins_destroy(struct lws_context * context)
|
||||
{
|
||||
#if (defined(LWS_WITH_PLUGINS) || defined(LWS_WITH_EVLIB_PLUGINS)) && \
|
||||
(UV_VERSION_MAJOR > 0)
|
||||
#if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0)
|
||||
if (lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV) &&
|
||||
context->plugin_list) {
|
||||
lws_plugins_destroy(&context->plugin_list, NULL, NULL);
|
||||
|
|
Loading…
Add table
Reference in a new issue