blob: 5700a04b94f34b7f4b575b5478e6a3d600be7b21 [file] [log] [blame]
Andy Greena0da8a82010-11-08 17:12:19 +00001/*
2 * libwebsockets - small server side websockets and web server implementation
Andy Greene77ddd82010-11-13 10:03:47 +00003 *
Andy Greena0da8a82010-11-08 17:12:19 +00004 * 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
Andy Greenab990e42010-10-31 12:42:52 +000022#ifndef __LIBWEBSOCKET_H__
23#define __LIBWEBSOCKET_H__
24
Andy Green4739e5c2011-01-22 12:51:57 +000025#define CONTEXT_PORT_NO_LISTEN 0
Andy Greenff95d7a2010-10-28 22:36:01 +010026
Andy Green775c0dd2010-10-29 14:15:22 +010027enum libwebsocket_callback_reasons {
28 LWS_CALLBACK_ESTABLISHED,
Andy Green90c7cbc2011-01-27 06:26:52 +000029 LWS_CALLBACK_CLIENT_ESTABLISHED,
Andy Green775c0dd2010-10-29 14:15:22 +010030 LWS_CALLBACK_CLOSED,
Andy Green775c0dd2010-10-29 14:15:22 +010031 LWS_CALLBACK_RECEIVE,
Andy Green4739e5c2011-01-22 12:51:57 +000032 LWS_CALLBACK_CLIENT_RECEIVE,
Andy Greena6cbece2011-01-27 20:06:03 +000033 LWS_CALLBACK_CLIENT_RECEIVE_PONG,
Andy Green90c7cbc2011-01-27 06:26:52 +000034 LWS_CALLBACK_CLIENT_WRITEABLE,
Andy Greena2b0ab02010-11-11 12:28:29 +000035 LWS_CALLBACK_HTTP,
Andy Green0ca6a172010-12-19 20:50:01 +000036 LWS_CALLBACK_BROADCAST
Andy Green5fd8a5e2010-10-31 11:57:17 +000037};
38
39enum libwebsocket_write_protocol {
40 LWS_WRITE_TEXT,
41 LWS_WRITE_BINARY,
Andy Green38e57bb2011-01-19 12:20:27 +000042 LWS_WRITE_HTTP,
43
44 /* special 04 opcodes */
45
46 LWS_WRITE_CLOSE,
47 LWS_WRITE_PING,
Andy Green90c7cbc2011-01-27 06:26:52 +000048 LWS_WRITE_PONG,
49
Andy Greenbd96d802011-01-30 08:24:31 +000050 /* flags */
51
52 LWS_WRITE_NO_FIN = 0x40,
53 /*
54 * client packet payload goes out on wire unmunged
55 * only useful for security tests since normal servers cannot
56 * decode the content if used
57 */
58 LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80
Andy Greenff95d7a2010-10-28 22:36:01 +010059};
60
Andy Green775c0dd2010-10-29 14:15:22 +010061struct libwebsocket;
Andy Greenb45993c2010-12-18 15:13:50 +000062struct libwebsocket_context;
Andy Greenff95d7a2010-10-28 22:36:01 +010063
Andy Green8f037e42010-12-19 22:13:26 +000064/* document the generic callback (it's a fake prototype under this) */
65/**
66 * callback() - User server actions
67 * @wsi: Opaque websocket instance pointer
68 * @reason: The reason for the call
69 * @user: Pointer to per-session user data allocated by library
70 * @in: Pointer used for some callback reasons
71 * @len: Length set for some callback reasons
72 *
73 * This callback is the way the user controls what is served. All the
74 * protocol detail is hidden and handled by the library.
Andy Green6964bb52011-01-23 16:50:33 +000075 *
Andy Green8f037e42010-12-19 22:13:26 +000076 * For each connection / session there is user data allocated that is
77 * pointed to by "user". You set the size of this user data area when
78 * the library is initialized with libwebsocket_create_server.
Andy Green6964bb52011-01-23 16:50:33 +000079 *
Andy Green8f037e42010-12-19 22:13:26 +000080 * You get an opportunity to initialize user data when called back with
81 * LWS_CALLBACK_ESTABLISHED reason.
82 *
Andy Green90c7cbc2011-01-27 06:26:52 +000083 * LWS_CALLBACK_ESTABLISHED: after the server completes a handshake with
84 * an incoming client
85 *
86 * LWS_CALLBACK_CLIENT_ESTABLISHED: after your client connection completed
87 * a handshake with the remote server
Andy Green8f037e42010-12-19 22:13:26 +000088 *
89 * LWS_CALLBACK_CLOSED: when the websocket session ends
90 *
91 * LWS_CALLBACK_BROADCAST: signal to send to client (you would use
92 * libwebsocket_write() taking care about the
93 * special buffer requirements
Andy Green90c7cbc2011-01-27 06:26:52 +000094 *
95 * LWS_CALLBACK_RECEIVE: data has appeared for this server endpoint from a
96 * remote client, it can be found at *in and is
97 * len bytes long
98 *
Andy Greena6cbece2011-01-27 20:06:03 +000099 * LWS_CALLBACK_CLIENT_RECEIVE_PONG: if you elected to see PONG packets,
100 * they appear with this callback reason. PONG
101 * packets only exist in 04+ protocol
102 *
Andy Green90c7cbc2011-01-27 06:26:52 +0000103 * LWS_CALLBACK_CLIENT_RECEIVE: data has appeared from the server for the
104 * client connection, it can be found at *in and
105 * is len bytes long
Andy Green8f037e42010-12-19 22:13:26 +0000106 *
Andy Green6964bb52011-01-23 16:50:33 +0000107 * LWS_CALLBACK_HTTP: an http request has come from a client that is not
Andy Green8f037e42010-12-19 22:13:26 +0000108 * asking to upgrade the connection to a websocket
109 * one. This is a chance to serve http content,
110 * for example, to send a script to the client
111 * which will then open the websockets connection.
Andy Green6964bb52011-01-23 16:50:33 +0000112 * @in points to the URI path requested and
Andy Green8f037e42010-12-19 22:13:26 +0000113 * libwebsockets_serve_http_file() makes it very
114 * simple to send back a file to the client.
Andy Green90c7cbc2011-01-27 06:26:52 +0000115 *
116 * LWS_CALLBACK_CLIENT_WRITEABLE: if you call
117 * libwebsocket_callback_on_writable() on a connection, you will
118 * get this callback coming when the connection socket is able to
119 * accept another write packet without blocking. If it already
120 * was able to take another packet without blocking, you'll get
121 * this callback at the next call to the service loop function.
Andy Green8f037e42010-12-19 22:13:26 +0000122 */
Andy Green6964bb52011-01-23 16:50:33 +0000123extern int callback(struct libwebsocket *wsi,
124 enum libwebsocket_callback_reasons reason, void *user,
Andy Green8f037e42010-12-19 22:13:26 +0000125 void *in, size_t len);
126
Andy Green4f3943a2010-11-12 10:44:16 +0000127/**
Andy Green6964bb52011-01-23 16:50:33 +0000128 * struct libwebsocket_protocols - List of protocols and handlers server
129 * supports.
Andy Green4f3943a2010-11-12 10:44:16 +0000130 * @name: Protocol name that must match the one given in the client
Andy Green6964bb52011-01-23 16:50:33 +0000131 * Javascript new WebSocket(url, 'protocol') name
Andy Green4f3943a2010-11-12 10:44:16 +0000132 * @callback: The service callback used for this protocol. It allows the
Andy Green6964bb52011-01-23 16:50:33 +0000133 * service action for an entire protocol to be encapsulated in
134 * the protocol-specific callback
Andy Green4f3943a2010-11-12 10:44:16 +0000135 * @per_session_data_size: Each new connection using this protocol gets
Andy Green6964bb52011-01-23 16:50:33 +0000136 * this much memory allocated on connection establishment and
137 * freed on connection takedown. A pointer to this per-connection
138 * allocation is passed into the callback in the 'user' parameter
Andy Greenb45993c2010-12-18 15:13:50 +0000139 * @owning_server: the server init call fills in this opaque pointer when
Andy Green6964bb52011-01-23 16:50:33 +0000140 * registering this protocol with the server.
Andy Greenb45993c2010-12-18 15:13:50 +0000141 * @broadcast_socket_port: the server init call fills this in with the
Andy Green6964bb52011-01-23 16:50:33 +0000142 * localhost port number used to forward broadcasts for this
143 * protocol
Andy Greenb45993c2010-12-18 15:13:50 +0000144 * @broadcast_socket_user_fd: the server init call fills this in ... the main()
Andy Green6964bb52011-01-23 16:50:33 +0000145 * process context can write to this socket to perform broadcasts
146 * (use the libwebsockets_broadcast() api to do this instead,
147 * it works from any process context)
Andy Greenb45993c2010-12-18 15:13:50 +0000148 * @protocol_index: which protocol we are starting from zero
Andy Greene77ddd82010-11-13 10:03:47 +0000149 *
Andy Green6964bb52011-01-23 16:50:33 +0000150 * This structure represents one protocol supported by the server. An
151 * array of these structures is passed to libwebsocket_create_server()
152 * allows as many protocols as you like to be handled by one server.
Andy Green4f3943a2010-11-12 10:44:16 +0000153 */
154
155struct libwebsocket_protocols {
156 const char *name;
Andy Greene77ddd82010-11-13 10:03:47 +0000157 int (*callback)(struct libwebsocket *wsi,
158 enum libwebsocket_callback_reasons reason, void *user,
Andy Green4f3943a2010-11-12 10:44:16 +0000159 void *in, size_t len);
160 size_t per_session_data_size;
Andy Greenb45993c2010-12-18 15:13:50 +0000161
162 /*
163 * below are filled in on server init and can be left uninitialized,
164 * no need for user to use them directly either
165 */
Andy Green6964bb52011-01-23 16:50:33 +0000166
Andy Greenb45993c2010-12-18 15:13:50 +0000167 struct libwebsocket_context *owning_server;
168 int broadcast_socket_port;
169 int broadcast_socket_user_fd;
170 int protocol_index;
Andy Green4f3943a2010-11-12 10:44:16 +0000171};
172
Andy Greene92cd172011-01-19 13:11:55 +0000173extern struct libwebsocket_context *
Andy Green4739e5c2011-01-22 12:51:57 +0000174libwebsocket_create_context(int port,
Andy Greenb45993c2010-12-18 15:13:50 +0000175 struct libwebsocket_protocols *protocols,
Andy Greene77ddd82010-11-13 10:03:47 +0000176 const char *ssl_cert_filepath,
177 const char *ssl_private_key_filepath, int gid, int uid);
Andy Greenff95d7a2010-10-28 22:36:01 +0100178
Andy Green6964bb52011-01-23 16:50:33 +0000179extern void
180libwebsocket_context_destroy(struct libwebsocket_context *this);
181
Andy Greene92cd172011-01-19 13:11:55 +0000182extern int
183libwebsockets_fork_service_loop(struct libwebsocket_context *this);
184
185extern int
186libwebsocket_service(struct libwebsocket_context *this, int timeout_ms);
187
Andy Green4ea60062010-10-30 12:15:07 +0100188/*
189 * IMPORTANT NOTICE!
Andy Greene77ddd82010-11-13 10:03:47 +0000190 *
Andy Green5fd8a5e2010-10-31 11:57:17 +0000191 * When sending with websocket protocol (LWS_WRITE_TEXT or LWS_WRITE_BINARY)
192 * the send buffer has to have LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE
Andy Green4ea60062010-10-30 12:15:07 +0100193 * buf, and LWS_SEND_BUFFER_POST_PADDING bytes valid AFTER (buf + len).
Andy Greene77ddd82010-11-13 10:03:47 +0000194 *
Andy Green4ea60062010-10-30 12:15:07 +0100195 * This allows us to add protocol info before and after the data, and send as
196 * one packet on the network without payload copying, for maximum efficiency.
Andy Greene77ddd82010-11-13 10:03:47 +0000197 *
Andy Green4ea60062010-10-30 12:15:07 +0100198 * So for example you need this kind of code to use libwebsocket_write with a
Andy Greene77ddd82010-11-13 10:03:47 +0000199 * 128-byte payload
200 *
Andy Greenab990e42010-10-31 12:42:52 +0000201 * char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING];
Andy Greene77ddd82010-11-13 10:03:47 +0000202 *
Andy Greenab990e42010-10-31 12:42:52 +0000203 * // fill your part of the buffer... for example here it's all zeros
204 * memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128);
Andy Greene77ddd82010-11-13 10:03:47 +0000205 *
Andy Greenab990e42010-10-31 12:42:52 +0000206 * libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128);
Andy Greene77ddd82010-11-13 10:03:47 +0000207 *
Andy Green5fd8a5e2010-10-31 11:57:17 +0000208 * When sending LWS_WRITE_HTTP, there is no protocol addition and you can just
209 * use the whole buffer without taking care of the above.
Andy Green4ea60062010-10-30 12:15:07 +0100210 */
211
Andy Green4739e5c2011-01-22 12:51:57 +0000212/* this is the frame nonce plus two header plus 8 length */
213
214#define LWS_SEND_BUFFER_PRE_PADDING (4 + 10)
Andy Green4ea60062010-10-30 12:15:07 +0100215#define LWS_SEND_BUFFER_POST_PADDING 1
216
Andy Green5fd8a5e2010-10-31 11:57:17 +0000217extern int
Andy Greene77ddd82010-11-13 10:03:47 +0000218libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len,
Andy Green5fd8a5e2010-10-31 11:57:17 +0000219 enum libwebsocket_write_protocol protocol);
Andy Greena2b0ab02010-11-11 12:28:29 +0000220
Andy Green5fd8a5e2010-10-31 11:57:17 +0000221extern int
Andy Greene77ddd82010-11-13 10:03:47 +0000222libwebsockets_serve_http_file(struct libwebsocket *wsi, const char *file,
223 const char *content_type);
Andy Greenab990e42010-10-31 12:42:52 +0000224
Andy Greenb45993c2010-12-18 15:13:50 +0000225/* notice - you need the pre- and post- padding allocation for buf below */
226
227extern int
Andy Green6964bb52011-01-23 16:50:33 +0000228libwebsockets_broadcast(const struct libwebsocket_protocols *protocol,
Andy Greenb45993c2010-12-18 15:13:50 +0000229 unsigned char *buf, size_t len);
230
231extern const struct libwebsocket_protocols *
232libwebsockets_get_protocol(struct libwebsocket *wsi);
233
Andy Green90c7cbc2011-01-27 06:26:52 +0000234extern int
235libwebsocket_callback_on_writable(struct libwebsocket *wsi);
236
237extern int
238libwebsocket_callback_on_writable_all_protocol(
239 const struct libwebsocket_protocols *protocol);
240
Andy Greena6cbece2011-01-27 20:06:03 +0000241extern int
242libwebsocket_get_socket_fd(struct libwebsocket *wsi);
Andy Green90c7cbc2011-01-27 06:26:52 +0000243
244extern int
245libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable);
246
Andy Green38e57bb2011-01-19 12:20:27 +0000247extern size_t
248libwebsockets_remaining_packet_payload(struct libwebsocket *wsi);
249
Andy Green4739e5c2011-01-22 12:51:57 +0000250extern struct libwebsocket *
251libwebsocket_client_connect(struct libwebsocket_context *clients,
252 const char *address,
253 int port,
Andy Green90c7cbc2011-01-27 06:26:52 +0000254 int ssl_connection,
Andy Green4739e5c2011-01-22 12:51:57 +0000255 const char *path,
256 const char *host,
257 const char *origin,
258 const char *protocol);
259
Andy Green2ac5a6f2011-01-28 10:00:18 +0000260extern const char *
261libwebsocket_canonical_hostname(struct libwebsocket_context *this);
262
263extern void
Andy Green4739e5c2011-01-22 12:51:57 +0000264libwebsocket_client_close(struct libwebsocket *wsi);
265
Andy Greenab990e42010-10-31 12:42:52 +0000266#endif