1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-16 00:00:07 +01:00

test server add lws_status

Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
Andy Green 2016-02-21 13:44:07 +08:00
parent 9c6bd66859
commit 4038721baf
6 changed files with 351 additions and 40 deletions

View file

@ -748,7 +748,7 @@ if (NOT LWS_WITHOUT_TESTAPPS)
# #
# Helper function for adding a test app. # Helper function for adding a test app.
# #
macro(create_test_app TEST_NAME MAIN_SRC S2 S3 S4 S5) macro(create_test_app TEST_NAME MAIN_SRC S2 S3 S4 S5 S6)
set(TEST_SRCS ${MAIN_SRC}) set(TEST_SRCS ${MAIN_SRC})
set(TEST_HDR) set(TEST_HDR)
@ -768,6 +768,10 @@ if (NOT LWS_WITHOUT_TESTAPPS)
else() else()
list(APPEND TEST_SRCS ${S5}) list(APPEND TEST_SRCS ${S5})
endif() endif()
if ("${S6}" STREQUAL "")
else()
list(APPEND TEST_SRCS ${S6})
endif()
if (WIN32) if (WIN32)
list(APPEND TEST_SRCS list(APPEND TEST_SRCS
${WIN32_HELPERS_PATH}/getopt.c ${WIN32_HELPERS_PATH}/getopt.c
@ -829,12 +833,14 @@ if (NOT LWS_WITHOUT_TESTAPPS)
"test-server/test-server-http.c" "test-server/test-server-http.c"
"test-server/test-server-dumb-increment.c" "test-server/test-server-dumb-increment.c"
"test-server/test-server-mirror.c" "test-server/test-server-mirror.c"
"test-server/test-server-status.c"
"test-server/test-server-echogen.c") "test-server/test-server-echogen.c")
if (UNIX) if (UNIX)
create_test_app(test-fuzxy "test-server/fuzxy.c" create_test_app(test-fuzxy "test-server/fuzxy.c"
"" ""
"" ""
"" ""
""
"") "")
endif() endif()
if (UNIX AND NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))) if (UNIX AND NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")))
@ -843,6 +849,7 @@ if (NOT LWS_WITHOUT_TESTAPPS)
"test-server/test-server-http.c" "test-server/test-server-http.c"
"test-server/test-server-dumb-increment.c" "test-server/test-server-dumb-increment.c"
"test-server/test-server-mirror.c" "test-server/test-server-mirror.c"
"test-server/test-server-status.c"
"test-server/test-server-echogen.c") "test-server/test-server-echogen.c")
endif() endif()
if (UNIX AND NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) if (UNIX AND NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
@ -852,6 +859,7 @@ if (NOT LWS_WITHOUT_TESTAPPS)
"test-server/test-server-http.c" "test-server/test-server-http.c"
"test-server/test-server-dumb-increment.c" "test-server/test-server-dumb-increment.c"
"test-server/test-server-mirror.c" "test-server/test-server-mirror.c"
"test-server/test-server-status.c"
"test-server/test-server-echogen.c") "test-server/test-server-echogen.c")
endif() endif()
if (UNIX AND NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) if (UNIX AND NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
@ -861,6 +869,7 @@ if (NOT LWS_WITHOUT_TESTAPPS)
"test-server/test-server-http.c" "test-server/test-server-http.c"
"test-server/test-server-dumb-increment.c" "test-server/test-server-dumb-increment.c"
"test-server/test-server-mirror.c" "test-server/test-server-mirror.c"
"test-server/test-server-status.c"
"test-server/test-server-echogen.c") "test-server/test-server-echogen.c")
endif() endif()
endif() endif()
@ -873,6 +882,7 @@ if (NOT LWS_WITHOUT_TESTAPPS)
"test-server/test-server-http.c" "test-server/test-server-http.c"
"test-server/test-server-dumb-increment.c" "test-server/test-server-dumb-increment.c"
"test-server/test-server-mirror.c" "test-server/test-server-mirror.c"
"test-server/test-server-status.c"
"test-server/test-server-echogen.c") "test-server/test-server-echogen.c")
# Set defines for this executable only. # Set defines for this executable only.
set_property( set_property(
@ -978,27 +988,27 @@ if (NOT LWS_WITHOUT_TESTAPPS)
# test-client # test-client
# #
if (NOT LWS_WITHOUT_TEST_CLIENT) if (NOT LWS_WITHOUT_TEST_CLIENT)
create_test_app(test-client "test-server/test-client.c" "" "" "" "") create_test_app(test-client "test-server/test-client.c" "" "" "" "" "")
endif() endif()
# #
# test-fraggle # test-fraggle
# #
if (NOT LWS_WITHOUT_TEST_FRAGGLE) if (NOT LWS_WITHOUT_TEST_FRAGGLE)
create_test_app(test-fraggle "test-server/test-fraggle.c" "" "" "" "") create_test_app(test-fraggle "test-server/test-fraggle.c" "" "" "" "" "")
endif() endif()
# #
# test-ping # test-ping
# #
if (NOT LWS_WITHOUT_TEST_PING) if (NOT LWS_WITHOUT_TEST_PING)
create_test_app(test-ping "test-server/test-ping.c" "" "" "" "") create_test_app(test-ping "test-server/test-ping.c" "" "" "" "" "")
endif() endif()
# #
# test-echo # test-echo
# #
if (NOT LWS_WITHOUT_TEST_ECHO) if (NOT LWS_WITHOUT_TEST_ECHO)
create_test_app(test-echo "test-server/test-echo.c" "" "" "" "") create_test_app(test-echo "test-server/test-echo.c" "" "" "" "" "")
endif() endif()
endif(NOT LWS_WITHOUT_CLIENT) endif(NOT LWS_WITHOUT_CLIENT)

View file

@ -6,6 +6,13 @@ Fixes
1) libuv one-per-session valgrind leak fixed 1) libuv one-per-session valgrind leak fixed
Changes
-------
1) test server html is updated with tabs and a new live server monitoring
feature. Input sanitization added to the js.
v1.7.1 v1.7.1
====== ======

View file

@ -0,0 +1,154 @@
/*
* 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 "test-server.h"
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;
char date[128];
time_t t;
struct tm tm;
p += snprintf(p, 512, " { %s, \"wsi\":\"%d\", \"conns\":[",
server_info, live_wsi);
/* render the list */
while (*pp) {
t = (*pp)->tv_established.tv_sec;
if (!localtime_r(&t, &tm))
strcpy(date, "unknown");
else
strftime(date, sizeof(date), "%F %H:%M %Z", &tm);
if ((p - cache) > (sizeof(cache) - 512))
break;
if (subsequent)
*p++ = ',';
subsequent = 1;
p += snprintf(p, sizeof(cache) - (p - cache) - 1,
"{\"peer\":\"%s\",\"time\":\"%s\","
"\"ua\":\"%s\"}",
(*pp)->ip, date, (*pp)->user_agent);
pp = &((*pp)->list);
}
p += sprintf(p, "]}");
cache_len = p - cache;
lwsl_err("cache_len %d\n", cache_len);
cache[cache_len] = '\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_SERVER_WRITEABLE:
m = lws_write(wsi, (unsigned char *)cache, 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_err("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;
}

View file

@ -68,6 +68,7 @@ enum demo_protocols {
PROTOCOL_DUMB_INCREMENT, PROTOCOL_DUMB_INCREMENT,
PROTOCOL_LWS_MIRROR, PROTOCOL_LWS_MIRROR,
PROTOCOL_LWS_ECHOGEN, PROTOCOL_LWS_ECHOGEN,
PROTOCOL_LWS_STATUS,
/* always last */ /* always last */
DEMO_PROTOCOL_COUNT DEMO_PROTOCOL_COUNT
@ -102,6 +103,12 @@ static struct lws_protocols protocols[] = {
sizeof(struct per_session_data__echogen), sizeof(struct per_session_data__echogen),
128, 128,
}, },
{
"lws-status",
callback_lws_status,
sizeof(struct per_session_data__lws_status),
128,
},
{ NULL, NULL, 0, 0 } /* terminator */ { NULL, NULL, 0, 0 } /* terminator */
}; };

View file

@ -94,6 +94,16 @@ struct per_session_data__echogen {
int wr; 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 extern int
callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
void *in, size_t len); void *in, size_t len);
@ -106,6 +116,10 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
extern int extern int
callback_lws_echogen(struct lws *wsi, enum lws_callback_reasons reason, callback_lws_echogen(struct lws *wsi, enum lws_callback_reasons reason,
void *user, void *in, size_t len); 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);
extern void extern void
dump_handshake_info(struct lws *wsi); dump_handshake_info(struct lws *wsi);

View file

@ -4,7 +4,7 @@
<meta charset=utf-8 http-equiv="Content-Language" content="en"/> <meta charset=utf-8 http-equiv="Content-Language" content="en"/>
<title>Minimal Websocket test app</title> <title>Minimal Websocket test app</title>
<style type="text/css"> <style type="text/css">
div.title { font-size:18pt; font: Arial; font-weight:normal; text-align:center; color:#000000; } span.title { font-size:18pt; 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;} .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; .group2 { vertical-align:middle;
text-align:center; text-align:center;
@ -20,6 +20,20 @@
-moz-border-radius:10px; -moz-border-radius:10px;
border-radius:10px; border-radius:10px;
color:#404000; } 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; }
.content { vertical-align:top; text-align:center; background:#fffff0; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px; } .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; } .canvas { vertical-align:top; text-align:center; background:#efefd0; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px; }
.tabs { .tabs {
@ -96,17 +110,12 @@ have the test server send a big picture by http.
<div id="dumb" class="group2"> <div id="dumb" class="group2">
<table> <table>
<tr> <tr>
<td width=200px id=wsdi_statustd align=center class="explain"> <td id=wsdi_statustd align=center class="wsstatus">
<div id=wsdi_status>Not initialized</div> <span id=wsdi_status>Websocket connection not initialized</span></td>
</td> <td><span class="title">dumb increment-protocol</span></td>
<td align=center><div id=number> </div></td>
<td align=center>
<input type=button id=offset value="Reset counter" onclick="reset();" >
</td>
</tr> </tr>
<tr> <tr>
<td class="explain" colspan=3> <td class="explain" colspan=2>
The incrementing number is coming from the server at 20Hz and is individual for The incrementing number is coming from the server at 20Hz and is individual for
each connection to the server... try opening a second browser window. each connection to the server... try opening a second browser window.
<br/><br/> <br/><br/>
@ -114,6 +123,12 @@ The button sends a message over the websocket link to ask the server
to zero just this connection's number. to zero just this connection's number.
</td> </td>
</tr> </tr>
<tr>
<td align=center><div id=number style="font-size:120%;"> </div></td>
<td align=center>
<input type=button id=offset value="Reset counter" onclick="reset();" >
</td>
</tr>
</table> </table>
</div> </div>
</div> </div>
@ -127,8 +142,15 @@ to zero just this connection's number.
<div id="mirror" class="group2"> <div id="mirror" class="group2">
<table> <table>
<tr> <tr>
<td colspan="3"> <td colspan=1 id=wslm_statustd align=center class="wsstatus">
<div class="title">libwebsockets "lws-mirror-protocol"</div> <span id=wslm_status>Websocket connection not initialized</span>
</td>
<td>
<span class="title">lws-mirror-protocol</span>
</td>
</tr>
<tr>
<td colspan=2>
<div class="explain"> <div class="explain">
Use the mouse to draw on the canvas below -- all other browser windows open Use the mouse to draw on the canvas below -- all other browser windows open
on this page see your drawing in realtime and you can see any of theirs as on this page see your drawing in realtime and you can see any of theirs as
@ -144,20 +166,16 @@ run.
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Drawing color: <td colspan=2>Drawing color:
<select id="color" onchange="update_color();"> <select id="color" onchange="update_color();">
<option value=#000000>Black</option> <option value=#000000>Black</option>
<option value=#0000ff>Blue</option> <option value=#0000ff>Blue</option>
<option value=#20ff20>Green</option> <option value=#20ff20>Green</option>
<option value=#802020>Dark Red</option> <option value=#802020>Dark Red</option>
</select> </select>
</td>
<td colspan=2 id=wslm_statustd align=center class="explain">
<div id=wslm_status>Not initialized</div>
</td>
</tr> </tr>
<tr> <tr>
<td colspan=3 width=500 height=320> <td colspan=2 width=500 height=320>
<div id="wslm_drawing" style="background:white"></div> <div id="wslm_drawing" style="background:white"></div>
</td> </td>
</tr> </tr>
@ -174,26 +192,61 @@ run.
<div id="ot" class="group2"> <div id="ot" class="group2">
<table> <table>
<tr> <tr>
<td colspan=3> <td>
<div class="title">libwebsockets "open and close testing"</div>
</td></tr> </td></tr>
<tr> <tr><td id=ot_statustd align=center class="wsstatus">
<td align=center><input type=button id=ot_open_btn value="Open" onclick="ot_open();" ></td> <span id=ot_status>Websocket connection not initialized</span>
<td align=center><input type=button id=ot_close_btn disabled value="Close" onclick="ot_close();" ></td>
<td align=center><input type=button id=ot_req_close_btn disabled value="Request Server Close" onclick="ot_req_close();" ></td>
</tr>
<tr><td id=ot_statustd align=center class="explain">
<div id=ot_status>Not initialized</div>
</td> </td>
<td class="explain" colspan=2> <td colspan=2><span class="title">Open and close testing</span></td>
</tr>
<tr>
<td class="explain" colspan=3 style="padding:3">
To help with open and close testing, you can open and close a connection by hand using To help with open and close testing, you can open and close a connection by hand using
the buttons.<br> the buttons.<br>
"<b>Close</b>" closes the connection from the browser with code 3000 "<b>Close</b>" closes the connection from the browser with code 3000
and reason 'Bye!".<br> and reason 'Bye!".<br>
"<b>Request Server Close</b>" sends a message asking the server to "<b>Request Server Close</b>" sends a message asking the server to
initiate the close, which it does with code 1001 and reason "Seeya". initiate the close, which it does with code 1001 and reason "Seeya".
</td></tr></table> </td></tr>
<tr>
<td align=center><input type=button id=ot_open_btn value="Open" onclick="ot_open();" ></td>
<td align=center><input type=button id=ot_close_btn disabled value="Close" onclick="ot_close();" ></td>
<td align=center><input type=button id=ot_req_close_btn disabled value="Request Server Close" onclick="ot_req_close();" ></td>
</tr>
</table>
</div>
</div>
</div>
<div class="tab">
<input type="radio" id="tab-4" name="tab-group-1">
<label for="tab-4">Server info</label>
<div class="content">
<div id="ot" class="group2">
<table>
<tr>
<td id=s_statustd align=center class="wsstatus">
<div id=s_status>Websocket connection not initialized</div>
</td>
<td colspan=1>
<span class="title">Server Info</span>
</td>
</tr><tr>
<td class="explain" colspan=2>
This information is sent by the server over a ws[s] link and updated live
whenever the information changes server-side.
</td></tr>
<tr>
<td align=center colspan=2><div id=servinfo></</div></td>
</tr>
<tr>
<td align=center colspan=2><div id=conninfo style="border : solid 2px #e0d040; padding : 4px; width : 500px; height : 350px; overflow : auto; "></</div></td>
</tr>
</table>
</div> </div>
</div> </div>
</div> </div>
@ -208,6 +261,19 @@ Join the mailing list: <a href="https://libwebsockets.org/mailman/listinfo/libwe
<script> <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;
}
/* BrowserDetect came from http://www.quirksmode.org/js/detect.html */ /* BrowserDetect came from http://www.quirksmode.org/js/detect.html */
var BrowserDetect = { var BrowserDetect = {
@ -378,7 +444,9 @@ document.getElementById("number").textContent = get_appropriate_ws_url();
try { try {
socket_di.onopen = function() { socket_di.onopen = function() {
document.getElementById("wsdi_statustd").style.backgroundColor = "#40ff40"; document.getElementById("wsdi_statustd").style.backgroundColor = "#40ff40";
document.getElementById("wsdi_status").innerHTML = " <b>websocket connection opened</b><br>" + socket_di.extensions; document.getElementById("wsdi_status").innerHTML =
" <b>websocket connection opened</b><br>" +
san(socket_di.extensions);
} }
socket_di.onmessage =function got_packet(msg) { socket_di.onmessage =function got_packet(msg) {
@ -393,6 +461,55 @@ document.getElementById("number").textContent = get_appropriate_ws_url();
alert('<p>Error' + exception); alert('<p>Error' + exception);
} }
var socket_status, jso, s;
if (typeof MozWebSocket != "undefined") {
socket_status = new MozWebSocket(get_appropriate_ws_url(),
"lws-status");
} else {
socket_status = new WebSocket(get_appropriate_ws_url(),
"lws-status");
}
try {
socket_status.onopen = function() {
document.getElementById("s_statustd").style.backgroundColor = "#40ff40";
document.getElementById("s_status").innerHTML =
" <b>websocket connection opened</b><br>" +
san(socket_di.extensions);
}
socket_status.onmessage =function got_packet(msg) {
jso = JSON.parse(msg.data);
document.getElementById("servinfo").innerHTML =
"<table><tr><td class=l>Build info</td><td>"+
san(jso.version) + "</td></tr>" +
"<tr><td class=l>Server info</td><td>" +
san(jso.hostname) + "</td></tr>" +
"</table>";
s="<table>";
var n;
for (n = 0; n < jso.conns.length; n++)
s = s + "<tr><td class=l>client " + (n + 1) +
"</td><td><b>" + san(jso.conns[n].peer) +
"</b><br>" + san(jso.conns[n].time) +
"<br>" + san(jso.conns[n].ua) +
"</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);
}
function reset() { function reset() {
socket_di.send("reset\n"); socket_di.send("reset\n");
} }
@ -410,7 +527,7 @@ function ot_open() {
try { try {
socket_ot.onopen = function() { socket_ot.onopen = function() {
document.getElementById("ot_statustd").style.backgroundColor = "#40ff40"; document.getElementById("ot_statustd").style.backgroundColor = "#40ff40";
document.getElementById("ot_status").innerHTML = " <b>websocket connection opened</b><br>" + socket_di.extensions; document.getElementById("ot_status").innerHTML = " <b>websocket connection opened</b><br>" + san(socket_di.extensions);
document.getElementById("ot_open_btn").disabled = true; document.getElementById("ot_open_btn").disabled = true;
document.getElementById("ot_close_btn").disabled = false; document.getElementById("ot_close_btn").disabled = false;
document.getElementById("ot_req_close_btn").disabled = false; document.getElementById("ot_req_close_btn").disabled = false;
@ -460,7 +577,9 @@ function ot_req_close() {
try { try {
socket_lm.onopen = function() { socket_lm.onopen = function() {
document.getElementById("wslm_statustd").style.backgroundColor = "#40ff40"; document.getElementById("wslm_statustd").style.backgroundColor = "#40ff40";
document.getElementById("wslm_status").innerHTML = " <b>websocket connection opened</b><br>" + socket_di.extensions; document.getElementById("wslm_status").innerHTML =
" <b>websocket connection opened</b><br>" +
san(socket_di.extensions);
} }
socket_lm.onmessage =function got_packet(msg) { socket_lm.onmessage =function got_packet(msg) {