fix-rx-action-76.patch
[profile/ivi/libwebsockets.git] / test-server / test-server.c
1 /*
2  * libwebsockets-test-server - libwebsockets test implementation
3  * 
4  * Copyright (C) 2010 Andy Green <andy@warmcat.com>
5  *
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.
10  *
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.
15  *
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,
19  *  MA  02110-1301  USA
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <getopt.h>
26 #include <string.h>
27
28 #include "../lib/libwebsockets.h"
29
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;
34
35 struct per_session_data {
36         int number;
37 };
38
39  /**
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
46  * 
47  *      This callback is the way the user controls what is served.  All the
48  *      protocol detail is hidden and handled by the library.
49  * 
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.
53  * 
54  *      You get an opportunity to initialize user data when called back with
55  *      LWS_CALLBACK_ESTABLISHED reason.
56  * 
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.
73  */
74
75 static int websocket_callback(struct libwebsocket * wsi,
76                 enum libwebsocket_callback_reasons reason, void * user,
77                                                            void *in, size_t len)
78 {
79         int n;
80         char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 +
81                                                   LWS_SEND_BUFFER_POST_PADDING];
82         char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
83         const char *uri;
84         struct per_session_data * pss = user;
85         
86         switch (reason) {
87         /*
88          * Websockets session handshake completed and is established
89          */
90         case LWS_CALLBACK_ESTABLISHED:
91                 fprintf(stderr, "Websocket connection established\n");
92                 pss->number = 0;
93                 break;
94
95         /*
96          * Websockets session is closed
97          */
98         case LWS_CALLBACK_CLOSED:
99                 fprintf(stderr, "Websocket connection closed\n");
100                 break;
101
102         /*
103          * Opportunity for us to send something on the connection
104          */
105         case LWS_CALLBACK_SEND: 
106                 n = sprintf(p, "%d", pss->number++);
107                 n = libwebsocket_write(wsi, (unsigned char *)p, n,
108                                                                 LWS_WRITE_TEXT);
109                 if (n < 0) {
110                         fprintf(stderr, "ERROR writing to socket");
111                         exit(1);
112                 }
113                 break;
114         /*
115          * Something has arrived for us on the connection, it's len bytes long
116          * and is available at *in
117          */
118         case LWS_CALLBACK_RECEIVE:
119                 fprintf(stderr, "Received %d bytes payload\n", (int)len);
120                 break;
121
122         /*
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.
127          * 
128          * Interpret the URI string to figure out what is needed to send
129          */
130                  
131         case LWS_CALLBACK_HTTP:
132
133                 uri = libwebsocket_get_uri(wsi);
134
135                 fprintf(stderr, "serving HTTP URI %s\n", uri);
136                 
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");
141                         break;
142                 }
143                 
144                 /* send the script... when it runs it'll start websockets */
145
146                 if (libwebsockets_serve_http_file(wsi,
147                                   LOCAL_RESOURCE_PATH"/test.html", "text/html"))
148                         fprintf(stderr, "Failed to send HTTP file\n");
149
150                 break;
151         }
152
153         return 0;
154 }
155
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' },
161         { NULL, 0, 0, 0 }
162 };
163
164 int main(int argc, char **argv)
165 {
166         int n = 0;
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";
171
172         fprintf(stderr, "libwebsockets test server\n"
173                         "(C) Copyright 2010 Andy Green <andy@warmcat.com> "
174                                                     "licensed under LGPL2.1\n");
175         
176         while (n >= 0) {
177                 n = getopt_long(argc, argv, "hp:r:", options, NULL);
178                 if (n < 0)
179                         continue;
180                 switch (n) {
181                 case 's':
182                         use_ssl = 1;
183                         break;
184                 case 'p':
185                         port = atoi(optarg);
186                         break;
187                 case 'r':
188                         ws_protocol = atoi(optarg);
189                         break;
190                 case 'h':
191                         fprintf(stderr, "Usage: test-server "
192                                              "[--port=<p>] [--protocol=<v>]\n");
193                         exit(1);
194                 }
195         }
196
197         if (!use_ssl)
198                 cert_path = key_path = NULL;
199         
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");
204                 return -1;
205         }
206         
207         /* just sit there until killed */
208                 
209         while (1)
210                 sleep(10);
211
212         return 0;
213 }