2 * libwebsockets-test-server - libwebsockets test implementation
4 * Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
6 * This file is made available under the Creative Commons CC0 1.0
7 * Universal Public Domain Dedication.
9 * The person who associated a work with this deed has dedicated
10 * the work to the public domain by waiving all of his or her rights
11 * to the work worldwide under copyright law, including all related
12 * and neighboring rights, to the extent allowed by law. You can copy,
13 * modify, distribute and perform the work, even for commercial purposes,
14 * all without asking permission.
16 * The test apps are intended to be adapted for use in your code, which
17 * may be proprietary. So unlike the library itself, they are licensed
20 #include "test-server.h"
23 static unsigned char server_info[1024];
24 static int server_info_len;
26 static char cache[16384];
28 static struct per_session_data__lws_status *list;
33 update_status(struct lws *wsi, struct per_session_data__lws_status *pss)
35 struct per_session_data__lws_status **pp = &list;
37 char *p = cache + LWS_PRE, *start = p;
45 p += snprintf(p, 512, " { %s, \"wsi\":\"%d\", \"conns\":[",
46 server_info, live_wsi);
50 t = (*pp)->tv_established.tv_sec;
56 if (!localtime_r(&t, &tm))
58 strcpy(date, "unknown");
61 strftime(date, sizeof(date), "%Y %H:%M %Z", ptm);
63 strftime(date, sizeof(date), "%F %H:%M %Z", ptm);
65 if ((p - start) > (sizeof(cache) - 512))
70 p += snprintf(p, sizeof(cache) - (p - start) - 1,
71 "{\"peer\":\"%s\",\"time\":\"%s\","
73 (*pp)->ip, date, (*pp)->user_agent);
77 p += sprintf(p, "]}");
78 cache_len = p - start;
79 lwsl_err("cache_len %d\n", cache_len);
82 /* since we changed the list, increment the 'version' */
85 lws_callback_on_writable_all_protocol(lws_get_context(wsi),
86 lws_get_protocol(wsi));
90 /* lws-status protocol */
93 callback_lws_status(struct lws *wsi, enum lws_callback_reasons reason,
94 void *user, void *in, size_t len)
96 struct per_session_data__lws_status *pss =
97 (struct per_session_data__lws_status *)user,
99 char name[128], rip[128];
104 case LWS_CALLBACK_PROTOCOL_INIT:
106 * Prepare the static server info
108 server_info_len = sprintf((char *)server_info,
109 "\"version\":\"%s\","
110 " \"hostname\":\"%s\"",
111 lws_get_library_version(),
112 lws_canonical_hostname(
113 lws_get_context(wsi)));
116 case LWS_CALLBACK_ESTABLISHED:
118 * we keep a linked list of live pss, so we can walk it
124 lws_get_peer_addresses(wsi, lws_get_socket_fd(wsi), name,
125 sizeof(name), rip, sizeof(rip));
126 sprintf(pss->ip, "%s (%s)", name, rip);
127 gettimeofday(&pss->tv_established, NULL);
128 strcpy(pss->user_agent, "unknown");
129 lws_hdr_copy(wsi, pss->user_agent, sizeof(pss->user_agent),
130 WSI_TOKEN_HTTP_USER_AGENT);
131 update_status(wsi, pss);
134 case LWS_CALLBACK_SERVER_WRITEABLE:
135 m = lws_write(wsi, (unsigned char *)cache + LWS_PRE, cache_len,
137 if (m < server_info_len) {
138 lwsl_err("ERROR %d writing to di socket\n", m);
143 case LWS_CALLBACK_CLOSED:
145 * remove ourselves from live pss list
147 lwsl_err("CLOSING pss %p ********\n", pss);
160 update_status(wsi, pss);