2010-11-08 17:12:19 +00:00
|
|
|
/*
|
|
|
|
* libwebsockets - small server side websockets and web server implementation
|
2010-11-13 10:03:47 +00:00
|
|
|
*
|
2010-11-08 17:12:19 +00:00
|
|
|
* Copyright (C) 2010 Andy Green <andy@warmcat.com>
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation:
|
|
|
|
* version 2.1 of the License.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
|
|
* MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
2010-10-31 12:42:52 +00:00
|
|
|
#ifndef __LIBWEBSOCKET_H__
|
|
|
|
#define __LIBWEBSOCKET_H__
|
|
|
|
|
2011-01-22 12:51:57 +00:00
|
|
|
#define CONTEXT_PORT_NO_LISTEN 0
|
2010-10-28 22:36:01 +01:00
|
|
|
|
2010-10-29 14:15:22 +01:00
|
|
|
enum libwebsocket_callback_reasons {
|
|
|
|
LWS_CALLBACK_ESTABLISHED,
|
2011-01-27 06:26:52 +00:00
|
|
|
LWS_CALLBACK_CLIENT_ESTABLISHED,
|
2010-10-29 14:15:22 +01:00
|
|
|
LWS_CALLBACK_CLOSED,
|
|
|
|
LWS_CALLBACK_RECEIVE,
|
2011-01-22 12:51:57 +00:00
|
|
|
LWS_CALLBACK_CLIENT_RECEIVE,
|
2011-01-27 20:06:03 +00:00
|
|
|
LWS_CALLBACK_CLIENT_RECEIVE_PONG,
|
2011-01-27 06:26:52 +00:00
|
|
|
LWS_CALLBACK_CLIENT_WRITEABLE,
|
2010-11-11 12:28:29 +00:00
|
|
|
LWS_CALLBACK_HTTP,
|
2010-12-19 20:50:01 +00:00
|
|
|
LWS_CALLBACK_BROADCAST
|
2010-10-31 11:57:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum libwebsocket_write_protocol {
|
|
|
|
LWS_WRITE_TEXT,
|
|
|
|
LWS_WRITE_BINARY,
|
2011-01-19 12:20:27 +00:00
|
|
|
LWS_WRITE_HTTP,
|
|
|
|
|
|
|
|
/* special 04 opcodes */
|
|
|
|
|
|
|
|
LWS_WRITE_CLOSE,
|
|
|
|
LWS_WRITE_PING,
|
2011-01-27 06:26:52 +00:00
|
|
|
LWS_WRITE_PONG,
|
|
|
|
|
|
|
|
LWS_WRITE_NO_FIN = 0x40
|
2010-10-28 22:36:01 +01:00
|
|
|
};
|
|
|
|
|
2010-10-29 14:15:22 +01:00
|
|
|
struct libwebsocket;
|
2010-12-18 15:13:50 +00:00
|
|
|
struct libwebsocket_context;
|
2010-10-28 22:36:01 +01:00
|
|
|
|
2010-12-19 22:13:26 +00:00
|
|
|
/* document the generic callback (it's a fake prototype under this) */
|
|
|
|
/**
|
|
|
|
* callback() - User server actions
|
|
|
|
* @wsi: Opaque websocket instance pointer
|
|
|
|
* @reason: The reason for the call
|
|
|
|
* @user: Pointer to per-session user data allocated by library
|
|
|
|
* @in: Pointer used for some callback reasons
|
|
|
|
* @len: Length set for some callback reasons
|
|
|
|
*
|
|
|
|
* This callback is the way the user controls what is served. All the
|
|
|
|
* protocol detail is hidden and handled by the library.
|
2011-01-23 16:50:33 +00:00
|
|
|
*
|
2010-12-19 22:13:26 +00:00
|
|
|
* For each connection / session there is user data allocated that is
|
|
|
|
* pointed to by "user". You set the size of this user data area when
|
|
|
|
* the library is initialized with libwebsocket_create_server.
|
2011-01-23 16:50:33 +00:00
|
|
|
*
|
2010-12-19 22:13:26 +00:00
|
|
|
* You get an opportunity to initialize user data when called back with
|
|
|
|
* LWS_CALLBACK_ESTABLISHED reason.
|
|
|
|
*
|
2011-01-27 06:26:52 +00:00
|
|
|
* LWS_CALLBACK_ESTABLISHED: after the server completes a handshake with
|
|
|
|
* an incoming client
|
|
|
|
*
|
|
|
|
* LWS_CALLBACK_CLIENT_ESTABLISHED: after your client connection completed
|
|
|
|
* a handshake with the remote server
|
2010-12-19 22:13:26 +00:00
|
|
|
*
|
|
|
|
* LWS_CALLBACK_CLOSED: when the websocket session ends
|
|
|
|
*
|
|
|
|
* LWS_CALLBACK_BROADCAST: signal to send to client (you would use
|
|
|
|
* libwebsocket_write() taking care about the
|
|
|
|
* special buffer requirements
|
2011-01-27 06:26:52 +00:00
|
|
|
*
|
|
|
|
* LWS_CALLBACK_RECEIVE: data has appeared for this server endpoint from a
|
|
|
|
* remote client, it can be found at *in and is
|
|
|
|
* len bytes long
|
|
|
|
*
|
2011-01-27 20:06:03 +00:00
|
|
|
* LWS_CALLBACK_CLIENT_RECEIVE_PONG: if you elected to see PONG packets,
|
|
|
|
* they appear with this callback reason. PONG
|
|
|
|
* packets only exist in 04+ protocol
|
|
|
|
*
|
2011-01-27 06:26:52 +00:00
|
|
|
* LWS_CALLBACK_CLIENT_RECEIVE: data has appeared from the server for the
|
|
|
|
* client connection, it can be found at *in and
|
|
|
|
* is len bytes long
|
2010-12-19 22:13:26 +00:00
|
|
|
*
|
2011-01-23 16:50:33 +00:00
|
|
|
* LWS_CALLBACK_HTTP: an http request has come from a client that is not
|
2010-12-19 22:13:26 +00:00
|
|
|
* asking to upgrade the connection to a websocket
|
|
|
|
* one. This is a chance to serve http content,
|
|
|
|
* for example, to send a script to the client
|
|
|
|
* which will then open the websockets connection.
|
2011-01-23 16:50:33 +00:00
|
|
|
* @in points to the URI path requested and
|
2010-12-19 22:13:26 +00:00
|
|
|
* libwebsockets_serve_http_file() makes it very
|
|
|
|
* simple to send back a file to the client.
|
2011-01-27 06:26:52 +00:00
|
|
|
*
|
|
|
|
* LWS_CALLBACK_CLIENT_WRITEABLE: if you call
|
|
|
|
* libwebsocket_callback_on_writable() on a connection, you will
|
|
|
|
* get this callback coming when the connection socket is able to
|
|
|
|
* accept another write packet without blocking. If it already
|
|
|
|
* was able to take another packet without blocking, you'll get
|
|
|
|
* this callback at the next call to the service loop function.
|
2010-12-19 22:13:26 +00:00
|
|
|
*/
|
2011-01-23 16:50:33 +00:00
|
|
|
extern int callback(struct libwebsocket *wsi,
|
|
|
|
enum libwebsocket_callback_reasons reason, void *user,
|
2010-12-19 22:13:26 +00:00
|
|
|
void *in, size_t len);
|
|
|
|
|
2010-11-12 10:44:16 +00:00
|
|
|
/**
|
2011-01-23 16:50:33 +00:00
|
|
|
* struct libwebsocket_protocols - List of protocols and handlers server
|
|
|
|
* supports.
|
2010-11-12 10:44:16 +00:00
|
|
|
* @name: Protocol name that must match the one given in the client
|
2011-01-23 16:50:33 +00:00
|
|
|
* Javascript new WebSocket(url, 'protocol') name
|
2010-11-12 10:44:16 +00:00
|
|
|
* @callback: The service callback used for this protocol. It allows the
|
2011-01-23 16:50:33 +00:00
|
|
|
* service action for an entire protocol to be encapsulated in
|
|
|
|
* the protocol-specific callback
|
2010-11-12 10:44:16 +00:00
|
|
|
* @per_session_data_size: Each new connection using this protocol gets
|
2011-01-23 16:50:33 +00:00
|
|
|
* this much memory allocated on connection establishment and
|
|
|
|
* freed on connection takedown. A pointer to this per-connection
|
|
|
|
* allocation is passed into the callback in the 'user' parameter
|
2010-12-18 15:13:50 +00:00
|
|
|
* @owning_server: the server init call fills in this opaque pointer when
|
2011-01-23 16:50:33 +00:00
|
|
|
* registering this protocol with the server.
|
2010-12-18 15:13:50 +00:00
|
|
|
* @broadcast_socket_port: the server init call fills this in with the
|
2011-01-23 16:50:33 +00:00
|
|
|
* localhost port number used to forward broadcasts for this
|
|
|
|
* protocol
|
2010-12-18 15:13:50 +00:00
|
|
|
* @broadcast_socket_user_fd: the server init call fills this in ... the main()
|
2011-01-23 16:50:33 +00:00
|
|
|
* process context can write to this socket to perform broadcasts
|
|
|
|
* (use the libwebsockets_broadcast() api to do this instead,
|
|
|
|
* it works from any process context)
|
2010-12-18 15:13:50 +00:00
|
|
|
* @protocol_index: which protocol we are starting from zero
|
2010-11-13 10:03:47 +00:00
|
|
|
*
|
2011-01-23 16:50:33 +00:00
|
|
|
* This structure represents one protocol supported by the server. An
|
|
|
|
* array of these structures is passed to libwebsocket_create_server()
|
|
|
|
* allows as many protocols as you like to be handled by one server.
|
2010-11-12 10:44:16 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
struct libwebsocket_protocols {
|
|
|
|
const char *name;
|
2010-11-13 10:03:47 +00:00
|
|
|
int (*callback)(struct libwebsocket *wsi,
|
|
|
|
enum libwebsocket_callback_reasons reason, void *user,
|
2010-11-12 10:44:16 +00:00
|
|
|
void *in, size_t len);
|
|
|
|
size_t per_session_data_size;
|
2010-12-18 15:13:50 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* below are filled in on server init and can be left uninitialized,
|
|
|
|
* no need for user to use them directly either
|
|
|
|
*/
|
2011-01-23 16:50:33 +00:00
|
|
|
|
2010-12-18 15:13:50 +00:00
|
|
|
struct libwebsocket_context *owning_server;
|
|
|
|
int broadcast_socket_port;
|
|
|
|
int broadcast_socket_user_fd;
|
|
|
|
int protocol_index;
|
2010-11-12 10:44:16 +00:00
|
|
|
};
|
|
|
|
|
2011-01-19 13:11:55 +00:00
|
|
|
extern struct libwebsocket_context *
|
2011-01-22 12:51:57 +00:00
|
|
|
libwebsocket_create_context(int port,
|
2010-12-18 15:13:50 +00:00
|
|
|
struct libwebsocket_protocols *protocols,
|
2010-11-13 10:03:47 +00:00
|
|
|
const char *ssl_cert_filepath,
|
|
|
|
const char *ssl_private_key_filepath, int gid, int uid);
|
2010-10-28 22:36:01 +01:00
|
|
|
|
2011-01-23 16:50:33 +00:00
|
|
|
extern void
|
|
|
|
libwebsocket_context_destroy(struct libwebsocket_context *this);
|
|
|
|
|
2011-01-19 13:11:55 +00:00
|
|
|
extern int
|
|
|
|
libwebsockets_fork_service_loop(struct libwebsocket_context *this);
|
|
|
|
|
|
|
|
extern int
|
|
|
|
libwebsocket_service(struct libwebsocket_context *this, int timeout_ms);
|
|
|
|
|
2010-10-30 12:15:07 +01:00
|
|
|
/*
|
|
|
|
* IMPORTANT NOTICE!
|
2010-11-13 10:03:47 +00:00
|
|
|
*
|
2010-10-31 11:57:17 +00:00
|
|
|
* When sending with websocket protocol (LWS_WRITE_TEXT or LWS_WRITE_BINARY)
|
|
|
|
* the send buffer has to have LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE
|
2010-10-30 12:15:07 +01:00
|
|
|
* buf, and LWS_SEND_BUFFER_POST_PADDING bytes valid AFTER (buf + len).
|
2010-11-13 10:03:47 +00:00
|
|
|
*
|
2010-10-30 12:15:07 +01:00
|
|
|
* This allows us to add protocol info before and after the data, and send as
|
|
|
|
* one packet on the network without payload copying, for maximum efficiency.
|
2010-11-13 10:03:47 +00:00
|
|
|
*
|
2010-10-30 12:15:07 +01:00
|
|
|
* So for example you need this kind of code to use libwebsocket_write with a
|
2010-11-13 10:03:47 +00:00
|
|
|
* 128-byte payload
|
|
|
|
*
|
2010-10-31 12:42:52 +00:00
|
|
|
* char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING];
|
2010-11-13 10:03:47 +00:00
|
|
|
*
|
2010-10-31 12:42:52 +00:00
|
|
|
* // fill your part of the buffer... for example here it's all zeros
|
|
|
|
* memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128);
|
2010-11-13 10:03:47 +00:00
|
|
|
*
|
2010-10-31 12:42:52 +00:00
|
|
|
* libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128);
|
2010-11-13 10:03:47 +00:00
|
|
|
*
|
2010-10-31 11:57:17 +00:00
|
|
|
* When sending LWS_WRITE_HTTP, there is no protocol addition and you can just
|
|
|
|
* use the whole buffer without taking care of the above.
|
2010-10-30 12:15:07 +01:00
|
|
|
*/
|
|
|
|
|
2011-01-22 12:51:57 +00:00
|
|
|
/* this is the frame nonce plus two header plus 8 length */
|
|
|
|
|
|
|
|
#define LWS_SEND_BUFFER_PRE_PADDING (4 + 10)
|
2010-10-30 12:15:07 +01:00
|
|
|
#define LWS_SEND_BUFFER_POST_PADDING 1
|
|
|
|
|
2010-10-31 11:57:17 +00:00
|
|
|
extern int
|
2010-11-13 10:03:47 +00:00
|
|
|
libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len,
|
2010-10-31 11:57:17 +00:00
|
|
|
enum libwebsocket_write_protocol protocol);
|
2010-11-11 12:28:29 +00:00
|
|
|
|
2010-10-31 11:57:17 +00:00
|
|
|
extern int
|
2010-11-13 10:03:47 +00:00
|
|
|
libwebsockets_serve_http_file(struct libwebsocket *wsi, const char *file,
|
|
|
|
const char *content_type);
|
2010-10-31 12:42:52 +00:00
|
|
|
|
2010-12-18 15:13:50 +00:00
|
|
|
/* notice - you need the pre- and post- padding allocation for buf below */
|
|
|
|
|
|
|
|
extern int
|
2011-01-23 16:50:33 +00:00
|
|
|
libwebsockets_broadcast(const struct libwebsocket_protocols *protocol,
|
2010-12-18 15:13:50 +00:00
|
|
|
unsigned char *buf, size_t len);
|
|
|
|
|
|
|
|
extern const struct libwebsocket_protocols *
|
|
|
|
libwebsockets_get_protocol(struct libwebsocket *wsi);
|
|
|
|
|
2011-01-27 06:26:52 +00:00
|
|
|
extern int
|
|
|
|
libwebsocket_callback_on_writable(struct libwebsocket *wsi);
|
|
|
|
|
|
|
|
extern int
|
|
|
|
libwebsocket_callback_on_writable_all_protocol(
|
|
|
|
const struct libwebsocket_protocols *protocol);
|
|
|
|
|
2011-01-27 20:06:03 +00:00
|
|
|
extern int
|
|
|
|
libwebsocket_get_socket_fd(struct libwebsocket *wsi);
|
2011-01-27 06:26:52 +00:00
|
|
|
|
|
|
|
extern int
|
|
|
|
libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable);
|
|
|
|
|
2011-01-19 12:20:27 +00:00
|
|
|
extern size_t
|
|
|
|
libwebsockets_remaining_packet_payload(struct libwebsocket *wsi);
|
|
|
|
|
2011-01-22 12:51:57 +00:00
|
|
|
extern struct libwebsocket *
|
|
|
|
libwebsocket_client_connect(struct libwebsocket_context *clients,
|
|
|
|
const char *address,
|
|
|
|
int port,
|
2011-01-27 06:26:52 +00:00
|
|
|
int ssl_connection,
|
2011-01-22 12:51:57 +00:00
|
|
|
const char *path,
|
|
|
|
const char *host,
|
|
|
|
const char *origin,
|
|
|
|
const char *protocol);
|
|
|
|
|
|
|
|
void
|
|
|
|
libwebsocket_client_close(struct libwebsocket *wsi);
|
|
|
|
|
2010-10-31 12:42:52 +00:00
|
|
|
#endif
|