/*
* libwebsockets - small server side websockets and web server implementation
*
- * Copyright (C) 2010-2015 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2010-2016 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
#ifndef LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C
#define LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C
-/* old (pre 1.6) api name compatibility defines */
-
-#define libwebsocket_create_context lws_create_context
-#define libwebsocket_set_proxy lws_set_proxy
-#define libwebsocket_context_destroy lws_context_destroy
-#define libwebsocket_service lws_service
-#define libwebsocket_cancel_service lws_cancel_service
-#define libwebsocket_sigint_cfg lws_sigint_cfg
-#define libwebsocket_initloop lws_initloop
-#define libwebsocket_sigint_cb lws_sigint_cb
-#define libwebsocket_service_fd lws_service_fd
-#define libwebsocket_context_user lws_context_user
-#define libwebsocket_set_timeout lws_set_timeout
-#define libwebsocket_write lws_write
-#define libwebsockets_serve_http_file_fragment lws_serve_http_file_fragment
-#define libwebsockets_serve_http_file lws_serve_http_file
-#define libwebsockets_return_http_status lws_return_http_status
-#define libwebsockets_get_protocol lws_get_protocol
-#define libwebsocket_callback_on_writable_all_protocol lws_callback_on_writable_all_protocol
-#define libwebsocket_callback_on_writable lws_callback_on_writable
-#define libwebsocket_callback_all_protocol lws_callback_all_protocol
-#define libwebsocket_get_socket_fd lws_get_socket_fd
-#define libwebsocket_is_final_fragment lws_is_final_fragment
-#define libwebsocket_get_reserved_bits lws_get_reserved_bits
-#define libwebsocket_rx_flow_control lws_rx_flow_control
-#define libwebsocket_rx_flow_allow_all_protocol lws_rx_flow_allow_all_protocol
-#define libwebsockets_remaining_packet_payload lws_remaining_packet_payload
-#define libwebsocket_client_connect lws_client_connect
-#define libwebsocket_canonical_hostname lws_canonical_hostname
-#define libwebsockets_get_peer_addresses lws_get_peer_addresses
-#define libwebsockets_get_random lws_get_random
-#define libwebsockets_SHA1 lws_SHA1
-#define libwebsocket_read lws_read
-#define libwebsocket_get_internal_extensions lws_get_internal_extensions
-#define libwebsocket_write_protocol lws_write_protocol
-
-#define libwebsocket_protocols lws_protocols
-#define libwebsocket_extension lws_extension
-#define libwebsocket_context lws_context
-#define libwebsocket_pollfd lws_pollfd
-#define libwebsocket_callback_reasons lws_callback_reasons
-#define libwebsocket lws
-
#ifdef __cplusplus
#include <cstddef>
#include <cstdarg>
#include "sal-stack-lwip/lwipv4_init.h"
namespace {
- const int SERVER_PORT = 80;
- const int BUFFER_SIZE = 4096;
}
using namespace mbed::Sockets::v0;
+
+struct sockaddr_in;
struct lws;
-struct lws_context;
class lws_conn {
public:
public:
TCPStream *ts;
-
+
public:
struct lws *wsi;
- char buffer[BUFFER_SIZE];
char writeable;
char awaiting_on_writeable;
};
lws_conn_listener():
srv(SOCKET_STACK_LWIP_IPV4)
{
- srv.setOnError(TCPStream::ErrorHandler_t(this, &lws_conn_listener::onError));
+ srv.setOnError(TCPStream::ErrorHandler_t(this,
+ &lws_conn_listener::onError));
}
void start(const uint16_t port);
#endif
#ifdef MBED_OPERATORS
+struct sockaddr_in;
#define LWS_POSIX 0
#else
#define LWS_POSIX 1
#endif
-
+
#include "lws_config.h"
#if defined(WIN32) || defined(_WIN32)
-#if (WINVER < 0x0501)
-#undef WINVER
-#undef _WIN32_WINNT
-#define WINVER 0x0501
-#define _WIN32_WINNT WINVER
-#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
+
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stddef.h>
#include <stdint.h>
#include <basetsd.h>
+#ifndef _WIN32_WCE
#include <fcntl.h>
+#else
+#define _O_RDONLY 0x0000
+#define O_RDONLY _O_RDONLY
+#endif
+#ifdef _WIN32_WCE
+#define strcasecmp _stricmp
+#else
#define strcasecmp stricmp
+#endif
#define getdtablesize() 30000
+#define LWS_INLINE __inline
#define LWS_VISIBLE
+#define LWS_WARN_UNUSED_RESULT
+#define LWS_WARN_DEPRECATED
#ifdef LWS_DLL
#ifdef LWS_INTERNAL
#else
#define LWS_EXTERN
#endif
-
+
#define LWS_INVALID_FILE INVALID_HANDLE_VALUE
#define LWS_O_RDONLY _O_RDONLY
+#define lws_snprintf _snprintf
+
#else /* NOT WIN32 */
#include <unistd.h>
-
-#define LWS_INVALID_FILE -1
+
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+#include <netinet/in.h>
+#endif
+
+#define LWS_INLINE inline
#define LWS_O_RDONLY O_RDONLY
#ifndef MBED_OPERATORS
#include <poll.h>
#include <netdb.h>
+#define LWS_INVALID_FILE -1
#else
#define getdtablesize() (20)
+#define LWS_INVALID_FILE NULL
#endif
#if defined(__GNUC__)
+
+/* warn_unused_result attribute only supported by GCC 3.4 or later */
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define LWS_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define LWS_WARN_UNUSED_RESULT
+#endif
+
#define LWS_VISIBLE __attribute__((visibility("default")))
+#define LWS_WARN_DEPRECATED __attribute__ ((deprecated))
#else
#define LWS_VISIBLE
+#define LWS_WARN_UNUSED_RESULT
+#define LWS_WARN_DEPRECATED
#endif
#if defined(__ANDROID__)
-#define getdtablesize() 1024
+#include <unistd.h>
+#define getdtablesize() sysconf(_SC_OPEN_MAX)
#endif
#endif
#ifdef LWS_USE_LIBEV
#include <ev.h>
#endif /* LWS_USE_LIBEV */
+#ifdef LWS_USE_LIBUV
+#include <uv.h>
+#endif /* LWS_USE_LIBUV */
#ifndef LWS_EXTERN
#define LWS_EXTERN extern
#endif
-
+
#ifdef _WIN32
#define random rand
#else
#endif
#define CONTEXT_PORT_NO_LISTEN -1
-#define MAX_MUX_RECURSION 2
enum lws_log_levels {
LLL_ERR = 1 << 0,
* add it at where specified so existing users are unaffected.
*/
enum lws_context_options {
- LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = 2,
- LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = 4,
- LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = 8,
- LWS_SERVER_OPTION_LIBEV = 16,
- LWS_SERVER_OPTION_DISABLE_IPV6 = 32,
- LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = 64,
- LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED = 128,
-
+ LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = (1 << 1),
+ LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = (1 << 2),
+ LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = (1 << 3),
+ LWS_SERVER_OPTION_LIBEV = (1 << 4),
+ LWS_SERVER_OPTION_DISABLE_IPV6 = (1 << 5),
+ LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = (1 << 6),
+ LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED = (1 << 7),
+ LWS_SERVER_OPTION_VALIDATE_UTF8 = (1 << 8),
+ LWS_SERVER_OPTION_SSL_ECDH = (1 << 9),
+ LWS_SERVER_OPTION_LIBUV = (1 << 10),
+
/****** add new things just above ---^ ******/
};
LWS_CALLBACK_UNLOCK_POLL = 36,
LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY = 37,
+ LWS_CALLBACK_WS_PEER_INITIATED_CLOSE = 38,
+
+ LWS_CALLBACK_WS_EXT_DEFAULTS = 39,
/****** add new things just above ---^ ******/
};
-#if defined(_WIN32) && (_WIN32_WINNT < 0x0600)
+#if defined(_WIN32)
typedef SOCKET lws_sockfd_type;
typedef HANDLE lws_filefd_type;
#define lws_sockfd_valid(sfd) (!!sfd)
SHORT events;
SHORT revents;
};
-WINSOCK_API_LINKAGE int WSAAPI WSAPoll(struct lws_pollfd fdArray[], ULONG fds, INT timeout);
#else
#if defined(MBED_OPERATORS)
short events;
short revents;
};
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
+#define POLLIN 0x0001
+#define POLLPRI 0x0002
+#define POLLOUT 0x0004
+#define POLLERR 0x0008
+#define POLLHUP 0x0010
+#define POLLNVAL 0x0020
struct lws;
* passed in via 'in'
*/
struct lws_pollargs {
- lws_sockfd_type fd; /* applicable socket descriptor */
- int events; /* the new event mask */
- int prev_events; /* the previous event mask */
+ lws_sockfd_type fd; /* applicable socket descriptor */
+ int events; /* the new event mask */
+ int prev_events; /* the previous event mask */
};
/**
unsigned char *buf, unsigned long len);
/* Add new things just above here ---^
- * This is part of the ABI, don't needlessly break compatibilty */
+ * This is part of the ABI, don't needlessly break compatibility */
};
/*
* add it at where specified so existing users are unaffected.
*/
enum lws_extension_callback_reasons {
- LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT = 0,
- LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT = 1,
- LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT = 2,
- LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT = 3,
- LWS_EXT_CALLBACK_CONSTRUCT = 4,
- LWS_EXT_CALLBACK_CLIENT_CONSTRUCT = 5,
- LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE = 6,
- LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION = 7,
- LWS_EXT_CALLBACK_DESTROY = 8,
- LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING = 9,
- LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED = 10,
- LWS_EXT_CALLBACK_PACKET_RX_PREPARSE = 11,
- LWS_EXT_CALLBACK_PACKET_TX_PRESEND = 12,
- LWS_EXT_CALLBACK_PACKET_TX_DO_SEND = 13,
- LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX = 14,
- LWS_EXT_CALLBACK_FLUSH_PENDING_TX = 15,
- LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX = 16,
- LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION = 17,
- LWS_EXT_CALLBACK_1HZ = 18,
- LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE = 19,
- LWS_EXT_CALLBACK_IS_WRITEABLE = 20,
- LWS_EXT_CALLBACK_PAYLOAD_TX = 21,
- LWS_EXT_CALLBACK_PAYLOAD_RX = 22,
+ LWS_EXT_CB_SERVER_CONTEXT_CONSTRUCT = 0,
+ LWS_EXT_CB_CLIENT_CONTEXT_CONSTRUCT = 1,
+ LWS_EXT_CB_SERVER_CONTEXT_DESTRUCT = 2,
+ LWS_EXT_CB_CLIENT_CONTEXT_DESTRUCT = 3,
+ LWS_EXT_CB_CONSTRUCT = 4,
+ LWS_EXT_CB_CLIENT_CONSTRUCT = 5,
+ LWS_EXT_CB_CHECK_OK_TO_REALLY_CLOSE = 6,
+ LWS_EXT_CB_CHECK_OK_TO_PROPOSE_EXTENSION = 7,
+ LWS_EXT_CB_DESTROY = 8,
+ LWS_EXT_CB_DESTROY_ANY_WSI_CLOSING = 9,
+ LWS_EXT_CB_ANY_WSI_ESTABLISHED = 10,
+ LWS_EXT_CB_PACKET_RX_PREPARSE = 11,
+ LWS_EXT_CB_PACKET_TX_PRESEND = 12,
+ LWS_EXT_CB_PACKET_TX_DO_SEND = 13,
+ LWS_EXT_CB_HANDSHAKE_REPLY_TX = 14,
+ LWS_EXT_CB_FLUSH_PENDING_TX = 15,
+ LWS_EXT_CB_EXTENDED_PAYLOAD_RX = 16,
+ LWS_EXT_CB_CAN_PROXY_CLIENT_CONNECTION = 17,
+ LWS_EXT_CB_1HZ = 18,
+ LWS_EXT_CB_REQUEST_ON_WRITEABLE = 19,
+ LWS_EXT_CB_IS_WRITEABLE = 20,
+ LWS_EXT_CB_PAYLOAD_TX = 21,
+ LWS_EXT_CB_PAYLOAD_RX = 22,
+ LWS_EXT_CB_OPTION_DEFAULT = 23,
+ LWS_EXT_CB_OPTION_SET = 24,
+ LWS_EXT_CB_OPTION_CONFIRM = 25,
/****** add new things just above ---^ ******/
};
/* special 04+ opcodes */
- LWS_WRITE_CLOSE = 4,
+ /* LWS_WRITE_CLOSE is handled by lws_close_reason() */
LWS_WRITE_PING = 5,
LWS_WRITE_PONG = 6,
/* Same as write_http but we know this write ends the transaction */
LWS_WRITE_HTTP_FINAL = 7,
-
+
/* HTTP2 */
LWS_WRITE_HTTP_HEADERS = 8,
-
+
/****** add new things just above ---^ ******/
-
+
/* flags */
LWS_WRITE_NO_FIN = 0x40,
};
/*
- * don't forget to update test server header dump accordingly
- *
* these have to be kept in sync with lextable.h / minilex.c
*
* NOTE: These public enums are part of the abi. If you want to add one,
WSI_TOKEN_HTTP_COLON_PATH = 37,
WSI_TOKEN_HTTP_COLON_SCHEME = 38,
WSI_TOKEN_HTTP_COLON_STATUS = 39,
-
+
WSI_TOKEN_HTTP_ACCEPT_CHARSET = 40,
WSI_TOKEN_HTTP_ACCEPT_RANGES = 41,
WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN = 42,
WSI_TOKEN_HTTP_VARY = 70,
WSI_TOKEN_HTTP_VIA = 71,
WSI_TOKEN_HTTP_WWW_AUTHENTICATE = 72,
- WSI_TOKEN_PROXY,
-
+
WSI_TOKEN_PATCH_URI = 73,
WSI_TOKEN_PUT_URI = 74,
WSI_TOKEN_DELETE_URI = 75,
-
+
WSI_TOKEN_HTTP_URI_ARGS = 76,
-
- /* use token storage to stash these */
-
- _WSI_TOKEN_CLIENT_SENT_PROTOCOLS = 77,
- _WSI_TOKEN_CLIENT_PEER_ADDRESS = 78,
- _WSI_TOKEN_CLIENT_URI = 79,
- _WSI_TOKEN_CLIENT_HOST = 80,
- _WSI_TOKEN_CLIENT_ORIGIN = 81,
-
+ WSI_TOKEN_PROXY = 77,
+ WSI_TOKEN_HTTP_X_REAL_IP = 78,
+
/****** add new things just above ---^ ******/
-
+
+ /* use token storage to stash these internally, not for
+ * user use */
+
+ _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
+ _WSI_TOKEN_CLIENT_PEER_ADDRESS,
+ _WSI_TOKEN_CLIENT_URI,
+ _WSI_TOKEN_CLIENT_HOST,
+ _WSI_TOKEN_CLIENT_ORIGIN,
+
/* always last real token index*/
WSI_TOKEN_COUNT,
- /* parser state additions */
+ /* parser state additions, no storage associated */
WSI_TOKEN_NAME_PART,
WSI_TOKEN_SKIPPING,
WSI_TOKEN_SKIPPING_SAW_CR,
};
struct lws_token_limits {
- unsigned short token_limit[WSI_TOKEN_COUNT];
+ unsigned short token_limit[WSI_TOKEN_COUNT];
};
/*
* add it at where specified so existing users are unaffected.
*/
enum lws_close_status {
- LWS_CLOSE_STATUS_NOSTATUS = 0,
- LWS_CLOSE_STATUS_NORMAL = 1000,
- LWS_CLOSE_STATUS_GOINGAWAY = 1001,
- LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002,
- LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003,
- LWS_CLOSE_STATUS_RESERVED = 1004,
- LWS_CLOSE_STATUS_NO_STATUS = 1005,
- LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006,
- LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007,
- LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008,
- LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009,
- LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010,
- LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011,
- LWS_CLOSE_STATUS_TLS_FAILURE = 1015,
-
+ LWS_CLOSE_STATUS_NOSTATUS = 0,
+ LWS_CLOSE_STATUS_NORMAL = 1000,
+ LWS_CLOSE_STATUS_GOINGAWAY = 1001,
+ LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002,
+ LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003,
+ LWS_CLOSE_STATUS_RESERVED = 1004,
+ LWS_CLOSE_STATUS_NO_STATUS = 1005,
+ LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006,
+ LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007,
+ LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008,
+ LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009,
+ LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010,
+ LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011,
+ LWS_CLOSE_STATUS_TLS_FAILURE = 1015,
+
/****** add new things just above ---^ ******/
- LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY = 9999,
+ LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY = 9999,
};
enum http_status {
- HTTP_STATUS_OK = 200,
- HTTP_STATUS_NO_CONTENT = 204,
+ HTTP_STATUS_OK = 200,
+ HTTP_STATUS_NO_CONTENT = 204,
- HTTP_STATUS_BAD_REQUEST = 400,
+ HTTP_STATUS_BAD_REQUEST = 400,
HTTP_STATUS_UNAUTHORIZED,
HTTP_STATUS_PAYMENT_REQUIRED,
HTTP_STATUS_FORBIDDEN,
HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE,
HTTP_STATUS_EXPECTATION_FAILED,
- HTTP_STATUS_INTERNAL_SERVER_ERROR = 500,
+ HTTP_STATUS_INTERNAL_SERVER_ERROR = 500,
HTTP_STATUS_NOT_IMPLEMENTED,
HTTP_STATUS_BAD_GATEWAY,
HTTP_STATUS_SERVICE_UNAVAILABLE,
struct lws_extension;
/**
- * callback_function() - User server actions
- * @context: Websockets context
+ * typedef lws_callback_function() - User server actions
* @wsi: Opaque websocket instance pointer
* @reason: The reason for the call
* @user: Pointer to per-session user data allocated by library
* receiving anything. Because this happens immediately after the
* network connection from the client, there's no websocket protocol
* selected yet so this callback is issued only to protocol 0.
- *
+ *
* LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED: A new client just had
* been connected, accepted, and instantiated into the pool. This
* callback allows setting any relevant property to it. Because this
* is the server's OpenSSL SSL_CTX*
*
* LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY: if configured for
- * including OpenSSL support but no private key file has been specified
- * (ssl_private_key_filepath is NULL), this callback is called to
+ * including OpenSSL support but no private key file has been
+ * specified (ssl_private_key_filepath is NULL), this is called to
* allow the user to set the private key directly via libopenssl
* and perform further operations if required; this might be useful
- * in situations where the private key is not directly accessible by
- * the OS, for example if it is stored on a smartcard
+ * in situations where the private key is not directly accessible
+ * by the OS, for example if it is stored on a smartcard
* @user is the server's OpenSSL SSL_CTX*
*
* LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION: if the
* len == 1 allows external threads to be synchronized against
* wsi lifecycle changes if it acquires the same lock for the
* duration of wsi dereference from the other thread context.
+ *
+ * LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
+ * The peer has sent an unsolicited Close WS packet. @in and
+ * @len are the optional close code (first 2 bytes, network
+ * order) and the optional additional information which is not
+ * defined in the standard, and may be a string or non-human-
+ * readble data.
+ * If you return 0 lws will echo the close and then close the
+ * connection. If you return nonzero lws will just close the
+ * connection.
*/
-LWS_VISIBLE LWS_EXTERN int
-callback(const struct lws_context *context, const struct lws *wsi,
- enum lws_callback_reasons reason, void *user, void *in, size_t len);
-
-typedef int (callback_function)(struct lws_context *context,
- struct lws *wsi,
- enum lws_callback_reasons reason, void *user,
- void *in, size_t len);
+typedef int
+lws_callback_function(struct lws *wsi, enum lws_callback_reasons reason,
+ void *user, void *in, size_t len);
-#ifndef LWS_NO_EXTENSIONS
/**
- * extension_callback_function() - Hooks to allow extensions to operate
+ * typedef lws_extension_callback_function() - Hooks to allow extensions to operate
* @context: Websockets context
* @ext: This extension
* @wsi: Opaque websocket instance pointer
* @reason: The reason for the call
- * @user: Pointer to per-session user data allocated by library
+ * @user: Pointer to ptr to per-session user data allocated by library
* @in: Pointer used for some callback reasons
* @len: Length set for some callback reasons
*
* each active extension on each connection. That is what is pointed to
* by the @user parameter.
*
- * LWS_EXT_CALLBACK_CONSTRUCT: called when the server has decided to
+ * LWS_EXT_CB_CONSTRUCT: called when the server has decided to
* select this extension from the list provided by the client,
* just before the server will send back the handshake accepting
* the connection with this extension active. This gives the
* extension a chance to initialize its connection context found
* in @user.
*
- * LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: same as LWS_EXT_CALLBACK_CONSTRUCT
+ * LWS_EXT_CB_CLIENT_CONSTRUCT: same as LWS_EXT_CB_CONSTRUCT
* but called when client is instantiating this extension. Some
* extensions will work the same on client and server side and then
* you can just merge handlers for both CONSTRUCTS.
*
- * LWS_EXT_CALLBACK_DESTROY: called when the connection the extension was
+ * LWS_EXT_CB_DESTROY: called when the connection the extension was
* being used on is about to be closed and deallocated. It's the
* last chance for the extension to deallocate anything it has
* allocated in the user data (pointed to by @user) before the
* user data is deleted. This same callback is used whether you
* are in client or server instantiation context.
*
- * LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: when this extension was active on
+ * LWS_EXT_CB_PACKET_RX_PREPARSE: when this extension was active on
* a connection, and a packet of data arrived at the connection,
* it is passed to this callback to give the extension a chance to
* change the data, eg, decompress it. @user is pointing to the
* a new buffer allocated in its private user context data and
* set the pointed-to lws_tokens members to point to its buffer.
*
- * LWS_EXT_CALLBACK_PACKET_TX_PRESEND: this works the same way as
- * LWS_EXT_CALLBACK_PACKET_RX_PREPARSE above, except it gives the
+ * LWS_EXT_CB_PACKET_TX_PRESEND: this works the same way as
+ * LWS_EXT_CB_PACKET_RX_PREPARSE above, except it gives the
* extension a chance to change websocket data just before it will
* be sent out. Using the same lws_token pointer scheme in @in,
* the extension can change the buffer and the length to be
* transmitted how it likes. Again if it wants to grow the
* buffer safely, it should copy the data into its own buffer and
* set the lws_tokens token pointer to it.
+ *
+ * LWS_EXT_CB_ARGS_VALIDATE:
*/
-LWS_VISIBLE LWS_EXTERN int
-extension_callback(struct lws_context *context, const struct lws_extension *ext,
- struct lws *wsi, enum lws_extension_callback_reasons reason,
- void *user, void *in, size_t len);
-
-typedef int (extension_callback_function)(struct lws_context *context,
- const struct lws_extension *ext, struct lws *wsi,
- enum lws_extension_callback_reasons reason,
- void *user, void *in, size_t len);
-#endif
+typedef int
+lws_extension_callback_function(struct lws_context *context,
+ const struct lws_extension *ext, struct lws *wsi,
+ enum lws_extension_callback_reasons reason,
+ void *user, void *in, size_t len);
/**
* struct lws_protocols - List of protocols and handlers server
* error, but the buffer will spill to the user callback when
* full, which you can detect by using
* lws_remaining_packet_payload(). Notice that you
- * just talk about frame size here, the LWS_SEND_BUFFER_PRE_PADDING
+ * just talk about frame size here, the LWS_PRE
* and post-padding are automatically also allocated on top.
* @id: ignored by lws, but useful to contain user information bound
* to the selected protocol. For example if this protocol was
struct lws_protocols {
const char *name;
- callback_function *callback;
+ lws_callback_function *callback;
size_t per_session_data_size;
size_t rx_buffer_size;
unsigned int id;
void *user;
/* Add new things just above here ---^
- * This is part of the ABI, don't needlessly break compatibilty */
+ * This is part of the ABI, don't needlessly break compatibility */
+};
+
+enum lws_ext_options_types {
+ EXTARG_NONE,
+ EXTARG_DEC,
+ EXTARG_OPT_DEC
+
+ /* Add new things just above here ---^
+ * This is part of the ABI, don't needlessly break compatibility */
+};
+
+/**
+ * struct lws_ext_options - Option arguments to the extension. These are
+ * used in the negotiation at ws upgrade time.
+ * The helper function lws_ext_parse_options()
+ * uses these to generate callbacks
+ *
+ * @name: Option name, eg, "server_no_context_takeover"
+ * @type: What kind of args the option can take
+ */
+struct lws_ext_options {
+ const char *name;
+ enum lws_ext_options_types type;
+
+ /* Add new things just above here ---^
+ * This is part of the ABI, don't needlessly break compatibility */
+};
+
+struct lws_ext_option_arg {
+ int option_index;
+ const char *start;
+ int len;
};
-#ifndef LWS_NO_EXTENSIONS
/**
* struct lws_extension - An extension we know how to cope with
*
- * @name: Formal extension name, eg, "deflate-stream"
+ * @name: Formal extension name, eg, "permessage-deflate"
* @callback: Service callback
- * @per_session_data_size: Libwebsockets will auto-malloc this much
- * memory for the use of the extension, a pointer
- * to it comes in the @user callback parameter
- * @per_context_private_data: Optional storage for this extension that
- * is per-context, so it can track stuff across
- * all sessions, etc, if it wants
+ * @client_offer: String containing exts and options client offers
*/
struct lws_extension {
const char *name;
- extension_callback_function *callback;
- size_t per_session_data_size;
- void *per_context_private_data;
+ lws_extension_callback_function *callback;
+ const char *client_offer;
/* Add new things just above here ---^
- * This is part of the ABI, don't needlessly break compatibilty */
+ * This is part of the ABI, don't needlessly break compatibility */
};
-#endif
+
+/*
+ * The internal exts are part of the public abi
+ * If we add more extensions, publish the callback here ------v
+ */
+
+extern int lws_extension_callback_pm_deflate(
+ struct lws_context *context, const struct lws_extension *ext,
+ struct lws *wsi, enum lws_extension_callback_reasons reason,
+ void *user, void *in, size_t len);
+
/**
- * struct lws_context_creation_info: parameters to create context with
+ * struct lws_context_creation_info - parameters to create context with
*
* @port: Port to listen on... you can use CONTEXT_PORT_NO_LISTEN to
* suppress listening on any port, that's what you want if you are
* extensions this context supports. If you configured with
* --without-extensions, you should give NULL here.
* @token_limits: NULL or struct lws_token_limits pointer which is initialized
- * with a token length limit for each possible WSI_TOKEN_***
+ * with a token length limit for each possible WSI_TOKEN_***
* @ssl_cert_filepath: If libwebsockets was compiled to use ssl, and you want
* to listen using SSL, set to the filepath to fetch the
* server cert from, otherwise NULL for unencrypted
* @ssl_private_key_filepath: filepath to private key if wanting SSL mode;
* if this is set to NULL but sll_cert_filepath is set, the
- * OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY callback is called to allow
- * setting of the private key directly via openSSL library calls
+ * OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY callback is called
+ * to allow setting of the private key directly via openSSL
+ * library calls
* @ssl_ca_filepath: CA certificate filepath or NULL
* @ssl_cipher_list: List of valid ciphers to use (eg,
* "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"
* @http_proxy_address: If non-NULL, attempts to proxy via the given address.
* If proxy auth is required, use format
* "username:password@server:port"
- * @http_proxy_port: If http_proxy_address was non-NULL, uses this port at the address
+ * @http_proxy_port: If http_proxy_address was non-NULL, uses this port at
+ * the address
* @gid: group id to change to after setting listen socket, or -1.
* @uid: user id to change to after setting listen socket, or -1.
- * @options: 0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK
+ * @options: 0, or LWS_SERVER_OPTION_... bitfields
* @user: optional user pointer that can be recovered via the context
* pointer using lws_context_user
* @ka_time: 0 for no keepalive, otherwise apply this keepalive timeout to
* implementation for the one provided by provided_ssl_ctx.
* Libwebsockets no longer is responsible for freeing the context
* if this option is selected.
+ * @max_http_header_data: The max amount of header payload that can be handled
+ * in an http request (unrecognized header payload is dropped)
+ * @max_http_header_pool: The max number of connections with http headers that
+ * can be processed simultaneously (the corresponding memory is
+ * allocated for the lifetime of the context). If the pool is
+ * busy new incoming connections must wait for accept until one
+ * becomes free.
+ * @count_threads: how many contexts to create in an array, 0 = 1
+ * @fd_limit_per_thread: nonzero means restrict each service thread to this
+ * many fds, 0 means the default which is divide the process fd
+ * limit by the number of threads.
+ * @timeout_secs: various processes involving network roundtrips in the
+ * library are protected from hanging forever by timeouts. If
+ * nonzero, this member lets you set the timeout used in seconds.
+ * Otherwise a default timeout is used.
*/
struct lws_context_creation_info {
#ifdef LWS_OPENSSL_SUPPORT
SSL_CTX *provided_client_ssl_ctx;
#else /* maintain structure layout either way */
- void *provided_client_ssl_ctx;
+ void *provided_client_ssl_ctx;
#endif
+ short max_http_header_data;
+ short max_http_header_pool;
+
+ unsigned int count_threads;
+ unsigned int fd_limit_per_thread;
+ unsigned int timeout_secs;
+
/* Add new things just above here ---^
- * This is part of the ABI, don't needlessly break compatibilty */
+ * This is part of the ABI, don't needlessly break compatibility
+ *
+ * The below is to ensure later library versions with new
+ * members added above will see 0 (default) even if the app
+ * was not built against the newer headers.
+ */
+
+ void *_unused[8];
+};
+
+/**
+ * struct lws_client_connect_info - parameters to connect with when using
+ * lws_client_connect_via_info()
+ *
+ * @context: lws context to create connection in
+ * @address: remote address to connect to
+ * @port: remote port to connect to
+ * @ssl_connection: nonzero for ssl
+ * @path: uri path
+ * @host: content of host header
+ * @origin: content of origin header
+ * @protocol: list of ws protocols
+ * @ietf_version_or_minus_one: currently leave at 0 or -1
+ * @userdata: if non-NULL, use this as wsi user_data instead of malloc it
+ * @client_exts: array of extensions that may be used on connection
+ */
+
+struct lws_client_connect_info {
+ struct lws_context *context;
+ const char *address;
+ int port;
+ int ssl_connection;
+ const char *path;
+ const char *host;
+ const char *origin;
+ const char *protocol;
+ int ietf_version_or_minus_one;
+ void *userdata;
+ const struct lws_extension *client_exts;
+
+ /* Add new things just above here ---^
+ * This is part of the ABI, don't needlessly break compatibility
+ *
+ * The below is to ensure later library versions with new
+ * members added above will see 0 (default) even if the app
+ * was not built against the newer headers.
+ */
+
+ void *_unused[4];
};
LWS_VISIBLE LWS_EXTERN void
LWS_VISIBLE LWS_EXTERN struct lws_context *
lws_create_context(struct lws_context_creation_info *info);
-
+
LWS_VISIBLE LWS_EXTERN int
lws_set_proxy(struct lws_context *context, const char *proxy);
LWS_VISIBLE LWS_EXTERN int
lws_service(struct lws_context *context, int timeout_ms);
+LWS_VISIBLE LWS_EXTERN int
+lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_cancel_service_pt(struct lws *wsi);
+
LWS_VISIBLE LWS_EXTERN void
lws_cancel_service(struct lws_context *context);
+LWS_VISIBLE LWS_EXTERN int
+lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr,
+ size_t addrlen);
+
LWS_VISIBLE LWS_EXTERN const unsigned char *
lws_token_to_string(enum lws_token_indexes token);
LWS_VISIBLE LWS_EXTERN int
-lws_add_http_header_by_name(struct lws_context *context,
- struct lws *wsi,
- const unsigned char *name,
- const unsigned char *value,
- int length,
- unsigned char **p,
- unsigned char *end);
-LWS_VISIBLE LWS_EXTERN int
-lws_finalize_http_header(struct lws_context *context,
- struct lws *wsi,
- unsigned char **p,
- unsigned char *end);
+lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name,
+ const unsigned char *value, int length,
+ unsigned char **p, unsigned char *end);
LWS_VISIBLE LWS_EXTERN int
-lws_add_http_header_by_token(struct lws_context *context,
- struct lws *wsi,
- enum lws_token_indexes token,
- const unsigned char *value,
- int length,
- unsigned char **p,
- unsigned char *end);
+lws_finalize_http_header(struct lws *wsi, unsigned char **p,
+ unsigned char *end);
LWS_VISIBLE LWS_EXTERN int
-lws_add_http_header_content_length(struct lws_context *context,
- struct lws *wsi,
- unsigned long content_length,
- unsigned char **p,
- unsigned char *end);
+lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token,
+ const unsigned char *value, int length,
+ unsigned char **p, unsigned char *end);
LWS_VISIBLE LWS_EXTERN int
-lws_add_http_header_status(struct lws_context *context,
- struct lws *wsi,
- unsigned int code,
- unsigned char **p,
- unsigned char *end);
+lws_add_http_header_content_length(struct lws *wsi,
+ unsigned long content_length,
+ unsigned char **p, unsigned char *end);
+LWS_VISIBLE LWS_EXTERN int
+lws_add_http_header_status(struct lws *wsi,
+ unsigned int code, unsigned char **p,
+ unsigned char *end);
-LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_http_transaction_completed(struct lws *wsi);
#ifdef LWS_USE_LIBEV
-typedef void (lws_ev_signal_cb)(EV_P_ struct ev_signal *w, int revents);
+typedef void (lws_ev_signal_cb_t)(EV_P_ struct ev_signal *w, int revents);
LWS_VISIBLE LWS_EXTERN int
-lws_sigint_cfg(
- struct lws_context *context,
- int use_ev_sigint,
- lws_ev_signal_cb* cb);
+lws_ev_sigint_cfg(struct lws_context *context, int use_ev_sigint,
+ lws_ev_signal_cb_t *cb);
LWS_VISIBLE LWS_EXTERN int
-lws_initloop(
- struct lws_context *context, struct ev_loop *loop);
+lws_ev_initloop(struct lws_context *context, struct ev_loop *loop, int tsi);
LWS_VISIBLE void
-lws_sigint_cb(
- struct ev_loop *loop, struct ev_signal *watcher, int revents);
+lws_ev_sigint_cb(struct ev_loop *loop, struct ev_signal *watcher, int revents);
#endif /* LWS_USE_LIBEV */
+#ifdef LWS_USE_LIBUV
+typedef void (lws_uv_signal_cb_t)(uv_loop_t *l, uv_signal_t *w, int signum);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_uv_sigint_cfg(struct lws_context *context, int use_uv_sigint,
+ lws_uv_signal_cb_t *cb);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_libuv_run(const struct lws_context *context, int tsi);
+
+LWS_VISIBLE void
+lws_libuv_stop(struct lws_context *context);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, uv_signal_cb cb, int tsi);
+
+LWS_VISIBLE LWS_EXTERN uv_loop_t *
+lws_uv_getloop(struct lws_context *context, int tsi);
+
+LWS_VISIBLE void
+lws_uv_sigint_cb(uv_loop_t *loop, uv_signal_t *watcher, int signum);
+#endif /* LWS_USE_LIBUV */
+
+LWS_VISIBLE LWS_EXTERN int
+lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd);
+
LWS_VISIBLE LWS_EXTERN int
-lws_service_fd(struct lws_context *context,
- struct lws_pollfd *pollfd);
+lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd,
+ int tsi);
LWS_VISIBLE LWS_EXTERN void *
lws_context_user(struct lws_context *context);
+LWS_VISIBLE LWS_EXTERN void *
+lws_wsi_user(struct lws *wsi);
+
/*
* NOTE: These public enums are part of the abi. If you want to add one,
* add it at where specified so existing users are unaffected.
PENDING_TIMEOUT_HTTP_CONTENT = 10,
PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND = 11,
PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE = 12,
-
+ PENDING_TIMEOUT_SHUTDOWN_FLUSH = 13,
+
/****** add new things just above ---^ ******/
};
/*
* IMPORTANT NOTICE!
*
- * 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
- * buf, and LWS_SEND_BUFFER_POST_PADDING bytes valid AFTER (buf + len).
+ * When sending with websocket protocol
+ *
+ * LWS_WRITE_TEXT,
+ * LWS_WRITE_BINARY,
+ * LWS_WRITE_CONTINUATION,
+ * LWS_WRITE_PING,
+ * LWS_WRITE_PONG
+ *
+ * the send buffer has to have LWS_PRE bytes valid BEFORE
+ * the buffer pointer you pass to lws_write().
*
* 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.
* So for example you need this kind of code to use lws_write with a
* 128-byte payload
*
- * char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING];
+ * char buf[LWS_PRE + 128];
*
* // fill your part of the buffer... for example here it's all zeros
- * memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128);
+ * memset(&buf[LWS_PRE], 0, 128);
*
- * lws_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128,
- * LWS_WRITE_TEXT);
+ * lws_write(wsi, &buf[LWS_PRE], 128, LWS_WRITE_TEXT);
*
- * When sending LWS_WRITE_HTTP, there is no protocol addition and you can just
- * use the whole buffer without taking care of the above.
- */
-
-/*
- * this is the frame nonce plus two header plus 8 length
- * there's an additional two for mux extension per mux nesting level
- * 2 byte prepend on close will already fit because control frames cannot use
- * the big length style
- */
-
-/*
- * Pad LWS_SEND_BUFFER_PRE_PADDING to the CPU word size, so that word references
+ * When sending HTTP, with
+ *
+ * LWS_WRITE_HTTP,
+ * LWS_WRITE_HTTP_HEADERS
+ * LWS_WRITE_HTTP_FINAL
+ *
+ * there is no protocol data prepended, and don't need to take care about the
+ * LWS_PRE bytes valid before the buffer pointer.
+ *
+ * LWS_PRE is at least the frame nonce + 2 header + 8 length
+ * LWS_SEND_BUFFER_POST_PADDING is deprecated, it's now 0 and can be left off.
+ * The example apps no longer use it.
+ *
+ * Pad LWS_PRE to the CPU word size, so that word references
* to the address immediately after the padding won't cause an unaligned access
* error. Sometimes for performance reasons the recommended padding is even
* larger than sizeof(void *).
#if __x86_64__
#define _LWS_PAD_SIZE 16 /* Intel recommended for best performance */
#else
-#define _LWS_PAD_SIZE LWS_SIZEOFPTR /* Size of a pointer on the target architecture */
+#define _LWS_PAD_SIZE LWS_SIZEOFPTR /* Size of a pointer on the target arch */
#endif
#define _LWS_PAD(n) (((n) % _LWS_PAD_SIZE) ? \
((n) + (_LWS_PAD_SIZE - ((n) % _LWS_PAD_SIZE))) : (n))
-#define LWS_SEND_BUFFER_PRE_PADDING _LWS_PAD(4 + 10 + (2 * MAX_MUX_RECURSION))
-#define LWS_SEND_BUFFER_POST_PADDING 4
+#define LWS_PRE _LWS_PAD(4 + 10)
+/* used prior to 1.7 and retained for backward compatibility */
+#define LWS_SEND_BUFFER_PRE_PADDING LWS_PRE
+#define LWS_SEND_BUFFER_POST_PADDING 0
LWS_VISIBLE LWS_EXTERN int
lws_write(struct lws *wsi, unsigned char *buf, size_t len,
enum lws_write_protocol protocol);
+/**
+ * lws_close_reason - Set reason and aux data to send with Close packet
+ * If you are going to return nonzero from the callback
+ * requesting the connection to close, you can optionally
+ * call this to set the reason the peer will be told if
+ * possible.
+ *
+ * @wsi: The websocket connection to set the close reason on
+ * @status: A valid close status from websocket standard
+ * @buf: NULL or buffer containing up to 124 bytes of auxiliary data
+ * @len: Length of data in @buf to send
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_close_reason(struct lws *wsi, enum lws_close_status status,
+ unsigned char *buf, size_t len);
+
/* helper for case where buffer may be const */
#define lws_write_http(wsi, buf, len) \
lws_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP)
LWS_VISIBLE LWS_EXTERN int
-lws_serve_http_file(struct lws_context *context, struct lws *wsi,
- const char *file, const char *content_type,
+lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
const char *other_headers, int other_headers_len);
LWS_VISIBLE LWS_EXTERN int
-lws_serve_http_file_fragment(struct lws_context *context, struct lws *wsi);
+lws_serve_http_file_fragment(struct lws *wsi);
LWS_VISIBLE LWS_EXTERN int
-lws_return_http_status(struct lws_context *context, struct lws *wsi,
- unsigned int code, const char *html_body);
+lws_return_http_status(struct lws *wsi, unsigned int code,
+ const char *html_body);
LWS_VISIBLE LWS_EXTERN const struct lws_protocols *
lws_get_protocol(struct lws *wsi);
LWS_VISIBLE LWS_EXTERN int
-lws_callback_on_writable(const struct lws_context *context, struct lws *wsi);
+lws_callback_on_writable(struct lws *wsi);
LWS_VISIBLE LWS_EXTERN int
lws_callback_on_writable_all_protocol(const struct lws_context *context,
* if the protocol does not have any guidance, returns -1. Currently only
* http2 connections get send window information from this API. But your code
* should use it so it can work properly with any protocol.
- *
+ *
* If nonzero return is the amount of payload data the peer or intermediary has
* reported it has buffer space for. That has NO relationship with the amount
* of buffer space your OS can accept on this connection for a write action.
- *
+ *
* This number represents the maximum you could send to the peer or intermediary
* on this connection right now without it complaining.
- *
+ *
* lws manages accounting for send window updates and payload writes
* automatically, so this number reflects the situation at the peer or
* intermediary dynamically.
LWS_VISIBLE LWS_EXTERN size_t
lws_get_peer_write_allowance(struct lws *wsi);
-LWS_VISIBLE LWS_EXTERN struct lws *
+/* deprecated, use lws_client_connect_via_info() */
+LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
lws_client_connect(struct lws_context *clients, const char *address,
int port, int ssl_connection, const char *path,
const char *host, const char *origin, const char *protocol,
- int ietf_version_or_minus_one);
-
-LWS_VISIBLE LWS_EXTERN struct lws *
+ int ietf_version_or_minus_one) LWS_WARN_DEPRECATED;
+/* deprecated, use lws_client_connect_via_info() */
+LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
lws_client_connect_extended(struct lws_context *clients, const char *address,
int port, int ssl_connection, const char *path,
const char *host, const char *origin,
const char *protocol, int ietf_version_or_minus_one,
- void *userdata);
+ void *userdata) LWS_WARN_DEPRECATED;
-LWS_VISIBLE LWS_EXTERN const char *
+LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
+lws_client_connect_via_info(struct lws_client_connect_info * ccinfo);
+
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd);
+
+LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT
lws_canonical_hostname(struct lws_context *context);
LWS_VISIBLE LWS_EXTERN void
-lws_get_peer_addresses(struct lws_context *context, struct lws *wsi,
- lws_sockfd_type fd, char *name, int name_len,
- char *rip, int rip_len);
+lws_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name,
+ int name_len, char *rip, int rip_len);
LWS_VISIBLE LWS_EXTERN int
lws_get_random(struct lws_context *context, void *buf, int len);
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_daemonize(const char *_lock_path);
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_send_pipe_choked(struct lws *wsi);
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_partial_buffered(struct lws *wsi);
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_frame_is_binary(struct lws *wsi);
LWS_VISIBLE LWS_EXTERN int
LWS_VISIBLE LWS_EXTERN int
lws_b64_decode_string(const char *in, char *out, int out_size);
-LWS_VISIBLE LWS_EXTERN const char *
+LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT
lws_get_library_version(void);
-/* access to headers... only valid while headers valid */
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_parse_uri(char *p, const char **prot, const char **ads, int *port,
+ const char **path);
-LWS_VISIBLE LWS_EXTERN int
+/*
+ * Access to http headers
+ *
+ * In lws the client http headers are temporarily malloc'd only for the
+ * duration of the http part of the handshake. It's because in most cases,
+ * the header content is ignored for the whole rest of the connection lifetime
+ * and would then just be taking up space needlessly.
+ *
+ * During LWS_CALLBACK_HTTP when the URI path is delivered is the last time
+ * the http headers are still allocated, you can use these apis then to
+ * look at and copy out interesting header content (cookies, etc)
+ *
+ * Notice that the header total length reported does not include a terminating
+ * '\0', however you must allocate for it when using the _copy apis. So the
+ * length reported for a header containing "123" is 3, but you must provide
+ * a buffer of length 4 so that "123\0" may be copied into it, or the copy
+ * will fail with a nonzero return code.
+ */
+
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h);
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx);
+
+/*
+ * copies the whole, aggregated header, even if it was delivered in
+ * several actual headers piece by piece
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h);
+
+/*
+ * copies only fragment frag_idx of a header. Normally this is only useful
+ * to parse URI arguments like ?x=1&y=2, token index WSI_TOKEN_HTTP_URI_ARGS
+ * fragment 0 will contain "x=1" and fragment 1 "y=2"
+ */
LWS_VISIBLE LWS_EXTERN int
-lws_hdr_copy(struct lws *wsi, char *dest, int len,
- enum lws_token_indexes h);
+lws_hdr_copy_fragment(struct lws *wsi, char *dest, int len,
+ enum lws_token_indexes h, int frag_idx);
+
/* get the active file operations struct */
-LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops *
+LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops * LWS_WARN_UNUSED_RESULT
lws_get_fops(struct lws_context *context);
-LWS_VISIBLE LWS_EXTERN struct lws_context *
-lws_get_ctx(const struct lws *wsi);
+LWS_VISIBLE LWS_EXTERN struct lws_context * LWS_WARN_UNUSED_RESULT
+lws_get_context(const struct lws *wsi);
+
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_get_count_threads(struct lws_context *context);
/*
* Wsi-associated File Operations access helpers
* without having to deal with differences between platforms.
*/
-static inline lws_filefd_type
+static LWS_INLINE lws_filefd_type LWS_WARN_UNUSED_RESULT
lws_plat_file_open(struct lws *wsi, const char *filename,
unsigned long *filelen, int flags)
{
- return lws_get_fops(lws_get_ctx(wsi))->open(wsi, filename,
+ return lws_get_fops(lws_get_context(wsi))->open(wsi, filename,
filelen, flags);
}
-static inline int
+static LWS_INLINE int
lws_plat_file_close(struct lws *wsi, lws_filefd_type fd)
{
- return lws_get_fops(lws_get_ctx(wsi))->close(wsi, fd);
+ return lws_get_fops(lws_get_context(wsi))->close(wsi, fd);
}
-static inline unsigned long
+static LWS_INLINE unsigned long
lws_plat_file_seek_cur(struct lws *wsi, lws_filefd_type fd, long offset)
{
- return lws_get_fops(lws_get_ctx(wsi))->seek_cur(wsi, fd, offset);
+ return lws_get_fops(lws_get_context(wsi))->seek_cur(wsi, fd, offset);
}
-static inline int
+static LWS_INLINE int LWS_WARN_UNUSED_RESULT
lws_plat_file_read(struct lws *wsi, lws_filefd_type fd, unsigned long *amount,
unsigned char *buf, unsigned long len)
{
- return lws_get_fops(lws_get_ctx(wsi))->read(wsi, fd, amount, buf, len);
+ return lws_get_fops(lws_get_context(wsi))->read(wsi, fd, amount, buf,
+ len);
}
-static inline int
+static LWS_INLINE int LWS_WARN_UNUSED_RESULT
lws_plat_file_write(struct lws *wsi, lws_filefd_type fd, unsigned long *amount,
unsigned char *buf, unsigned long len)
{
- return lws_get_fops(lws_get_ctx(wsi))->write(wsi, fd, amount, buf, len);
+ return lws_get_fops(lws_get_context(wsi))->write(wsi, fd, amount, buf,
+ len);
}
/*
* Note: this is not normally needed as a user api. It's provided in case it is
* useful when integrating with other app poll loop service code.
*/
-
LWS_VISIBLE LWS_EXTERN int
-lws_read(struct lws_context *context, struct lws *wsi,
- unsigned char *buf, size_t len);
+lws_read(struct lws *wsi, unsigned char *buf, size_t len);
#ifndef LWS_NO_EXTENSIONS
-LWS_VISIBLE LWS_EXTERN struct lws_extension *lws_get_internal_extensions();
+/* Deprecated
+ *
+ * There is no longer a set internal extensions table. The table is provided
+ * by user code along with application-specific settings. See the test
+ * client and server for how to do.
+ */
+static LWS_INLINE LWS_WARN_DEPRECATED const struct lws_extension *
+lws_get_internal_extensions() { return NULL; }
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_ext_parse_options(const struct lws_extension *ext, struct lws *wsi,
+ void *ext_user, const struct lws_ext_options *opts,
+ const char *o, int len);
#endif
/*
LWS_VISIBLE LWS_EXTERN void
lws_set_allocator(void *(*realloc)(void *ptr, size_t size));
+/**
+ * lws_snprintf(): lws_snprintf that truncates the returned length too
+ *
+ * \param str: destination buffer
+ * \param size: bytes left in destination buffer
+ * \param format: format string
+ * \param ...: args for format
+ *
+ * This lets you correctly truncate buffers by concatenating lengths, if you
+ * reach the limit the reported length doesn't exceed the limit.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_snprintf(char *str, size_t size, const char *format, ...);
+
#ifdef __cplusplus
}
#endif