2 * libwebsockets-test-server - libwebsockets test implementation
4 * Copyright (C) 2010-2015 Andy Green <andy@warmcat.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation:
9 * version 2.1 of the License.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 #include "test-server.h"
23 /* lws-mirror_protocol */
25 #define MAX_MESSAGE_QUEUE 512
32 static struct a_message ringbuffer[MAX_MESSAGE_QUEUE];
33 static int ringbuffer_head;
36 callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
37 void *user, void *in, size_t len)
39 struct per_session_data__lws_mirror *pss =
40 (struct per_session_data__lws_mirror *)user;
45 case LWS_CALLBACK_ESTABLISHED:
46 lwsl_info("%s: LWS_CALLBACK_ESTABLISHED\n", __func__);
47 pss->ringbuffer_tail = ringbuffer_head;
51 case LWS_CALLBACK_PROTOCOL_DESTROY:
52 lwsl_notice("%s: mirror protocol cleaning up\n", __func__);
53 for (n = 0; n < sizeof ringbuffer / sizeof ringbuffer[0]; n++)
54 if (ringbuffer[n].payload)
55 free(ringbuffer[n].payload);
58 case LWS_CALLBACK_SERVER_WRITEABLE:
61 while (pss->ringbuffer_tail != ringbuffer_head) {
62 m = ringbuffer[pss->ringbuffer_tail].len;
63 n = lws_write(wsi, (unsigned char *)
64 ringbuffer[pss->ringbuffer_tail].payload +
65 LWS_PRE, m, LWS_WRITE_TEXT);
67 lwsl_err("ERROR %d writing to mirror socket\n", n);
71 lwsl_err("mirror partial write %d vs %d\n", n, m);
73 if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1))
74 pss->ringbuffer_tail = 0;
76 pss->ringbuffer_tail++;
78 if (((ringbuffer_head - pss->ringbuffer_tail) &
79 (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15))
80 lws_rx_flow_allow_all_protocol(lws_get_context(wsi),
81 lws_get_protocol(wsi));
83 if (lws_send_pipe_choked(wsi)) {
84 lws_callback_on_writable(wsi);
90 case LWS_CALLBACK_RECEIVE:
91 if (((ringbuffer_head - pss->ringbuffer_tail) &
92 (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 1)) {
93 lwsl_err("dropping!\n");
97 if (ringbuffer[ringbuffer_head].payload)
98 free(ringbuffer[ringbuffer_head].payload);
100 ringbuffer[ringbuffer_head].payload = malloc(LWS_PRE + len);
101 ringbuffer[ringbuffer_head].len = len;
102 memcpy((char *)ringbuffer[ringbuffer_head].payload +
104 if (ringbuffer_head == (MAX_MESSAGE_QUEUE - 1))
109 if (((ringbuffer_head - pss->ringbuffer_tail) &
110 (MAX_MESSAGE_QUEUE - 1)) != (MAX_MESSAGE_QUEUE - 2))
114 lwsl_debug("LWS_CALLBACK_RECEIVE: throttling %p\n", wsi);
115 lws_rx_flow_control(wsi, 0);
118 lws_callback_on_writable_all_protocol(lws_get_context(wsi),
119 lws_get_protocol(wsi));
123 * this just demonstrates how to use the protocol filter. If you won't
124 * study and reject connections based on header content, you don't need
125 * to handle this callback
128 case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
129 dump_handshake_info(wsi);
130 /* you could return non-zero here and kill the connection */