我从https://github.com/warmcat/libwebsockets.git得到了libwebsockets的代码。
我发现在lws-context-vhost.h文件中有一个函数lws_json_dump_vhost的声明,但是我没有找到lws_json_dump_vhost的实现。
我使用命令行"grep -rn -s "lws_json_dump_vhost"在libwebsockets的根目录下搜索,我只在lws-context-vhost.h文件中找到了它的声明。
我编译了libwebsockets。所以使用cmake和nm -D libwebsockets。但是我没有在符号中找到lws_json_dump_vhost。 那么在libwebsockets库中lws_json_dump_vhost的实现在哪里,libwebsockets是否支持lws_json_dump_vhost函数?我下载了libwebsockets的v2.2-stable版本,我找到了lws_json_dump_vhost的实现。
我之前通过git clone下载了主分支代码,然后我使用了"git checkout -b remote v2.2-stable"但我认为它没有起作用。
它似乎在4.2版本中被删除了,最后出现在当前git的标签remote/origin/v4.1-stable:
core-net/server.c第52行:lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len)
看起来在4.3.99(我的当前版本,和main
截至日期)中,conn_stat结构体已被删除,因此信息不再可用,也有许多强制转换需要在不禁用窄化转换错误的情况下进行编译,但这里它重新适合使用:
在编译libwebsockets时将此添加到service.c中:
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, (size_t) (end - buf),
"{n "name":"%s",n"
" "port":"%d",n"
" "use_ssl":"%d",n"
" "sts":"%d"n"
,
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)
);
#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, (size_t) (end - buf), ",n "mounts":[");
first = 1;
while (m) {
if (!first)
buf += lws_snprintf(buf, (size_t) (end - buf), ",");
buf += lws_snprintf(buf, (size_t) (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, (size_t) (end - buf),
",n "default":"%s"",
m->def);
buf += lws_snprintf(buf, (size_t) (end - buf), "n }");
first = 0;
m = m->mount_next;
}
buf += lws_snprintf(buf, (size_t) (end - buf), "n ]");
}
#endif
if (vh->protocols) {
n = 0;
first = 1;
buf += lws_snprintf(buf, (size_t) (end - buf), ",n "ws-protocols":[");
while (n < vh->count_protocols) {
if (!first)
buf += lws_snprintf(buf, (size_t) (end - buf), ",");
buf += lws_snprintf(buf, (size_t) (end - buf),
"n {n "%s":{n"
" "status":"ok"n }n }"
,
vh->protocols[n].name);
first = 0;
n++;
}
buf += lws_snprintf(buf, (size_t) (end - buf), "n ]");
}
buf += lws_snprintf(buf, (size_t) (end - buf), "n}");
return (int)(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;
double dd;
#ifdef LWS_WITH_CGI
struct lws_cgi * const *pcgi;
#endif
#ifdef LWS_WITH_LIBUV
uv_uptime(&dd);
#endif
buf += lws_snprintf(buf, (size_t) (end - buf), "{ "
""version":"%s",n"
""uptime":"%ld",n",
lws_get_library_version(),
(long)dd);
#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, (size_t) (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 = (int)read(fd, contents, sizeof(contents) - 1);
if (n > 0) {
contents[n] = ' ';
if (contents[n - 1] == 'n')
contents[--n] = ' ';
lws_json_purify(pure, contents, sizeof(pure), NULL);
buf += lws_snprintf(buf, (size_t) (end - buf),
""statm": "%s",n", pure);
}
close(fd);
}
buf += lws_snprintf(buf, (size_t) (end - buf), ""heap":%lld,n"contexts":[n",
(long long)lws_get_allocated_heap());
buf += lws_snprintf(buf, (size_t) (end - buf), "{ "
""context_uptime":"%llu",n"
""cgi_spawned":"%d",n"
""pt_fd_max":"%d",n"
""ah_pool_max":"%d",n"
""deprecated":"%d",n"
""peers":"%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_peers);
buf += lws_snprintf(buf, (size_t) (end - buf), ""pt":[n ");
for (n = 0; n < context->count_threads; n++) {
pt = &context->pt[n];
if (n)
buf += lws_snprintf(buf, (size_t) (end - buf), ",");
buf += lws_snprintf(buf, (size_t) (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, (size_t) (end - buf), "]");
buf += lws_snprintf(buf, (size_t) (end - buf), ", "vhosts":[n ");
first = 1;
vh = context->vhost_list;
listening = (int) vh->listen_wsi.count;
while (vh) {
if (!hide_vhosts) {
if (!first)
if(buf != end)
*buf++ = ',';
buf += lws_json_dump_vhost(vh, buf, (int)(end - buf));
first = 0;
}
vh = vh->vhost_next;
}
buf += lws_snprintf(buf, (size_t) (end - buf),
"],n"listen_wsi":"%d",
listening);
#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, (size_t) (end - buf), "",n "cgi_alive":"%d"n ",
cgi_count);
buf += lws_snprintf(buf, (size_t) (end - buf), "}");
buf += lws_snprintf(buf, (size_t) (end - buf), "]}n ");
return (int)(buf - orig);
}
添加到lws-service.h:
LWS_VISIBLE LWS_EXTERN int
lws_json_dump_context(const struct lws_context *context, char *buf, int len,
int hide_vhosts);