2 * libwebsockets-test-server - libwebsockets test implementation
4 * Copyright (C) 2010 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,
28 #include "../lib/libwebsockets.h"
30 #define LOCAL_RESOURCE_PATH "/usr/share/libwebsockets-test-server"
31 static int port = 7681;
32 static int ws_protocol = 76;
33 static int use_ssl = 0;
35 struct per_session_data {
40 * libwebsocket_callback() - User server actions
41 * @wsi: Opaque websocket instance pointer
42 * @reason: The reason for the call
43 * @user: Pointer to per-session user data allocated by library
44 * @in: Pointer used for some callback reasons
45 * @len: Length set for some callback reasons
47 * This callback is the way the user controls what is served. All the
48 * protocol detail is hidden and handled by the library.
50 * For each connection / session there is user data allocated that is
51 * pointed to by "user". You set the size of this user data area when
52 * the library is initialized with libwebsocket_create_server.
54 * You get an opportunity to initialize user data when called back with
55 * LWS_CALLBACK_ESTABLISHED reason.
57 * LWS_CALLBACK_ESTABLISHED: after successful websocket handshake
58 * LWS_CALLBACK_CLOSED: when the websocket session ends
59 * LWS_CALLBACK_SEND: opportunity to send to client (you would use
60 * libwebsocket_write() taking care about the
61 * special buffer requirements
62 * LWS_CALLBACK_RECEIVE: data has appeared for the server, it can be
63 * found at *in and is len bytes long
64 * LWS_CALLBACK_HTTP: an http request has come from a client that is not
65 * asking to upgrade the connection to a websocket
66 * one. This is a chance to serve http content,
67 * for example, to send a script to the client
68 * which will then open the websockets connection.
69 * libwebsocket_get_uri() lets you find out the
70 * URI path requested and
71 * libwebsockets_serve_http_file() makes it very
72 * simple to send back a file to the client.
75 static int websocket_callback(struct libwebsocket * wsi,
76 enum libwebsocket_callback_reasons reason, void * user,
80 char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 +
81 LWS_SEND_BUFFER_POST_PADDING];
82 char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
84 struct per_session_data * pss = user;
88 * Websockets session handshake completed and is established
90 case LWS_CALLBACK_ESTABLISHED:
91 fprintf(stderr, "Websocket connection established\n");
96 * Websockets session is closed
98 case LWS_CALLBACK_CLOSED:
99 fprintf(stderr, "Websocket connection closed\n");
103 * Opportunity for us to send something on the connection
105 case LWS_CALLBACK_SEND:
106 n = sprintf(p, "%d", pss->number++);
107 n = libwebsocket_write(wsi, (unsigned char *)p, n,
110 fprintf(stderr, "ERROR writing to socket");
115 * Something has arrived for us on the connection, it's len bytes long
116 * and is available at *in
118 case LWS_CALLBACK_RECEIVE:
119 fprintf(stderr, "Received %d bytes payload\n", (int)len);
123 * The client has asked us for something in normal HTTP mode,
124 * not websockets mode. Normally it means we want to send
125 * our script / html to the client, and when that script runs
126 * it will start up separate websocket connections.
128 * Interpret the URI string to figure out what is needed to send
131 case LWS_CALLBACK_HTTP:
133 uri = libwebsocket_get_uri(wsi);
135 fprintf(stderr, "serving HTTP URI %s\n", uri);
137 if (uri && strcmp(uri, "/favicon.ico") == 0) {
138 if (libwebsockets_serve_http_file(wsi,
139 LOCAL_RESOURCE_PATH"/favicon.ico", "image/x-icon"))
140 fprintf(stderr, "Failed to send favicon\n");
144 /* send the script... when it runs it'll start websockets */
146 if (libwebsockets_serve_http_file(wsi,
147 LOCAL_RESOURCE_PATH"/test.html", "text/html"))
148 fprintf(stderr, "Failed to send HTTP file\n");
156 static struct option options[] = {
157 { "help", no_argument, NULL, 'h' },
158 { "port", required_argument, NULL, 'p' },
159 { "protocol", required_argument, NULL, 'r' },
160 { "ssl", no_argument, NULL, 's' },
164 int main(int argc, char **argv)
167 const char * cert_path =
168 LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem";
169 const char * key_path =
170 LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem";
172 fprintf(stderr, "libwebsockets test server\n"
173 "(C) Copyright 2010 Andy Green <andy@warmcat.com> "
174 "licensed under LGPL2.1\n");
177 n = getopt_long(argc, argv, "hp:r:", options, NULL);
188 ws_protocol = atoi(optarg);
191 fprintf(stderr, "Usage: test-server "
192 "[--port=<p>] [--protocol=<v>]\n");
198 cert_path = key_path = NULL;
200 if (libwebsocket_create_server(port, websocket_callback, ws_protocol,
201 sizeof(struct per_session_data),
202 cert_path, key_path, -1, -1) < 0) {
203 fprintf(stderr, "libwebsocket init failed\n");
207 /* just sit there until killed */