plugin lws server status
Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
parent
4714cf02f4
commit
980614035f
14 changed files with 490 additions and 22 deletions
|
@ -95,13 +95,14 @@ option(LWS_WITH_HTTP_PROXY "Support for rewriting HTTP proxying" OFF)
|
|||
option(LWS_WITH_LWSWS "Libwebsockets Webserver" OFF)
|
||||
option(LWS_WITH_PLUGINS "Support plugins for protocols and extensions" OFF)
|
||||
option(LWS_WITH_ACCESS_LOG "Support generating Apache-compatible access logs" OFF)
|
||||
|
||||
option(LWS_WITH_SERVER_STATUS "Support json + jscript server monitoring" OFF)
|
||||
|
||||
if (LWS_WITH_LWSWS)
|
||||
message(STATUS "LWS_WITH_LWSWS --> Enabling LWS_WITH_PLUGINS and LWS_WITH_LIBUV")
|
||||
set(LWS_WITH_PLUGINS 1)
|
||||
set(LWS_WITH_LIBUV 1)
|
||||
set(LWS_WITH_ACCESS_LOG 1)
|
||||
set(LWS_WITH_SERVER_STATUS 1)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_PLUGINS AND NOT LWS_WITH_LIBUV)
|
||||
|
@ -1199,6 +1200,10 @@ if (NOT LWS_WITHOUT_TESTAPPS)
|
|||
"plugins/protocol_lws_mirror.c")
|
||||
create_plugin(protocol_lws_status
|
||||
"plugins/protocol_lws_status.c")
|
||||
if (LWS_WITH_SERVER_STATUS)
|
||||
create_plugin(protocol_lws_server_status
|
||||
"plugins/protocol_lws_server_status.c")
|
||||
endif()
|
||||
endif(LWS_WITH_PLUGINS AND LWS_WITH_SHARED)
|
||||
|
||||
#
|
||||
|
@ -1399,6 +1404,11 @@ if (LWS_WITH_PLUGINS)
|
|||
PERMISSIONS OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE OWNER_READ GROUP_READ WORLD_READ
|
||||
DESTINATION share/libwebsockets-test-server/plugins
|
||||
COMPONENT plugins)
|
||||
if (LWS_WITH_SERVER_STATUS)
|
||||
install(FILES plugins/server-status.html
|
||||
DESTINATION share/libwebsockets-test-server/server-status
|
||||
COMPONENT examples)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Install the LibwebsocketsConfig.cmake and LibwebsocketsConfigVersion.cmake
|
||||
|
@ -1466,6 +1476,7 @@ message(" LWS_WITH_HTTP_PROXY = ${LWS_WITH_HTTP_PROXY}")
|
|||
message(" LIBHUBBUB_LIBRARIES = ${LIBHUBBUB_LIBRARIES}")
|
||||
message(" PLUGINS = ${PLUGINS_LIST}")
|
||||
message(" LWS_WITH_ACCESS_LOG = ${LWS_WITH_ACCESS_LOG}")
|
||||
message(" LWS_WITH_SERVER_STATUS = ${LWS_WITH_SERVER_STATUS}")
|
||||
message("---------------------------------------------------------------------")
|
||||
|
||||
# These will be available to parent projects including libwebsockets using add_subdirectory()
|
||||
|
|
|
@ -153,6 +153,11 @@ Vhosts can select which plugins they want to offer and give them per-vhost setti
|
|||
|
||||
```
|
||||
|
||||
The "x":"y" parameters like "status":"ok" are made available to the protocol during its per-vhost
|
||||
LWS_CALLBACK_PROTOCOL_INIT (@in is a pointer to a linked list of struct lws_protocol_vhost_options
|
||||
containing the name and value pointers).
|
||||
|
||||
|
||||
Other vhost options
|
||||
-------------------
|
||||
|
||||
|
@ -265,3 +270,28 @@ dumb increment, mirror and status protocol plugins are provided as examples.
|
|||
|
||||
|
||||
|
||||
lws-server-status plugin
|
||||
------------------------
|
||||
|
||||
One provided protocol can be used to monitor the server status.
|
||||
|
||||
Enable the protocol like this on a vhost's ws-protocols section
|
||||
|
||||
"lws-server-status": {
|
||||
"status": "ok",
|
||||
"update-ms": "5000"
|
||||
}
|
||||
|
||||
"update-ms" is used to control how often updated JSON is sent on a ws link.
|
||||
|
||||
And map the provided HTML into the vhost in the mounts section
|
||||
|
||||
{
|
||||
"mountpoint": "/server-status",
|
||||
"origin": "file:///usr/local/share/libwebsockets-test-server/server-status",
|
||||
"default": "server-status.html"
|
||||
}
|
||||
|
||||
You might choose to put it on its own vhost which has "interface": "lo", so it's not
|
||||
externally visible.
|
||||
|
||||
|
|
|
@ -440,7 +440,6 @@ lws_create_context(struct lws_context_creation_info *info)
|
|||
struct rlimit rt;
|
||||
#endif
|
||||
|
||||
|
||||
lwsl_notice("Initial logging level %d\n", log_level);
|
||||
lwsl_notice("Libwebsockets version: %s\n", library_version);
|
||||
#if LWS_POSIX
|
||||
|
@ -471,6 +470,8 @@ lws_create_context(struct lws_context_creation_info *info)
|
|||
lwsl_err("No memory for websocket context\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context->time_up = time(NULL);
|
||||
#ifndef LWS_NO_DAEMONIZE
|
||||
if (pid_daemon) {
|
||||
context->started_with_parent = pid_daemon;
|
||||
|
|
|
@ -2234,6 +2234,8 @@ lws_access_log(struct lws *wsi)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef LWS_WITH_SERVER_STATUS
|
||||
|
||||
LWS_EXTERN int
|
||||
lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len)
|
||||
{
|
||||
|
@ -2254,10 +2256,15 @@ lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len)
|
|||
buf += snprintf(buf, end - buf,
|
||||
"{\n \"name\":\"%s\",\n"
|
||||
" \"port\":\"%d\",\n"
|
||||
" \"use-ssl\":\"%d\",\n"
|
||||
" \"use_ssl\":\"%d\",\n"
|
||||
" \"sts\":\"%d\",\n"
|
||||
" \"rx\":\"%lu\",\n"
|
||||
" \"tx\":\"%lu\",\n",
|
||||
" \"tx\":\"%lu\",\n"
|
||||
" \"conn\":\"%lu\",\n"
|
||||
" \"trans\":\"%lu\",\n"
|
||||
" \"ws_upg\":\"%lu\",\n"
|
||||
" \"http2_upg\":\"%lu\""
|
||||
,
|
||||
vh->name, vh->listen_port,
|
||||
#ifdef LWS_OPENSSL_SUPPORT
|
||||
vh->use_ssl,
|
||||
|
@ -2265,7 +2272,8 @@ lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len)
|
|||
0,
|
||||
#endif
|
||||
!!(vh->options & LWS_SERVER_OPTION_STS),
|
||||
vh->rx, vh->tx
|
||||
vh->rx, vh->tx, vh->conn, vh->trans, vh->ws_upgrades,
|
||||
vh->http2_upgrades
|
||||
);
|
||||
|
||||
if (vh->mount_list) {
|
||||
|
@ -2277,7 +2285,7 @@ lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len)
|
|||
buf += snprintf(buf, end - buf, ",");
|
||||
buf += snprintf(buf, end - buf,
|
||||
"\n {\n \"mountpoint\":\"%s\",\n"
|
||||
" \"origin\":\"%s%s\""
|
||||
" \"origin\":\"%s%s\"\n"
|
||||
,
|
||||
m->mountpoint,
|
||||
prots[m->origin_protocol],
|
||||
|
@ -2316,3 +2324,34 @@ lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len)
|
|||
|
||||
return buf - orig;
|
||||
}
|
||||
|
||||
|
||||
LWS_EXTERN LWS_VISIBLE int
|
||||
lws_json_dump_context(const struct lws_context *context, char *buf, int len)
|
||||
{
|
||||
char *orig = buf, *end = buf + len - 1, first = 1;
|
||||
struct lws_vhost *vh = context->vhost_list;
|
||||
time_t t = time(NULL);
|
||||
|
||||
buf += snprintf(buf, end - buf, "{ "
|
||||
"\"uptime\":\"%ld\",\n"
|
||||
"\"wsi_alive\":\"%d\",\n"
|
||||
"\"vhosts\":[\n ",
|
||||
(unsigned long)(t - context->time_up),
|
||||
context->count_wsi_allocated);
|
||||
|
||||
while (vh) {
|
||||
if (!first)
|
||||
if(buf != end)
|
||||
*buf++ = ',';
|
||||
buf += lws_json_dump_vhost(vh, buf, end - buf);
|
||||
first = 0;
|
||||
vh = vh->vhost_next;
|
||||
}
|
||||
|
||||
buf += snprintf(buf, end - buf, "]}\n ");
|
||||
|
||||
return buf - orig;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1566,6 +1566,9 @@ lws_write_http_mount(struct lws_http_mount *next, struct lws_http_mount **res,
|
|||
LWS_EXTERN int
|
||||
lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len);
|
||||
|
||||
LWS_EXTERN int
|
||||
lws_json_dump_context(const struct lws_context *context, char *buf, int len);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lws_set_log_level(int level,
|
||||
void (*log_emit_function)(int level, const char *line));
|
||||
|
|
|
@ -251,6 +251,8 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len,
|
|||
#ifdef LWS_WITH_ACCESS_LOG
|
||||
wsi->access_log.sent += len;
|
||||
#endif
|
||||
if (wsi->vhost)
|
||||
wsi->vhost->tx += len;
|
||||
|
||||
if (wsi->state == LWSS_ESTABLISHED && wsi->u.ws.tx_draining_ext) {
|
||||
/* remove us from the list */
|
||||
|
@ -634,8 +636,11 @@ lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, int len)
|
|||
int n;
|
||||
|
||||
n = recv(wsi->sock, (char *)buf, len, 0);
|
||||
if (n > 0)
|
||||
if (n > 0) {
|
||||
if (wsi->vhost)
|
||||
wsi->vhost->rx += n;
|
||||
return n;
|
||||
}
|
||||
#if LWS_POSIX
|
||||
if (LWS_ERRNO == LWS_EAGAIN ||
|
||||
LWS_ERRNO == LWS_EWOULDBLOCK ||
|
||||
|
|
|
@ -668,7 +668,7 @@ struct lws_vhost {
|
|||
#ifndef LWS_NO_EXTENSIONS
|
||||
const struct lws_extension *extensions;
|
||||
#endif
|
||||
unsigned long rx, tx;
|
||||
unsigned long rx, tx, conn, trans, ws_upgrades, http2_upgrades;
|
||||
|
||||
int listen_port;
|
||||
unsigned int http_proxy_port;
|
||||
|
@ -698,6 +698,7 @@ struct lws_vhost {
|
|||
|
||||
struct lws_context {
|
||||
time_t last_timeout_check_s;
|
||||
time_t time_up;
|
||||
struct lws_plat_file_ops fops;
|
||||
struct lws_context_per_thread pt[LWS_MAX_SMP];
|
||||
#ifdef _WIN32
|
||||
|
@ -1255,6 +1256,7 @@ struct lws {
|
|||
unsigned int socket_is_permanently_unusable:1;
|
||||
unsigned int rxflow_change_to:2;
|
||||
unsigned int more_rx_waiting:1; /* has to live here since ah may stick to end */
|
||||
unsigned int conn_stat_done:1;
|
||||
#ifdef LWS_WITH_ACCESS_LOG
|
||||
unsigned int access_log_pending:1;
|
||||
#endif
|
||||
|
|
30
lib/server.c
30
lib/server.c
|
@ -700,6 +700,23 @@ lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
|
|||
lwsl_debug("%s: wsi->more_rx_waiting=%d\n", __func__,
|
||||
wsi->more_rx_waiting);
|
||||
|
||||
/* select vhost */
|
||||
|
||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_HOST)) {
|
||||
struct lws_vhost *vhost = lws_select_vhost(
|
||||
context, wsi->vhost->listen_port,
|
||||
lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST));
|
||||
|
||||
if (vhost)
|
||||
wsi->vhost = vhost;
|
||||
}
|
||||
|
||||
wsi->vhost->trans++;
|
||||
if (!wsi->conn_stat_done) {
|
||||
wsi->vhost->conn++;
|
||||
wsi->conn_stat_done = 1;
|
||||
}
|
||||
|
||||
wsi->mode = LWSCM_PRE_WS_SERVING_ACCEPT;
|
||||
lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
|
||||
|
||||
|
@ -708,12 +725,14 @@ lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
|
|||
if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) {
|
||||
if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE),
|
||||
"websocket")) {
|
||||
wsi->vhost->ws_upgrades++;
|
||||
lwsl_info("Upgrade to ws\n");
|
||||
goto upgrade_ws;
|
||||
}
|
||||
#ifdef LWS_USE_HTTP2
|
||||
if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE),
|
||||
"h2c")) {
|
||||
wsi->vhost->http2_upgrades++;
|
||||
lwsl_info("Upgrade to h2c\n");
|
||||
goto upgrade_h2c;
|
||||
}
|
||||
|
@ -728,17 +747,6 @@ lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
|
|||
lwsl_info("No upgrade\n");
|
||||
ah = wsi->u.hdr.ah;
|
||||
|
||||
/* select vhost */
|
||||
|
||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_HOST)) {
|
||||
struct lws_vhost *vhost = lws_select_vhost(
|
||||
context, wsi->vhost->listen_port,
|
||||
lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST));
|
||||
|
||||
if (vhost)
|
||||
wsi->vhost = vhost;
|
||||
}
|
||||
|
||||
lws_union_transition(wsi, LWSCM_HTTP_SERVING_ACCEPTED);
|
||||
wsi->state = LWSS_HTTP;
|
||||
wsi->u.http.fd = LWS_INVALID_FILE;
|
||||
|
|
|
@ -94,6 +94,7 @@
|
|||
|
||||
/* Http access log support */
|
||||
#cmakedefine LWS_WITH_ACCESS_LOG
|
||||
#cmakedefine LWS_WITH_SERVER_STATUS
|
||||
|
||||
/* Maximum supported service threads */
|
||||
#define LWS_MAX_SMP ${LWS_MAX_SMP}
|
||||
|
|
|
@ -59,7 +59,6 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
|
||||
switch (reason) {
|
||||
case LWS_CALLBACK_PROTOCOL_INIT:
|
||||
lwsl_notice("%s: pvo %p\n", __func__, in);
|
||||
vhd = lws_protocol_vh_priv_zalloc(lws_vhost_get(wsi),
|
||||
lws_protocol_get(wsi),
|
||||
sizeof(struct per_vhost_data__dumb_increment));
|
||||
|
@ -73,6 +72,8 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
break;
|
||||
|
||||
case LWS_CALLBACK_PROTOCOL_DESTROY:
|
||||
if (!vhd)
|
||||
break;
|
||||
uv_timer_stop(&vhd->timeout_watcher);
|
||||
break;
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
break;
|
||||
|
||||
case LWS_CALLBACK_PROTOCOL_DESTROY: /* per vhost */
|
||||
if (!v)
|
||||
break;
|
||||
lwsl_info("%s: mirror protocol cleaning up %p\n", __func__, v);
|
||||
for (n = 0; n < ARRAY_SIZE(v->ringbuffer); n++)
|
||||
if (v->ringbuffer[n].payload) {
|
||||
|
|
147
plugins/protocol_lws_server_status.c
Normal file
147
plugins/protocol_lws_server_status.c
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* libwebsockets-test-server - libwebsockets test implementation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 "../lib/libwebsockets.h"
|
||||
#include <string.h>
|
||||
|
||||
#define LWS_SS_VERSIONS 3
|
||||
|
||||
struct lws_ss_dumps {
|
||||
char buf[32768];
|
||||
int length;
|
||||
};
|
||||
|
||||
static struct lws_ss_dumps d[LWS_SS_VERSIONS];
|
||||
static int last_dump;
|
||||
static uv_timer_t timeout_watcher;
|
||||
static struct lws_context *context;
|
||||
static int tow_flag;
|
||||
|
||||
struct per_session_data__server_status {
|
||||
int ver;
|
||||
int pos;
|
||||
};
|
||||
|
||||
static const struct lws_protocols protocols[];
|
||||
|
||||
static void
|
||||
uv_timeout_cb_server_status(uv_timer_t *w
|
||||
#if UV_VERSION_MAJOR == 0
|
||||
, int status
|
||||
#endif
|
||||
)
|
||||
{
|
||||
int n;
|
||||
|
||||
last_dump = (last_dump + 1) % LWS_SS_VERSIONS;
|
||||
n = lws_json_dump_context(context, d[last_dump].buf + LWS_PRE,
|
||||
sizeof(d[0].buf) - LWS_PRE);
|
||||
d[last_dump].length = n;
|
||||
|
||||
lws_callback_on_writable_all_protocol(context, &protocols[0]);
|
||||
}
|
||||
|
||||
static int
|
||||
callback_lws_server_status(struct lws *wsi, enum lws_callback_reasons reason,
|
||||
void *user, void *in, size_t len)
|
||||
{
|
||||
struct lws_protocol_vhost_options *pvo =
|
||||
(struct lws_protocol_vhost_options *)in;
|
||||
int m, period = 1000;
|
||||
|
||||
switch (reason) {
|
||||
|
||||
case LWS_CALLBACK_ESTABLISHED:
|
||||
lwsl_info("%s: LWS_CALLBACK_ESTABLISHED\n", __func__);
|
||||
lws_callback_on_writable(wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_PROTOCOL_INIT: /* per vhost */
|
||||
if (tow_flag)
|
||||
break;
|
||||
while (pvo) {
|
||||
if (!strcmp(pvo->name, "update-ms"))
|
||||
period = atoi(pvo->value);
|
||||
pvo = pvo->next;
|
||||
}
|
||||
context = lws_get_context(wsi);
|
||||
uv_timer_init(lws_uv_getloop(context, 0), &timeout_watcher);
|
||||
uv_timer_start(&timeout_watcher,
|
||||
uv_timeout_cb_server_status, 2000, period);
|
||||
tow_flag = 1;
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_PROTOCOL_DESTROY: /* per vhost */
|
||||
if (!tow_flag)
|
||||
break;
|
||||
uv_timer_stop(&timeout_watcher);
|
||||
tow_flag = 0;
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_SERVER_WRITEABLE:
|
||||
m = lws_write(wsi, (unsigned char *)
|
||||
d[last_dump].buf + LWS_PRE, d[last_dump].length,
|
||||
LWS_WRITE_TEXT);
|
||||
if (m < 0)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct lws_protocols protocols[] = {
|
||||
{
|
||||
"lws-server-status",
|
||||
callback_lws_server_status,
|
||||
sizeof(struct per_session_data__server_status),
|
||||
1024,
|
||||
},
|
||||
};
|
||||
|
||||
LWS_VISIBLE int
|
||||
init_protocol_lws_server_status(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_lws_server_status(struct lws_context *context)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -102,8 +102,7 @@ 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;
|
||||
(struct per_session_data__lws_status *)user, **pp;
|
||||
char name[128], rip[128];
|
||||
int m;
|
||||
|
||||
|
|
219
plugins/server-status.html
Normal file
219
plugins/server-status.html
Normal file
|
@ -0,0 +1,219 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset=utf-8 http-equiv="Content-Language" content="en"/>
|
||||
<title>LWS Server Status</title>
|
||||
<style type="text/css">
|
||||
span.title { font-size:18pt; font: Arial; font-weight:normal;
|
||||
text-align:center; color:#000000; }
|
||||
span.mount { font-size:10pt; font: Arial; font-weight:normal;
|
||||
text-align:center; color:#000000; }
|
||||
.browser { font-size:18pt; font: Arial; font-weight:normal; text-align:center; color:#ffff00; vertical-align:middle; text-align:center; background:#d0b070; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px;}
|
||||
.group2 { vertical-align:middle;
|
||||
text-align:center;
|
||||
background:#f0f0e0;
|
||||
padding:12px;
|
||||
-webkit-border-radius:10px;
|
||||
-moz-border-radius:10px;
|
||||
border-radius:10px; }
|
||||
.explain { vertical-align:middle;
|
||||
text-align:center;
|
||||
background:#f0f0c0; padding:12px;
|
||||
-webkit-border-radius:10px;
|
||||
-moz-border-radius:10px;
|
||||
border-radius:10px;
|
||||
color:#404000; }
|
||||
td.wsstatus { vertical-align:middle; width:200px; height:50px;
|
||||
text-align:center;
|
||||
background:#f0f0c0; padding:6px;
|
||||
-webkit-border-radius:8px;
|
||||
-moz-border-radius:8px;
|
||||
border-radius:8px;
|
||||
color:#404000; }
|
||||
td.l { vertical-align:middle;
|
||||
text-align:center;
|
||||
background:#d0d0b0;
|
||||
padding:3px;
|
||||
-webkit-border-radius:3px;
|
||||
-moz-border-radius:3px;
|
||||
border-radius:3px; }
|
||||
td.c { vertical-align:middle;
|
||||
text-align:center;
|
||||
background:#c0c0a0;
|
||||
padding:3px;
|
||||
-webkit-border-radius:3px;
|
||||
-moz-border-radius:3px;
|
||||
border-radius:3px; }
|
||||
td.t { vertical-align:middle;
|
||||
text-align:center;
|
||||
background:#e0e0c0;
|
||||
padding:3px;
|
||||
-webkit-border-radius:3px;
|
||||
-moz-border-radius:3px;
|
||||
border-radius:3px; }
|
||||
.content { vertical-align:top; text-align:center; background:#fffff0; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px; }
|
||||
.canvas { vertical-align:top; text-align:center; background:#efefd0; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px; }
|
||||
.tabs {
|
||||
position: relative;
|
||||
min-height: 750px; /* This part sucks */
|
||||
clear: both;
|
||||
margin: 25px 0;
|
||||
}
|
||||
.tab {
|
||||
float: left;
|
||||
}
|
||||
.tab label {
|
||||
background: #eee;
|
||||
padding: 10px;
|
||||
border: 1px solid #ccc;
|
||||
margin-left: -1px;
|
||||
position: relative;
|
||||
left: 1px;
|
||||
}
|
||||
.tab [type=radio] {
|
||||
display: none;
|
||||
}
|
||||
.content {
|
||||
position: absolute;
|
||||
top: 28px;
|
||||
left: 0;
|
||||
background: white;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 20px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
[type=radio]:checked ~ label {
|
||||
background: white;
|
||||
border-bottom: 1px solid white;
|
||||
z-index: 2;
|
||||
}
|
||||
[type=radio]:checked ~ label ~ .content {
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header></header>
|
||||
<article>
|
||||
|
||||
<table><tr><td align=center>
|
||||
<div id="conninfo">...</div>
|
||||
</td></tr>
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
</article>
|
||||
|
||||
<script>
|
||||
|
||||
/*
|
||||
* We display untrusted stuff in html context... reject anything
|
||||
* that has HTML stuff in it
|
||||
*/
|
||||
|
||||
function san(s)
|
||||
{
|
||||
if (s.search("<") != -1)
|
||||
return "invalid string";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
var pos = 0;
|
||||
|
||||
function get_appropriate_ws_url()
|
||||
{
|
||||
var pcol;
|
||||
var u = document.URL;
|
||||
|
||||
/*
|
||||
* We open the websocket encrypted if this page came on an
|
||||
* https:// url itself, otherwise unencrypted
|
||||
*/
|
||||
|
||||
if (u.substring(0, 5) == "https") {
|
||||
pcol = "wss://";
|
||||
u = u.substr(8);
|
||||
} else {
|
||||
pcol = "ws://";
|
||||
if (u.substring(0, 4) == "http")
|
||||
u = u.substr(7);
|
||||
}
|
||||
|
||||
u = u.split('/');
|
||||
|
||||
/* + "/xxx" bit is for IE10 workaround */
|
||||
|
||||
return pcol + u[0] + "/xxx";
|
||||
}
|
||||
|
||||
|
||||
var socket_status, jso, s;
|
||||
|
||||
if (typeof MozWebSocket != "undefined") {
|
||||
socket_status = new MozWebSocket(get_appropriate_ws_url(),
|
||||
"lws-server-status");
|
||||
} else {
|
||||
socket_status = new WebSocket(get_appropriate_ws_url(),
|
||||
"lws-server-status");
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
socket_status.onopen = function() {
|
||||
}
|
||||
|
||||
socket_status.onmessage =function got_packet(msg) {
|
||||
document.getElementById("conninfo").innerHTML = "<pre>"+msg.data+"</pre>";
|
||||
jso = JSON.parse(msg.data);
|
||||
|
||||
s="<table><tr><td class=\"c\">" +
|
||||
"Context</td><td>Uptime: " + san(jso.uptime) + "<br>" +
|
||||
"Current wsi alive: " + san(jso.wsi_alive) +
|
||||
"</td></tr>";
|
||||
var n;
|
||||
for (n = 0; n < jso.vhosts.length; n++) {
|
||||
s = s + "<tr><td class=\"l\">vhost " + (n + 1) +
|
||||
"</td><td><b>" + san(jso.vhosts[n].name) + ":" +
|
||||
san(jso.vhosts[n].port) +
|
||||
"</b><br>" +
|
||||
"ssl " + san(jso.vhosts[n].use_ssl) + ", " +
|
||||
"sts " + san(jso.vhosts[n].sts) + "<br>" +
|
||||
"rx " + san(jso.vhosts[n].rx) + ", " +
|
||||
"tx " + san(jso.vhosts[n].tx) + "<br>" +
|
||||
"total connections " + san(jso.vhosts[n].conn) + ", " +
|
||||
"total http transactions " + san(jso.vhosts[n].trans) + "<br>" +
|
||||
"Upgrades to ws " + san(jso.vhosts[n].ws_upg) + ", " +
|
||||
"to http2 " + san(jso.vhosts[n].http2_upg) + "<br>" +
|
||||
"<table><tr><td class=t colspan=2>Mounts</td></tr>";
|
||||
|
||||
var m;
|
||||
for (m = 0; m < jso.vhosts[n].mounts.length; m++) {
|
||||
s = s + "<tr><td>";
|
||||
s = s + san(jso.vhosts[n].mounts[m].mountpoint) +
|
||||
"</td><td>" +
|
||||
san(jso.vhosts[n].mounts[m].origin);
|
||||
s = s + "</td></tr>"
|
||||
}
|
||||
s = s + "</table>";
|
||||
s = s + "</td></tr>";
|
||||
}
|
||||
s = s + "</table>";
|
||||
|
||||
document.getElementById("conninfo").innerHTML = s;
|
||||
}
|
||||
|
||||
socket_status.onclose = function(){
|
||||
document.getElementById("s_statustd").style.backgroundColor = "#ff4040";
|
||||
document.getElementById("s_status").textContent = " websocket connection CLOSED ";
|
||||
}
|
||||
} catch(exception) {
|
||||
alert('<p>Error' + exception);
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Reference in a new issue