1

I got the code of libwebsockets from https://github.com/warmcat/libwebsockets.git.

And I found that there is a declaration of the function lws_json_dump_vhost in the lws-context-vhost.h file, but I did not found the implementation of lws_json_dump_vhost.

I use the command line "grep -rn -s "lws_json_dump_vhost"" to search under the root directory of libwebsockets, I only found its declaration in the lws-context-vhost.h file.

I compiled libwebsockets.so with cmake and used nm -D libwebsockets.so to view the symbols, but I did not find lws_json_dump_vhost in the symbols.

So where is the implementation of lws_json_dump_vhost in the libwebsockets library and does libwebsockets support the lws_json_dump_vhost function?

leon.zhou
  • 11
  • 1

2 Answers2

0

I downloaded the version v2.2-stable of libwebsockets and I find the implementation of lws_json_dump_vhost.

I downloaded the master branch code through git clone before, then I use "git checkout -b remote v2.2-stable".But I think it didn't work.

leon.zhou
  • 11
  • 1
0

It appears to have been removed in version 4.2, last appears in the current git on tag remote/origin/v4.1-stable:

core-net/server.c line 52:

lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len)

It looks like in 4.3.99 (my current version, and main as of date) that the conn_stat struct has been removed so that information is no longer available, also there were many casts needed to get it to compile without disabling narrowing conversion errors, but here it is resuited for use:

Add this to service.c when compile libwebsockets:

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] = '\0';
            if (contents[n - 1] == '\n')
                contents[--n] = '\0';
            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);
}

Add this to lws-service.h:

LWS_VISIBLE LWS_EXTERN int
lws_json_dump_context(const struct lws_context *context, char *buf, int len,
                      int hide_vhosts);
Motomotes
  • 4,111
  • 1
  • 25
  • 24