From 5939d3a961f52cccbb2a6bd72772df2c34afd0c1 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 28 Jun 2017 11:16:48 +0800 Subject: [PATCH] test servers: convert to static inclusion of plugins This eliminates the duplicated implementations of the test protocols, except dumb-increment (which requires libuv). This has various advantages, including bringing all the test servers up to the same set of protocols support. Triggered by finding a bug in server status protocol that was long ago fixed in the plugins version. --- CMakeLists.txt | 38 ++++---- test-server/test-server-echogen.c | 122 -------------------------- test-server/test-server-libev.c | 56 +++--------- test-server/test-server-libuv.c | 46 +++------- test-server/test-server-mirror.c | 137 ----------------------------- test-server/test-server-pthreads.c | 18 ++-- test-server/test-server-status.c | 173 ------------------------------------- test-server/test-server.c | 57 +++++++----- test-server/test-server.h | 36 ++------ 9 files changed, 96 insertions(+), 587 deletions(-) delete mode 100644 test-server/test-server-echogen.c delete mode 100644 test-server/test-server-mirror.c delete mode 100644 test-server/test-server-status.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 0299b60..69e6ac5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1241,9 +1241,9 @@ if (NOT LWS_WITHOUT_TESTAPPS) create_test_app(test-server "test-server/test-server.c" "test-server/test-server-http.c" "test-server/test-server-dumb-increment.c" - "test-server/test-server-mirror.c" - "test-server/test-server-status.c" - "test-server/test-server-echogen.c") + "" + "" + "") if (UNIX) create_test_app(test-fuzxy "test-server/fuzxy.c" "" @@ -1257,9 +1257,9 @@ if (NOT LWS_WITHOUT_TESTAPPS) "test-server/test-server-pthreads.c" "test-server/test-server-http.c" "test-server/test-server-dumb-increment.c" - "test-server/test-server-mirror.c" - "test-server/test-server-status.c" - "test-server/test-server-echogen.c") + "" + "" + "") endif() if (NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) AND LWS_WITH_LIBEV) @@ -1267,19 +1267,19 @@ if (NOT LWS_WITHOUT_TESTAPPS) "test-server/test-server-libev.c" "test-server/test-server-http.c" "test-server/test-server-dumb-increment.c" - "test-server/test-server-mirror.c" - "test-server/test-server-status.c" - "test-server/test-server-echogen.c") + "" + "" + "") endif() if (NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) AND LWS_WITH_LIBUV) create_test_app(test-server-libuv "test-server/test-server-libuv.c" "test-server/test-server-http.c" - "test-server/test-server-dumb-increment.c" - "test-server/test-server-mirror.c" - "test-server/test-server-status.c" - "test-server/test-server-echogen.c") + "" + "" + "" + "") endif() if (NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) AND LWS_WITH_LIBEVENT) @@ -1287,9 +1287,9 @@ if (NOT LWS_WITHOUT_TESTAPPS) "test-server/test-server-libevent.c" "test-server/test-server-http.c" "test-server/test-server-dumb-increment.c" - "test-server/test-server-mirror.c" - "test-server/test-server-status.c" - "test-server/test-server-echogen.c") + "" + "" + "") endif() endif() @@ -1300,9 +1300,9 @@ if (NOT LWS_WITHOUT_TESTAPPS) create_test_app(test-server-extpoll "test-server/test-server.c" "test-server/test-server-http.c" "test-server/test-server-dumb-increment.c" - "test-server/test-server-mirror.c" - "test-server/test-server-status.c" - "test-server/test-server-echogen.c") + "" + "" + "") # Set defines for this executable only. set_property( TARGET test-server-extpoll diff --git a/test-server/test-server-echogen.c b/test-server/test-server-echogen.c deleted file mode 100644 index c8f0a24..0000000 --- a/test-server/test-server-echogen.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * libwebsockets-test-server - libwebsockets test implementation - * - * Copyright (C) 2010-2016 Andy Green - * - * 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. - * - * The test apps are intended to be adapted for use in your code, which - * may be proprietary. So unlike the library itself, they are licensed - * Public Domain. - */ -#include "test-server.h" - -/* echogen protocol - * - * if you connect to him using his protocol, he'll send you a file chopped - * up in various frame sizes repeated until he reaches a limit. - */ - -#define TOTAL 993840 - -int -callback_lws_echogen(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - unsigned char buf[LWS_PRE + 8192]; - struct per_session_data__echogen *pss = - (struct per_session_data__echogen *)user; - unsigned char *p = &buf[LWS_PRE]; - int n, m; - - switch (reason) { - - case LWS_CALLBACK_ESTABLISHED: - pss->total = TOTAL; - pss->fragsize = 2048; - pss->total_rx = 0; - sprintf((char *)buf, "%s/test.html", resource_path); - pss->fd = open((char *)buf, LWS_O_RDONLY); - if (pss->fd < 0) { - lwsl_err("Failed to open %s\n", buf); - return -1; - } - pss->wr = LWS_WRITE_TEXT | LWS_WRITE_NO_FIN; - lws_callback_on_writable(wsi); - break; - - case LWS_CALLBACK_CLOSED: - if (pss->fd >= 0) - close(pss->fd); - break; - - case LWS_CALLBACK_SERVER_WRITEABLE: - -// pss->fragsize += 16; -// if (pss->fragsize >= 4096) -// pss->fragsize = 32; - - lwsl_err("%s: cb writeable, total left %ld\n", __func__, (long)pss->total); - m = pss->fragsize; - if ((size_t)m >= pss->total) { - m = (int)pss->total; - pss->wr = LWS_WRITE_CONTINUATION; /* ie, FIN */ - } - n = read(pss->fd, p, m); - if (n < 0) { - lwsl_err("failed read\n"); - return -1; - } - if (n < m) { - lseek(pss->fd, 0, SEEK_SET); - m = read(pss->fd, p + n, m - n); - if (m < 0) - return -1; - } else - m = 0; - pss->total -= n + m; - m = lws_write(wsi, p, n + m, pss->wr); - if (m < n) { - lwsl_err("ERROR %d writing to di socket\n", n); - return -1; - } - if (!pss->total) { - lwsl_err("Completed OK\n"); - break; - } - pss->wr = LWS_WRITE_CONTINUATION | LWS_WRITE_NO_FIN; - lws_callback_on_writable(wsi); - break; - - case LWS_CALLBACK_RECEIVE: - pss->total_rx += len; - lwsl_err("rx %ld\n", (long)pss->total_rx); - if (pss->total_rx == TOTAL) { - lws_close_reason(wsi, LWS_CLOSE_STATUS_NORMAL, - (unsigned char *)"done", 4); - return -1; - } - break; - - case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: - lwsl_notice("LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: len %lu\n", - (unsigned long)len); - for (n = 0; n < (int)len; n++) - lwsl_notice(" %d: 0x%02X\n", n, - ((unsigned char *)in)[n]); - break; - - default: - break; - } - - return 0; -} diff --git a/test-server/test-server-libev.c b/test-server/test-server-libev.c index e1424ce..fab64a4 100644 --- a/test-server/test-server-libev.c +++ b/test-server/test-server-libev.c @@ -34,35 +34,9 @@ char *resource_path = LOCAL_RESOURCE_PATH; char crl_path[1024] = ""; #endif -/* - * libev dumps their hygiene problems on their users blaming compiler - * http://lists.schmorp.de/pipermail/libev/2008q4/000442.html - */ - -#if EV_MINPRI == EV_MAXPRI -# define _ev_set_priority(ev, pri) ((ev), (pri)) -#else -# define _ev_set_priority(ev, pri) { \ - ev_watcher *evw = (ev_watcher *)(void *)ev; \ - evw->priority = pri; \ -} -#endif - -#define _ev_init(ev,cb_) { \ - ev_watcher *evw = (ev_watcher *)(void *)ev; \ -\ - evw->active = evw->pending = 0; \ - _ev_set_priority((ev), 0); \ - ev_set_cb((ev), cb_); \ -} - -#define _ev_timer_init(ev, cb, after, _repeat) { \ - ev_watcher_time *evwt = (ev_watcher_time *)(void *)ev; \ -\ - _ev_init(ev, cb); \ - evwt->at = after; \ - (ev)->repeat = _repeat; \ -} +#define LWS_PLUGIN_STATIC +#include "../plugins/protocol_lws_mirror.c" +#include "../plugins/protocol_lws_status.c" /* singlethreaded version --> no locks */ @@ -94,6 +68,7 @@ enum demo_protocols { PROTOCOL_DUMB_INCREMENT, PROTOCOL_LWS_MIRROR, + PROTOCOL_LWS_STATUS, /* always last */ DEMO_PROTOCOL_COUNT @@ -114,20 +89,13 @@ static struct lws_protocols protocols[] = { "dumb-increment-protocol", callback_dumb_increment, sizeof(struct per_session_data__dumb_increment), - 10, - }, - { - "lws-mirror-protocol", - callback_lws_mirror, - sizeof(struct per_session_data__lws_mirror), - 128, - }, - { - "lws-status", - callback_lws_status, - sizeof(struct per_session_data__lws_status), - 128, + 10, /* rx buf size must be >= permessage-deflate rx size + * dumb-increment only sends very small packets, so we set + * this accordingly. If your protocol will send bigger + * things, adjust this to match */ }, + LWS_PLUGIN_PROTOCOL_MIRROR, + LWS_PLUGIN_PROTOCOL_LWS_STATUS, { NULL, NULL, 0, 0 } /* terminator */ }; @@ -296,7 +264,7 @@ int main(int argc, char **argv) #endif for (n = 0; n < ARRAY_SIZE(sigs); n++) { - _ev_init(&signals[n], signal_cb); + ev_init(&signals[n], signal_cb); ev_signal_set(&signals[n], sigs[n]); ev_signal_start(loop, &signals[n]); } @@ -364,7 +332,7 @@ int main(int argc, char **argv) lws_ev_initloop(context, loop, 0); - _ev_timer_init(&timeout_watcher, ev_timeout_cb, 0.05, 0.05); + ev_timer_init(&timeout_watcher, ev_timeout_cb, 0.05, 0.05); ev_timer_start(loop, &timeout_watcher); ev_run(loop, 0); diff --git a/test-server/test-server-libuv.c b/test-server/test-server-libuv.c index 3e1b271..cf8d755 100644 --- a/test-server/test-server-libuv.c +++ b/test-server/test-server-libuv.c @@ -19,6 +19,7 @@ * MA 02110-1301 USA */ +#define DI_HANDLED_BY_PLUGIN #include "test-server.h" #include @@ -45,6 +46,11 @@ void test_server_unlock(int care) { } +#define LWS_PLUGIN_STATIC +#include "../plugins/protocol_dumb_increment.c" +#include "../plugins/protocol_lws_mirror.c" +#include "../plugins/protocol_lws_status.c" + /* * This demo server shows how to use libwebsockets for one or more * websocket protocols in the same server @@ -66,6 +72,7 @@ enum demo_protocols { PROTOCOL_DUMB_INCREMENT, PROTOCOL_LWS_MIRROR, + PROTOCOL_LWS_STATUS, /* always last */ DEMO_PROTOCOL_COUNT @@ -82,24 +89,9 @@ static struct lws_protocols protocols[] = { sizeof (struct per_session_data__http), /* per_session_data_size */ 0, /* max frame size / rx buffer */ }, - { - "dumb-increment-protocol", - callback_dumb_increment, - sizeof(struct per_session_data__dumb_increment), - 10, - }, - { - "lws-mirror-protocol", - callback_lws_mirror, - sizeof(struct per_session_data__lws_mirror), - 128, - }, - { - "lws-status", - callback_lws_status, - sizeof(struct per_session_data__lws_status), - 128, - }, + LWS_PLUGIN_PROTOCOL_DUMB_INCREMENT, + LWS_PLUGIN_PROTOCOL_MIRROR, + LWS_PLUGIN_PROTOCOL_LWS_STATUS, { NULL, NULL, 0, 0 } /* terminator */ }; @@ -132,16 +124,6 @@ void signal_cb(uv_signal_t *watcher, int signum) lws_libuv_stop(context); } -static void -uv_timeout_cb_dumb_increment(uv_timer_t *w -#if UV_VERSION_MAJOR == 0 - , int status -#endif -) -{ - lws_callback_on_writable_all_protocol(context, - &protocols[PROTOCOL_DUMB_INCREMENT]); -} static struct option options[] = { { "help", no_argument, NULL, 'h' }, @@ -222,7 +204,6 @@ int main(int argc, char **argv) int foreign_libuv_loop = 0; /* <--- only needed for foreign loop test --- */ #endif - uv_timer_t timeout_watcher; const char *iface = NULL; char cert_path[1024]; char key_path[1024]; @@ -406,9 +387,6 @@ int main(int argc, char **argv) } } - uv_timer_init(lws_uv_getloop(context, 0), &timeout_watcher); - uv_timer_start(&timeout_watcher, uv_timeout_cb_dumb_increment, 50, 50); - #if UV_VERSION_MAJOR > 0 if (foreign_libuv_loop) { /* @@ -437,8 +415,6 @@ int main(int argc, char **argv) uv_timer_stop(&timer_inner); uv_close((uv_handle_t*)&timer_inner, timer_close_cb); - /* stop the dumb increment timer */ - uv_timer_stop(&timeout_watcher); lwsl_notice("Destroying lws context\n"); @@ -491,5 +467,7 @@ bail: lwsl_notice("libwebsockets-test-server exited cleanly\n"); + context = NULL; + return 0; } diff --git a/test-server/test-server-mirror.c b/test-server/test-server-mirror.c deleted file mode 100644 index f0d6111..0000000 --- a/test-server/test-server-mirror.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * libwebsockets-test-server - libwebsockets test implementation - * - * Copyright (C) 2010-2016 Andy Green - * - * 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. - * - * The test apps are intended to be adapted for use in your code, which - * may be proprietary. So unlike the library itself, they are licensed - * Public Domain. - */ -#include "test-server.h" - -/* lws-mirror_protocol */ - -#define MAX_MESSAGE_QUEUE 512 - -struct a_message { - void *payload; - size_t len; -}; - -static struct a_message ringbuffer[MAX_MESSAGE_QUEUE]; -static int ringbuffer_head; - -int -callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct per_session_data__lws_mirror *pss = - (struct per_session_data__lws_mirror *)user; - int n, m; - - switch (reason) { - - case LWS_CALLBACK_ESTABLISHED: - lwsl_info("%s: LWS_CALLBACK_ESTABLISHED\n", __func__); - pss->ringbuffer_tail = ringbuffer_head; - pss->wsi = wsi; - break; - - case LWS_CALLBACK_PROTOCOL_DESTROY: - lwsl_notice("%s: mirror protocol cleaning up\n", __func__); - for (n = 0; n < sizeof ringbuffer / sizeof ringbuffer[0]; n++) - if (ringbuffer[n].payload) - free(ringbuffer[n].payload); - break; - - case LWS_CALLBACK_SERVER_WRITEABLE: - if (close_testing) - break; - while (pss->ringbuffer_tail != ringbuffer_head) { - m = ringbuffer[pss->ringbuffer_tail].len; - n = lws_write(wsi, (unsigned char *) - ringbuffer[pss->ringbuffer_tail].payload + - LWS_PRE, m, LWS_WRITE_TEXT); - if (n < 0) { - lwsl_err("ERROR %d writing to mirror socket\n", n); - return -1; - } - if (n < m) - lwsl_err("mirror partial write %d vs %d\n", n, m); - - if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1)) - pss->ringbuffer_tail = 0; - else - pss->ringbuffer_tail++; - - if (((ringbuffer_head - pss->ringbuffer_tail) & - (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15)) - lws_rx_flow_allow_all_protocol(lws_get_context(wsi), - lws_get_protocol(wsi)); - - if (lws_send_pipe_choked(wsi)) { - lws_callback_on_writable(wsi); - break; - } - } - break; - - case LWS_CALLBACK_RECEIVE: - if (((ringbuffer_head - pss->ringbuffer_tail) & - (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 1)) { - lwsl_err("dropping!\n"); - goto choke; - } - - if (ringbuffer[ringbuffer_head].payload) - free(ringbuffer[ringbuffer_head].payload); - - ringbuffer[ringbuffer_head].payload = malloc(LWS_PRE + len); - ringbuffer[ringbuffer_head].len = len; - memcpy((char *)ringbuffer[ringbuffer_head].payload + - LWS_PRE, in, len); - if (ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) - ringbuffer_head = 0; - else - ringbuffer_head++; - - if (((ringbuffer_head - pss->ringbuffer_tail) & - (MAX_MESSAGE_QUEUE - 1)) != (MAX_MESSAGE_QUEUE - 2)) - goto done; - -choke: - lwsl_debug("LWS_CALLBACK_RECEIVE: throttling %p\n", wsi); - lws_rx_flow_control(wsi, 0); - -done: - lws_callback_on_writable_all_protocol(lws_get_context(wsi), - lws_get_protocol(wsi)); - break; - - /* - * this just demonstrates how to use the protocol filter. If you won't - * study and reject connections based on header content, you don't need - * to handle this callback - */ - - case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: - dump_handshake_info(wsi); - /* you could return non-zero here and kill the connection */ - break; - - default: - break; - } - - return 0; -} diff --git a/test-server/test-server-pthreads.c b/test-server/test-server-pthreads.c index b1b1f6d..cf4302c 100644 --- a/test-server/test-server-pthreads.c +++ b/test-server/test-server-pthreads.c @@ -37,6 +37,10 @@ struct lws_context *context; char crl_path[1024] = ""; #endif +#define LWS_PLUGIN_STATIC +#include "../plugins/protocol_lws_mirror.c" +#include "../plugins/protocol_lws_status.c" + /* * This mutex lock protects code that changes or relies on wsi list outside of * the service thread. The service thread will acquire it when changing the @@ -87,6 +91,7 @@ enum demo_protocols { PROTOCOL_DUMB_INCREMENT, PROTOCOL_LWS_MIRROR, + PROTOCOL_LWS_STATUS, /* always last */ DEMO_PROTOCOL_COUNT @@ -107,14 +112,13 @@ static struct lws_protocols protocols[] = { "dumb-increment-protocol", callback_dumb_increment, sizeof(struct per_session_data__dumb_increment), - 10, - }, - { - "lws-mirror-protocol", - callback_lws_mirror, - sizeof(struct per_session_data__lws_mirror), - 128, + 10, /* rx buf size must be >= permessage-deflate rx size + * dumb-increment only sends very small packets, so we set + * this accordingly. If your protocol will send bigger + * things, adjust this to match */ }, + LWS_PLUGIN_PROTOCOL_MIRROR, + LWS_PLUGIN_PROTOCOL_LWS_STATUS, { NULL, NULL, 0, 0 } /* terminator */ }; diff --git a/test-server/test-server-status.c b/test-server/test-server-status.c deleted file mode 100644 index bdfaf96..0000000 --- a/test-server/test-server-status.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * libwebsockets-test-server - libwebsockets test implementation - * - * Copyright (C) 2010-2016 Andy Green - * - * 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. - * - * The test apps are intended to be adapted for use in your code, which - * may be proprietary. So unlike the library itself, they are licensed - * Public Domain. - */ -#include "test-server.h" -#include - -static unsigned char server_info[1024]; -static int server_info_len; -static int current; -static char cache[16384]; -static int cache_len; -static struct per_session_data__lws_status *list; -static int live_wsi; - - -static void -update_status(struct lws *wsi, struct per_session_data__lws_status *pss) -{ - struct per_session_data__lws_status **pp = &list; - int subsequent = 0; - char *p = cache + LWS_PRE, *start = p; - char date[128]; - time_t t; - struct tm *ptm; -#ifndef WIN32 - struct tm tm; -#endif - - p += lws_snprintf(p, 512, " { %s, \"wsi\":\"%d\", \"conns\":[", - server_info, live_wsi); - - /* render the list */ - while (*pp) { - t = (*pp)->tv_established.tv_sec; -#ifdef WIN32 - ptm = localtime(&t); - if (!ptm) -#else - ptm = &tm; - if (!localtime_r(&t, &tm)) -#endif - strcpy(date, "unknown"); - else -#ifdef WIN32 - strftime(date, sizeof(date), "%Y %H:%M %Z", ptm); -#else - strftime(date, sizeof(date), "%F %H:%M %Z", ptm); -#endif - if ((p - start) > (sizeof(cache) - 512)) - break; - if (subsequent) - *p++ = ','; - subsequent = 1; - p += lws_snprintf(p, sizeof(cache) - (p - start) - 1, - "{\"peer\":\"%s\",\"time\":\"%s\"," - "\"ua\":\"%s\"}", - (*pp)->ip, date, (*pp)->user_agent); - pp = &((*pp)->list); - } - - p += sprintf(p, "]}"); - cache_len = p - start; - lwsl_err("cache_len %d\n", cache_len); - *p = '\0'; - - /* since we changed the list, increment the 'version' */ - current++; - /* update everyone */ - lws_callback_on_writable_all_protocol(lws_get_context(wsi), - lws_get_protocol(wsi)); -} - - -/* lws-status protocol */ - -int -callback_lws_status(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct per_session_data__lws_status *pss = - (struct per_session_data__lws_status *)user, - **pp; - char name[128], rip[128]; - int m; - - switch (reason) { - - case LWS_CALLBACK_PROTOCOL_INIT: - /* - * Prepare the static server info - */ - server_info_len = sprintf((char *)server_info, - "\"version\":\"%s\"," - " \"hostname\":\"%s\"", - lws_get_library_version(), - lws_canonical_hostname( - lws_get_context(wsi))); - break; - - case LWS_CALLBACK_ESTABLISHED: - /* - * we keep a linked list of live pss, so we can walk it - */ - pss->last = 0; - pss->list = list; - list = pss; - live_wsi++; - lws_get_peer_addresses(wsi, lws_get_socket_fd(wsi), name, - sizeof(name), rip, sizeof(rip)); - sprintf(pss->ip, "%s (%s)", name, rip); - gettimeofday(&pss->tv_established, NULL); - strcpy(pss->user_agent, "unknown"); - lws_hdr_copy(wsi, pss->user_agent, sizeof(pss->user_agent), - WSI_TOKEN_HTTP_USER_AGENT); - update_status(wsi, pss); - break; - - case LWS_CALLBACK_RECEIVE: - lwsl_notice("pmd test: RX len %d\n", (int)len); - puts(in); - break; - - case LWS_CALLBACK_SERVER_WRITEABLE: - m = lws_write(wsi, (unsigned char *)cache + LWS_PRE, cache_len, - LWS_WRITE_TEXT); - if (m < server_info_len) { - lwsl_err("ERROR %d writing to di socket\n", m); - return -1; - } - break; - - case LWS_CALLBACK_CLOSED: - /* - * remove ourselves from live pss list - */ - lwsl_debug("CLOSING pss %p ********\n", pss); - - pp = &list; - while (*pp) { - if (*pp == pss) { - *pp = pss->list; - pss->list = NULL; - live_wsi--; - break; - } - pp = &((*pp)->list); - } - - update_status(wsi, pss); - break; - - default: - break; - } - - return 0; -} diff --git a/test-server/test-server.c b/test-server/test-server.c index 426db3c..f4c4bc6 100644 --- a/test-server/test-server.c +++ b/test-server/test-server.c @@ -40,6 +40,34 @@ char *resource_path = LOCAL_RESOURCE_PATH; char crl_path[1024] = ""; #endif +/* + * This demonstrates how to use the clean protocol service separation of + * plugins, but with static inclusion instead of runtime dynamic loading + * (which requires libuv). + * + * dumb-increment doesn't use the plugin, both to demonstrate how to + * do the protocols directly, and because it wants libuv for a timer. + * + * Please consider using test-server-v2.0.c instead of this: it has the + * same functionality but + * + * 1) uses lws built-in http handling so you don't need to deal with it in + * your callback + * + * 2) Links with libuv and uses the plugins at runtime + * + * 3) Uses advanced lws features like mounts to bind parts of the filesystem + * to the served URL space + * + * Another option is lwsws, this operates like test-server-v2,0.c but is + * configured using JSON, do you do not need to provide any code for the + * serving action at all, just implement your protocols in plugins. + */ + +#define LWS_PLUGIN_STATIC +#include "../plugins/protocol_lws_mirror.c" +#include "../plugins/protocol_lws_status.c" + /* singlethreaded version --> no locks */ void test_server_lock(int care) @@ -62,6 +90,9 @@ void test_server_unlock(int care) * * lws-mirror-protocol: copies any received packet to every connection also * using this protocol, including the sender + * + * lws-status: informs connected browsers of who else is + * connected. */ enum demo_protocols { @@ -70,7 +101,6 @@ enum demo_protocols { PROTOCOL_DUMB_INCREMENT, PROTOCOL_LWS_MIRROR, - PROTOCOL_LWS_ECHOGEN, PROTOCOL_LWS_STATUS, /* always last */ @@ -92,26 +122,13 @@ static struct lws_protocols protocols[] = { "dumb-increment-protocol", callback_dumb_increment, sizeof(struct per_session_data__dumb_increment), - 10, /* rx buf size must be >= permessage-deflate rx size */ - }, - { - "lws-mirror-protocol", - callback_lws_mirror, - sizeof(struct per_session_data__lws_mirror), - 128, /* rx buf size must be >= permessage-deflate rx size */ - }, - { - "lws-echogen", - callback_lws_echogen, - sizeof(struct per_session_data__echogen), - 128, /* rx buf size must be >= permessage-deflate rx size */ - }, - { - "lws-status", - callback_lws_status, - sizeof(struct per_session_data__lws_status), - 512, /* rx buf size must be >= permessage-deflate rx size */ + 10, /* rx buf size must be >= permessage-deflate rx size + * dumb-increment only sends very small packets, so we set + * this accordingly. If your protocol will send bigger + * things, adjust this to match */ }, + LWS_PLUGIN_PROTOCOL_MIRROR, + LWS_PLUGIN_PROTOCOL_LWS_STATUS, { NULL, NULL, 0, 0 } /* terminator */ }; diff --git a/test-server/test-server.h b/test-server/test-server.h index ed936bf..29e6717 100644 --- a/test-server/test-server.h +++ b/test-server/test-server.h @@ -96,48 +96,22 @@ struct per_session_data__http { * connection. */ +#if !defined(DI_HANDLED_BY_PLUGIN) struct per_session_data__dumb_increment { int number; }; +#endif -struct per_session_data__lws_mirror { - struct lws *wsi; - int ringbuffer_tail; -}; - -struct per_session_data__echogen { - size_t total; - size_t total_rx; - int fd; - int fragsize; - int wr; -}; - -struct per_session_data__lws_status { - struct per_session_data__lws_status *list; - struct timeval tv_established; - int last; - char ip[270]; - char user_agent[512]; - const char *pos; - int len; -}; extern int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); -extern int -callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len); + +#if !defined(DI_HANDLED_BY_PLUGIN) extern int callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); -extern int -callback_lws_echogen(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len); -extern int -callback_lws_status(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len); +#endif extern void -- 2.7.4