mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
plugin standalone example for oot build
Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
parent
d5dc5dff13
commit
4d5ac9c910
3 changed files with 263 additions and 0 deletions
|
@ -339,6 +339,43 @@ Example config for this case is
|
|||
|
||||
cmake .. -DLWS_USE_POLARSSL=1 -DLWS_POLARSSL_LIBRARIES=/usr/lib64/libmbedtls.so \
|
||||
-DLWS_POLARSSL_INCLUDE_DIRS=/usr/include/polarssl/
|
||||
|
||||
|
||||
Building plugins outside of lws itself
|
||||
--------------------------------------
|
||||
|
||||
The directory ./plugin-standalone/ shows how easy it is to create plugins
|
||||
outside of lws itself. First build lws itself with -DLWS_WITH_PLUGINS,
|
||||
then use the same flow to build the standalone plugin
|
||||
|
||||
```
|
||||
cd ./plugin-standalone
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make && sudo make install
|
||||
```
|
||||
|
||||
if you changed the default plugin directory when you built lws, you must
|
||||
also give the same arguments to cmake here (eg,
|
||||
` -DCMAKE_INSTALL_PREFIX:PATH=/usr/something/else...` )
|
||||
|
||||
Otherwise if you run lwsws or libwebsockets-test-server-v2.0, it will now
|
||||
find the additional plugin "libprotocol_example_standalone.so"
|
||||
|
||||
```
|
||||
lwsts[21257]: Plugins:
|
||||
lwsts[21257]: libprotocol_dumb_increment.so
|
||||
lwsts[21257]: libprotocol_example_standalone.so
|
||||
lwsts[21257]: libprotocol_lws_mirror.so
|
||||
lwsts[21257]: libprotocol_lws_server_status.so
|
||||
lwsts[21257]: libprotocol_lws_status.so
|
||||
```
|
||||
|
||||
If you have multiple vhosts, you must enable plugins at the vhost
|
||||
additionally, discovered plugins are not enabled automatically for security
|
||||
reasons. You do this using info->pvo or for lwsws, in the JSON config.
|
||||
|
||||
|
||||
Reproducing HTTP2.0 tests
|
||||
-------------------------
|
||||
|
|
78
plugin-standalone/CMakeLists.txt
Normal file
78
plugin-standalone/CMakeLists.txt
Normal file
|
@ -0,0 +1,78 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
if(NOT DEFINED CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type")
|
||||
endif()
|
||||
|
||||
# This shows one way to build a standalone plugin
|
||||
# outside of lws itself
|
||||
|
||||
project(lws-protocol-plugin-example C)
|
||||
|
||||
set(PACKAGE "lws-protocol-plugin-example")
|
||||
set(CPACK_PACKAGE_NAME "${PACKAGE}")
|
||||
set(CPACK_PACKAGE_VERSION "0.1")
|
||||
set(CPACK_PACKAGE_VENDOR "andy@warmcat.com")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PACKAGE} ${PACKAGE_VERSION}")
|
||||
set(SOVERSION "1")
|
||||
set(VERSION "0.1")
|
||||
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/")
|
||||
|
||||
message(STATUS "CMAKE_TOOLCHAIN_FILE='${CMAKE_TOOLCHAIN_FILE}'")
|
||||
|
||||
# Try to find the current Git hash.
|
||||
find_package(Git)
|
||||
if(GIT_EXECUTABLE)
|
||||
execute_process(
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMAND "${GIT_EXECUTABLE}" describe
|
||||
OUTPUT_VARIABLE GIT_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
execute_process(
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMAND "whoami"
|
||||
OUTPUT_VARIABLE GIT_USER
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
execute_process(
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMAND "hostname"
|
||||
OUTPUT_VARIABLE GIT_HOST
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
string(REGEX REPLACE "([^\\])[\\]([^\\])" "\\1\\\\\\\\\\2" GIT_USER ${GIT_USER})
|
||||
set(LWS_BUILD_HASH ${GIT_USER}@${GIT_HOST}-${GIT_HASH})
|
||||
message("Git commit hash: ${LWS_BUILD_HASH}")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
|
||||
|
||||
macro(create_plugin PLUGIN_NAME MAIN_SRC)
|
||||
set(PLUGIN_SRCS ${MAIN_SRC})
|
||||
|
||||
source_group("Headers Private" FILES ${PLUGIN_HDR})
|
||||
source_group("Sources" FILES ${PLUGIN_SRCS})
|
||||
add_library(${PLUGIN_NAME} SHARED ${PLUGIN_SRCS} ${PLUGIN_HDR})
|
||||
|
||||
target_link_libraries(${PLUGIN_NAME} -lwebsockets)
|
||||
|
||||
# Set test app specific defines.
|
||||
set_property(TARGET ${PLUGIN_NAME}
|
||||
PROPERTY COMPILE_DEFINITIONS
|
||||
INSTALL_DATADIR="${CMAKE_INSTALL_PREFIX}/plugins"
|
||||
)
|
||||
|
||||
list(APPEND PLUGINS_LIST ${PLUGIN_NAME})
|
||||
endmacro()
|
||||
|
||||
|
||||
create_plugin(protocol_example_standalone
|
||||
"protocol_example_standalone.c")
|
||||
|
||||
install(TARGETS ${PLUGINS_LIST}
|
||||
PERMISSIONS OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE OWNER_READ GROUP_READ WORLD_READ
|
||||
DESTINATION share/libwebsockets-test-server/plugins
|
||||
COMPONENT plugins)
|
148
plugin-standalone/protocol_example_standalone.c
Normal file
148
plugin-standalone/protocol_example_standalone.c
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* ws protocol handler plugin for "dumb increment"
|
||||
*
|
||||
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*
|
||||
* The person who associated a work with this deed has dedicated
|
||||
* the work to the public domain by waiving all of his or her rights
|
||||
* to the work worldwide under copyright law, including all related
|
||||
* and neighboring rights, to the extent allowed by law. You can copy,
|
||||
* modify, distribute and perform the work, even for commercial purposes,
|
||||
* all without asking permission.
|
||||
*
|
||||
* These test plugins are intended to be adapted for use in your code, which
|
||||
* may be proprietary. So unlike the library itself, they are licensed
|
||||
* Public Domain.
|
||||
*
|
||||
* This is a copy of dumb_increment adapted slightly to serve as the
|
||||
* "example-standalone-protocol", to show how to build protocol plugins
|
||||
* outside the library easily.
|
||||
*/
|
||||
#include "../lib/libwebsockets.h"
|
||||
#include <string.h>
|
||||
|
||||
struct per_vhost_data__dumb_increment {
|
||||
uv_timer_t timeout_watcher;
|
||||
struct lws_context *context;
|
||||
struct lws_vhost *vhost;
|
||||
const struct lws_protocols *protocol;
|
||||
};
|
||||
|
||||
struct per_session_data__dumb_increment {
|
||||
int number;
|
||||
};
|
||||
|
||||
static void
|
||||
uv_timeout_cb_dumb_increment(uv_timer_t *w
|
||||
#if UV_VERSION_MAJOR == 0
|
||||
, int status
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct per_vhost_data__dumb_increment *vhd = lws_container_of(w,
|
||||
struct per_vhost_data__dumb_increment, timeout_watcher);
|
||||
lws_callback_on_writable_all_protocol_vhost(vhd->vhost, vhd->protocol);
|
||||
}
|
||||
|
||||
static int
|
||||
callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
|
||||
void *user, void *in, size_t len)
|
||||
{
|
||||
struct per_session_data__dumb_increment *pss =
|
||||
(struct per_session_data__dumb_increment *)user;
|
||||
struct per_vhost_data__dumb_increment *vhd =
|
||||
(struct per_vhost_data__dumb_increment *)
|
||||
lws_protocol_vh_priv_get(lws_vhost_get(wsi),
|
||||
lws_protocol_get(wsi));
|
||||
unsigned char buf[LWS_PRE + 512];
|
||||
unsigned char *p = &buf[LWS_PRE];
|
||||
int n, m;
|
||||
|
||||
switch (reason) {
|
||||
case LWS_CALLBACK_PROTOCOL_INIT:
|
||||
vhd = lws_protocol_vh_priv_zalloc(lws_vhost_get(wsi),
|
||||
lws_protocol_get(wsi),
|
||||
sizeof(struct per_vhost_data__dumb_increment));
|
||||
vhd->context = lws_get_context(wsi);
|
||||
vhd->protocol = lws_protocol_get(wsi);
|
||||
vhd->vhost = lws_vhost_get(wsi);
|
||||
uv_timer_init(lws_uv_getloop(vhd->context, 0),
|
||||
&vhd->timeout_watcher);
|
||||
uv_timer_start(&vhd->timeout_watcher,
|
||||
uv_timeout_cb_dumb_increment, 50, 50);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_PROTOCOL_DESTROY:
|
||||
if (!vhd)
|
||||
break;
|
||||
uv_timer_stop(&vhd->timeout_watcher);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_ESTABLISHED:
|
||||
pss->number = 0;
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_SERVER_WRITEABLE:
|
||||
n = sprintf((char *)p, "%d", pss->number++);
|
||||
m = lws_write(wsi, p, n, LWS_WRITE_TEXT);
|
||||
if (m < n) {
|
||||
lwsl_err("ERROR %d writing to di socket\n", n);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
if (len < 6)
|
||||
break;
|
||||
if (strcmp((const char *)in, "reset\n") == 0)
|
||||
pss->number = 0;
|
||||
if (strcmp((const char *)in, "closeme\n") == 0) {
|
||||
lwsl_notice("dumb_inc: closing as requested\n");
|
||||
lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY,
|
||||
(unsigned char *)"seeya", 5);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct lws_protocols protocols[] = {
|
||||
{
|
||||
"example-standalone-protocol",
|
||||
callback_dumb_increment,
|
||||
sizeof(struct per_session_data__dumb_increment),
|
||||
10, /* rx buf size must be >= permessage-deflate rx size */
|
||||
},
|
||||
};
|
||||
|
||||
LWS_VISIBLE int
|
||||
init_protocol_example_standalone(struct lws_context *context,
|
||||
struct lws_plugin_capability *c)
|
||||
{
|
||||
if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
|
||||
lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
|
||||
c->api_magic);
|
||||
return 1;
|
||||
}
|
||||
|
||||
c->protocols = protocols;
|
||||
c->count_protocols = ARRAY_SIZE(protocols);
|
||||
c->extensions = NULL;
|
||||
c->count_extensions = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LWS_VISIBLE int
|
||||
destroy_protocol_example_standalone(struct lws_context *context)
|
||||
{
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue