| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- /*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
- #include "private-lib-core.h"
- #if defined(LWS_WITH_SERVER_STATUS)
- void
- lws_sum_stats(const struct lws_context *ctx, struct lws_conn_stats *cs)
- {
- const struct lws_vhost *vh = ctx->vhost_list;
- while (vh) {
- cs->rx += vh->conn_stats.rx;
- cs->tx += vh->conn_stats.tx;
- cs->h1_conn += vh->conn_stats.h1_conn;
- cs->h1_trans += vh->conn_stats.h1_trans;
- cs->h2_trans += vh->conn_stats.h2_trans;
- cs->ws_upg += vh->conn_stats.ws_upg;
- cs->h2_upg += vh->conn_stats.h2_upg;
- cs->h2_alpn += vh->conn_stats.h2_alpn;
- cs->h2_subs += vh->conn_stats.h2_subs;
- cs->rejected += vh->conn_stats.rejected;
- vh = vh->vhost_next;
- }
- }
- int
- lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len)
- {
- #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
- static const char * const prots[] = {
- "http://",
- "https://",
- "file://",
- "cgi://",
- ">http://",
- ">https://",
- "callback://"
- };
- #endif
- char *orig = buf, *end = buf + len - 1, first;
- int n;
- if (len < 100)
- return 0;
- buf += lws_snprintf(buf, end - buf,
- "{\n \"name\":\"%s\",\n"
- " \"port\":\"%d\",\n"
- " \"use_ssl\":\"%d\",\n"
- " \"sts\":\"%d\",\n"
- " \"rx\":\"%llu\",\n"
- " \"tx\":\"%llu\",\n"
- " \"h1_conn\":\"%lu\",\n"
- " \"h1_trans\":\"%lu\",\n"
- " \"h2_trans\":\"%lu\",\n"
- " \"ws_upg\":\"%lu\",\n"
- " \"rejected\":\"%lu\",\n"
- " \"h2_upg\":\"%lu\",\n"
- " \"h2_alpn\":\"%lu\",\n"
- " \"h2_subs\":\"%lu\""
- ,
- vh->name, vh->listen_port,
- #if defined(LWS_WITH_TLS)
- vh->tls.use_ssl & LCCSCF_USE_SSL,
- #else
- 0,
- #endif
- !!(vh->options & LWS_SERVER_OPTION_STS),
- vh->conn_stats.rx, vh->conn_stats.tx,
- vh->conn_stats.h1_conn,
- vh->conn_stats.h1_trans,
- vh->conn_stats.h2_trans,
- vh->conn_stats.ws_upg,
- vh->conn_stats.rejected,
- vh->conn_stats.h2_upg,
- vh->conn_stats.h2_alpn,
- vh->conn_stats.h2_subs
- );
- #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
- if (vh->http.mount_list) {
- const struct lws_http_mount *m = vh->http.mount_list;
- buf += lws_snprintf(buf, end - buf, ",\n \"mounts\":[");
- first = 1;
- while (m) {
- if (!first)
- buf += lws_snprintf(buf, end - buf, ",");
- buf += lws_snprintf(buf, end - buf,
- "\n {\n \"mountpoint\":\"%s\",\n"
- " \"origin\":\"%s%s\",\n"
- " \"cache_max_age\":\"%d\",\n"
- " \"cache_reuse\":\"%d\",\n"
- " \"cache_revalidate\":\"%d\",\n"
- " \"cache_intermediaries\":\"%d\"\n"
- ,
- m->mountpoint,
- prots[m->origin_protocol],
- m->origin,
- m->cache_max_age,
- m->cache_reusable,
- m->cache_revalidate,
- m->cache_intermediaries);
- if (m->def)
- buf += lws_snprintf(buf, end - buf,
- ",\n \"default\":\"%s\"",
- m->def);
- buf += lws_snprintf(buf, end - buf, "\n }");
- first = 0;
- m = m->mount_next;
- }
- buf += lws_snprintf(buf, end - buf, "\n ]");
- }
- #endif
- if (vh->protocols) {
- n = 0;
- first = 1;
- buf += lws_snprintf(buf, end - buf, ",\n \"ws-protocols\":[");
- while (n < vh->count_protocols) {
- if (!first)
- buf += lws_snprintf(buf, end - buf, ",");
- buf += lws_snprintf(buf, end - buf,
- "\n {\n \"%s\":{\n"
- " \"status\":\"ok\"\n }\n }"
- ,
- vh->protocols[n].name);
- first = 0;
- n++;
- }
- buf += lws_snprintf(buf, end - buf, "\n ]");
- }
- buf += lws_snprintf(buf, end - buf, "\n}");
- return buf - orig;
- }
- int
- lws_json_dump_context(const struct lws_context *context, char *buf, int len,
- int hide_vhosts)
- {
- char *orig = buf, *end = buf + len - 1, first = 1;
- const struct lws_vhost *vh = context->vhost_list;
- const struct lws_context_per_thread *pt;
- int n, listening = 0, cgi_count = 0, fd;
- struct lws_conn_stats cs;
- double d = 0;
- #ifdef LWS_WITH_CGI
- struct lws_cgi * const *pcgi;
- #endif
- //#ifdef LWS_WITH_LIBUV &&
- // uv_uptime(&d);
- //#endif
- buf += lws_snprintf(buf, end - buf, "{ "
- "\"version\":\"%s\",\n"
- "\"uptime\":\"%ld\",\n",
- lws_get_library_version(),
- (long)d);
- #ifdef LWS_HAVE_GETLOADAVG
- #if defined(__sun)
- #include <sys/loadavg.h>
- #endif
- {
- double d[3];
- int m;
- m = getloadavg(d, 3);
- for (n = 0; n < m; n++) {
- buf += lws_snprintf(buf, end - buf,
- "\"l%d\":\"%.2f\",\n",
- n + 1, d[n]);
- }
- }
- #endif
- fd = lws_open("/proc/self/statm", LWS_O_RDONLY);
- if (fd >= 0) {
- char contents[96], pure[96];
- n = read(fd, contents, sizeof(contents) - 1);
- if (n > 0) {
- contents[n] = '\0';
- if (contents[n - 1] == '\n')
- contents[--n] = '\0';
- lws_json_purify(pure, contents, sizeof(pure), NULL);
- buf += lws_snprintf(buf, end - buf,
- "\"statm\": \"%s\",\n", pure);
- }
- close(fd);
- }
- buf += lws_snprintf(buf, end - buf, "\"heap\":%lld,\n\"contexts\":[\n",
- (long long)lws_get_allocated_heap());
- buf += lws_snprintf(buf, end - buf, "{ "
- "\"context_uptime\":\"%llu\",\n"
- "\"cgi_spawned\":\"%d\",\n"
- "\"pt_fd_max\":\"%d\",\n"
- "\"ah_pool_max\":\"%d\",\n"
- "\"deprecated\":\"%d\",\n"
- "\"wsi_alive\":\"%d\",\n",
- (unsigned long long)(lws_now_usecs() - context->time_up) /
- LWS_US_PER_SEC,
- context->count_cgi_spawned,
- context->fd_limit_per_thread,
- context->max_http_header_pool,
- context->deprecated,
- context->count_wsi_allocated);
- buf += lws_snprintf(buf, end - buf, "\"pt\":[\n ");
- for (n = 0; n < context->count_threads; n++) {
- pt = &context->pt[n];
- if (n)
- buf += lws_snprintf(buf, end - buf, ",");
- buf += lws_snprintf(buf, end - buf,
- "\n {\n"
- " \"fds_count\":\"%d\",\n"
- " \"ah_pool_inuse\":\"%d\",\n"
- " \"ah_wait_list\":\"%d\"\n"
- " }",
- pt->fds_count,
- pt->http.ah_count_in_use,
- pt->http.ah_wait_list_length);
- }
- buf += lws_snprintf(buf, end - buf, "]");
- buf += lws_snprintf(buf, end - buf, ", \"vhosts\":[\n ");
- first = 1;
- vh = context->vhost_list;
- listening = 0;
- cs = context->conn_stats;
- lws_sum_stats(context, &cs);
- while (vh) {
- if (!hide_vhosts) {
- if (!first)
- if(buf != end)
- *buf++ = ',';
- buf += lws_json_dump_vhost(vh, buf, end - buf);
- first = 0;
- }
- if (vh->lserv_wsi)
- listening++;
- vh = vh->vhost_next;
- }
- buf += lws_snprintf(buf, end - buf,
- "],\n\"listen_wsi\":\"%d\",\n"
- " \"rx\":\"%llu\",\n"
- " \"tx\":\"%llu\",\n"
- " \"h1_conn\":\"%lu\",\n"
- " \"h1_trans\":\"%lu\",\n"
- " \"h2_trans\":\"%lu\",\n"
- " \"ws_upg\":\"%lu\",\n"
- " \"rejected\":\"%lu\",\n"
- " \"h2_alpn\":\"%lu\",\n"
- " \"h2_subs\":\"%lu\",\n"
- " \"h2_upg\":\"%lu\"",
- listening, cs.rx, cs.tx,
- cs.h1_conn,
- cs.h1_trans,
- cs.h2_trans,
- cs.ws_upg,
- cs.rejected,
- cs.h2_alpn,
- cs.h2_subs,
- cs.h2_upg);
- #ifdef LWS_WITH_CGI
- for (n = 0; n < context->count_threads; n++) {
- pt = &context->pt[n];
- pcgi = &pt->http.cgi_list;
- while (*pcgi) {
- pcgi = &(*pcgi)->cgi_list;
- cgi_count++;
- }
- }
- #endif
- buf += lws_snprintf(buf, end - buf, ",\n \"cgi_alive\":\"%d\"\n ",
- cgi_count);
- buf += lws_snprintf(buf, end - buf, "}");
- buf += lws_snprintf(buf, end - buf, "]}\n ");
- return buf - orig;
- }
- #endif
|