#include <syslog.h>
#endif
+/* windows has no SIGUSR1 */
+#if !defined(WIN32) && !defined(_WIN32)
+#define TEST_DYNAMIC_VHOST
+#endif
+
+struct lws_context_creation_info info;
int debug_level = 7;
struct lws_context *context;
+#if defined(TEST_DYNAMIC_VHOST)
+volatile int dynamic_vhost_enable = 0;
+struct lws_vhost *dynamic_vhost;
+uv_timer_t timeout_watcher;
+#endif
+
/* http server gets files from this path */
#define LOCAL_RESOURCE_PATH INSTALL_DATADIR"/libwebsockets-test-server"
char *resource_path = LOCAL_RESOURCE_PATH;
* You can find the individual protocol plugin sources in ../plugins
*/
+#if defined(TEST_DYNAMIC_VHOST)
+
+/*
+ * to test dynamic vhost creation, fire a SIGUSR1 at the test server.
+ * It will toggle the existence of a second identical vhost at port + 1
+ *
+ * To synchronize with the event loop, it uses a libuv timer with 0 delay
+ * to get the business end called as the next event.
+ */
+
+static void
+uv_timeout_dynamic_vhost_toggle(uv_timer_t *w
+#if UV_VERSION_MAJOR == 0
+ , int status
+#endif
+)
+{
+ if (dynamic_vhost_enable && !dynamic_vhost) {
+ lwsl_notice("creating dynamic vhost...\n");
+ dynamic_vhost = lws_create_vhost(context, &info);
+ } else
+ if (!dynamic_vhost_enable && dynamic_vhost) {
+ lwsl_notice("destroying dynamic vhost...\n");
+ lws_vhost_destroy(dynamic_vhost);
+ dynamic_vhost = NULL;
+ }
+}
+
+void sighandler_USR1(int sig)
+{
+ dynamic_vhost_enable ^= 1;
+ lwsl_notice("SIGUSR1: dynamic_vhost_enable: %d\n",
+ dynamic_vhost_enable);
+ uv_timer_start(&timeout_watcher,
+ uv_timeout_dynamic_vhost_toggle, 0, 0);
+}
+#endif
+
void sighandler(int sig)
{
lws_cancel_service(context);
* linked-list. We can also give the plugin per-vhost options here.
*/
-static const struct lws_protocol_vhost_options pvo_4 = {
+static const struct lws_protocol_vhost_options pvo_5 = {
NULL,
+ NULL,
+ "lws-meta",
+ "" /* ignored, just matches the protocol name above */
+};
+
+static const struct lws_protocol_vhost_options pvo_4 = {
+ &pvo_5,
&pvo_opt4, /* set us as the protocol who gets raw connections */
"protocol-lws-raw-test",
"" /* ignored, just matches the protocol name above */
int main(int argc, char **argv)
{
- struct lws_context_creation_info info;
+ struct lws_vhost *vhost;
char interface_name[128] = "";
const char *iface = NULL;
char cert_path[1024] = "";
#endif
signal(SIGINT, sighandler);
+#if defined(TEST_DYNAMIC_VHOST)
+ signal(SIGUSR1, sighandler_USR1);
+#endif
#ifndef _WIN32
/* we will only try to log things according to our debug_level */
lws_set_log_level(debug_level, lwsl_emit_syslog);
lwsl_notice("libwebsockets test server - license LGPL2.1+SLE\n");
- lwsl_notice("(C) Copyright 2010-2016 Andy Green <andy@warmcat.com>\n");
+ lwsl_notice("(C) Copyright 2010-2017 Andy Green <andy@warmcat.com>\n");
lwsl_notice(" Using resource path \"%s\"\n", resource_path);
info.gid = gid;
info.uid = uid;
info.max_http_header_pool = 16;
- info.options = opts | LWS_SERVER_OPTION_FALLBACK_TO_RAW |
+ info.options = opts | LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
+ LWS_SERVER_OPTION_FALLBACK_TO_RAW |
LWS_SERVER_OPTION_VALIDATE_UTF8 |
LWS_SERVER_OPTION_LIBUV; /* plugins require this */
/* tell lws about our mount we want */
info.mounts = &mount;
/*
- * give it our linked-list of Per-Vhost Options, these control
+ * give it our linked-list of Per-Vhost Options, these control
* which protocols (from plugins) are allowed to be enabled on
* our vhost
*/
info.pvo = &pvo;
/*
- * As it is, this creates the context and a single Vhost at the same
- * time. You can use LWS_SERVER_OPTION_EXPLICIT_VHOSTS option above
- * to just create the context, and call lws_create_vhost() afterwards
- * multiple times with different info to get multiple listening vhosts.
+ * Since we used LWS_SERVER_OPTION_EXPLICIT_VHOSTS, this only creates
+ * the context. We can modify info and create as many vhosts as we
+ * like subsequently.
*/
context = lws_create_context(&info);
if (context == NULL) {
return -1;
}
+ /*
+ * normally we would adapt at least info.name to reflect the
+ * external hostname for this server.
+ */
+ vhost = lws_create_vhost(context, &info);
+ if (!vhost) {
+ lwsl_err("vhost creation failed\n");
+ return -1;
+ }
+
+#if defined(TEST_DYNAMIC_VHOST)
+ /* our dynamic vhost is on port + 1 */
+ info.port++;
+#endif
+
/* libuv event loop */
lws_uv_sigint_cfg(context, 1, signal_cb);
- if (lws_uv_initloop(context, NULL, 0))
+ if (lws_uv_initloop(context, NULL, 0)) {
lwsl_err("lws_uv_initloop failed\n");
- else
- lws_libuv_run(context, 0);
+ goto bail;
+ }
+
+#if defined(TEST_DYNAMIC_VHOST)
+ uv_timer_init(lws_uv_getloop(context, 0), &timeout_watcher);
+#endif
+ lws_libuv_run(context, 0);
+
+#if defined(TEST_DYNAMIC_VHOST)
+ uv_timer_stop(&timeout_watcher);
+ uv_close((uv_handle_t *)&timeout_watcher, NULL);
+#endif
+bail:
/* when we decided to exit the event loop */
lws_context_destroy(context);
+ lws_context_destroy2(context);
lwsl_notice("libwebsockets-test-server exited cleanly\n");
#ifndef _WIN32