libwebsockets.h (1.7.9) | | libwebsockets.h (2.1.0) |
| | |
skipping to change at line 22 ¶ | | skipping to change at line 22 ¶ |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
* Lesser General Public License for more details. | | * Lesser General Public License for more details. |
* | | * |
* You should have received a copy of the GNU Lesser General Public | | * You should have received a copy of the GNU Lesser General Public |
* License along with this library; if not, write to the Free Software | | * License along with this library; if not, write to the Free Software |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
* MA 02110-1301 USA | | * MA 02110-1301 USA |
*/ | | */ |
| | |
| | /** @file */ |
| | |
#ifndef LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C | | #ifndef LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C |
#define LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C | | #define LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C |
| | |
#ifdef __cplusplus | | #ifdef __cplusplus |
#include <cstddef> | | #include <cstddef> |
#include <cstdarg> | | #include <cstdarg> |
#ifdef MBED_OPERATORS | | #ifdef MBED_OPERATORS |
#include "mbed-drivers/mbed.h" | | #include "mbed-drivers/mbed.h" |
#include "sal-iface-eth/EthernetInterface.h" | | #include "sal-iface-eth/EthernetInterface.h" |
#include "sockets/TCPListener.h" | | #include "sockets/TCPListener.h" |
| | |
skipping to change at line 78 ¶ | | skipping to change at line 80 ¶ |
| | |
class lws_conn_listener : lws_conn { | | class lws_conn_listener : lws_conn { |
public: | | public: |
lws_conn_listener(): | | lws_conn_listener(): |
srv(SOCKET_STACK_LWIP_IPV4) | | srv(SOCKET_STACK_LWIP_IPV4) |
{ | | { |
srv.setOnError(TCPStream::ErrorHandler_t(this, | | srv.setOnError(TCPStream::ErrorHandler_t(this, |
&lws_conn_listener::onError)); | | &lws_conn_listener::onError)); |
} | | } |
| | |
void start(const uint16_t port); | | void start(const uint16_t port); /**< start listening */ |
| | |
protected: | | protected: |
void onRX(Socket *s); | | void onRX(Socket *s); /**< incoming data ready */ |
void onError(Socket *s, socket_error_t err); | | void onError(Socket *s, socket_error_t err); /**< if error occurs */ |
void onIncoming(TCPListener *s, void *impl); | | void onIncoming(TCPListener *s, void *impl); /**< new connection */ |
void onDisconnect(TCPStream *s); | | void onDisconnect(TCPStream *s); /**< disconnection */ |
| | |
public: | | public: |
TCPListener srv; | | TCPListener srv; |
}; | | }; |
| | |
#endif | | #endif |
| | |
extern "C" { | | extern "C" { |
#else | | #else |
#include <stdarg.h> | | #include <stdarg.h> |
#endif | | #endif |
| | |
#ifdef MBED_OPERATORS | | #if defined(MBED_OPERATORS) || defined(LWS_WITH_ESP8266) |
struct sockaddr_in; | | struct sockaddr_in; |
#define LWS_POSIX 0 | | #define LWS_POSIX 0 |
#else | | #else |
#define LWS_POSIX 1 | | #define LWS_POSIX 1 |
#endif | | #endif |
| | |
#include "lws_config.h" | | #include "lws_config.h" |
| | |
#if defined(WIN32) || defined(_WIN32) | | #if defined(WIN32) || defined(_WIN32) |
#ifndef WIN32_LEAN_AND_MEAN | | #ifndef WIN32_LEAN_AND_MEAN |
#define WIN32_LEAN_AND_MEAN | | #define WIN32_LEAN_AND_MEAN |
#endif | | #endif |
| | |
#include <winsock2.h> | | #include <winsock2.h> |
#include <ws2tcpip.h> | | #include <ws2tcpip.h> |
#include <stddef.h> | | #include <stddef.h> |
#include <stdint.h> | | |
#include <basetsd.h> | | #include <basetsd.h> |
#ifndef _WIN32_WCE | | #ifndef _WIN32_WCE |
#include <fcntl.h> | | #include <fcntl.h> |
#else | | #else |
#define _O_RDONLY 0x0000 | | #define _O_RDONLY 0x0000 |
#define O_RDONLY _O_RDONLY | | #define O_RDONLY _O_RDONLY |
#endif | | #endif |
| | |
#ifdef _WIN32_WCE | | // Visual studio older than 2015 and WIN_CE has only _stricmp |
| | #if (defined(_MSC_VER) && _MSC_VER < 1900) || defined(_WIN32_WCE) |
#define strcasecmp _stricmp | | #define strcasecmp _stricmp |
#else | | #else |
#define strcasecmp stricmp | | #define strcasecmp stricmp |
#endif | | #endif |
#define getdtablesize() 30000 | | #define getdtablesize() 30000 |
| | |
#define LWS_INLINE __inline | | #define LWS_INLINE __inline |
#define LWS_VISIBLE | | #define LWS_VISIBLE |
#define LWS_WARN_UNUSED_RESULT | | #define LWS_WARN_UNUSED_RESULT |
#define LWS_WARN_DEPRECATED | | #define LWS_WARN_DEPRECATED |
| | |
skipping to change at line 148 ¶ | | skipping to change at line 150 ¶ |
#else | | #else |
#define LWS_EXTERN extern __declspec(dllimport) | | #define LWS_EXTERN extern __declspec(dllimport) |
#endif | | #endif |
#else | | #else |
#define LWS_EXTERN | | #define LWS_EXTERN |
#endif | | #endif |
| | |
#define LWS_INVALID_FILE INVALID_HANDLE_VALUE | | #define LWS_INVALID_FILE INVALID_HANDLE_VALUE |
#define LWS_O_RDONLY _O_RDONLY | | #define LWS_O_RDONLY _O_RDONLY |
| | |
| | #if !defined(_MSC_VER) || _MSC_VER < 1900 /* Visual Studio 2015 already def
ines this in <stdio.h> */ |
#define lws_snprintf _snprintf | | #define lws_snprintf _snprintf |
| | #endif |
| | |
| | #ifndef __func__ |
| | #define __func__ __FUNCTION__ |
| | #endif |
| | |
#else /* NOT WIN32 */ | | #else /* NOT WIN32 */ |
#include <unistd.h> | | #include <unistd.h> |
| | |
#if defined(__NetBSD__) || defined(__FreeBSD__) | | #if defined(__NetBSD__) || defined(__FreeBSD__) |
#include <netinet/in.h> | | #include <netinet/in.h> |
#endif | | #endif |
| | |
#define LWS_INLINE inline | | #define LWS_INLINE inline |
#define LWS_O_RDONLY O_RDONLY | | #define LWS_O_RDONLY O_RDONLY |
| | |
#ifndef MBED_OPERATORS | | #if !defined(MBED_OPERATORS) && !defined(LWS_WITH_ESP8266) |
#include <poll.h> | | #include <poll.h> |
#include <netdb.h> | | #include <netdb.h> |
#define LWS_INVALID_FILE -1 | | #define LWS_INVALID_FILE -1 |
#else | | #else |
#define getdtablesize() (20) | | #define getdtablesize() (20) |
#define LWS_INVALID_FILE NULL | | #define LWS_INVALID_FILE NULL |
#endif | | #endif |
| | |
#if defined(__GNUC__) | | #if defined(__GNUC__) |
| | |
| | |
skipping to change at line 198 ¶ | | skipping to change at line 206 ¶ |
#define getdtablesize() sysconf(_SC_OPEN_MAX) | | #define getdtablesize() sysconf(_SC_OPEN_MAX) |
#endif | | #endif |
| | |
#endif | | #endif |
| | |
#ifdef LWS_USE_LIBEV | | #ifdef LWS_USE_LIBEV |
#include <ev.h> | | #include <ev.h> |
#endif /* LWS_USE_LIBEV */ | | #endif /* LWS_USE_LIBEV */ |
#ifdef LWS_USE_LIBUV | | #ifdef LWS_USE_LIBUV |
#include <uv.h> | | #include <uv.h> |
| | #ifdef LWS_HAVE_UV_VERSION_H |
| | #include <uv-version.h> |
| | #endif |
#endif /* LWS_USE_LIBUV */ | | #endif /* LWS_USE_LIBUV */ |
| | |
#ifndef LWS_EXTERN | | #ifndef LWS_EXTERN |
#define LWS_EXTERN extern | | #define LWS_EXTERN extern |
#endif | | #endif |
| | |
#ifdef _WIN32 | | #ifdef _WIN32 |
#define random rand | | #define random rand |
#else | | #else |
#include <sys/time.h> | | #include <sys/time.h> |
| | |
skipping to change at line 212 ¶ | | skipping to change at line 223 ¶ |
#endif | | #endif |
| | |
#ifdef _WIN32 | | #ifdef _WIN32 |
#define random rand | | #define random rand |
#else | | #else |
#include <sys/time.h> | | #include <sys/time.h> |
#include <unistd.h> | | #include <unistd.h> |
#endif | | #endif |
| | |
#ifdef LWS_OPENSSL_SUPPORT | | #ifdef LWS_OPENSSL_SUPPORT |
| | |
#ifdef USE_WOLFSSL | | #ifdef USE_WOLFSSL |
#ifdef USE_OLD_CYASSL | | #ifdef USE_OLD_CYASSL |
#include <cyassl/openssl/ssl.h> | | #include <cyassl/openssl/ssl.h> |
| | #include <cyassl/error-ssl.h> |
#else | | #else |
#include <wolfssl/openssl/ssl.h> | | #include <wolfssl/openssl/ssl.h> |
| | #include <wolfssl/error-ssl.h> |
#endif /* not USE_OLD_CYASSL */ | | #endif /* not USE_OLD_CYASSL */ |
#else | | #else |
| | #if defined(LWS_USE_POLARSSL) |
| | #include <polarssl/ssl.h> |
| | struct lws_polarssl_context { |
| | x509_crt ca; /**< ca */ |
| | x509_crt certificate; /**< cert */ |
| | rsa_context key; /**< key */ |
| | }; |
| | typedef struct lws_polarssl_context SSL_CTX; |
| | typedef ssl_context SSL; |
| | #else |
| | #if defined(LWS_USE_MBEDTLS) |
| | #include <mbedtls/ssl.h> |
| | #else |
#include <openssl/ssl.h> | | #include <openssl/ssl.h> |
| | #include <openssl/err.h> |
| | #endif /* not USE_MBEDTLS */ |
| | #endif /* not USE_POLARSSL */ |
#endif /* not USE_WOLFSSL */ | | #endif /* not USE_WOLFSSL */ |
#endif | | #endif |
| | |
#define CONTEXT_PORT_NO_LISTEN -1 | | #define CONTEXT_PORT_NO_LISTEN -1 |
| | |
| | /** \defgroup log Logging |
| | * |
| | * ##Logging |
| | * |
| | * Lws provides flexible and filterable logging facilities, which can be |
| | * used inside lws and in user code. |
| | * |
| | * Log categories may be individually filtered bitwise, and directed to bui |
| | lt-in |
| | * sinks for syslog-compatible logging, or a user-defined function. |
| | */ |
| | ///@{ |
| | |
enum lws_log_levels { | | enum lws_log_levels { |
LLL_ERR = 1 << 0, | | LLL_ERR = 1 << 0, |
LLL_WARN = 1 << 1, | | LLL_WARN = 1 << 1, |
LLL_NOTICE = 1 << 2, | | LLL_NOTICE = 1 << 2, |
LLL_INFO = 1 << 3, | | LLL_INFO = 1 << 3, |
LLL_DEBUG = 1 << 4, | | LLL_DEBUG = 1 << 4, |
LLL_PARSER = 1 << 5, | | LLL_PARSER = 1 << 5, |
LLL_HEADER = 1 << 6, | | LLL_HEADER = 1 << 6, |
LLL_EXT = 1 << 7, | | LLL_EXT = 1 << 7, |
LLL_CLIENT = 1 << 8, | | LLL_CLIENT = 1 << 8, |
LLL_LATENCY = 1 << 9, | | LLL_LATENCY = 1 << 9, |
| | |
LLL_COUNT = 10 /* set to count of valid flags */ | | LLL_COUNT = 10 /* set to count of valid flags */ |
}; | | }; |
| | |
LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...); | | LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...); |
LWS_VISIBLE LWS_EXTERN void _lws_logv(int filter, const char *format, va_li
st vl); | | LWS_VISIBLE LWS_EXTERN void _lws_logv(int filter, const char *format, va_li
st vl); |
| | /** |
| | * lwsl_timestamp: generate logging timestamp string |
| | * |
| | * \param level: logging level |
| | * \param p: char * buffer to take timestamp |
| | * \param len: length of p |
| | * |
| | * returns length written in p |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lwsl_timestamp(int level, char *p, int len); |
| | |
| | #define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__) |
| | |
| | #if !defined(LWS_WITH_NO_LOGS) |
/* notice, warn and log are always compiled in */ | | /* notice, warn and log are always compiled in */ |
#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) | | |
#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) | | #define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) |
#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__) | | #define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) |
| | #endif |
/* | | /* |
* weaker logging can be deselected at configure time using --disable-debu
g | | * weaker logging can be deselected at configure time using --disable-debu
g |
* that gets rid of the overhead of checking while keeping _warn and _err | | * that gets rid of the overhead of checking while keeping _warn and _err |
* active | | * active |
*/ | | */ |
#ifdef _DEBUG | | |
| | |
| | #if defined(LWS_WITH_ESP8266) |
| | #undef _DEBUG |
| | #endif |
| | |
| | #ifdef _DEBUG |
| | #if defined(LWS_WITH_NO_LOGS) |
| | /* notice, warn and log are always compiled in */ |
| | //#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__) |
| | #define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) |
| | #define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) |
| | #endif |
#define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__) | | #define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__) |
#define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__) | | #define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__) |
#define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__) | | #define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__) |
#define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__) | | #define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__) |
#define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__) | | #define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__) |
#define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__) | | #define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__) |
#define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__) | | #define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__) |
| | /** |
| | * lwsl_hexdump() - helper to hexdump a buffer (DEBUG builds only) |
| | * |
| | * \param buf: buffer start to dump |
| | * \param len: length of buffer to dump |
| | */ |
LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len); | | LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len); |
| | |
#else /* no debug */ | | #else /* no debug */ |
| | #if defined(LWS_WITH_NO_LOGS) |
#define lwsl_info(...) {} | | //#define lwsl_err(...) do {} while(0) |
#define lwsl_debug(...) {} | | #define lwsl_warn(...) do {} while(0) |
#define lwsl_parser(...) {} | | #define lwsl_notice(...) do {} while(0) |
#define lwsl_header(...) {} | | #endif |
#define lwsl_ext(...) {} | | #define lwsl_info(...) do {} while(0) |
#define lwsl_client(...) {} | | #define lwsl_debug(...) do {} while(0) |
#define lwsl_latency(...) {} | | #define lwsl_parser(...) do {} while(0) |
| | #define lwsl_header(...) do {} while(0) |
| | #define lwsl_ext(...) do {} while(0) |
| | #define lwsl_client(...) do {} while(0) |
| | #define lwsl_latency(...) do {} while(0) |
#define lwsl_hexdump(a, b) | | #define lwsl_hexdump(a, b) |
| | |
#endif | | #endif |
| | |
| | /** |
| | * lws_set_log_level() - Set the logging bitfield |
| | * \param level: OR together the LLL_ debug contexts you want output |
| | from |
| | * \param log_emit_function: NULL to leave it as it is, or a user-supplie |
| | d |
| | * function to perform log string emission instead of |
| | * the default stderr one. |
| | * |
| | * log level defaults to "err", "warn" and "notice" contexts enabled an |
| | d |
| | * emission on stderr. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN void |
| | lws_set_log_level(int level, |
| | void (*log_emit_function)(int level, const char *line)); |
| | |
| | /** |
| | * lwsl_emit_syslog() - helper log emit function writes to system log |
| | * |
| | * \param level: one of LLL_ log level indexes |
| | * \param line: log string |
| | * |
| | * You use this by passing the function pointer to lws_set_log_level(), to |
| | set |
| | * it as the log emit function, it is not called directly. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN void |
| | lwsl_emit_syslog(int level, const char *line); |
| | |
| | ///@} |
| | |
| | #include <stddef.h> |
| | |
| | #ifndef lws_container_of |
| | #define lws_container_of(P,T,M) ((T *)((char *)(P) - offsetof(T, M)) |
| | ) |
| | #endif |
| | |
struct lws; | | struct lws; |
| | #ifndef ARRAY_SIZE |
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) | | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) |
| | #endif |
| | |
/* api change list for user code to test against */ | | /* api change list for user code to test against */ |
| | |
#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_ARG | | #define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_ARG |
| | |
/* the struct lws_protocols has the id field present */ | | /* the struct lws_protocols has the id field present */ |
#define LWS_FEATURE_PROTOCOLS_HAS_ID_FIELD | | #define LWS_FEATURE_PROTOCOLS_HAS_ID_FIELD |
| | |
/* you can call lws_get_peer_write_allowance */ | | /* you can call lws_get_peer_write_allowance */ |
#define LWS_FEATURE_PROTOCOLS_HAS_PEER_WRITE_ALLOWANCE | | #define LWS_FEATURE_PROTOCOLS_HAS_PEER_WRITE_ALLOWANCE |
| | |
/* extra parameter introduced in 917f43ab821 */ | | /* extra parameter introduced in 917f43ab821 */ |
#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_LEN | | #define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_LEN |
| | |
/* File operations stuff exists */ | | /* File operations stuff exists */ |
#define LWS_FEATURE_FOPS | | #define LWS_FEATURE_FOPS |
| | |
| | #if defined(_WIN32) |
| | typedef SOCKET lws_sockfd_type; |
| | typedef HANDLE lws_filefd_type; |
| | #define lws_sockfd_valid(sfd) (!!sfd) |
| | struct lws_pollfd { |
| | lws_sockfd_type fd; /**< file descriptor */ |
| | SHORT events; /**< which events to respond to */ |
| | SHORT revents; /**< which events happened */ |
| | }; |
| | #define LWS_POLLHUP (FD_CLOSE) |
| | #define LWS_POLLIN (FD_READ | FD_ACCEPT) |
| | #define LWS_POLLOUT (FD_WRITE) |
| | #else |
| | |
| | #if defined(MBED_OPERATORS) |
| | /* it's a class lws_conn * */ |
| | typedef void * lws_sockfd_type; |
| | typedef void * lws_filefd_type; |
| | #define lws_sockfd_valid(sfd) (!!sfd) |
| | struct pollfd { |
| | lws_sockfd_type fd; /**< fd related to */ |
| | short events; /**< which POLL... events to respond to */ |
| | short revents; /**< which POLL... events occurred */ |
| | }; |
| | #define POLLIN 0x0001 |
| | #define POLLPRI 0x0002 |
| | #define POLLOUT 0x0004 |
| | #define POLLERR 0x0008 |
| | #define POLLHUP 0x0010 |
| | #define POLLNVAL 0x0020 |
| | |
| | struct lws; |
| | |
| | void * mbed3_create_tcp_stream_socket(void); |
| | void mbed3_delete_tcp_stream_socket(void *sockfd); |
| | void mbed3_tcp_stream_bind(void *sock, int port, struct lws *); |
| | void mbed3_tcp_stream_accept(void *sock, struct lws *); |
| | #else |
| | #if defined(LWS_WITH_ESP8266) |
| | |
| | #include <user_interface.h> |
| | #include <espconn.h> |
| | |
| | typedef struct espconn * lws_sockfd_type; |
| | typedef void * lws_filefd_type; |
| | #define lws_sockfd_valid(sfd) (!!sfd) |
| | struct pollfd { |
| | lws_sockfd_type fd; /**< fd related to */ |
| | short events; /**< which POLL... events to respond to */ |
| | short revents; /**< which POLL... events occurred */ |
| | }; |
| | #define POLLIN 0x0001 |
| | #define POLLPRI 0x0002 |
| | #define POLLOUT 0x0004 |
| | #define POLLERR 0x0008 |
| | #define POLLHUP 0x0010 |
| | #define POLLNVAL 0x0020 |
| | |
| | struct lws_vhost; |
| | |
| | lws_sockfd_type esp8266_create_tcp_listen_socket(struct lws_vhost *vh); |
| | void esp8266_tcp_stream_accept(lws_sockfd_type fd, struct lws *wsi); |
| | |
| | #include <os_type.h> |
| | #include <osapi.h> |
| | #include "ets_sys.h" |
| | |
| | int ets_snprintf(char *str, size_t size, const char *format, ...); |
| | #define snprintf ets_snprintf |
| | |
| | typedef os_timer_t uv_timer_t; |
| | typedef void uv_cb_t(uv_timer_t *); |
| | |
| | void os_timer_disarm(void *); |
| | void os_timer_setfn(os_timer_t *, os_timer_func_t *, void *); |
| | |
| | void ets_timer_arm_new(os_timer_t *, int, int, int); |
| | |
| | //void os_timer_arm(os_timer_t *, int, int); |
| | |
| | #define UV_VERSION_MAJOR 1 |
| | |
| | #define lws_uv_getloop(a, b) (NULL) |
| | |
| | static inline void uv_timer_init(void *l, uv_timer_t *t) |
| | { |
| | (void)l; |
| | memset(t, 0, sizeof(*t)); |
| | os_timer_disarm(t); |
| | } |
| | |
| | static inline void uv_timer_start(uv_timer_t *t, uv_cb_t *cb, int first, in |
| | t rep) |
| | { |
| | os_timer_setfn(t, (os_timer_func_t *)cb, t); |
| | /* ms, repeat */ |
| | os_timer_arm(t, first, !!rep); |
| | } |
| | |
| | static inline void uv_timer_stop(uv_timer_t *t) |
| | { |
| | os_timer_disarm(t); |
| | } |
| | |
| | #else |
| | typedef int lws_sockfd_type; |
| | typedef int lws_filefd_type; |
| | #define lws_sockfd_valid(sfd) (sfd >= 0) |
| | #endif |
| | #endif |
| | |
| | #define lws_pollfd pollfd |
| | #define LWS_POLLHUP (POLLHUP|POLLERR) |
| | #define LWS_POLLIN (POLLIN) |
| | #define LWS_POLLOUT (POLLOUT) |
| | #endif |
| | |
| | /** struct lws_pollargs - argument structure for all external poll related |
| | calls |
| | * 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 */ |
| | }; |
| | |
| | struct lws_tokens; |
| | struct lws_token_limits; |
| | |
| | /*! \defgroup wsclose Websocket Close |
| | * |
| | * ##Websocket close frame control |
| | * |
| | * When we close a ws connection, we can send a reason code and a short |
| | * UTF-8 description back with the close packet. |
| | */ |
| | ///@{ |
| | |
/* | | /* |
* NOTE: These public enums are part of the abi. If you want to add one, | | * 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. | | * add it at where specified so existing users are unaffected. |
*/ | | */ |
enum lws_context_options { | | /** enum lws_close_status - RFC6455 close status codes */ |
LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = (1 << 1), | | enum lws_close_status { |
LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = (1 << 2), | | LWS_CLOSE_STATUS_NOSTATUS = 0, |
LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = (1 << 3), | | LWS_CLOSE_STATUS_NORMAL = 1000, |
LWS_SERVER_OPTION_LIBEV = (1 << 4), | | /**< 1000 indicates a normal closure, meaning that the purpose for |
LWS_SERVER_OPTION_DISABLE_IPV6 = (1 << 5), | | which the connection was established has been fulfilled. */ |
LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = (1 << 6), | | LWS_CLOSE_STATUS_GOINGAWAY = 1001, |
LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED = (1 << 7), | | /**< 1001 indicates that an endpoint is "going away", such as a serv |
LWS_SERVER_OPTION_VALIDATE_UTF8 = (1 << 8), | | er |
LWS_SERVER_OPTION_SSL_ECDH = (1 << 9), | | going down or a browser having navigated away from a page. */ |
LWS_SERVER_OPTION_LIBUV = (1 << 10), | | LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002, |
| | /**< 1002 indicates that an endpoint is terminating the connection d |
| | ue |
| | to a protocol error. */ |
| | LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003, |
| | /**< 1003 indicates that an endpoint is terminating the connection |
| | because it has received a type of data it cannot accept (e.g., an |
| | endpoint that understands only text data MAY send this if it |
| | receives a binary message). */ |
| | LWS_CLOSE_STATUS_RESERVED = 1004, |
| | /**< Reserved. The specific meaning might be defined in the future. |
| | */ |
| | LWS_CLOSE_STATUS_NO_STATUS = 1005, |
| | /**< 1005 is a reserved value and MUST NOT be set as a status code i |
| | n a |
| | Close control frame by an endpoint. It is designated for use in |
| | applications expecting a status code to indicate that no status |
| | code was actually present. */ |
| | LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006, |
| | /**< 1006 is a reserved value and MUST NOT be set as a status code i |
| | n a |
| | Close control frame by an endpoint. It is designated for use in |
| | applications expecting a status code to indicate that the |
| | connection was closed abnormally, e.g., without sending or |
| | receiving a Close control frame. */ |
| | LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007, |
| | /**< 1007 indicates that an endpoint is terminating the connection |
| | because it has received data within a message that was not |
| | consistent with the type of the message (e.g., non-UTF-8 [RFC3629] |
| | data within a text message). */ |
| | LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008, |
| | /**< 1008 indicates that an endpoint is terminating the connection |
| | because it has received a message that violates its policy. This |
| | is a generic status code that can be returned when there is no |
| | other more suitable status code (e.g., 1003 or 1009) or if there |
| | is a need to hide specific details about the policy. */ |
| | LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009, |
| | /**< 1009 indicates that an endpoint is terminating the connection |
| | because it has received a message that is too big for it to |
| | process. */ |
| | LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010, |
| | /**< 1010 indicates that an endpoint (client) is terminating the |
| | connection because it has expected the server to negotiate one or |
| | more extension, but the server didn't return them in the response |
| | message of the WebSocket handshake. The list of extensions that |
| | are needed SHOULD appear in the /reason/ part of the Close frame. |
| | Note that this status code is not used by the server, because it |
| | can fail the WebSocket handshake instead */ |
| | LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011, |
| | /**< 1011 indicates that a server is terminating the connection beca |
| | use |
| | it encountered an unexpected condition that prevented it from |
| | fulfilling the request. */ |
| | LWS_CLOSE_STATUS_TLS_FAILURE = 1015, |
| | /**< 1015 is a reserved value and MUST NOT be set as a status code i |
| | n a |
| | Close control frame by an endpoint. It is designated for use in |
| | applications expecting a status code to indicate that the |
| | connection was closed due to a failure to perform a TLS handshake |
| | (e.g., the server certificate can't be verified). */ |
| | |
/****** add new things just above ---^ ******/ | | /****** add new things just above ---^ ******/ |
| | |
| | LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY = 9999, |
}; | | }; |
| | |
| | /** |
| | * 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. |
| | * |
| | * \param wsi: The websocket connection to set the close reason on |
| | * \param status: A valid close status from websocket standard |
| | * \param buf: NULL or buffer containing up to 124 bytes of auxiliary data |
| | * \param len: Length of data in \param 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); |
| | |
| | ///@} |
| | |
| | struct lws; |
| | struct lws_context; |
| | /* needed even with extensions disabled for create context */ |
| | struct lws_extension; |
| | |
| | /*! \defgroup usercb User Callback |
| | * |
| | * ##User protocol callback |
| | * |
| | * The protocol callback is the primary way lws interacts with |
| | * user code. For one of a list of a few dozen reasons the callback gets |
| | * called at some event to be handled. |
| | * |
| | * All of the events can be ignored, returning 0 is taken as "OK" and retur |
| | ning |
| | * nonzero in most cases indicates that the connection should be closed. |
| | */ |
| | ///@{ |
| | |
/* | | /* |
* NOTE: These public enums are part of the abi. If you want to add one, | | * 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. | | * add it at where specified so existing users are unaffected. |
*/ | | */ |
| | /** enum lws_callback_reasons - reason you're getting a protocol callback *
/ |
enum lws_callback_reasons { | | enum lws_callback_reasons { |
LWS_CALLBACK_ESTABLISHED = 0, | | LWS_CALLBACK_ESTABLISHED = 0, |
| | /**< (VH) after the server completes a handshake with an incoming |
| | * client. If you built the library with ssl support, in is a |
| | * pointer to the ssl struct associated with the connection or NULL. |
| | */ |
LWS_CALLBACK_CLIENT_CONNECTION_ERROR = 1, | | LWS_CALLBACK_CLIENT_CONNECTION_ERROR = 1, |
| | /**< the request client connection has been unable to complete a |
| | * handshake with the remote server. If in is non-NULL, you can |
| | * find an error string of length len where it points to |
| | * |
| | * Diagnostic strings that may be returned include |
| | * |
| | * "getaddrinfo (ipv6) failed" |
| | * "unknown address family" |
| | * "getaddrinfo (ipv4) failed" |
| | * "set socket opts failed" |
| | * "insert wsi failed" |
| | * "lws_ssl_client_connect1 failed" |
| | * "lws_ssl_client_connect2 failed" |
| | * "Peer hung up" |
| | * "read failed" |
| | * "HS: URI missing" |
| | * "HS: Redirect code but no Location" |
| | * "HS: URI did not parse" |
| | * "HS: Redirect failed" |
| | * "HS: Server did not return 200" |
| | * "HS: OOM" |
| | * "HS: disallowed by client filter" |
| | * "HS: disallowed at ESTABLISHED" |
| | * "HS: ACCEPT missing" |
| | * "HS: ws upgrade response not 101" |
| | * "HS: UPGRADE missing" |
| | * "HS: Upgrade to something other than websocket" |
| | * "HS: CONNECTION missing" |
| | * "HS: UPGRADE malformed" |
| | * "HS: PROTOCOL malformed" |
| | * "HS: Cannot match protocol" |
| | * "HS: EXT: list too big" |
| | * "HS: EXT: failed setting defaults" |
| | * "HS: EXT: failed parsing defaults" |
| | * "HS: EXT: failed parsing options" |
| | * "HS: EXT: Rejects server options" |
| | * "HS: EXT: unknown ext" |
| | * "HS: Accept hash wrong" |
| | * "HS: Rejected by filter cb" |
| | * "HS: OOM" |
| | * "HS: SO_SNDBUF failed" |
| | * "HS: Rejected at CLIENT_ESTABLISHED" |
| | */ |
LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH = 2, | | LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH = 2, |
| | /**< this is the last chance for the client user code to examine the |
| | * http headers and decide to reject the connection. If the |
| | * content in the headers is interesting to the |
| | * client (url, etc) it needs to copy it out at |
| | * this point since it will be destroyed before |
| | * the CLIENT_ESTABLISHED call */ |
LWS_CALLBACK_CLIENT_ESTABLISHED = 3, | | LWS_CALLBACK_CLIENT_ESTABLISHED = 3, |
| | /**< after your client connection completed |
| | * a handshake with the remote server */ |
LWS_CALLBACK_CLOSED = 4, | | LWS_CALLBACK_CLOSED = 4, |
| | /**< when the websocket session ends */ |
LWS_CALLBACK_CLOSED_HTTP = 5, | | LWS_CALLBACK_CLOSED_HTTP = 5, |
| | /**< when a HTTP (non-websocket) session ends */ |
LWS_CALLBACK_RECEIVE = 6, | | LWS_CALLBACK_RECEIVE = 6, |
| | /**< data has appeared for this server endpoint from a |
| | * remote client, it can be found at *in and is |
| | * len bytes long */ |
LWS_CALLBACK_RECEIVE_PONG = 7, | | LWS_CALLBACK_RECEIVE_PONG = 7, |
| | /**< servers receive PONG packets with this callback reason */ |
LWS_CALLBACK_CLIENT_RECEIVE = 8, | | LWS_CALLBACK_CLIENT_RECEIVE = 8, |
| | /**< data has appeared from the server for the client connection, it |
| | * can be found at *in and is len bytes long */ |
LWS_CALLBACK_CLIENT_RECEIVE_PONG = 9, | | LWS_CALLBACK_CLIENT_RECEIVE_PONG = 9, |
| | /**< clients receive PONG packets with this callback reason */ |
LWS_CALLBACK_CLIENT_WRITEABLE = 10, | | LWS_CALLBACK_CLIENT_WRITEABLE = 10, |
| | /**< If you call lws_callback_on_writable() on a connection, you wi |
| | ll |
| | * get one of these callbacks 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. Notice that CLIENTs get LWS_CALLBACK_CLIENT_WRITEABLE |
| | * and servers get LWS_CALLBACK_SERVER_WRITEABLE. */ |
LWS_CALLBACK_SERVER_WRITEABLE = 11, | | LWS_CALLBACK_SERVER_WRITEABLE = 11, |
| | /**< See LWS_CALLBACK_CLIENT_WRITEABLE */ |
LWS_CALLBACK_HTTP = 12, | | LWS_CALLBACK_HTTP = 12, |
| | /**< an http request has come from a client that is not |
| | * 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. |
| | * in points to the URI path requested and |
| | * lws_serve_http_file() makes it very |
| | * simple to send back a file to the client. |
| | * Normally after sending the file you are done |
| | * with the http connection, since the rest of the |
| | * activity will come by websockets from the script |
| | * that was delivered by http, so you will want to |
| | * return 1; to close and free up the connection. */ |
LWS_CALLBACK_HTTP_BODY = 13, | | LWS_CALLBACK_HTTP_BODY = 13, |
| | /**< the next len bytes data from the http |
| | * request body HTTP connection is now available in in. */ |
LWS_CALLBACK_HTTP_BODY_COMPLETION = 14, | | LWS_CALLBACK_HTTP_BODY_COMPLETION = 14, |
| | /**< the expected amount of http request body has been delivered */ |
LWS_CALLBACK_HTTP_FILE_COMPLETION = 15, | | LWS_CALLBACK_HTTP_FILE_COMPLETION = 15, |
| | /**< a file requested to be sent down http link has completed. */ |
LWS_CALLBACK_HTTP_WRITEABLE = 16, | | LWS_CALLBACK_HTTP_WRITEABLE = 16, |
| | /**< you can write more down the http protocol link now. */ |
LWS_CALLBACK_FILTER_NETWORK_CONNECTION = 17, | | LWS_CALLBACK_FILTER_NETWORK_CONNECTION = 17, |
| | /**< called when a client connects to |
| | * the server at network level; the connection is accepted but then |
| | * passed to this callback to decide whether to hang up immediately |
| | * or not, based on the client IP. in contains the connection |
| | * socket's descriptor. Since the client connection information is |
| | * not available yet, wsi still pointing to the main server socket. |
| | * Return non-zero to terminate the connection before sending or |
| | * 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_FILTER_HTTP_CONNECTION = 18, | | LWS_CALLBACK_FILTER_HTTP_CONNECTION = 18, |
| | /**< called when the request has |
| | * been received and parsed from the client, but the response is |
| | * not sent yet. Return non-zero to disallow the connection. |
| | * user is a pointer to the connection user space allocation, |
| | * in is the URI, eg, "/" |
| | * In your handler you can use the public APIs |
| | * lws_hdr_total_length() / lws_hdr_copy() to access all of the |
| | * headers using the header enums lws_token_indexes from |
| | * libwebsockets.h to check for and read the supported header |
| | * presence and content before deciding to allow the http |
| | * connection to proceed or to kill the connection. */ |
LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED = 19, | | LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED = 19, |
| | /**< A new client just had |
| | * been connected, accepted, and instantiated into the pool. This |
| | * callback allows setting any relevant property to it. Because this |
| | * happens immediately after the instantiation of a new client, |
| | * there's no websocket protocol selected yet so this callback is |
| | * issued only to protocol 0. Only wsi is defined, pointing to the |
| | * new client, and the return value is ignored. */ |
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION = 20, | | LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION = 20, |
| | /**< called when the handshake has |
| | * been received and parsed from the client, but the response is |
| | * not sent yet. Return non-zero to disallow the connection. |
| | * user is a pointer to the connection user space allocation, |
| | * in is the requested protocol name |
| | * In your handler you can use the public APIs |
| | * lws_hdr_total_length() / lws_hdr_copy() to access all of the |
| | * headers using the header enums lws_token_indexes from |
| | * libwebsockets.h to check for and read the supported header |
| | * presence and content before deciding to allow the handshake |
| | * to proceed or to kill the connection. */ |
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS = 21, | | LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS = 21, |
| | /**< if configured for |
| | * including OpenSSL support, this callback allows your user code |
| | * to perform extra SSL_CTX_load_verify_locations() or similar |
| | * calls to direct OpenSSL where to find certificates the client |
| | * can use to confirm the remote server identity. user is the |
| | * OpenSSL SSL_CTX* */ |
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS = 22, | | LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS = 22, |
| | /**< if configured for |
| | * including OpenSSL support, this callback allows your user code |
| | * to load extra certifcates into the server which allow it to |
| | * verify the validity of certificates returned by clients. user |
| | * is the server's OpenSSL SSL_CTX* */ |
LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION = 23, | | LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION = 23, |
| | /**< if the libwebsockets vhost was created with the option |
| | * LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this |
| | * callback is generated during OpenSSL verification of the cert |
| | * sent from the client. It is sent to protocol[0] callback as |
| | * no protocol has been negotiated on the connection yet. |
| | * Notice that the libwebsockets context and wsi are both NULL |
| | * during this callback. See |
| | * http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html |
| | * to understand more detail about the OpenSSL callback that |
| | * generates this libwebsockets callback and the meanings of the |
| | * arguments passed. In this callback, user is the x509_ctx, |
| | * in is the ssl pointer and len is preverify_ok |
| | * Notice that this callback maintains libwebsocket return |
| | * conventions, return 0 to mean the cert is OK or 1 to fail it. |
| | * This also means that if you don't handle this callback then |
| | * the default callback action of returning 0 allows the client |
| | * certificates. */ |
LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER = 24, | | LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER = 24, |
| | /**< this callback happens |
| | * when a client handshake is being compiled. user is NULL, |
| | * in is a char **, it's pointing to a char * which holds the |
| | * next location in the header buffer where you can add |
| | * headers, and len is the remaining space in the header buffer, |
| | * which is typically some hundreds of bytes. So, to add a canned |
| | * cookie, your handler code might look similar to: |
| | * |
| | * char **p = (char **)in; |
| | * |
| | * if (len < 100) |
| | * return 1; |
| | * |
| | * *p += sprintf(*p, "Cookie: a=b\x0d\x0a"); |
| | * |
| | * return 0; |
| | * |
| | * Notice if you add anything, you just have to take care about |
| | * the CRLF on the line you added. Obviously this callback is |
| | * optional, if you don't handle it everything is fine. |
| | * |
| | * Notice the callback is coming to protocols[0] all the time, |
| | * because there is no specific protocol negotiated yet. */ |
LWS_CALLBACK_CONFIRM_EXTENSION_OKAY = 25, | | LWS_CALLBACK_CONFIRM_EXTENSION_OKAY = 25, |
| | /**< When the server handshake code |
| | * sees that it does support a requested extension, before |
| | * accepting the extension by additing to the list sent back to |
| | * the client it gives this callback just to check that it's okay |
| | * to use that extension. It calls back to the requested protocol |
| | * and with in being the extension name, len is 0 and user is |
| | * valid. Note though at this time the ESTABLISHED callback hasn't |
| | * happened yet so if you initialize user content there, user |
| | * content during this callback might not be useful for anything. |
| | * Notice this callback comes to protocols[0]. */ |
LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED = 26, | | LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED = 26, |
| | /**< When a client |
| | * connection is being prepared to start a handshake to a server, |
| | * each supported extension is checked with protocols[0] callback |
| | * with this reason, giving the user code a chance to suppress the |
| | * claim to support that extension by returning non-zero. If |
| | * unhandled, by default 0 will be returned and the extension |
| | * support included in the header to the server. Notice this |
| | * callback comes to protocols[0]. */ |
LWS_CALLBACK_PROTOCOL_INIT = 27, | | LWS_CALLBACK_PROTOCOL_INIT = 27, |
| | /**< One-time call per protocol, per-vhost using it, so it can |
| | * do initial setup / allocations etc */ |
LWS_CALLBACK_PROTOCOL_DESTROY = 28, | | LWS_CALLBACK_PROTOCOL_DESTROY = 28, |
LWS_CALLBACK_WSI_CREATE /* always protocol[0] */ = 29, | | /**< One-time call per protocol, per-vhost using it, indicating |
LWS_CALLBACK_WSI_DESTROY /* always protocol[0] */ = 30, | | * this protocol won't get used at all after this callback, the |
| | * vhost is getting destroyed. Take the opportunity to |
| | * deallocate everything that was allocated by the protocol. */ |
| | LWS_CALLBACK_WSI_CREATE = 29, |
| | /**< outermost (earliest) wsi create notification to protocols[0] */ |
| | LWS_CALLBACK_WSI_DESTROY = 30, |
| | /**< outermost (latest) wsi destroy notification to protocols[0] */ |
LWS_CALLBACK_GET_THREAD_ID = 31, | | LWS_CALLBACK_GET_THREAD_ID = 31, |
| | /**< lws can accept callback when writable requests from other |
| | * threads, if you implement this callback and return an opaque |
| | * current thread ID integer. */ |
| | |
/* external poll() management support */ | | /* external poll() management support */ |
LWS_CALLBACK_ADD_POLL_FD = 32, | | LWS_CALLBACK_ADD_POLL_FD = 32, |
| | /**< lws normally deals with its poll() or other event loop |
| | * internally, but in the case you are integrating with another |
| | * server you will need to have lws sockets share a |
| | * polling array with the other server. This and the other |
| | * POLL_FD related callbacks let you put your specialized |
| | * poll array interface code in the callback for protocol 0, the |
| | * first protocol you support, usually the HTTP protocol in the |
| | * serving case. |
| | * This callback happens when a socket needs to be |
| | * added to the polling loop: in points to a struct |
| | * lws_pollargs; the fd member of the struct is the file |
| | * descriptor, and events contains the active events |
| | * |
| | * If you are using the internal lws polling / event loop |
| | * you can just ignore these callbacks. */ |
LWS_CALLBACK_DEL_POLL_FD = 33, | | LWS_CALLBACK_DEL_POLL_FD = 33, |
| | /**< This callback happens when a socket descriptor |
| | * needs to be removed from an external polling array. in is |
| | * again the struct lws_pollargs containing the fd member |
| | * to be removed. If you are using the internal polling |
| | * loop, you can just ignore it. */ |
LWS_CALLBACK_CHANGE_MODE_POLL_FD = 34, | | LWS_CALLBACK_CHANGE_MODE_POLL_FD = 34, |
| | /**< This callback happens when lws wants to modify the events for |
| | * a connection. |
| | * in is the struct lws_pollargs with the fd to change. |
| | * The new event mask is in events member and the old mask is in |
| | * the prev_events member. |
| | * If you are using the internal polling loop, you can just ignore |
| | * it. */ |
LWS_CALLBACK_LOCK_POLL = 35, | | LWS_CALLBACK_LOCK_POLL = 35, |
| | /**< These allow the external poll changes driven |
| | * by lws to participate in an external thread locking |
| | * scheme around the changes, so the whole thing is threadsafe. |
| | * These are called around three activities in the library, |
| | * - inserting a new wsi in the wsi / fd table (len=1) |
| | * - deleting a wsi from the wsi / fd table (len=1) |
| | * - changing a wsi's POLLIN/OUT state (len=0) |
| | * Locking and unlocking external synchronization objects when |
| | * 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_UNLOCK_POLL = 36, | | LWS_CALLBACK_UNLOCK_POLL = 36, |
| | /**< See LWS_CALLBACK_LOCK_POLL, ignore if using lws internal poll *
/ |
| | |
LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY = 37, | | LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY = 37, |
| | /**< if configured for 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 access |
| | ible |
| | * by the OS, for example if it is stored on a smartcard. |
| | * user is the server's OpenSSL SSL_CTX* */ |
LWS_CALLBACK_WS_PEER_INITIATED_CLOSE = 38, | | LWS_CALLBACK_WS_PEER_INITIATED_CLOSE = 38, |
| | /**< 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- readab |
| | le 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_CALLBACK_WS_EXT_DEFAULTS = 39, | | LWS_CALLBACK_WS_EXT_DEFAULTS = 39, |
| | /**< */ |
| | |
/****** add new things just above ---^ ******/ | | LWS_CALLBACK_CGI = 40, |
| | /**< */ |
LWS_CALLBACK_USER = 1000, /* user code can use any including / above | | LWS_CALLBACK_CGI_TERMINATED = 41, |
*/ | | /**< */ |
}; | | LWS_CALLBACK_CGI_STDIN_DATA = 42, |
| | /**< */ |
#if defined(_WIN32) | | LWS_CALLBACK_CGI_STDIN_COMPLETED = 43, |
typedef SOCKET lws_sockfd_type; | | /**< */ |
typedef HANDLE lws_filefd_type; | | LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP = 44, |
#define lws_sockfd_valid(sfd) (!!sfd) | | /**< */ |
struct lws_pollfd { | | LWS_CALLBACK_CLOSED_CLIENT_HTTP = 45, |
lws_sockfd_type fd; | | /**< */ |
SHORT events; | | LWS_CALLBACK_RECEIVE_CLIENT_HTTP = 46, |
SHORT revents; | | /**< */ |
}; | | LWS_CALLBACK_COMPLETED_CLIENT_HTTP = 47, |
#else | | /**< */ |
| | LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ = 48, |
#if defined(MBED_OPERATORS) | | /**< */ |
/* it's a class lws_conn * */ | | LWS_CALLBACK_HTTP_BIND_PROTOCOL = 49, |
typedef void * lws_sockfd_type; | | /**< */ |
typedef void * lws_filefd_type; | | LWS_CALLBACK_HTTP_DROP_PROTOCOL = 50, |
#define lws_sockfd_valid(sfd) (!!sfd) | | /**< */ |
struct pollfd { | | LWS_CALLBACK_CHECK_ACCESS_RIGHTS = 51, |
lws_sockfd_type fd; | | /**< */ |
short events; | | LWS_CALLBACK_PROCESS_HTML = 52, |
short revents; | | /**< */ |
}; | | LWS_CALLBACK_ADD_HEADERS = 53, |
#define POLLIN 0x0001 | | /**< */ |
#define POLLPRI 0x0002 | | LWS_CALLBACK_SESSION_INFO = 54, |
#define POLLOUT 0x0004 | | /**< */ |
#define POLLERR 0x0008 | | |
#define POLLHUP 0x0010 | | |
#define POLLNVAL 0x0020 | | |
| | |
struct lws; | | |
| | |
void * mbed3_create_tcp_stream_socket(void); | | LWS_CALLBACK_GS_EVENT = 55, |
void mbed3_delete_tcp_stream_socket(void *sockfd); | | /**< */ |
void mbed3_tcp_stream_bind(void *sock, int port, struct lws *); | | LWS_CALLBACK_HTTP_PMO = 56, |
void mbed3_tcp_stream_accept(void *sock, struct lws *); | | /**< per-mount options for this connection, called before |
#else | | * the normal LWS_CALLBACK_HTTP when the mount has per-mount |
typedef int lws_sockfd_type; | | * options |
typedef int lws_filefd_type; | | */ |
#define lws_sockfd_valid(sfd) (sfd >= 0) | | LWS_CALLBACK_CLIENT_HTTP_WRITEABLE = 57, |
#endif | | /**< when doing an HTTP type client connection, you can call |
| | * lws_client_http_body_pending(wsi, 1) from |
| | * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER to get these callback |
| | s |
| | * sending the HTTP headers. |
| | * |
| | * From this callback, when you have sent everything, you should let |
| | * lws know by calling lws_client_http_body_pending(wsi, 0) |
| | */ |
| | |
#define lws_pollfd pollfd | | /****** add new things just above ---^ ******/ |
#endif | | |
| | |
/* argument structure for all external poll related calls | | LWS_CALLBACK_USER = 1000, |
* passed in via 'in' | | /**< user code can use any including / above without fear of clashe |
*/ | | s */ |
struct lws_pollargs { | | |
lws_sockfd_type fd; /* applicable socket descriptor */ | | |
int events; /* the new event mask */ | | |
int prev_events; /* the previous event mask */ | | |
}; | | }; |
| | |
/** | | /** |
* struct lws_plat_file_ops - Platform-specific file operations | | * typedef lws_callback_function() - User server actions |
| | * \param wsi: Opaque websocket instance pointer |
| | * \param reason: The reason for the call |
| | * \param user: Pointer to per-session user data allocated by librar |
| | y |
| | * \param in: Pointer used for some callback reasons |
| | * \param len: Length set for some callback reasons |
* | | * |
* These provide platform-agnostic ways to deal with filesystem access in t | | * This callback is the way the user controls what is served. All the |
he | | * protocol detail is hidden and handled by the library. |
* library and in the user code. | | |
* | | * |
* @open: Open file (always binary access if plat supports it) | | * For each connection / session there is user data allocated that is |
* filelen is filled on exit to be the length of the f | | * pointed to by "user". You set the size of this user data area when |
ile | | * the library is initialized with lws_create_server. |
* flags should be set to O_RDONLY or O_RDWR | | |
* @close: Close file | | |
* @seek_cur: Seek from current position | | |
* @read: Read fron file *amount is set on exit to amount read | | |
* @write: Write to file *amount is set on exit as amount writt | | |
en | | |
*/ | | */ |
struct lws_plat_file_ops { | | typedef int |
lws_filefd_type (*open)(struct lws *wsi, const char *filename, | | lws_callback_function(struct lws *wsi, enum lws_callback_reasons reason, |
unsigned long *filelen, int flags); | | void *user, void *in, size_t len); |
int (*close)(struct lws *wsi, lws_filefd_type fd); | | ///@} |
unsigned long (*seek_cur)(struct lws *wsi, lws_filefd_type fd, | | |
long offset_from_cur_pos); | | |
int (*read)(struct lws *wsi, lws_filefd_type fd, unsigned long *amou | | |
nt, | | |
unsigned char *buf, unsigned long len); | | |
int (*write)(struct lws *wsi, lws_filefd_type fd, unsigned long *amo | | |
unt, | | |
unsigned char *buf, unsigned long len); | | |
| | |
/* Add new things just above here ---^ | | /*! \defgroup extensions |
* This is part of the ABI, don't needlessly break compatibility */ | | * |
}; | | * ##Extension releated functions |
| | * |
| | * Ws defines optional extensions, lws provides the ability to implement t |
| | hese |
| | * in user code if so desired. |
| | * |
| | * We provide one extensions permessage-deflate. |
| | */ |
| | ///@{ |
| | |
/* | | /* |
* NOTE: These public enums are part of the abi. If you want to add one, | | * 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. | | * add it at where specified so existing users are unaffected. |
*/ | | */ |
enum lws_extension_callback_reasons { | | enum lws_extension_callback_reasons { |
LWS_EXT_CB_SERVER_CONTEXT_CONSTRUCT = 0, | | LWS_EXT_CB_SERVER_CONTEXT_CONSTRUCT = 0, |
LWS_EXT_CB_CLIENT_CONTEXT_CONSTRUCT = 1, | | LWS_EXT_CB_CLIENT_CONTEXT_CONSTRUCT = 1, |
LWS_EXT_CB_SERVER_CONTEXT_DESTRUCT = 2, | | LWS_EXT_CB_SERVER_CONTEXT_DESTRUCT = 2, |
LWS_EXT_CB_CLIENT_CONTEXT_DESTRUCT = 3, | | LWS_EXT_CB_CLIENT_CONTEXT_DESTRUCT = 3, |
| | |
skipping to change at line 480 ¶ | | skipping to change at line 1081 ¶ |
LWS_EXT_CB_EXTENDED_PAYLOAD_RX = 16, | | LWS_EXT_CB_EXTENDED_PAYLOAD_RX = 16, |
LWS_EXT_CB_CAN_PROXY_CLIENT_CONNECTION = 17, | | LWS_EXT_CB_CAN_PROXY_CLIENT_CONNECTION = 17, |
LWS_EXT_CB_1HZ = 18, | | LWS_EXT_CB_1HZ = 18, |
LWS_EXT_CB_REQUEST_ON_WRITEABLE = 19, | | LWS_EXT_CB_REQUEST_ON_WRITEABLE = 19, |
LWS_EXT_CB_IS_WRITEABLE = 20, | | LWS_EXT_CB_IS_WRITEABLE = 20, |
LWS_EXT_CB_PAYLOAD_TX = 21, | | LWS_EXT_CB_PAYLOAD_TX = 21, |
LWS_EXT_CB_PAYLOAD_RX = 22, | | LWS_EXT_CB_PAYLOAD_RX = 22, |
LWS_EXT_CB_OPTION_DEFAULT = 23, | | LWS_EXT_CB_OPTION_DEFAULT = 23, |
LWS_EXT_CB_OPTION_SET = 24, | | LWS_EXT_CB_OPTION_SET = 24, |
LWS_EXT_CB_OPTION_CONFIRM = 25, | | LWS_EXT_CB_OPTION_CONFIRM = 25, |
| | LWS_EXT_CB_NAMED_OPTION_SET = 26, |
| | |
/****** add new things just above ---^ ******/ | | /****** add new things just above ---^ ******/ |
}; | | }; |
| | |
| | /** enum lws_ext_options_types */ |
| | enum lws_ext_options_types { |
| | EXTARG_NONE, /**< does not take an argument */ |
| | EXTARG_DEC, /**< requires a decimal argument */ |
| | EXTARG_OPT_DEC /**< may have an optional decimal argument */ |
| | |
| | /* 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 ar |
| | e |
| | * used in the negotiation at ws upgrade time. |
| | * The helper function lws_ext_parse_options() |
| | * uses these to generate callbacks */ |
| | struct lws_ext_options { |
| | const char *name; /**< Option name, eg, "server_no_context_takeover" |
| | */ |
| | enum lws_ext_options_types type; /**< What kind of args the option c |
| | an take */ |
| | |
| | /* Add new things just above here ---^ |
| | * This is part of the ABI, don't needlessly break compatibility */ |
| | }; |
| | |
| | /** struct lws_ext_option_arg */ |
| | struct lws_ext_option_arg { |
| | const char *option_name; /**< may be NULL, option_index used then */ |
| | int option_index; /**< argument ordinal to use if option_name missin |
| | g */ |
| | const char *start; /**< value */ |
| | int len; /**< length of value */ |
| | }; |
| | |
| | /** |
| | * typedef lws_extension_callback_function() - Hooks to allow extensions to |
| | operate |
| | * \param context: Websockets context |
| | * \param ext: This extension |
| | * \param wsi: Opaque websocket instance pointer |
| | * \param reason: The reason for the call |
| | * \param user: Pointer to ptr to per-session user data allocated by |
| | library |
| | * \param in: Pointer used for some callback reasons |
| | * \param len: Length set for some callback reasons |
| | * |
| | * Each extension that is active on a particular connection receives |
| | * callbacks during the connection lifetime to allow the extension to |
| | * operate on websocket data and manage itself. |
| | * |
| | * Libwebsockets takes care of allocating and freeing "user" memory for |
| | * each active extension on each connection. That is what is pointed t |
| | o |
| | * by the user parameter. |
| | * |
| | * 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 acceptin |
| | g |
| | * the connection with this extension active. This gives the |
| | * extension a chance to initialize its connection context foun |
| | d |
| | * in user. |
| | * |
| | * LWS_EXT_CB_CLIENT_CONSTRUCT: same as LWS_EXT_CB_CONSTRUCT |
| | * but called when client is instantiating this extension. Som |
| | e |
| | * extensions will work the same on client and server side and |
| | then |
| | * you can just merge handlers for both CONSTRUCTS. |
| | * |
| | * LWS_EXT_CB_DESTROY: called when the connection the extension was |
| | * being used on is about to be closed and deallocated. It's t |
| | he |
| | * 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 yo |
| | u |
| | * are in client or server instantiation context. |
| | * |
| | * 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 |
| | * extension's private connection context data, in is pointing |
| | * to an lws_tokens struct, it consists of a char * pointer cal |
| | led |
| | * token, and an int called token_len. At entry, these are |
| | * set to point to the received buffer and set to the content |
| | * length. If the extension will grow the content, it should u |
| | se |
| | * 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_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 w |
| | ill |
| | * 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 a |
| | nd |
| | * set the lws_tokens token pointer to it. |
| | * |
| | * LWS_EXT_CB_ARGS_VALIDATE: |
| | */ |
| | typedef int |
| | lws_extension_callback_function(struct lws_context *context, |
| | const struct lws_extension *ext, struct lws *w |
| | si, |
| | enum lws_extension_callback_reasons reason, |
| | void *user, void *in, size_t len); |
| | |
| | /** struct lws_extension - An extension we support */ |
| | struct lws_extension { |
| | const char *name; /**< Formal extension name, eg, "permessage-deflat |
| | e" */ |
| | lws_extension_callback_function *callback; /**< Service callback */ |
| | const char *client_offer; /**< String containing exts and options cl |
| | ient offers */ |
| | |
| | /* Add new things just above here ---^ |
| | * This is part of the ABI, don't needlessly break compatibility */ |
| | }; |
| | |
| | /** |
| | * lws_set_extension_option(): set extension option if possible |
| | * |
| | * \param wsi: websocket connection |
| | * \param ext_name: name of ext, like "permessage-deflate" |
| | * \param opt_name: name of option, like "rx_buf_size" |
| | * \param opt_val: value to set option to |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_set_extension_option(struct lws *wsi, const char *ext_name, |
| | const char *opt_name, const char *opt_val); |
| | |
| | #ifndef LWS_NO_EXTENSIONS |
| | /* lws_get_internal_extensions() - DEPRECATED |
| | * |
| | * \Deprecated There is no longer a set internal extensions table. The tab |
| | le 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_ext_parse_options() - deal with parsing negotiated extension options |
| | * |
| | * \param ext: related extension struct |
| | * \param wsi: websocket connection |
| | * \param ext_user: per-connection extension private data |
| | * \param opts: list of supported options |
| | * \param o: option string to parse |
| | * \param len: length |
| | */ |
| | 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_extension_callback_pm_deflate() - extension for RFC7692 |
| | * |
| | * \param context: lws context |
| | * \param ext: related lws_extension struct |
| | * \param wsi: websocket connection |
| | * \param reason: incoming callback reason |
| | * \param user: per-connection extension private data |
| | * \param in: pointer parameter |
| | * \param len: length parameter |
| | * |
| | * Built-in callback implementing RFC7692 permessage-deflate |
| | */ |
| | LWS_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); |
| | |
| | /* |
| | * The internal exts are part of the public abi |
| | * If we add more extensions, publish the callback here ------v |
| | */ |
| | ///@} |
| | |
| | /*! \defgroup Protocols-and-Plugins Protocols and Plugins |
| | * \ingroup lwsapi |
| | * |
| | * ##Protocol and protocol plugin -related apis |
| | * |
| | * Protocols bind ws protocol names to a custom callback specific to that |
| | * protocol implementaion. |
| | * |
| | * A list of protocols can be passed in at context creation time, but it is |
| | * also legal to leave that NULL and add the protocols and their callback c |
| | ode |
| | * using plugins. |
| | * |
| | * Plugins are much preferable compared to cut and pasting code into an |
| | * application each time, since they can be used standalone. |
| | */ |
| | ///@{ |
| | /** struct lws_protocols - List of protocols and handlers client or ser |
| | ver |
| | * supports. */ |
| | |
| | struct lws_protocols { |
| | const char *name; |
| | /**< Protocol name that must match the one given in the client |
| | * Javascript new WebSocket(url, 'protocol') name. */ |
| | lws_callback_function *callback; |
| | /**< The service callback used for this protocol. It allows the |
| | * service action for an entire protocol to be encapsulated in |
| | * the protocol-specific callback */ |
| | size_t per_session_data_size; |
| | /**< Each new connection using this protocol gets |
| | * 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 */ |
| | size_t rx_buffer_size; |
| | /**< lws allocates this much space for rx data and informs callback |
| | * when something came. Due to rx flow control, the callback may no |
| | t |
| | * be able to consume it all without having to return to the event |
| | * loop. That is supported in lws. |
| | * |
| | * This also controls how much may be sent at once at the moment, |
| | * although this is likely to change. |
| | */ |
| | unsigned int id; |
| | /**< ignored by lws, but useful to contain user information bound |
| | * to the selected protocol. For example if this protocol was |
| | * called "myprotocol-v2", you might set id to 2, and the user |
| | * code that acts differently according to the version can do so by |
| | * switch (wsi->protocol->id), user code might use some bits as |
| | * capability flags based on selected protocol version, etc. */ |
| | void *user; /**< ignored by lws, but user code can pass a pointer |
| | here it can later access from the protocol callback |
| | */ |
| | |
| | /* Add new things just above here ---^ |
| | * This is part of the ABI, don't needlessly break compatibility */ |
| | }; |
| | |
| | struct lws_vhost; |
| | |
| | /** |
| | * lws_vhost_name_to_protocol() - get vhost's protocol object from its name |
| | * |
| | * \param vh: vhost to search |
| | * \param name: protocol name |
| | * |
| | * Returns NULL or a pointer to the vhost's protocol of the requested name |
| | */ |
| | LWS_VISIBLE LWS_EXTERN const struct lws_protocols * |
| | lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name); |
| | |
| | /** |
| | * lws_get_protocol() - Returns a protocol pointer from a websocket |
| | * connection. |
| | * \param wsi: pointer to struct websocket you want to know the protocol of |
| | * |
| | * |
| | * Some apis can act on all live connections of a given protocol, |
| | * this is how you can get a pointer to the active protocol if needed. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN const struct lws_protocols * |
| | lws_get_protocol(struct lws *wsi); |
| | |
| | /** lws_protocol_get() - deprecated: use lws_get_protocol */ |
| | LWS_VISIBLE LWS_EXTERN const struct lws_protocols * |
| | lws_protocol_get(struct lws *wsi) LWS_WARN_DEPRECATED; |
| | |
| | /** |
| | * lws_protocol_vh_priv_zalloc() - Allocate and zero down a protocol's per- |
| | vhost |
| | * storage |
| | * \param vhost: vhost the instance is related to |
| | * \param prot: protocol the instance is related to |
| | * \param size: bytes to allocate |
| | * |
| | * Protocols often find it useful to allocate a per-vhost struct, this is a |
| | * helper to be called in the per-vhost init LWS_CALLBACK_PROTOCOL_INIT |
| | */ |
| | LWS_VISIBLE LWS_EXTERN void * |
| | lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_proto |
| | cols *prot, |
| | int size); |
| | |
| | /** |
| | * lws_protocol_vh_priv_get() - retreive a protocol's per-vhost storage |
| | * |
| | * \param vhost: vhost the instance is related to |
| | * \param prot: protocol the instance is related to |
| | * |
| | * Recover a pointer to the allocated per-vhost storage for the protocol cr |
| | eated |
| | * by lws_protocol_vh_priv_zalloc() earlier |
| | */ |
| | LWS_VISIBLE LWS_EXTERN void * |
| | lws_protocol_vh_priv_get(struct lws_vhost *vhost, const struct lws_protocol |
| | s *prot); |
| | |
| | /** |
| | * lws_finalize_startup() - drop initial process privileges |
| | * |
| | * \param context: lws context |
| | * |
| | * This is called after the end of the vhost protocol initializations, but |
| | * you may choose to call it earlier |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_finalize_startup(struct lws_context *context); |
| | |
| | #ifdef LWS_WITH_PLUGINS |
| | |
| | /* PLUGINS implies LIBUV */ |
| | |
| | #define LWS_PLUGIN_API_MAGIC 180 |
| | |
| | /** struct lws_plugin_capability - how a plugin introduces itself to lws */ |
| | struct lws_plugin_capability { |
| | unsigned int api_magic; /**< caller fills this in, plugin fills rest |
| | */ |
| | const struct lws_protocols *protocols; /**< array of supported proto |
| | cols provided by plugin */ |
| | int count_protocols; /**< how many protocols */ |
| | const struct lws_extension *extensions; /**< array of extensions pro |
| | vided by plugin */ |
| | int count_extensions; /**< how many extensions */ |
| | }; |
| | |
| | typedef int (*lws_plugin_init_func)(struct lws_context *, |
| | struct lws_plugin_capability *); |
| | typedef int (*lws_plugin_destroy_func)(struct lws_context *); |
| | |
| | /** struct lws_plugin */ |
| | struct lws_plugin { |
| | struct lws_plugin *list; /**< linked list */ |
| | #if (UV_VERSION_MAJOR > 0) |
| | uv_lib_t lib; /**< shared library pointer */ |
| | #else |
| | void *l; /**< so we can compile on ancient libuv */ |
| | #endif |
| | char name[64]; /**< name of the plugin */ |
| | struct lws_plugin_capability caps; /**< plugin capabilities */ |
| | }; |
| | |
| | #endif |
| | |
| | ///@} |
| | |
| | /*! \defgroup generic-sessions plugin: generic-sessions |
| | * \ingroup Protocols-and-Plugins |
| | * |
| | * ##Plugin Generic-sessions related |
| | * |
| | * generic-sessions plugin provides a reusable, generic session and login / |
| | * register / forgot password framework including email verification. |
| | */ |
| | ///@{ |
| | |
| | #define LWSGS_EMAIL_CONTENT_SIZE 16384 |
| | /**< Maximum size of email we might send */ |
| | |
| | /* SHA-1 binary and hexified versions */ |
| | /** typedef struct lwsgw_hash_bin */ |
| | typedef struct { unsigned char bin[20]; /**< binary representation of hash |
| | */} lwsgw_hash_bin; |
| | /** typedef struct lwsgw_hash */ |
| | typedef struct { char id[41]; /**< ascii hex representation of hash */ } lw |
| | sgw_hash; |
| | |
| | /** enum lwsgs_auth_bits */ |
| | enum lwsgs_auth_bits { |
| | LWSGS_AUTH_LOGGED_IN = 1, /**< user is logged in as somebody */ |
| | LWSGS_AUTH_ADMIN = 2, /**< logged in as the admin user */ |
| | LWSGS_AUTH_VERIFIED = 4, /**< user has verified his email */ |
| | LWSGS_AUTH_FORGOT_FLOW = 8, /**< he just completed "forgot passw |
| | ord" flow */ |
| | }; |
| | |
| | /** struct lws_session_info - information about user session status */ |
| | struct lws_session_info { |
| | char username[32]; /**< username logged in as, or empty string */ |
| | char email[100]; /**< email address associated with login, or empty |
| | string */ |
| | char ip[72]; /**< ip address session was started from */ |
| | unsigned int mask; /**< access rights mask associated with session |
| | * see enum lwsgs_auth_bits */ |
| | char session[42]; /**< session id string, usable as opaque uid when |
| | not logged in */ |
| | }; |
| | |
| | /** enum lws_gs_event */ |
| | enum lws_gs_event { |
| | LWSGSE_CREATED, /**< a new user was created */ |
| | LWSGSE_DELETED /**< an existing user was deleted */ |
| | }; |
| | |
| | /** struct lws_gs_event_args */ |
| | struct lws_gs_event_args { |
| | enum lws_gs_event event; /**< which event happened */ |
| | const char *username; /**< which username the event happened to */ |
| | const char *email; /**< the email address of that user */ |
| | }; |
| | |
| | ///@} |
| | |
| | /*! \defgroup context-and-vhost |
| | * \ingroup lwsapi |
| | * |
| | * ##Context and Vhost releated functions |
| | * |
| | * LWS requires that there is one context, in which you may define multipl |
| | e |
| | * vhosts. Each vhost is a virtual host, with either its own listen port |
| | * or sharing an existing one. Each vhost has its own SSL context that ca |
| | n |
| | * be set up individually or left disabled. |
| | * |
| | * If you don't care about multiple "site" support, you can ignore it and |
| | * lws will create a single default vhost at context creation time. |
| | */ |
| | ///@{ |
| | |
/* | | /* |
* NOTE: These public enums are part of the abi. If you want to add one, | | * 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. | | * add it at where specified so existing users are unaffected. |
*/ | | */ |
enum lws_write_protocol { | | |
LWS_WRITE_TEXT = 0, | | |
LWS_WRITE_BINARY = 1, | | |
LWS_WRITE_CONTINUATION = 2, | | |
LWS_WRITE_HTTP = 3, | | |
| | |
/* special 04+ opcodes */ | | /** enum lws_context_options - context and vhost options */ |
| | enum lws_context_options { |
| | LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = (1 << 1) | |
| | (1 << 12), |
| | /**< (VH) Don't allow the connection unless the client has a |
| | * client cert that we recognize; provides |
| | * LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT */ |
| | LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = (1 << 2), |
| | /**< (CTX) Don't try to get the server's hostname */ |
| | LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = (1 << 3) | |
| | (1 << 12), |
| | /**< (VH) Allow non-SSL (plaintext) connections on the same |
| | * port as SSL is listening... undermines the security of SSL; |
| | * provides LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT */ |
| | LWS_SERVER_OPTION_LIBEV = (1 << 4), |
| | /**< (CTX) Use libev event loop */ |
| | LWS_SERVER_OPTION_DISABLE_IPV6 = (1 << 5), |
| | /**< (VH) Disable IPV6 support */ |
| | LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = (1 << 6), |
| | /**< (VH) Don't load OS CA certs, you will need to load your |
| | * own CA cert(s) */ |
| | LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED = (1 << 7), |
| | /**< (VH) Accept connections with no valid Cert (eg, selfsigned) */ |
| | LWS_SERVER_OPTION_VALIDATE_UTF8 = (1 << 8), |
| | /**< (VH) Check UT-8 correctness */ |
| | LWS_SERVER_OPTION_SSL_ECDH = (1 << 9) | |
| | (1 << 12), |
| | /**< (VH) initialize ECDH ciphers */ |
| | LWS_SERVER_OPTION_LIBUV = (1 << 10), |
| | /**< (CTX) Use libuv event loop */ |
| | LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS = (1 << 11) |
| | | |
| | (1 << 12), |
| | /**< (VH) Use http redirect to force http to https |
| | * (deprecated: use mount redirection) */ |
| | LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT = (1 << 12), |
| | /**< (CTX) Initialize the SSL library at all */ |
| | LWS_SERVER_OPTION_EXPLICIT_VHOSTS = (1 << 13), |
| | /**< (CTX) Only create the context when calling context |
| | * create api, implies user code will create its own vhosts */ |
| | LWS_SERVER_OPTION_UNIX_SOCK = (1 << 14), |
| | /**< (VH) Use Unix socket */ |
| | LWS_SERVER_OPTION_STS = (1 << 15), |
| | /**< (VH) Send Strict Transport Security header, making |
| | * clients subsequently go to https even if user asked for http */ |
| | LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY = (1 << 16), |
| | /**< (VH) Enable LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE to take effect |
| | */ |
| | LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE = (1 << 17), |
| | /**< (VH) if set, only ipv6 allowed on the vhost */ |
| | LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN = (1 << 18), |
| | /**< (CTX) Libuv only: Do not spin on SIGSEGV / SIGFPE. A segfault |
| | * normally makes the lib spin so you can attach a debugger to it |
| | * even if it happened without a debugger in place. You can disable |
| | * that by giving this option. |
| | */ |
| | |
/* LWS_WRITE_CLOSE is handled by lws_close_reason() */ | | /****** add new things just above ---^ ******/ |
LWS_WRITE_PING = 5, | | }; |
LWS_WRITE_PONG = 6, | | |
| | |
/* Same as write_http but we know this write ends the transaction */ | | #define lws_check_opt(c, f) (((c) & (f)) == (f)) |
LWS_WRITE_HTTP_FINAL = 7, | | |
| | |
/* HTTP2 */ | | /** struct lws_context_creation_info - parameters to create context and /or |
| | vhost with |
| | * |
| | * This is also used to create vhosts.... if LWS_SERVER_OPTION_EXPLICIT_VHO |
| | STS |
| | * is not given, then for backwards compatibility one vhost is created at |
| | * context-creation time using the info from this struct. |
| | * |
| | * If LWS_SERVER_OPTION_EXPLICIT_VHOSTS is given, then no vhosts are create |
| | d |
| | * at the same time as the context, they are expected to be created afterwa |
| | rds. |
| | */ |
| | struct lws_context_creation_info { |
| | int port; |
| | /**< VHOST: 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 |
| | * not running a websocket server at all but just using it as a |
| | * client */ |
| | const char *iface; |
| | /**< VHOST: NULL to bind the listen socket to all interfaces, or the |
| | * interface name, eg, "eth2" |
| | * If options specifies LWS_SERVER_OPTION_UNIX_SOCK, this member is |
| | * the pathname of a UNIX domain socket. you can use the UNIX domain |
| | * sockets in abstract namespace, by prepending an at symbol to the |
| | * socket name. */ |
| | const struct lws_protocols *protocols; |
| | /**< VHOST: Array of structures listing supported protocols and a pr |
| | otocol- |
| | * specific callback for each one. The list is ended with an |
| | * entry that has a NULL callback pointer. */ |
| | const struct lws_extension *extensions; |
| | /**< VHOST: NULL or array of lws_extension structs listing the |
| | * extensions this context supports. */ |
| | const struct lws_token_limits *token_limits; |
| | /**< CONTEXT: NULL or struct lws_token_limits pointer which is initi |
| | alized |
| | * with a token length limit for each possible WSI_TOKEN_ */ |
| | const char *ssl_private_key_password; |
| | /**< VHOST: NULL or the passphrase needed for the private key */ |
| | const char *ssl_cert_filepath; |
| | /**< VHOST: 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 */ |
| | const char *ssl_private_key_filepath; |
| | /**< VHOST: 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 */ |
| | const char *ssl_ca_filepath; |
| | /**< VHOST: CA certificate filepath or NULL */ |
| | const char *ssl_cipher_list; |
| | /**< VHOST: List of valid ciphers to use (eg, |
| | * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" |
| | * or you can leave it as NULL to get "DEFAULT" */ |
| | const char *http_proxy_address; |
| | /**< VHOST: If non-NULL, attempts to proxy via the given address. |
| | * If proxy auth is required, use format "username:password\@server: |
| | port" */ |
| | unsigned int http_proxy_port; |
| | /**< VHOST: If http_proxy_address was non-NULL, uses this port */ |
| | int gid; |
| | /**< CONTEXT: group id to change to after setting listen socket, or |
| | -1. */ |
| | int uid; |
| | /**< CONTEXT: user id to change to after setting listen socket, or - |
| | 1. */ |
| | unsigned int options; |
| | /**< VHOST + CONTEXT: 0, or LWS_SERVER_OPTION_... bitfields */ |
| | void *user; |
| | /**< CONTEXT: optional user pointer that can be recovered via the co |
| | ntext |
| | * pointer using lws_context_user */ |
| | int ka_time; |
| | /**< CONTEXT: 0 for no TCP keepalive, otherwise apply this keepalive |
| | * timeout to all libwebsocket sockets, client or server */ |
| | int ka_probes; |
| | /**< CONTEXT: if ka_time was nonzero, after the timeout expires how |
| | many |
| | * times to try to get a response from the peer before giving up |
| | * and killing the connection */ |
| | int ka_interval; |
| | /**< CONTEXT: if ka_time was nonzero, how long to wait before each k |
| | a_probes |
| | * attempt */ |
| | #ifdef LWS_OPENSSL_SUPPORT |
| | SSL_CTX *provided_client_ssl_ctx; |
| | /**< CONTEXT: If non-null, swap out libwebsockets ssl |
| | * implementation for the one provided by provided_ssl_ctx. |
| | * Libwebsockets no longer is responsible for freeing the conte |
| | xt |
| | * if this option is selected. */ |
| | #else /* maintain structure layout either way */ |
| | void *provided_client_ssl_ctx; /**< dummy if ssl disabled */ |
| | #endif |
| | |
LWS_WRITE_HTTP_HEADERS = 8, | | short max_http_header_data; |
| | /**< CONTEXT: The max amount of header payload that can be handled |
| | * in an http request (unrecognized header payload is dropped) */ |
| | short max_http_header_pool; |
| | /**< CONTEXT: 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. */ |
| | |
/****** add new things just above ---^ ******/ | | unsigned int count_threads; |
| | /**< CONTEXT: how many contexts to create in an array, 0 = 1 */ |
| | unsigned int fd_limit_per_thread; |
| | /**< CONTEXT: 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. */ |
| | unsigned int timeout_secs; |
| | /**< VHOST: 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. */ |
| | const char *ecdh_curve; |
| | /**< VHOST: if NULL, defaults to initializing server with "prime256v |
| | 1" */ |
| | const char *vhost_name; |
| | /**< VHOST: name of vhost, must match external DNS name used to |
| | * access the site, like "warmcat.com" as it's used to match |
| | * Host: header and / or SNI name for SSL. */ |
| | const char * const *plugin_dirs; |
| | /**< CONTEXT: NULL, or NULL-terminated array of directories to |
| | * scan for lws protocol plugins at context creation time */ |
| | const struct lws_protocol_vhost_options *pvo; |
| | /**< VHOST: pointer to optional linked list of per-vhost |
| | * options made accessible to protocols */ |
| | int keepalive_timeout; |
| | /**< VHOST: (default = 0 = 60s) seconds to allow remote |
| | * client to hold on to an idle HTTP/1.1 connection */ |
| | const char *log_filepath; |
| | /**< VHOST: filepath to append logs to... this is opened before |
| | * any dropping of initial privileges */ |
| | const struct lws_http_mount *mounts; |
| | /**< VHOST: optional linked list of mounts for this vhost */ |
| | const char *server_string; |
| | /**< CONTEXT: string used in HTTP headers to identify server |
| | * software, if NULL, "libwebsockets". */ |
| | unsigned int pt_serv_buf_size; |
| | /**< CONTEXT: 0 = default of 4096. This buffer is used by |
| | * various service related features including file serving, it |
| | * defines the max chunk of file that can be sent at once. |
| | * At the risk of lws having to buffer failed large sends, it |
| | * can be increased to, eg, 128KiB to improve throughput. */ |
| | unsigned int max_http_header_data2; |
| | /**< CONTEXT: if max_http_header_data is 0 and this |
| | * is nonzero, this will be used in place of the default. It's |
| | * like this for compatibility with the original short version, |
| | * this is unsigned int length. */ |
| | long ssl_options_set; |
| | /**< VHOST: Any bits set here will be set as SSL options */ |
| | long ssl_options_clear; |
| | /**< VHOST: Any bits set here will be cleared as SSL options */ |
| | unsigned short ws_ping_pong_interval; |
| | /**< CONTEXT: 0 for none, else interval in seconds between sending |
| | * PINGs on idle websocket connections. When the PING is sent, |
| | * the PONG must come within the normal timeout_secs timeout period |
| | * or the connection will be dropped. |
| | * Any RX or TX traffic on the connection restarts the interval time |
| | r, |
| | * so a connection which always sends or receives something at inter |
| | vals |
| | * less than the interval given here will never send PINGs / expect |
| | * PONGs. Conversely as soon as the ws connection is established, a |
| | n |
| | * idle connection will do the PING / PONG roundtrip as soon as |
| | * ws_ping_pong_interval seconds has passed without traffic |
| | */ |
| | const struct lws_protocol_vhost_options *headers; |
| | /**< VHOST: pointer to optional linked list of per-vhost |
| | * canned headers that are added to server responses */ |
| | |
/* flags */ | | /* 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. |
| | */ |
| | |
LWS_WRITE_NO_FIN = 0x40, | | void *_unused[8]; /**< dummy */ |
/* | | }; |
* client packet payload goes out on wire unmunged | | |
* only useful for security tests since normal servers cannot | | /** |
* decode the content if used | | * lws_create_context() - Create the websocket handler |
| | * \param info: pointer to struct with parameters |
| | * |
| | * This function creates the listening socket (if serving) and takes ca |
| | re |
| | * of all initialization in one step. |
| | * |
| | * If option LWS_SERVER_OPTION_EXPLICIT_VHOSTS is given, no vhost is |
| | * created; you're expected to create your own vhosts afterwards using |
| | * lws_create_vhost(). Otherwise a vhost named "default" is also creat |
| | ed |
| | * using the information in the vhost-related members, for compatibilit |
| | y. |
| | * |
| | * After initialization, it returns a struct lws_context * that |
| | * represents this server. After calling, user code needs to take care |
| | * of calling lws_service() with the context pointer to get the |
| | * server's sockets serviced. This must be done in the same process |
| | * context as the initialization call. |
| | * |
| | * The protocol callback functions are called for a handful of events |
| | * including http requests coming in, websocket connections becoming |
| | * established, and data arriving; it's also called periodically to all |
| | ow |
| | * async transmission. |
| | * |
| | * HTTP requests are sent always to the FIRST protocol in protocol, sin |
| | ce |
| | * at that time websocket protocol has not been negotiated. Other |
| | * protocols after the first one never see any HTTP callack activity. |
| | * |
| | * The server created is a simple http server by default; part of the |
| | * websocket standard is upgrading this http connection to a websocket |
| | one. |
| | * |
| | * This allows the same server to provide files like scripts and favico |
| | n / |
| | * images or whatever over http and dynamic data over websockets all in |
| | * one place; they're all handled in the user callback. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN struct lws_context * |
| | lws_create_context(struct lws_context_creation_info *info); |
| | |
| | /** |
| | * lws_context_destroy() - Destroy the websocket context |
| | * \param context: Websocket context |
| | * |
| | * This function closes any active connections and then frees the |
| | * context. After calling this, any further use of the context is |
| | * undefined. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN void |
| | lws_context_destroy(struct lws_context *context); |
| | |
| | /** |
| | * lws_set_proxy() - Setups proxy to lws_context. |
| | * \param vhost: pointer to struct lws_vhost you want set proxy for |
| | * \param proxy: pointer to c string containing proxy in format address:por |
| | t |
| | * |
| | * Returns 0 if proxy string was parsed and proxy was setup. |
| | * Returns -1 if proxy is NULL or has incorrect format. |
| | * |
| | * This is only required if your OS does not provide the http_proxy |
| | * environment variable (eg, OSX) |
| | * |
| | * IMPORTANT! You should call this function right after creation of the |
| | * lws_context and before call to connect. If you call this |
| | * function after connect behavior is undefined. |
| | * This function will override proxy settings made on lws_context |
| | * creation with genenv() call. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_set_proxy(struct lws_vhost *vhost, const char *proxy); |
| | |
| | struct lws_vhost; |
| | |
| | /** |
| | * lws_create_vhost() - Create a vhost (virtual server context) |
| | * \param context: pointer to result of lws_create_context() |
| | * \param info: pointer to struct with parameters |
| | * |
| | * This function creates a virtual server (vhost) using the vhost-related |
| | * members of the info struct. You can create many vhosts inside one conte |
| | xt |
| | * if you created the context with the option LWS_SERVER_OPTION_EXPLICIT_VH |
| | OSTS |
| | */ |
| | LWS_EXTERN LWS_VISIBLE struct lws_vhost * |
| | lws_create_vhost(struct lws_context *context, |
| | struct lws_context_creation_info *info); |
| | |
| | /** |
| | * lwsws_get_config_globals() - Parse a JSON server config file |
| | * \param info: pointer to struct with parameters |
| | * \param d: filepath of the config file |
| | * \param config_strings: storage for the config strings extracted from JSO |
| | N, |
| | * the pointer is incremented as strings are stored |
| | * \param len: pointer to the remaining length left in config_strin |
| | gs |
| | * the value is decremented as strings are stored |
| | * |
| | * This function prepares a n lws_context_creation_info struct with global |
| | * settings from a file d. |
| | * |
| | * Requires CMake option LWS_WITH_LEJP_CONF to have been enabled |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lwsws_get_config_globals(struct lws_context_creation_info *info, const char |
| | *d, |
| | char **config_strings, int *len); |
| | |
| | /** |
| | * lwsws_get_config_vhosts() - Create vhosts from a JSON server config file |
| | * \param context: pointer to result of lws_create_context() |
| | * \param info: pointer to struct with parameters |
| | * \param d: filepath of the config file |
| | * \param config_strings: storage for the config strings extracted from JSO |
| | N, |
| | * the pointer is incremented as strings are stored |
| | * \param len: pointer to the remaining length left in config_strin |
| | gs |
| | * the value is decremented as strings are stored |
| | * |
| | * This function creates vhosts into a context according to the settings in |
| | *JSON files found in directory d. |
| | * |
| | * Requires CMake option LWS_WITH_LEJP_CONF to have been enabled |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lwsws_get_config_vhosts(struct lws_context *context, |
| | struct lws_context_creation_info *info, const char * |
| | d, |
| | char **config_strings, int *len); |
| | |
| | /** lws_vhost_get() - \deprecated deprecated: use lws_get_vhost() */ |
| | LWS_VISIBLE LWS_EXTERN struct lws_vhost * |
| | lws_vhost_get(struct lws *wsi) LWS_WARN_DEPRECATED; |
| | |
| | /** |
| | * lws_get_vhost() - return the vhost a wsi belongs to |
| | * |
| | * \param wsi: which connection |
| | */ |
| | LWS_VISIBLE LWS_EXTERN struct lws_vhost * |
| | lws_get_vhost(struct lws *wsi); |
| | |
| | /** |
| | * lws_json_dump_vhost() - describe vhost state and stats in JSON |
| | * |
| | * \param vh: the vhost |
| | * \param buf: buffer to fill with JSON |
| | * \param len: max length of buf |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len); |
| | |
| | /** |
| | * lws_json_dump_context() - describe context state and stats in JSON |
| | * |
| | * \param context: the context |
| | * \param buf: buffer to fill with JSON |
| | * \param len: max length of buf |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_json_dump_context(const struct lws_context *context, char *buf, int len |
| | ); |
| | |
| | /** |
| | * lws_context_user() - get the user data associated with the context |
| | * \param context: Websocket context |
| | * |
| | * This returns the optional user allocation that can be attached to |
| | * the context the sockets live in at context_create time. It's a way |
| | * to let all sockets serviced in the same context share data without |
| | * using globals statics in the user code. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN void * |
| | lws_context_user(struct lws_context *context); |
| | |
| | /*! \defgroup vhost-mounts Vhost mounts and options |
| | * \ingroup context-and-vhost-creation |
| | * |
| | * ##Vhost mounts and options |
| | */ |
| | ///@{ |
| | /** struct lws_protocol_vhost_options - linked list of per-vhost protocol |
| | * name=value options |
| | * |
| | * This provides a general way to attach a linked-list of name=value pairs, |
| | * which can also have an optional child link-list using the options member |
| | . |
| | */ |
| | struct lws_protocol_vhost_options { |
| | const struct lws_protocol_vhost_options *next; /**< linked list */ |
| | const struct lws_protocol_vhost_options *options; /**< child linked- |
| | list of more options for this node */ |
| | const char *name; /**< name of name=value pair */ |
| | const char *value; /**< value of name=value pair */ |
| | }; |
| | |
| | /** enum lws_mount_protocols |
| | * This specifies the mount protocol for a mountpoint, whether it is to be |
| | * served from a filesystem, or it is a cgi etc. |
| | */ |
| | enum lws_mount_protocols { |
| | LWSMPRO_HTTP = 0, /**< not supported yet */ |
| | LWSMPRO_HTTPS = 1, /**< not supported yet */ |
| | LWSMPRO_FILE = 2, /**< serve from filesystem directory */ |
| | LWSMPRO_CGI = 3, /**< pass to CGI to handle */ |
| | LWSMPRO_REDIR_HTTP = 4, /**< redirect to http:// url */ |
| | LWSMPRO_REDIR_HTTPS = 5, /**< redirect to https:// url */ |
| | LWSMPRO_CALLBACK = 6, /**< hand by named protocol's callback |
| | */ |
| | }; |
| | |
| | /** struct lws_http_mount |
| | * |
| | * arguments for mounting something in a vhost's url namespace |
| | */ |
| | struct lws_http_mount { |
| | const struct lws_http_mount *mount_next; |
| | /**< pointer to next struct lws_http_mount */ |
| | const char *mountpoint; |
| | /**< mountpoint in http pathspace, eg, "/" */ |
| | const char *origin; |
| | /**< path to be mounted, eg, "/var/www/warmcat.com" */ |
| | const char *def; |
| | /**< default target, eg, "index.html" */ |
| | const char *protocol; |
| | /**<"protocol-name" to handle mount */ |
| | |
| | const struct lws_protocol_vhost_options *cgienv; |
| | /**< optional linked-list of cgi options. These are created |
| | * as environment variables for the cgi process |
*/ | | */ |
LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80 | | const struct lws_protocol_vhost_options *extra_mimetypes; |
| | /**< optional linked-list of mimetype mappings */ |
| | const struct lws_protocol_vhost_options *interpret; |
| | /**< optional linked-list of files to be interpreted */ |
| | |
| | int cgi_timeout; |
| | /**< seconds cgi is allowed to live, if cgi://mount type */ |
| | int cache_max_age; |
| | /**< max-age for reuse of client cache of files, seconds */ |
| | unsigned int auth_mask; |
| | /**< bits set here must be set for authorized client session */ |
| | |
| | unsigned int cache_reusable:1; /**< set if client cache may reuse th |
| | is */ |
| | unsigned int cache_revalidate:1; /**< set if client cache should rev |
| | alidate on use */ |
| | unsigned int cache_intermediaries:1; /**< set if intermediaries are |
| | allowed to cache */ |
| | |
| | unsigned char origin_protocol; /**< one of enum lws_mount_protocols |
| | */ |
| | unsigned char mountpoint_len; /**< length of mountpoint string */ |
}; | | }; |
| | ///@} |
| | ///@} |
| | |
/* | | /*! \defgroup client |
| | * \ingroup lwsapi |
| | * |
| | * ##Client releated functions |
| | * */ |
| | ///@{ |
| | |
| | /** enum lws_client_connect_ssl_connection_flags - flags that may be used |
| | * with struct lws_client_connect_info ssl_connection member to control if |
| | * and how SSL checks apply to the client connection being created |
| | */ |
| | |
| | enum lws_client_connect_ssl_connection_flags { |
| | LCCSCF_USE_SSL = (1 << 0), |
| | LCCSCF_ALLOW_SELFSIGNED = (1 << 1), |
| | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK = (1 << 2) |
| | }; |
| | |
| | /** struct lws_client_connect_info - parameters to connect with when using |
| | * lws_client_connect_via_info() */ |
| | |
| | struct lws_client_connect_info { |
| | struct lws_context *context; |
| | /**< lws context to create connection in */ |
| | const char *address; |
| | /**< remote address to connect to */ |
| | int port; |
| | /**< remote port to connect to */ |
| | int ssl_connection; |
| | /**< nonzero for ssl */ |
| | const char *path; |
| | /**< uri path */ |
| | const char *host; |
| | /**< content of host header */ |
| | const char *origin; |
| | /**< content of origin header */ |
| | const char *protocol; |
| | /**< list of ws protocols we could accept */ |
| | int ietf_version_or_minus_one; |
| | /**< deprecated: currently leave at 0 or -1 */ |
| | void *userdata; |
| | /**< if non-NULL, use this as wsi user_data instead of malloc it */ |
| | const struct lws_extension *client_exts; |
| | /**< array of extensions that may be used on connection */ |
| | const char *method; |
| | /**< if non-NULL, do this http method instead of ws[s] upgrade. |
| | * use "GET" to be a simple http client connection */ |
| | struct lws *parent_wsi; |
| | /**< if another wsi is responsible for this connection, give it here |
| | . |
| | * this is used to make sure if the parent closes so do any |
| | * child connections first. */ |
| | const char *uri_replace_from; |
| | /**< if non-NULL, when this string is found in URIs in |
| | * text/html content-encoding, it's replaced with uri_replace_to */ |
| | const char *uri_replace_to; |
| | /**< see uri_replace_from */ |
| | struct lws_vhost *vhost; |
| | /**< vhost to bind to (used to determine related SSL_CTX) */ |
| | struct lws **pwsi; |
| | /**< if not NULL, store the new wsi here early in the connection |
| | * process. Although we return the new wsi, the call to create the |
| | * client connection does progress the connection somewhat and may |
| | * meet an error that will result in the connection being scrubbed a |
| | nd |
| | * NULL returned. While the wsi exists though, he may process a |
| | * callback like CLIENT_CONNECTION_ERROR with his wsi: this gives th |
| | e |
| | * user callback a way to identify which wsi it is that faced the er |
| | ror |
| | * even before the new wsi is returned and even if ultimately no wsi |
| | * is returned. |
| | */ |
| | |
| | /* 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]; /**< dummy */ |
| | }; |
| | |
| | /** |
| | * lws_client_connect_via_info() - Connect to another websocket server |
| | * \param ccinfo: pointer to lws_client_connect_info struct |
| | * |
| | * This function creates a connection to a remote server using the |
| | * information provided in ccinfo. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN struct lws * |
| | lws_client_connect_via_info(struct lws_client_connect_info * ccinfo); |
| | |
| | /** |
| | * lws_client_connect() - Connect to another websocket server |
| | * \deprecated DEPRECATED use lws_client_connect_via_info |
| | * \param clients: Websocket context |
| | * \param address: Remote server address, eg, "myserver.com" |
| | * \param port: Port to connect to on the remote server, eg, 80 |
| | * \param ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// |
| | allow self |
| | * signed certs |
| | * \param path: Websocket path on server |
| | * \param host: Hostname on server |
| | * \param origin: Socket origin name |
| | * \param protocol: Comma-separated list of protocols being asked for fr |
| | om |
| | * the server, or just one. The server will pick the one it |
| | * likes best. If you don't want to specify a protocol, which |
| | is |
| | * legal, use NULL here. |
| | * \param ietf_version_or_minus_one: -1 to ask to connect using the default |
| | , latest |
| | * protocol supported, or the specific protocol ordinal |
| | * |
| | * This function creates a connection to a remote server |
| | */ |
| | /* 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 *protoco |
| | l, |
| | int ietf_version_or_minus_one) LWS_WARN_DEPRECATED; |
| | /* deprecated, use lws_client_connect_via_info() */ |
| | /** |
| | * lws_client_connect_extended() - Connect to another websocket server |
| | * \deprecated DEPRECATED use lws_client_connect_via_in |
| | fo |
| | * \param clients: Websocket context |
| | * \param address: Remote server address, eg, "myserver.com" |
| | * \param port: Port to connect to on the remote server, eg, 80 |
| | * \param ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// |
| | allow self |
| | * signed certs |
| | * \param path: Websocket path on server |
| | * \param host: Hostname on server |
| | * \param origin: Socket origin name |
| | * \param protocol: Comma-separated list of protocols being asked for fr |
| | om |
| | * the server, or just one. The server will pick the one it |
| | * likes best. |
| | * \param ietf_version_or_minus_one: -1 to ask to connect using the default |
| | , latest |
| | * protocol supported, or the specific protocol ordinal |
| | * \param userdata: Pre-allocated user data |
| | * |
| | * This function creates a connection to a remote server |
| | */ |
| | LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT |
| | lws_client_connect_extended(struct lws_context *clients, const char *addres |
| | s, |
| | 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) LWS_WARN_DEPRECATED; |
| | |
| | /** |
| | * lws_init_vhost_client_ssl() - also enable client SSL on an existing vhos |
| | t |
| | * |
| | * \param info: client ssl related info |
| | * \param vhost: which vhost to initialize client ssl operations on |
| | * |
| | * You only need to call this if you plan on using SSL client connections o |
| | n |
| | * the vhost. For non-SSL client connections, it's not necessary to call t |
| | his. |
| | * |
| | * The following members of info are used during the call |
| | * |
| | * - options must have LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT set, |
| | * otherwise the call does nothing |
| | * - provided_client_ssl_ctx must be NULL to get a generated client |
| | * ssl context, otherwise you can pass a prepared one in by settin |
| | g it |
| | * - ssl_cipher_list may be NULL or set to the client valid cipher lis |
| | t |
| | * - ssl_ca_filepath may be NULL or client cert filepath |
| | * - ssl_cert_filepath may be NULL or client cert filepath |
| | * - ssl_private_key_filepath may be NULL or client cert private key |
| | * |
| | * You must create your vhost explicitly if you want to use this, so you ha |
| | ve |
| | * a pointer to the vhost. Create the context first with the option flag |
| | * LWS_SERVER_OPTION_EXPLICIT_VHOSTS and then call lws_create_vhost() with |
| | * the same info struct. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_init_vhost_client_ssl(const struct lws_context_creation_info *info, |
| | struct lws_vhost *vhost); |
| | |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_http_client_read(struct lws *wsi, char **buf, int *len); |
| | |
| | LWS_VISIBLE LWS_EXTERN void |
| | lws_client_http_body_pending(struct lws *wsi, int something_left_to_send); |
| | |
| | /** |
| | * lws_client_http_body_pending() - control if client connection neeeds to |
| | send body |
| | * |
| | * \param wsi: client connection |
| | * \param something_left_to_send: nonzero if need to send more body, 0 (def |
| | ault) |
| | * if nothing more to send |
| | * |
| | * If you will send payload data with your HTTP client connection, eg, for |
| | POST, |
| | * when you set the related http headers in |
| | * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER callback you should also cal |
| | l |
| | * this API with something_left_to_send nonzero, and call |
| | * lws_callback_on_writable(wsi); |
| | * |
| | * After sending the headers, lws will call your callback with |
| | * LWS_CALLBACK_CLIENT_HTTP_WRITEABLE reason when writable. You can send t |
| | he |
| | * next part of the http body payload, calling lws_callback_on_writable(wsi |
| | ); |
| | * if there is more to come, or lws_client_http_body_pending(wsi, 0); to |
| | * let lws know the last part is sent and the connection can move on. |
| | */ |
| | |
| | ///@} |
| | |
| | /** \defgroup service Built-in service loop entry |
| | * |
| | * ##Built-in service loop entry |
| | * |
| | * If you're not using libev / libuv, these apis are needed to enter the po |
| | ll() |
| | * wait in lws and service any connections with pending events. |
| | */ |
| | ///@{ |
| | |
| | /** |
| | * lws_service() - Service any pending websocket activity |
| | * \param context: Websocket context |
| | * \param timeout_ms: Timeout for poll; 0 means return immediately if noth |
| | ing needed |
| | * service otherwise block and service immediately, returning |
| | * after the timeout if nothing needed service. |
| | * |
| | * This function deals with any pending websocket traffic, for three |
| | * kinds of event. It handles these events on both server and client |
| | * types of connection the same. |
| | * |
| | * 1) Accept new connections to our context's server |
| | * |
| | * 2) Call the receive callback for incoming frame data received by |
| | * server or client connections. |
| | * |
| | * You need to call this service function periodically to all the above |
| | * functions to happen; if your application is single-threaded you can |
| | * just call it in your main event loop. |
| | * |
| | * Alternatively you can fork a new process that asynchronously handles |
| | * calling this service in a loop. In that case you are happy if this |
| | * call blocks your thread until it needs to take care of something and |
| | * would call it with a large nonzero timeout. Your loop then takes no |
| | * CPU while there is nothing happening. |
| | * |
| | * If you are calling it in a single-threaded app, you don't want it to |
| | * wait around blocking other things in your loop from happening, so yo |
| | u |
| | * would call it with a timeout_ms of 0, so it returns immediately if |
| | * nothing is pending, or as soon as it services whatever was pending. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_service(struct lws_context *context, int timeout_ms); |
| | |
| | /** |
| | * lws_service() - Service any pending websocket activity |
| | * |
| | * \param context: Websocket context |
| | * \param timeout_ms: Timeout for poll; 0 means return immediately if noth |
| | ing needed |
| | * service otherwise block and service immediately, returning |
| | * after the timeout if nothing needed service. |
| | * |
| | * Same as lws_service(), but for a specific thread service index. Only ne |
| | eded |
| | * if you are spawning multiple service threads. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi); |
| | |
| | /** |
| | * lws_cancel_service_pt() - Cancel servicing of pending socket activity |
| | * on one thread |
| | * \param wsi: Cancel service on the thread this wsi is serviced by |
| | * |
| | * This function lets a call to lws_service() waiting for a timeout |
| | * immediately return. |
| | * |
| | * It works by creating a phony event and then swallowing it silently. |
| | * |
| | * The reason it may be needed is when waiting in poll(), changes to |
| | * the event masks are ignored by the OS until poll() is reentered. Th |
| | is |
| | * lets you halt the poll() wait and make the reentry happen immediatel |
| | y |
| | * instead of having the wait out the rest of the poll timeout. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN void |
| | lws_cancel_service_pt(struct lws *wsi); |
| | |
| | /** |
| | * lws_cancel_service() - Cancel wait for new pending socket activity |
| | * \param context: Websocket context |
| | * |
| | * This function let a call to lws_service() waiting for a timeout |
| | * immediately return. |
| | * |
| | * What it basically does is provide a fake event that will be swallowe |
| | d, |
| | * so the wait in poll() is ended. That's useful because poll() doesn' |
| | t |
| | * attend to changes in POLLIN/OUT/ERR until it re-enters the wait. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN void |
| | lws_cancel_service(struct lws_context *context); |
| | |
| | /** |
| | * lws_service_fd() - Service polled socket with something waiting |
| | * \param context: Websocket context |
| | * \param pollfd: The pollfd entry describing the socket fd and which |
| | events |
| | * happened. |
| | * |
| | * This function takes a pollfd that has POLLIN or POLLOUT activity and |
| | * services it according to the state of the associated |
| | * struct lws. |
| | * |
| | * The one call deals with all "service" that might happen on a socket |
| | * including listen accepts, http files as well as websocket protocol. |
| | * |
| | * If a pollfd says it has something, you can just pass it to |
| | * lws_service_fd() whether it is a socket handled by lws or not. |
| | * If it sees it is a lws socket, the traffic will be handled and |
| | * pollfd->revents will be zeroed now. |
| | * |
| | * If the socket is foreign to lws, it leaves revents alone. So you can |
| | * see if you should service yourself by checking the pollfd revents |
| | * after letting lws try to service it. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd); |
| | |
| | /** |
| | * lws_service_fd_tsi() - Service polled socket in specific service thread |
| | * \param context: Websocket context |
| | * \param pollfd: The pollfd entry describing the socket fd and which |
| | events |
| | * happened. |
| | * \param tsi: thread service index |
| | * |
| | * Same as lws_service_fd() but used with multiple service threads |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, |
| | int tsi); |
| | |
| | /** |
| | * lws_service_adjust_timeout() - Check for any connection needing forced s |
| | ervice |
| | * \param context: Websocket context |
| | * \param timeout_ms: The original poll timeout value. You can just set t |
| | his |
| | * to 1 if you don't really have a poll timeout. |
| | * \param tsi: thread service index |
| | * |
| | * Under some conditions connections may need service even though there is |
| | no |
| | * pending network action on them, this is "forced service". For default |
| | * poll() and libuv / libev, the library takes care of calling this and |
| | * dealing with it for you. But for external poll() integration, you need |
| | * access to the apis. |
| | * |
| | * If anybody needs "forced service", returned timeout is zero. In that ca |
| | se, |
| | * you can call lws_plat_service_tsi() with a timeout of -1 to only service |
| | * guys who need forced service. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_service_adjust_timeout(struct lws_context *context, int timeout_ms, int |
| | tsi); |
| | |
| | /** |
| | * lws_plat_service_tsi() - Lowlevel platform-specific service api |
| | * \param context: Websocket context |
| | * \param timeout_ms: The original poll timeout value. You can just set t |
| | his |
| | * to 1 if you don't really have a poll timeout. |
| | * \param tsi: thread service index |
| | * |
| | * For default poll() and libuv/ev, lws takes care of using this for you. a |
| | nd |
| | * you can ignore it. |
| | * |
| | * But for external poll() integration, you need access to this api to serv |
| | ice |
| | * connections that need to be serviced but have no pending network activit |
| | y. |
| | * |
| | * See lws_service_adjust_timeout() for more info. |
| | */ |
| | LWS_EXTERN LWS_VISIBLE int |
| | lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi); |
| | |
| | ///@} |
| | |
| | /*! \defgroup http HTTP |
| | |
| | Modules related to handling HTTP |
| | */ |
| | //@{ |
| | |
| | /*! \defgroup httpft HTTP File transfer |
| | * \ingroup http |
| | |
| | APIs for sending local files in response to HTTP requests |
| | */ |
| | //@{ |
| | |
| | /** |
| | * lws_get_mimetype() - Determine mimetype to use from filename |
| | * |
| | * \param file: filename |
| | * \param m: NULL, or mount context |
| | * |
| | * This uses a canned list of known filetypes first, if no match and m is |
| | * non-NULL, then tries a list of per-mount file suffix to mimtype mappings |
| | . |
| | * |
| | * Returns either NULL or a pointer to the mimetype matching the file. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN const char * |
| | lws_get_mimetype(const char *file, const struct lws_http_mount *m); |
| | |
| | /** |
| | * lws_serve_http_file() - Send a file back to the client using http |
| | * \param wsi: Websocket instance (available from user callback) |
| | * \param file: The file to issue over http |
| | * \param content_type: The http content type, eg, text/html |
| | * \param other_headers: NULL or pointer to header string |
| | * \param other_headers_len: length of the other headers if non-NULL |
| | * |
| | * This function is intended to be called from the callback in response |
| | * to http requests from the client. It allows the callback to issue |
| | * local files down the http link in a single step. |
| | * |
| | * Returning <0 indicates error and the wsi should be closed. Returnin |
| | g |
| | * >0 indicates the file was completely sent and |
| | * lws_http_transaction_completed() called on the wsi (and close if != |
| | 0) |
| | * ==0 indicates the file transfer is started and needs more service la |
| | ter, |
| | * the wsi should be left alone. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | 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 *wsi); |
| | //@} |
| | |
| | /*! \defgroup html-chunked-substitution HTML Chunked Substitution |
| | * \ingroup http |
| | * |
| | * ##HTML chunked Substitution |
| | * |
| | * APIs for receiving chunks of text, replacing a set of variable names via |
| | * a callback, and then prepending and appending HTML chunked encoding |
| | * headers. |
| | */ |
| | //@{ |
| | |
| | enum http_status { |
| | HTTP_STATUS_OK = 200, |
| | HTTP_STATUS_NO_CONTENT = 204, |
| | |
| | HTTP_STATUS_MOVED_PERMANENTLY = 301, |
| | HTTP_STATUS_FOUND = 302, |
| | HTTP_STATUS_SEE_OTHER = 303, |
| | |
| | HTTP_STATUS_BAD_REQUEST = 400, |
| | HTTP_STATUS_UNAUTHORIZED, |
| | HTTP_STATUS_PAYMENT_REQUIRED, |
| | HTTP_STATUS_FORBIDDEN, |
| | HTTP_STATUS_NOT_FOUND, |
| | HTTP_STATUS_METHOD_NOT_ALLOWED, |
| | HTTP_STATUS_NOT_ACCEPTABLE, |
| | HTTP_STATUS_PROXY_AUTH_REQUIRED, |
| | HTTP_STATUS_REQUEST_TIMEOUT, |
| | HTTP_STATUS_CONFLICT, |
| | HTTP_STATUS_GONE, |
| | HTTP_STATUS_LENGTH_REQUIRED, |
| | HTTP_STATUS_PRECONDITION_FAILED, |
| | HTTP_STATUS_REQ_ENTITY_TOO_LARGE, |
| | HTTP_STATUS_REQ_URI_TOO_LONG, |
| | HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, |
| | HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE, |
| | HTTP_STATUS_EXPECTATION_FAILED, |
| | |
| | HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, |
| | HTTP_STATUS_NOT_IMPLEMENTED, |
| | HTTP_STATUS_BAD_GATEWAY, |
| | HTTP_STATUS_SERVICE_UNAVAILABLE, |
| | HTTP_STATUS_GATEWAY_TIMEOUT, |
| | HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED, |
| | }; |
| | |
| | struct lws_process_html_args { |
| | char *p; /**< pointer to the buffer containing the data */ |
| | int len; /**< length of the original data at p */ |
| | int max_len; /**< maximum length we can grow the data to */ |
| | int final; /**< set if this is the last chunk of the file */ |
| | }; |
| | |
| | typedef const char *(*lws_process_html_state_cb)(void *data, int index); |
| | |
| | struct lws_process_html_state { |
| | char *start; /**< pointer to start of match */ |
| | char swallow[16]; /**< matched character buffer */ |
| | int pos; /**< position in match */ |
| | void *data; /**< opaque pointer */ |
| | const char * const *vars; /**< list of variable names */ |
| | int count_vars; /**< count of variable names */ |
| | |
| | lws_process_html_state_cb replace; /**< called on match to perform s |
| | ubstitution */ |
| | }; |
| | |
| | /*! lws_chunked_html_process() - generic chunked substitution |
| | * \param args: buffer to process using chunked encoding |
| | * \param s: current processing state |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_chunked_html_process(struct lws_process_html_args *args, |
| | struct lws_process_html_state *s); |
| | //@} |
| | |
| | /** \defgroup HTTP-headers-read HTTP headers: read |
| | * \ingroup http |
| | * |
| | * ##HTTP header releated functions |
| | * |
| | * In lws the client http headers are temporarily stored in a pool, only f |
| | or 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 life |
| | time |
| | * and would then just be taking up space needlessly. |
| | * |
| | * During LWS_CALLBACK_HTTP when the URI path is delivered is the last tim |
| | e |
| | * 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 termina |
| | ting |
| | * '\0', however you must allocate for it when using the _copy apis. So t |
| | he |
| | * length reported for a header containing "123" is 3, but you must provid |
| | e |
| | * a buffer of length 4 so that "123\0" may be copied into it, or the copy |
| | * will fail with a nonzero return code. |
| | * |
| | * In the special case of URL arguments, like ?x=1&y=2, the arguments are |
| | * stored in a token named for the method, eg, WSI_TOKEN_GET_URI if it |
| | * was a GET or WSI_TOKEN_POST_URI if POST. You can check the total |
| | * length to confirm the method. |
| | * |
| | * For URL arguments, each argument is stored urldecoded in a "fragment", |
| | so |
| | * you can use the fragment-aware api lws_hdr_copy_fragment() to access ea |
| | ch |
| | * argument in turn: the fragments contain urldecoded strings like x=1 or |
| | y=2. |
| | * |
| | * As a convenience, lws has an api that will find the fragment with a |
| | * given name= part, lws_get_urlarg_by_name(). |
| | */ |
| | ///@{ |
| | |
| | /** struct lws_tokens |
* you need these to look at headers that have been parsed if using the | | * you need these to look at headers that have been parsed if using the |
* LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum | | * LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum |
* list below is absent, .token = NULL and token_len = 0. Otherwise .token | | * list below is absent, .token = NULL and token_len = 0. Otherwise .token |
* points to .token_len chars containing that header content. | | * points to .token_len chars containing that header content. |
*/ | | */ |
| | |
struct lws_tokens { | | struct lws_tokens { |
char *token; | | char *token; /**< pointer to start of the token */ |
int token_len; | | int token_len; /**< length of the token's value */ |
}; | | }; |
| | |
/* | | /* enum lws_token_indexes |
* these have to be kept in sync with lextable.h / minilex.c | | * 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, | | * 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. | | * add it at where specified so existing users are unaffected. |
*/ | | */ |
enum lws_token_indexes { | | enum lws_token_indexes { |
WSI_TOKEN_GET_URI = 0, | | WSI_TOKEN_GET_URI = 0, |
WSI_TOKEN_POST_URI = 1, | | WSI_TOKEN_POST_URI = 1, |
WSI_TOKEN_OPTIONS_URI = 2, | | WSI_TOKEN_OPTIONS_URI = 2, |
WSI_TOKEN_HOST = 3, | | WSI_TOKEN_HOST = 3, |
| | |
skipping to change at line 622 ¶ | | skipping to change at line 2583 ¶ |
WSI_TOKEN_HTTP_VIA = 71, | | WSI_TOKEN_HTTP_VIA = 71, |
WSI_TOKEN_HTTP_WWW_AUTHENTICATE = 72, | | WSI_TOKEN_HTTP_WWW_AUTHENTICATE = 72, |
| | |
WSI_TOKEN_PATCH_URI = 73, | | WSI_TOKEN_PATCH_URI = 73, |
WSI_TOKEN_PUT_URI = 74, | | WSI_TOKEN_PUT_URI = 74, |
WSI_TOKEN_DELETE_URI = 75, | | WSI_TOKEN_DELETE_URI = 75, |
| | |
WSI_TOKEN_HTTP_URI_ARGS = 76, | | WSI_TOKEN_HTTP_URI_ARGS = 76, |
WSI_TOKEN_PROXY = 77, | | WSI_TOKEN_PROXY = 77, |
WSI_TOKEN_HTTP_X_REAL_IP = 78, | | WSI_TOKEN_HTTP_X_REAL_IP = 78, |
| | WSI_TOKEN_HTTP1_0 = 79, |
| | |
/****** add new things just above ---^ ******/ | | /****** add new things just above ---^ ******/ |
| | |
/* use token storage to stash these internally, not for | | /* use token storage to stash these internally, not for |
* user use */ | | * user use */ |
| | |
_WSI_TOKEN_CLIENT_SENT_PROTOCOLS, | | _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, |
_WSI_TOKEN_CLIENT_PEER_ADDRESS, | | _WSI_TOKEN_CLIENT_PEER_ADDRESS, |
_WSI_TOKEN_CLIENT_URI, | | _WSI_TOKEN_CLIENT_URI, |
_WSI_TOKEN_CLIENT_HOST, | | _WSI_TOKEN_CLIENT_HOST, |
_WSI_TOKEN_CLIENT_ORIGIN, | | _WSI_TOKEN_CLIENT_ORIGIN, |
| | _WSI_TOKEN_CLIENT_METHOD, |
| | |
/* always last real token index*/ | | /* always last real token index*/ |
WSI_TOKEN_COUNT, | | WSI_TOKEN_COUNT, |
| | |
/* parser state additions, no storage associated */ | | /* parser state additions, no storage associated */ |
WSI_TOKEN_NAME_PART, | | WSI_TOKEN_NAME_PART, |
WSI_TOKEN_SKIPPING, | | WSI_TOKEN_SKIPPING, |
WSI_TOKEN_SKIPPING_SAW_CR, | | WSI_TOKEN_SKIPPING_SAW_CR, |
WSI_PARSING_COMPLETE, | | WSI_PARSING_COMPLETE, |
WSI_INIT_TOKEN_MUXURL, | | WSI_INIT_TOKEN_MUXURL, |
}; | | }; |
| | |
struct lws_token_limits { | | struct lws_token_limits { |
unsigned short token_limit[WSI_TOKEN_COUNT]; | | unsigned short token_limit[WSI_TOKEN_COUNT]; /**< max chars for this
token */ |
}; | | }; |
| | |
/* | | /** |
* From RFC 6455 | | * lws_token_to_string() - returns a textual representation of a hdr token |
1000 | | index |
| | * |
1000 indicates a normal closure, meaning that the purpose for | | * \param: token index |
which the connection was established has been fulfilled. | | |
| | |
1001 | | |
| | |
1001 indicates that an endpoint is "going away", such as a server | | |
going down or a browser having navigated away from a page. | | |
| | |
1002 | | |
| | |
1002 indicates that an endpoint is terminating the connection due | | |
to a protocol error. | | |
| | |
1003 | | |
| | |
1003 indicates that an endpoint is terminating the connection | | |
because it has received a type of data it cannot accept (e.g., an | | |
endpoint that understands only text data MAY send this if it | | |
receives a binary message). | | |
| | |
1004 | | |
| | |
Reserved. The specific meaning might be defined in the future. | | |
| | |
1005 | | |
| | |
1005 is a reserved value and MUST NOT be set as a status code in a | | |
Close control frame by an endpoint. It is designated for use in | | |
applications expecting a status code to indicate that no status | | |
code was actually present. | | |
| | |
1006 | | |
| | |
1006 is a reserved value and MUST NOT be set as a status code in a | | |
Close control frame by an endpoint. It is designated for use in | | |
applications expecting a status code to indicate that the | | |
connection was closed abnormally, e.g., without sending or | | |
receiving a Close control frame. | | |
| | |
1007 | | |
| | |
1007 indicates that an endpoint is terminating the connection | | |
because it has received data within a message that was not | | |
consistent with the type of the message (e.g., non-UTF-8 [RFC3629] | | |
data within a text message). | | |
| | |
1008 | | |
| | |
1008 indicates that an endpoint is terminating the connection | | |
because it has received a message that violates its policy. This | | |
is a generic status code that can be returned when there is no | | |
other more suitable status code (e.g., 1003 or 1009) or if there | | |
is a need to hide specific details about the policy. | | |
| | |
1009 | | |
| | |
1009 indicates that an endpoint is terminating the connection | | |
because it has received a message that is too big for it to | | |
process. | | |
| | |
1010 | | |
| | |
1010 indicates that an endpoint (client) is terminating the | | |
connection because it has expected the server to negotiate one or | | |
more extension, but the server didn't return them in the response | | |
message of the WebSocket handshake. The list of extensions that | | |
are needed SHOULD appear in the /reason/ part of the Close frame. | | |
Note that this status code is not used by the server, because it | | |
can fail the WebSocket handshake instead. | | |
| | |
1011 | | |
| | |
1011 indicates that a server is terminating the connection because | | |
it encountered an unexpected condition that prevented it from | | |
fulfilling the request. | | |
| | |
1015 | | |
| | |
1015 is a reserved value and MUST NOT be set as a status code in a | | |
Close control frame by an endpoint. It is designated for use in | | |
applications expecting a status code to indicate that the | | |
connection was closed due to a failure to perform a TLS handshake | | |
(e.g., the server certificate can't be verified). | | |
*/ | | |
| | |
/* | | |
* 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. | | |
*/ | | */ |
enum lws_close_status { | | LWS_VISIBLE LWS_EXTERN const unsigned char * |
LWS_CLOSE_STATUS_NOSTATUS = 0, | | lws_token_to_string(enum lws_token_indexes token); |
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, | | |
}; | | |
| | |
enum http_status { | | |
HTTP_STATUS_OK = 200, | | |
HTTP_STATUS_NO_CONTENT = 204, | | |
| | |
HTTP_STATUS_BAD_REQUEST = 400, | | |
HTTP_STATUS_UNAUTHORIZED, | | |
HTTP_STATUS_PAYMENT_REQUIRED, | | |
HTTP_STATUS_FORBIDDEN, | | |
HTTP_STATUS_NOT_FOUND, | | |
HTTP_STATUS_METHOD_NOT_ALLOWED, | | |
HTTP_STATUS_NOT_ACCEPTABLE, | | |
HTTP_STATUS_PROXY_AUTH_REQUIRED, | | |
HTTP_STATUS_REQUEST_TIMEOUT, | | |
HTTP_STATUS_CONFLICT, | | |
HTTP_STATUS_GONE, | | |
HTTP_STATUS_LENGTH_REQUIRED, | | |
HTTP_STATUS_PRECONDITION_FAILED, | | |
HTTP_STATUS_REQ_ENTITY_TOO_LARGE, | | |
HTTP_STATUS_REQ_URI_TOO_LONG, | | |
HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, | | |
HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE, | | |
HTTP_STATUS_EXPECTATION_FAILED, | | |
| | |
HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, | | |
HTTP_STATUS_NOT_IMPLEMENTED, | | |
HTTP_STATUS_BAD_GATEWAY, | | |
HTTP_STATUS_SERVICE_UNAVAILABLE, | | |
HTTP_STATUS_GATEWAY_TIMEOUT, | | |
HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED, | | |
}; | | |
| | |
struct lws; | | |
struct lws_context; | | |
/* needed even with extensions disabled for create context */ | | |
struct lws_extension; | | |
| | |
/** | | /** |
* typedef lws_callback_function() - User server actions | | * lws_hdr_total_length: report length of all fragments of a header totalle |
* @wsi: Opaque websocket instance pointer | | d up |
* @reason: The reason for the call | | * The returned length does not include the space for a |
* @user: Pointer to per-session user data allocated by library | | * terminating '\0' |
* @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. | | |
* | | |
* 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 lws_create_server. | | |
* | | |
* You get an opportunity to initialize user data when called back with | | |
* LWS_CALLBACK_ESTABLISHED reason. | | |
* | | |
* LWS_CALLBACK_ESTABLISHED: after the server completes a handshake with | | |
* an incoming client. If you built the librar | | |
y | | |
* with ssl support, @in is a pointer to the | | |
* ssl struct associated with the connection or | | |
* NULL. | | |
* | | |
* LWS_CALLBACK_CLIENT_CONNECTION_ERROR: the request client connection has | | |
* been unable to complete a handshake with the remote server. If | | |
* in is non-NULL, you can find an error string of length len where | | |
* it points to. | | |
* | | |
* LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: this is the last chance for t | | |
he | | |
* client user code to examine the http headers | | |
* and decide to reject the connection. If the | | |
* content in the headers is interesting to the | | |
* client (url, etc) it needs to copy it out at | | |
* this point since it will be destroyed before | | |
* the CLIENT_ESTABLISHED call | | |
* | | |
* LWS_CALLBACK_CLIENT_ESTABLISHED: after your client connection completed | | |
* a handshake with the remote server | | |
* | | |
* LWS_CALLBACK_CLOSED: when the websocket session ends | | |
* | | |
* LWS_CALLBACK_CLOSED_HTTP: when a HTTP (non-websocket) session ends | | |
* | | |
* LWS_CALLBACK_RECEIVE: data has appeared for this server endpoint fro | | |
m a | | |
* remote client, it can be found at *in and is | | |
* len bytes long | | |
* | | |
* 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 | | |
* | | * |
* LWS_CALLBACK_CLIENT_RECEIVE: data has appeared from the server for t | | * \param wsi: websocket connection |
he | | * \param h: which header index we are interested in |
* client connection, it can be found at *in an | | */ |
d | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
* is len bytes long | | lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h); |
| | |
| | /** |
| | * lws_hdr_fragment_length: report length of a single fragment of a header |
| | * The returned length does not include the space for a |
| | * terminating '\0' |
* | | * |
* LWS_CALLBACK_HTTP: an http request has come from a client that is no | | * \param wsi: websocket connection |
t | | * \param h: which header index we are interested in |
* asking to upgrade the connection to a websoc | | * \param frag_idx: which fragment of h we want to get the length of |
ket | | */ |
* one. This is a chance to serve http content | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
, | | lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag |
* for example, to send a script to the client | | _idx); |
* which will then open the websockets connecti | | |
on. | | /** |
* @in points to the URI path requested and | | * lws_hdr_copy() - copy a single fragment of the given header to a buffer |
* lws_serve_http_file() makes it very | | * The buffer length len must include space for an additional |
* simple to send back a file to the client. | | * terminating '\0', or it will fail returning -1. |
* Normally after sending the file you are done | | |
* with the http connection, since the rest of | | |
the | | |
* activity will come by websockets from the sc | | |
ript | | |
* that was delivered by http, so you will want | | |
to | | |
* return 1; to close and free up the connectio | | |
n. | | |
* That's important because it uses a slot in t | | |
he | | |
* total number of client connections allowed s | | |
et | | |
* by MAX_CLIENTS. | | |
* | | * |
* LWS_CALLBACK_HTTP_BODY: the next @len bytes data from the http | | * \param wsi: websocket connection |
* request body HTTP connection is now available in @in. | | * \param dest: destination buffer |
| | * \param len: length of destination buffer |
| | * \param h: which header index we are interested in |
* | | * |
* LWS_CALLBACK_HTTP_BODY_COMPLETION: the expected amount of http reque | | * copies the whole, aggregated header, even if it was delivered in |
st | | * several actual headers piece by piece |
* body has been delivered | | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h |
| | ); |
| | |
| | /** |
| | * lws_hdr_copy_fragment() - copy a single fragment of the given header to |
| | a buffer |
| | * The buffer length len must include space for an additional |
| | * terminating '\0', or it will fail returning -1. |
| | * If the requested fragment index is not present, it fails |
| | * returning -1. |
* | | * |
* LWS_CALLBACK_HTTP_WRITEABLE: you can write more down the http protoc | | * \param wsi: websocket connection |
ol | | * \param dest: destination buffer |
* link now. | | * \param len: length of destination buffer |
| | * \param h: which header index we are interested in |
| | * \param frag_idx: which fragment of h we want to copy |
* | | * |
* LWS_CALLBACK_HTTP_FILE_COMPLETION: a file requested to be send down | | * Normally this is only useful |
* http link has completed. | | * to parse URI arguments like ?x=1&y=2, token index WSI_TOKEN_HTTP_URI_ARG |
| | S |
| | * fragment 0 will contain "x=1" and fragment 1 "y=2" |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_hdr_copy_fragment(struct lws *wsi, char *dest, int len, |
| | enum lws_token_indexes h, int frag_idx); |
| | |
| | /** |
| | * lws_get_urlarg_by_name() - return pointer to arg value if present |
| | * \param wsi: the connection to check |
| | * \param name: the arg name, like "token=" |
| | * \param buf: the buffer to receive the urlarg (including the name= part) |
| | * \param len: the length of the buffer to receive the urlarg |
* | | * |
* LWS_CALLBACK_CLIENT_WRITEABLE: | | * Returns NULL if not found or a pointer inside buf to just after the |
* LWS_CALLBACK_SERVER_WRITEABLE: If you call | | * name= part. |
* lws_callback_on_writable() on a connection, you will | | */ |
* get one of these callbacks coming when the connection socket | | LWS_VISIBLE LWS_EXTERN const char * |
* is able to accept another write packet without blocking. | | lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int le |
* If it already was able to take another packet without blocki | | n); |
ng, | | ///@} |
* you'll get this callback at the next call to the service loo | | |
p | | /*! \defgroup HTTP-headers-create HTTP headers: create |
* function. Notice that CLIENTs get LWS_CALLBACK_CLIENT_WRITE | | |
ABLE | | |
* and servers get LWS_CALLBACK_SERVER_WRITEABLE. | | |
* | | * |
* LWS_CALLBACK_FILTER_NETWORK_CONNECTION: called when a client connect | | * ## HTTP headers: Create |
s to | | |
* the server at network level; the connection is accepted but | | |
then | | |
* passed to this callback to decide whether to hang up immedia | | |
tely | | |
* or not, based on the client IP. @in contains the connection | | |
* socket's descriptor. Since the client connection information | | |
is | | |
* not available yet, @wsi still pointing to the main server so | | |
cket. | | |
* Return non-zero to terminate the connection before sending o | | |
r | | |
* receiving anything. Because this happens immediately after t | | |
he | | |
* network connection from the client, there's no websocket pro | | |
tocol | | |
* selected yet so this callback is issued only to protocol 0. | | |
* | | * |
* LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED: A new client just had | | * These apis allow you to create HTTP response headers in a way compatible |
* been connected, accepted, and instantiated into the pool. Th | | with |
is | | * both HTTP/1.x and HTTP/2. |
* callback allows setting any relevant property to it. Because | | |
this | | |
* happens immediately after the instantiation of a new client, | | |
* there's no websocket protocol selected yet so this callback | | |
is | | |
* issued only to protocol 0. Only @wsi is defined, pointing to | | |
the | | |
* new client, and the return value is ignored. | | |
* | | * |
* LWS_CALLBACK_FILTER_HTTP_CONNECTION: called when the request has | | * They each append to a buffer taking care about the buffer end, which is |
* been received and parsed from the client, but the response i | | * passed in as a pointer. When data is written to the buffer, the current |
s | | * position p is updated accordingly. |
* not sent yet. Return non-zero to disallow the connection. | | |
* @user is a pointer to the connection user space allocation, | | |
* @in is the URI, eg, "/" | | |
* In your handler you can use the public APIs | | |
* lws_hdr_total_length() / lws_hdr_copy() to access all of the | | |
* headers using the header enums lws_token_indexes from | | |
* libwebsockets.h to check for and read the supported header | | |
* presence and content before deciding to allow the http | | |
* connection to proceed or to kill the connection. | | |
* | | * |
* LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: called when the handshake h | | * All of these apis are LWS_WARN_UNUSED_RESULT as they can run out of spac |
as | | e |
* been received and parsed from the client, but the response i | | * and fail with nonzero return. |
s | | */ |
* not sent yet. Return non-zero to disallow the connection. | | ///@{ |
* @user is a pointer to the connection user space allocation, | | /** |
* @in is the requested protocol name | | * lws_add_http_header_status() - add the HTTP response status code |
* In your handler you can use the public APIs | | |
* lws_hdr_total_length() / lws_hdr_copy() to access all of the | | |
* headers using the header enums lws_token_indexes from | | |
* libwebsockets.h to check for and read the supported header | | |
* presence and content before deciding to allow the handshake | | |
* to proceed or to kill the connection. | | |
* | | * |
* LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: if configured f | | * \param wsi: the connection to check |
or | | * \param code: an HTTP code like 200, 404 etc (see enum http_status) |
* including OpenSSL support, this callback allows your user co | | * \param p: pointer to current position in buffer pointer |
de | | * \param end: pointer to end of buffer |
* to perform extra SSL_CTX_load_verify_locations() or similar | | |
* calls to direct OpenSSL where to find certificates the clien | | |
t | | |
* can use to confirm the remote server identity. @user is the | | |
* OpenSSL SSL_CTX* | | |
* | | * |
* LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS: if configured f | | * Adds the initial response code, so should be called first |
or | | */ |
* including OpenSSL support, this callback allows your user co | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
de | | lws_add_http_header_status(struct lws *wsi, |
* to load extra certifcates into the server which allow it to | | unsigned int code, unsigned char **p, |
* verify the validity of certificates returned by clients. @u | | unsigned char *end); |
ser | | /** |
* is the server's OpenSSL SSL_CTX* | | * lws_add_http_header_by_name() - append named header and value |
* | | * |
* LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY: if configured for | | * \param wsi: the connection to check |
* including OpenSSL support but no private key file has been | | * \param name: the hdr name, like "my-header" |
* specified (ssl_private_key_filepath is NULL), this is called | | * \param value: the value after the = for this header |
to | | * \param length: the length of the value |
* allow the user to set the private key directly via libopenss | | * \param p: pointer to current position in buffer pointer |
l | | * \param end: pointer to end of buffer |
* and perform further operations if required; this might be us | | |
eful | | |
* in situations where the private key is not directly accessib | | |
le | | |
* 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 | | * Appends name: value to the headers |
* libwebsockets context was created with the option | | */ |
* LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then th | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
is | | lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name, |
* callback is generated during OpenSSL verification of the cer | | const unsigned char *value, int length, |
t | | unsigned char **p, unsigned char *end); |
* sent from the client. It is sent to protocol[0] callback as | | /** |
* no protocol has been negotiated on the connection yet. | | * lws_add_http_header_by_token() - append given header and value |
* Notice that the libwebsockets context and wsi are both NULL | | |
* during this callback. See | | |
* http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html | | |
* to understand more detail about the OpenSSL callback that | | |
* generates this libwebsockets callback and the meanings of th | | |
e | | |
* arguments passed. In this callback, @user is the x509_ctx, | | |
* @in is the ssl pointer and @len is preverify_ok | | |
* Notice that this callback maintains libwebsocket return | | |
* conventions, return 0 to mean the cert is OK or 1 to fail it | | |
. | | |
* This also means that if you don't handle this callback then | | |
* the default callback action of returning 0 allows the client | | |
* certificates. | | |
* | | * |
* LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: this callback happens | | * \param wsi: the connection to check |
* when a client handshake is being compiled. @user is NULL, | | * \param token: the token index for the hdr |
* @in is a char **, it's pointing to a char * which holds the | | * \param value: the value after the = for this header |
* next location in the header buffer where you can add | | * \param length: the length of the value |
* headers, and @len is the remaining space in the header buffe | | * \param p: pointer to current position in buffer pointer |
r, | | * \param end: pointer to end of buffer |
* which is typically some hundreds of bytes. So, to add a can | | |
ned | | |
* cookie, your handler code might look similar to: | | |
* | | * |
* char **p = (char **)in; | | * Appends name=value to the headers, but is able to take advantage of bett |
| | er |
| | * HTTP/2 coding mechanisms where possible. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| | 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_add_http_header_by_name() - append content-length helper |
* | | * |
* if (len < 100) | | * \param wsi: the connection to check |
* return 1; | | * \param content_length: the content length to use |
| | * \param p: pointer to current position in buffer pointer |
| | * \param end: pointer to end of buffer |
* | | * |
* *p += sprintf(*p, "Cookie: a=b\x0d\x0a"); | | * Appends content-length: content_length to the headers |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| | lws_add_http_header_content_length(struct lws *wsi, |
| | unsigned long content_length, |
| | unsigned char **p, unsigned char *end); |
| | /** |
| | * lws_finalize_http_header() - terminate header block |
* | | * |
* return 0; | | * \param wsi: the connection to check |
| | * \param p: pointer to current position in buffer pointer |
| | * \param end: pointer to end of buffer |
* | | * |
* Notice if you add anything, you just have to take care about | | * Indicates no more headers will be added |
* the CRLF on the line you added. Obviously this callback is | | */ |
* optional, if you don't handle it everything is fine. | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| | lws_finalize_http_header(struct lws *wsi, unsigned char **p, |
| | unsigned char *end); |
| | ///@} |
| | |
| | /** \defgroup form-parsing Form Parsing |
| | * \ingroup http |
| | * ##POSTed form parsing functions |
* | | * |
* Notice the callback is coming to protocols[0] all the time, | | * These lws_spa (stateful post arguments) apis let you parse and urldecode |
* because there is no specific protocol handshook yet. | | * POSTed form arguments, both using simple urlencoded and multipart transf |
| | er |
| | * encoding. |
* | | * |
* LWS_CALLBACK_CONFIRM_EXTENSION_OKAY: When the server handshake code | | * It's capable of handling file uploads as well a named input parsing, |
* sees that it does support a requested extension, before | | * and the apis are the same for both form upload styles. |
* accepting the extension by additing to the list sent back to | | |
* the client it gives this callback just to check that it's ok | | |
ay | | |
* to use that extension. It calls back to the requested proto | | |
col | | |
* and with @in being the extension name, @len is 0 and @user i | | |
s | | |
* valid. Note though at this time the ESTABLISHED callback ha | | |
sn't | | |
* happened yet so if you initialize @user content there, @user | | |
* content during this callback might not be useful for anythin | | |
g. | | |
* Notice this callback comes to protocols[0]. | | |
* | | * |
* LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: When a clien | | * You feed it a list of parameter names and it creates pointers to the |
t | | * urldecoded arguments: file upload parameters pass the file data in chunk |
* connection is being prepared to start a handshake to a serve | | s to |
r, | | * a user-supplied callback as they come. |
* each supported extension is checked with protocols[0] callba | | |
ck | | |
* with this reason, giving the user code a chance to suppress | | |
the | | |
* claim to support that extension by returning non-zero. If | | |
* unhandled, by default 0 will be returned and the extension | | |
* support included in the header to the server. Notice this | | |
* callback comes to protocols[0]. | | |
* | | * |
* LWS_CALLBACK_PROTOCOL_INIT: One-time call per protocol so it can | | * Since it's stateful, it handles the incoming data needing more than one |
* do initial setup / allocations etc | | * POST_BODY callback and has no limit on uploaded file size. |
| | */ |
| | ///@{ |
| | |
| | /** enum lws_spa_fileupload_states */ |
| | enum lws_spa_fileupload_states { |
| | LWS_UFS_CONTENT, |
| | /**< a chunk of file content has arrived */ |
| | LWS_UFS_FINAL_CONTENT, |
| | /**< the last chunk (possibly zero length) of file content has arriv |
| | ed */ |
| | LWS_UFS_OPEN |
| | /**< a new file is starting to arrive */ |
| | }; |
| | |
| | /** |
| | * lws_spa_fileupload_cb() - callback to receive file upload data |
* | | * |
* LWS_CALLBACK_PROTOCOL_DESTROY: One-time call per protocol indicatin | | * \param data: opt_data pointer set in lws_spa_create |
g | | * \param name: name of the form field being uploaded |
* this protocol won't get used at all after this callback, the | | * \param filename: original filename from client |
* context is getting destroyed. Take the opportunity to | | * \param buf: start of data to receive |
* deallocate everything that was allocated by the protocol. | | * \param len: length of data to receive |
| | * \param state: information about how this call relates to file |
* | | * |
* LWS_CALLBACK_WSI_CREATE: outermost (earliest) wsi create notificatio | | * Notice name and filename shouldn't be trusted, as they are passed from |
n | | * HTTP provided by the client. |
| | */ |
| | typedef int (*lws_spa_fileupload_cb)(void *data, const char *name, |
| | const char *filename, char *buf, int len, |
| | enum lws_spa_fileupload_states state); |
| | |
| | /** struct lws_spa - opaque urldecode parser capable of handling multipart |
| | * and file uploads */ |
| | struct lws_spa; |
| | |
| | /** |
| | * lws_spa_create() - create urldecode parser |
* | | * |
* LWS_CALLBACK_WSI_DESTROY: outermost (latest) wsi destroy notificatio | | * \param wsi: lws connection (used to find Content Type) |
n | | * \param param_names: array of form parameter names, like "username" |
| | * \param count_params: count of param_names |
| | * \param max_storage: total amount of form parameter values we can store |
| | * \param opt_cb: NULL, or callback to receive file upload data. |
| | * \param opt_data: NULL, or user pointer provided to opt_cb. |
* | | * |
* The next five reasons are optional and only need taking care of if y | | * Creates a urldecode parser and initializes it. |
ou | | |
* will be integrating libwebsockets sockets into an external polling | | |
* array. | | |
* | | * |
* For these calls, @in points to a struct lws_pollargs that | | * opt_cb can be NULL if you just want normal name=value parsing, however |
* contains @fd, @events and @prev_events members | | * if one or more entries in your form are bulk data (file transfer), you |
| | * can provide this callback and filter on the name callback parameter to |
| | * treat that urldecoded data separately. The callback should return -1 |
| | * in case of fatal error, and 0 if OK. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN struct lws_spa * |
| | lws_spa_create(struct lws *wsi, const char * const *param_names, |
| | int count_params, int max_storage, lws_spa_fileupload_cb opt_ |
| | cb, |
| | void *opt_data); |
| | |
| | /** |
| | * lws_spa_process() - parses a chunk of input data |
* | | * |
* LWS_CALLBACK_ADD_POLL_FD: libwebsocket deals with its poll() loop | | * \param spa: the parser object previously created |
* internally, but in the case you are integrating with another | | * \param in: incoming, urlencoded data |
* server you will need to have libwebsocket sockets share a | | * \param len: count of bytes valid at \param in |
* polling array with the other server. This and the other | | */ |
* POLL_FD related callbacks let you put your specialized | | LWS_VISIBLE LWS_EXTERN int |
* poll array interface code in the callback for protocol 0, th | | lws_spa_process(struct lws_spa *spa, const char *in, int len); |
e | | |
* first protocol you support, usually the HTTP protocol in the | | /** |
* serving case. | | * lws_spa_finalize() - indicate incoming data completed |
* This callback happens when a socket needs to be | | |
* added to the polling loop: @in points to a struct | | |
* lws_pollargs; the @fd member of the struct is the file | | |
* descriptor, and @events contains the active events. | | |
* | | * |
* If you are using the internal polling loop (the "service" | | * \param spa: the parser object previously created |
* callback), you can just ignore these callbacks. | | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_spa_finalize(struct lws_spa *spa); |
| | |
| | /** |
| | * lws_spa_get_length() - return length of parameter value |
* | | * |
* LWS_CALLBACK_DEL_POLL_FD: This callback happens when a socket descri | | * \param spa: the parser object previously created |
ptor | | * \param n: parameter ordinal to return length of value for |
* needs to be removed from an external polling array. @in is | | */ |
* again the struct lws_pollargs containing the @fd member | | LWS_VISIBLE LWS_EXTERN int |
* to be removed. If you are using the internal polling | | lws_spa_get_length(struct lws_spa *spa, int n); |
* loop, you can just ignore it. | | |
| | /** |
| | * lws_spa_get_string() - return pointer to parameter value |
| | * \param spa: the parser object previously created |
| | * \param n: parameter ordinal to return pointer to value for |
| | */ |
| | LWS_VISIBLE LWS_EXTERN const char * |
| | lws_spa_get_string(struct lws_spa *spa, int n); |
| | |
| | /** |
| | * lws_spa_destroy() - destroy parser object |
* | | * |
* LWS_CALLBACK_CHANGE_MODE_POLL_FD: This callback happens when | | * \param spa: the parser object previously created |
* libwebsockets wants to modify the events for a connectiion. | | */ |
* @in is the struct lws_pollargs with the @fd to change. | | LWS_VISIBLE LWS_EXTERN int |
* The new event mask is in @events member and the old mask is | | lws_spa_destroy(struct lws_spa *spa); |
in | | ///@} |
* the @prev_events member. | | |
* If you are using the internal polling loop, you can just ign | | /*! \defgroup urlendec Urlencode and Urldecode |
ore | | * \ingroup http |
* it. | | |
* | | * |
* LWS_CALLBACK_LOCK_POLL: | | * ##HTML chunked Substitution |
* LWS_CALLBACK_UNLOCK_POLL: These allow the external poll changes driv | | |
en | | |
* by libwebsockets to participate in an external thread lockin | | |
g | | |
* scheme around the changes, so the whole thing is threadsafe. | | |
* These are called around three activities in the library, | | |
* - inserting a new wsi in the wsi / fd table (len=1) | | |
* - deleting a wsi from the wsi / fd table (len=1) | | |
* - changing a wsi's POLLIN/OUT state (len=0) | | |
* Locking and unlocking external synchronization objects when | | |
* 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: | | * APIs for receiving chunks of text, replacing a set of variable names via |
* The peer has sent an unsolicited Close WS packet. @in and | | * a callback, and then prepending and appending HTML chunked encoding |
* @len are the optional close code (first 2 bytes, network | | * headers. |
* 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. | | |
*/ | | */ |
typedef int | | //@{ |
lws_callback_function(struct lws *wsi, enum lws_callback_reasons reason, | | |
void *user, void *in, size_t len); | | |
| | |
/** | | /** |
* typedef lws_extension_callback_function() - Hooks to allow extensions to | | * lws_urlencode() - like strncpy but with urlencoding |
operate | | |
* @context: Websockets context | | |
* @ext: This extension | | |
* @wsi: Opaque websocket instance pointer | | |
* @reason: The reason for the call | | |
* @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 extension that is active on a particular connection receives | | |
* callbacks during the connection lifetime to allow the extension to | | |
* operate on websocket data and manage itself. | | |
* | | |
* Libwebsockets takes care of allocating and freeing "user" memory for | | |
* each active extension on each connection. That is what is pointed t | | |
o | | |
* by the @user parameter. | | |
* | | * |
* LWS_EXT_CB_CONSTRUCT: called when the server has decided to | | * \param escaped: output buffer |
* select this extension from the list provided by the client, | | * \param string: input buffer ('/0' terminated) |
* just before the server will send back the handshake acceptin | | * \param len: output buffer max length |
g | | |
* the connection with this extension active. This gives the | | |
* extension a chance to initialize its connection context foun | | |
d | | |
* in @user. | | |
* | | * |
* LWS_EXT_CB_CLIENT_CONSTRUCT: same as LWS_EXT_CB_CONSTRUCT | | * Because urlencoding expands the output string, it's not |
* but called when client is instantiating this extension. Som | | * possible to do it in-place, ie, with escaped == string |
e | | */ |
* extensions will work the same on client and server side and | | LWS_VISIBLE LWS_EXTERN const char * |
then | | lws_urlencode(char *escaped, const char *string, int len); |
* you can just merge handlers for both CONSTRUCTS. | | |
| | /* |
| | * URLDECODE 1 / 2 |
* | | * |
* LWS_EXT_CB_DESTROY: called when the connection the extension was | | * This simple urldecode only operates until the first '\0' and requires th |
* being used on is about to be closed and deallocated. It's t | | e |
he | | * data to exist all at once |
* 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 yo | | * lws_urldecode() - like strncpy but with urldecoding |
u | | |
* are in client or server instantiation context. | | |
* | | * |
* LWS_EXT_CB_PACKET_RX_PREPARSE: when this extension was active on | | * \param string: output buffer |
* a connection, and a packet of data arrived at the connection | | * \param escaped: input buffer ('\0' terminated) |
, | | * \param len: output buffer max length |
* it is passed to this callback to give the extension a chance | | |
to | | |
* change the data, eg, decompress it. @user is pointing to th | | |
e | | |
* extension's private connection context data, @in is pointing | | |
* to an lws_tokens struct, it consists of a char * pointer cal | | |
led | | |
* token, and an int called token_len. At entry, these are | | |
* set to point to the received buffer and set to the content | | |
* length. If the extension will grow the content, it should u | | |
se | | |
* 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_CB_PACKET_TX_PRESEND: this works the same way as | | * This is only useful for '\0' terminated strings |
* LWS_EXT_CB_PACKET_RX_PREPARSE above, except it gives the | | |
* extension a chance to change websocket data just before it w | | |
ill | | |
* 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 a | | |
nd | | |
* set the lws_tokens token pointer to it. | | |
* | | * |
* LWS_EXT_CB_ARGS_VALIDATE: | | * Since urldecoding only shrinks the output string, it is possible to |
| | * do it in-place, ie, string == escaped |
*/ | | */ |
typedef int | | LWS_VISIBLE LWS_EXTERN int |
lws_extension_callback_function(struct lws_context *context, | | lws_urldecode(char *string, const char *escaped, int len); |
const struct lws_extension *ext, struct lws *w | | ///@} |
si, | | |
enum lws_extension_callback_reasons reason, | | |
void *user, void *in, size_t len); | | |
| | |
/** | | /** |
* struct lws_protocols - List of protocols and handlers server | | * lws_return_http_status() - Return simple http status |
* supports. | | * \param wsi: Websocket instance (available from user callback) |
* @name: Protocol name that must match the one given in the client | | * \param code: Status index, eg, 404 |
* Javascript new WebSocket(url, 'protocol') name. | | * \param html_body: User-readable HTML description < 1KB, or NUL |
* @callback: The service callback used for this protocol. It allows the | | L |
* service action for an entire protocol to be encapsulated in | | |
* the protocol-specific callback | | |
* @per_session_data_size: Each new connection using this protocol gets | | |
* this much memory allocated on connection establishment and | | |
* freed on connection takedown. A pointer to this per-connect | | |
ion | | |
* allocation is passed into the callback in the 'user' paramet | | |
er | | |
* @rx_buffer_size: if you want atomic frames delivered to the callback, yo | | |
u | | |
* should set this to the size of the biggest legal frame that | | |
* you support. If the frame size is exceeded, there is no | | |
* 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_PRE | | |
* and post-padding are automatically also allocated on top. | | |
* @id: ignored by lws, but useful to contain user informati | | |
on bound | | |
* to the selected protocol. For example if this protocol was | | |
* called "myprotocol-v2", you might set id to 2, and the user | | |
* code that acts differently according to the version can do s | | |
o by | | |
* switch (wsi->protocol->id), user code might use some bits as | | |
* capability flags based on selected protocol version, etc. | | |
* @user: User provided context data at the protocol level. | | |
* Accessible via lws_get_protocol(wsi)->user | | |
* This should not be confused with wsi->user, it is not the sa | | |
me. | | |
* The library completely ignores any value in here. | | |
* | | |
* This structure represents one protocol supported by the server. An | | |
* array of these structures is passed to lws_create_server() | | |
* allows as many protocols as you like to be handled by one server. | | |
* | | * |
* The first protocol given has its callback used for user callbacks wh | | * Helper to report HTTP errors back to the client cleanly and |
en | | * consistently |
* there is no agreed protocol name, that's true during HTTP part of th | | |
e | | |
* connection and true if the client did not send a Protocol: header. | | |
*/ | | */ |
| | LWS_VISIBLE LWS_EXTERN int |
struct lws_protocols { | | lws_return_http_status(struct lws *wsi, unsigned int code, |
const char *name; | | const char *html_body); |
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 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 ar | | * lws_http_redirect() - write http redirect into buffer |
e | | |
* 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 | | * \param wsi: websocket connection |
" | | * \param code: HTTP response code (eg, 301) |
* @type: What kind of args the option can take | | * \param loc: where to redirect to |
| | * \param len: length of loc |
| | * \param p: pointer current position in buffer (updated as we write) |
| | * \param end: pointer to end of buffer |
*/ | | */ |
struct lws_ext_options { | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
const char *name; | | lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int |
enum lws_ext_options_types type; | | len, |
| | unsigned char **p, unsigned char *end); |
/* 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; | | |
}; | | |
| | |
/** | | /** |
* struct lws_extension - An extension we know how to cope with | | * lws_http_transaction_completed() - wait for new http transaction or clos |
| | e |
| | * \param wsi: websocket connection |
* | | * |
* @name: Formal extension name, eg, "permessage-defla | | * Returns 1 if the HTTP connection must close now |
te" | | * Returns 0 and resets connection to wait for new HTTP header / |
* @callback: Service callback | | * transaction if possible |
* @client_offer: String containing exts and options client of | | |
fers | | |
*/ | | */ |
| | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| | lws_http_transaction_completed(struct lws *wsi); |
| | ///@} |
| | |
struct lws_extension { | | /*! \defgroup pur Sanitize / purify SQL and JSON helpers |
const char *name; | | * |
lws_extension_callback_function *callback; | | * ##Sanitize / purify SQL and JSON helpers |
const char *client_offer; | | * |
| | * APIs for escaping untrusted JSON and SQL safely before use |
/* Add new things just above here ---^ | | |
* This is part of the ABI, don't needlessly break compatibility */ | | |
}; | | |
| | |
/* | | |
* 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 | | * lws_sql_purify() - like strncpy but with escaping for sql quotes |
* | | * |
* @port: Port to listen on... you can use CONTEXT_PORT_NO_LISTEN to | | * \param escaped: output buffer |
* suppress listening on any port, that's what you want if you | | * \param string: input buffer ('/0' terminated) |
are | | * \param len: output buffer max length |
* not running a websocket server at all but just using it as a | | * |
* client | | * Because escaping expands the output string, it's not |
* @iface: NULL to bind the listen socket to all interfaces, or the | | * possible to do it in-place, ie, with escaped == string |
* interface name, eg, "eth2" | | |
* @protocols: Array of structures listing supported protocols and a protoc | | |
ol- | | |
* specific callback for each one. The list is ended with an | | |
* entry that has a NULL callback pointer. | | |
* It's not const because we write the owning_server member | | |
* @extensions: NULL or array of lws_extension structs listing the | | |
* 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 initiali | | |
zed | | |
* with a token length limit for each possible WSI_TOKEN_*** | | |
* @ssl_cert_filepath: If libwebsockets was compiled to use ssl, and you wa | | |
nt | | |
* to listen using SSL, set to the filepath to fetch th | | |
e | | |
* 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 cal | | |
led | | |
* to allow setting of the private key directly via ope | | |
nSSL | | |
* 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:!aN | | |
ULL" | | |
* or you can leave it as NULL to get "DEFAULT" | | |
* @http_proxy_address: If non-NULL, attempts to proxy via the given addres | | |
s. | | |
* If proxy auth is required, use format | | |
* "username:password@server:port" | | |
* @http_proxy_port: If http_proxy_address was non-NULL, uses this port a | | |
t | | |
* 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_... 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 t | | |
o | | |
* all libwebsocket sockets, client or server | | |
* @ka_probes: if ka_time was nonzero, after the timeout expires how many | | |
* times to try to get a response from the peer before giving u | | |
p | | |
* and killing the connection | | |
* @ka_interval: if ka_time was nonzero, how long to wait before each ka_pr | | |
obes | | |
* attempt | | |
* @provided_client_ssl_ctx: If non-null, swap out libwebsockets ssl | | |
* implementation for the one provided by provided_ssl_ctx. | | |
* Libwebsockets no longer is responsible for freeing the conte | | |
xt | | |
* if this option is selected. | | |
* @max_http_header_data: The max amount of header payload that can be hand | | |
led | | |
* in an http request (unrecognized header payload is dropped) | | |
* @max_http_header_pool: The max number of connections with http headers t | | |
hat | | |
* 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 second | | |
s. | | |
* Otherwise a default timeout is used. | | |
*/ | | */ |
| | LWS_VISIBLE LWS_EXTERN const char * |
struct lws_context_creation_info { | | lws_sql_purify(char *escaped, const char *string, int len); |
int port; | | |
const char *iface; | | |
const struct lws_protocols *protocols; | | |
const struct lws_extension *extensions; | | |
const struct lws_token_limits *token_limits; | | |
const char *ssl_private_key_password; | | |
const char *ssl_cert_filepath; | | |
const char *ssl_private_key_filepath; | | |
const char *ssl_ca_filepath; | | |
const char *ssl_cipher_list; | | |
const char *http_proxy_address; | | |
unsigned int http_proxy_port; | | |
int gid; | | |
int uid; | | |
unsigned int options; | | |
void *user; | | |
int ka_time; | | |
int ka_probes; | | |
int ka_interval; | | |
#ifdef LWS_OPENSSL_SUPPORT | | |
SSL_CTX *provided_client_ssl_ctx; | | |
#else /* maintain structure layout either way */ | | |
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 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_json_purify() - like strncpy but with escaping for json chars |
* lws_client_connect_via_info() | | |
* | | * |
* @context: lws context to create connection in | | * \param escaped: output buffer |
* @address: remote address to connect to | | * \param string: input buffer ('/0' terminated) |
* @port: remote port to connect to | | * \param len: output buffer max length |
* @ssl_connection: nonzero for ssl | | * |
* @path: uri path | | * Because escaping expands the output string, it's not |
* @host: content of host header | | * possible to do it in-place, ie, with escaped == string |
* @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 | | |
*/ | | */ |
| | LWS_VISIBLE LWS_EXTERN const char * |
| | lws_json_purify(char *escaped, const char *string, int len); |
| | ///@} |
| | |
struct lws_client_connect_info { | | /*! \defgroup ev libev helpers |
struct lws_context *context; | | * |
const char *address; | | * ##libev helpers |
int port; | | * |
int ssl_connection; | | * APIs specific to libev event loop itegration |
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_set_log_level(int level, | | |
void (*log_emit_function)(int level, const char *line)); | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lwsl_emit_syslog(int level, const char *line); | | |
| | |
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 void | | |
lws_context_destroy(struct lws_context *context); | | |
| | |
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 *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 *wsi, unsigned char **p, | | |
unsigned char *end); | | |
LWS_VISIBLE LWS_EXTERN int | | |
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_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_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | |
lws_http_transaction_completed(struct lws *wsi); | | |
| | |
#ifdef LWS_USE_LIBEV | | #ifdef LWS_USE_LIBEV |
typedef void (lws_ev_signal_cb_t)(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_VISIBLE LWS_EXTERN int |
lws_ev_sigint_cfg(struct lws_context *context, int use_ev_sigint, | | lws_ev_sigint_cfg(struct lws_context *context, int use_ev_sigint, |
lws_ev_signal_cb_t *cb); | | lws_ev_signal_cb_t *cb); |
| | |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_ev_initloop(struct lws_context *context, struct ev_loop *loop, int tsi)
; | | lws_ev_initloop(struct lws_context *context, struct ev_loop *loop, int tsi)
; |
| | |
LWS_VISIBLE void | | LWS_VISIBLE LWS_EXTERN void |
lws_ev_sigint_cb(struct ev_loop *loop, struct ev_signal *watcher, int reven
ts); | | lws_ev_sigint_cb(struct ev_loop *loop, struct ev_signal *watcher, int reven
ts); |
#endif /* LWS_USE_LIBEV */ | | #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) | | |
; | | |
| | |
| | /*! \defgroup uv libuv helpers |
| | * |
| | * ##libuv helpers |
| | * |
| | * APIs specific to libuv event loop itegration |
| | */ |
| | ///@{ |
| | #ifdef LWS_USE_LIBUV |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_uv_sigint_cfg(struct lws_context *context, int use_uv_sigint, | | lws_uv_sigint_cfg(struct lws_context *context, int use_uv_sigint, |
lws_uv_signal_cb_t *cb); | | uv_signal_cb cb); |
| | |
LWS_VISIBLE LWS_EXTERN void | | LWS_VISIBLE LWS_EXTERN void |
lws_libuv_run(const struct lws_context *context, int tsi); | | lws_libuv_run(const struct lws_context *context, int tsi); |
| | |
LWS_VISIBLE void | | LWS_VISIBLE LWS_EXTERN void |
lws_libuv_stop(struct lws_context *context); | | lws_libuv_stop(struct lws_context *context); |
| | |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, uv_signal_cb
cb, int tsi); | | lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, int tsi); |
| | |
LWS_VISIBLE LWS_EXTERN uv_loop_t * | | LWS_VISIBLE LWS_EXTERN uv_loop_t * |
lws_uv_getloop(struct lws_context *context, int tsi); | | lws_uv_getloop(struct lws_context *context, int tsi); |
| | |
LWS_VISIBLE void | | LWS_VISIBLE LWS_EXTERN void |
lws_uv_sigint_cb(uv_loop_t *loop, uv_signal_t *watcher, int signum); | | lws_uv_sigint_cb(uv_signal_t *watcher, int signum); |
#endif /* LWS_USE_LIBUV */ | | #endif /* LWS_USE_LIBUV */ |
| | ///@} |
| | |
LWS_VISIBLE LWS_EXTERN int | | /*! \defgroup timeout Connection timeouts |
lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
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 * | | APIs related to setting connection timeouts |
lws_wsi_user(struct lws *wsi); | | */ |
| | //@{ |
| | |
/* | | /* |
* NOTE: These public enums are part of the abi. If you want to add one, | | * 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. | | * add it at where specified so existing users are unaffected. |
*/ | | */ |
enum pending_timeout { | | enum pending_timeout { |
NO_PENDING_TIMEOUT = 0, | | NO_PENDING_TIMEOUT = 0, |
PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE = 1, | | PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE = 1, |
PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE = 2, | | PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE = 2, |
PENDING_TIMEOUT_ESTABLISH_WITH_SERVER = 3, | | PENDING_TIMEOUT_ESTABLISH_WITH_SERVER = 3, |
PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE = 4, | | PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE = 4, |
PENDING_TIMEOUT_AWAITING_PING = 5, | | PENDING_TIMEOUT_AWAITING_PING = 5, |
PENDING_TIMEOUT_CLOSE_ACK = 6, | | PENDING_TIMEOUT_CLOSE_ACK = 6, |
PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE = 7, | | PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE = 7, |
PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE = 8, | | PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE = 8, |
PENDING_TIMEOUT_SSL_ACCEPT = 9, | | PENDING_TIMEOUT_SSL_ACCEPT = 9, |
PENDING_TIMEOUT_HTTP_CONTENT = 10, | | PENDING_TIMEOUT_HTTP_CONTENT = 10, |
PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND = 11, | | PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND = 11, |
PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE = 12, | | PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE = 12, |
PENDING_TIMEOUT_SHUTDOWN_FLUSH = 13, | | PENDING_TIMEOUT_SHUTDOWN_FLUSH = 13, |
| | PENDING_TIMEOUT_CGI = 14, |
| | PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE = 15, |
| | PENDING_TIMEOUT_WS_PONG_CHECK_SEND_PING = 16, |
| | PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG = 17, |
| | PENDING_TIMEOUT_CLIENT_ISSUE_PAYLOAD = 18, |
| | |
/****** add new things just above ---^ ******/ | | /****** add new things just above ---^ ******/ |
}; | | }; |
| | |
| | /** |
| | * lws_set_timeout() - marks the wsi as subject to a timeout |
| | * |
| | * You will not need this unless you are doing something special |
| | * |
| | * \param wsi: Websocket connection instance |
| | * \param reason: timeout reason |
| | * \param secs: how many seconds |
| | */ |
LWS_VISIBLE LWS_EXTERN void | | LWS_VISIBLE LWS_EXTERN void |
lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs); | | lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs); |
| | ///@} |
| | |
| | /*! \defgroup sending-data Sending data |
| | |
| | APIs related to writing data on a connection |
| | */ |
| | //@{ |
| | #if !defined(LWS_SIZEOFPTR) |
| | #define LWS_SIZEOFPTR (sizeof (void *)) |
| | #endif |
| | #if !defined(u_int64_t) |
| | #define u_int64_t unsigned long long |
| | #endif |
| | |
| | #if defined(__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 ar |
| | ch */ |
| | #endif |
| | #define _LWS_PAD(n) (((n) % _LWS_PAD_SIZE) ? \ |
| | ((n) + (_LWS_PAD_SIZE - ((n) % _LWS_PAD_SIZE))) : (n)) |
| | #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 |
| | |
/* | | /* |
| | * 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. |
| | */ |
| | enum lws_write_protocol { |
| | LWS_WRITE_TEXT = 0, |
| | /**< Send a ws TEXT message,the pointer must have LWS_PRE valid |
| | * memory behind it. The receiver expects only valid utf-8 in the |
| | * payload */ |
| | LWS_WRITE_BINARY = 1, |
| | /**< Send a ws BINARY message, the pointer must have LWS_PRE valid |
| | * memory behind it. Any sequence of bytes is valid */ |
| | LWS_WRITE_CONTINUATION = 2, |
| | /**< Continue a previous ws message, the pointer must have LWS_PRE v |
| | alid |
| | * memory behind it */ |
| | LWS_WRITE_HTTP = 3, |
| | /**< Send HTTP content */ |
| | |
| | /* 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, |
| | /**< Send http headers (http2 encodes this payload and LWS_WRITE_HTT |
| | P |
| | * payload differently, http 1.x links also handle this correctly. s |
| | o |
| | * to be compatible with both in the future,header response part sho |
| | uld |
| | * be sent using this regardless of http version expected) |
| | */ |
| | |
| | /****** add new things just above ---^ ******/ |
| | |
| | /* flags */ |
| | |
| | LWS_WRITE_NO_FIN = 0x40, |
| | /**< This part of the message is not the end of the message */ |
| | |
| | LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80 |
| | /**< client packet payload goes out on wire unmunged |
| | * only useful for security tests since normal servers cannot |
| | * decode the content if used */ |
| | }; |
| | |
| | /** |
| | * lws_write() - Apply protocol then write data to client |
| | * \param wsi: Websocket instance (available from user callback) |
| | * \param buf: The data to send. For data being sent on a websocket |
| | * connection (ie, not default http), this buffer MUST have |
| | * LWS_PRE bytes valid BEFORE the pointer. |
| | * This is so the protocol header data can be added in-situ. |
| | * \param len: Count of the data bytes in the payload starting from buf |
| | * \param protocol: Use LWS_WRITE_HTTP to reply to an http connection, a |
| | nd one |
| | * of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate |
| | * data on a websockets connection. Remember to allow the extr |
| | a |
| | * bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_ |
| | TEXT |
| | * are used. |
| | * |
| | * This function provides the way to issue data back to the client |
| | * for both http and websocket protocols. |
| | * |
* IMPORTANT NOTICE! | | * IMPORTANT NOTICE! |
* | | * |
* When sending with websocket protocol | | * When sending with websocket protocol |
* | | * |
* LWS_WRITE_TEXT, | | * LWS_WRITE_TEXT, |
* LWS_WRITE_BINARY, | | * LWS_WRITE_BINARY, |
* LWS_WRITE_CONTINUATION, | | * LWS_WRITE_CONTINUATION, |
* LWS_WRITE_PING, | | * LWS_WRITE_PING, |
* LWS_WRITE_PONG | | * LWS_WRITE_PONG |
* | | * |
| | |
skipping to change at line 1606 ¶ | | skipping to change at line 3252 ¶ |
* LWS_PRE bytes valid before the buffer pointer. | | * LWS_PRE bytes valid before the buffer pointer. |
* | | * |
* LWS_PRE is at least the frame nonce + 2 header + 8 length | | * 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 o
ff. | | * LWS_SEND_BUFFER_POST_PADDING is deprecated, it's now 0 and can be left o
ff. |
* The example apps no longer use it. | | * The example apps no longer use it. |
* | | * |
* Pad LWS_PRE to the CPU word size, so that word references | | * Pad LWS_PRE to the CPU word size, so that word references |
* to the address immediately after the padding won't cause an unaligned ac
cess | | * to the address immediately after the padding won't cause an unaligned ac
cess |
* error. Sometimes for performance reasons the recommended padding is even | | * error. Sometimes for performance reasons the recommended padding is even |
* larger than sizeof(void *). | | * larger than sizeof(void *). |
| | * |
| | * In the case of sending using websocket protocol, be sure to allocate |
| | * valid storage before and after buf as explained above. This scheme |
| | * allows maximum efficiency of sending data and protocol in a single |
| | * packet while not burdening the user code with any protocol knowledge |
| | . |
| | * |
| | * Return may be -1 for a fatal error needing connection close, or a |
| | * positive number reflecting the amount of bytes actually sent. This |
| | * can be less than the requested number of bytes due to OS memory |
| | * pressure at any given time. |
*/ | | */ |
| | |
#if !defined(LWS_SIZEOFPTR) | | |
#define LWS_SIZEOFPTR (sizeof (void *)) | | |
#endif | | |
#if !defined(u_int64_t) | | |
#define u_int64_t unsigned long long | | |
#endif | | |
| | |
#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 ar | | |
ch */ | | |
#endif | | |
#define _LWS_PAD(n) (((n) % _LWS_PAD_SIZE) ? \ | | |
((n) + (_LWS_PAD_SIZE - ((n) % _LWS_PAD_SIZE))) : (n)) | | |
#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_VISIBLE LWS_EXTERN int |
lws_write(struct lws *wsi, unsigned char *buf, size_t len, | | lws_write(struct lws *wsi, unsigned char *buf, size_t len, |
enum lws_write_protocol protocol); | | 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 */ | | /* helper for case where buffer may be const */ |
#define lws_write_http(wsi, buf, len) \ | | #define lws_write_http(wsi, buf, len) \ |
lws_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP) | | lws_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP) |
| | |
LWS_VISIBLE LWS_EXTERN int | | ///@} |
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 *wsi); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_return_http_status(struct lws *wsi, unsigned int code, | | |
const char *html_body); | | |
| | |
LWS_VISIBLE LWS_EXTERN const struct lws_protocols * | | /** \defgroup callback-when-writeable Callback when writeable |
lws_get_protocol(struct lws *wsi); | | * |
| | * ##Callback When Writeable |
| | * |
| | * lws can only write data on a connection when it is able to accept more |
| | * data without blocking. |
| | * |
| | * So a basic requirement is we should only use the lws_write() apis when t |
| | he |
| | * connection we want to write on says that he can accept more data. |
| | * |
| | * When lws cannot complete your send at the time, it will buffer the data |
| | * and send it in the background, suppressing any further WRITEABLE callbac |
| | ks |
| | * on that connection until it completes. So it is important to write new |
| | * things in a new writeable callback. |
| | * |
| | * These apis reflect the various ways we can indicate we would like to be |
| | * called back when one or more connections is writeable. |
| | */ |
| | ///@{ |
| | |
| | /** |
| | * lws_callback_on_writable() - Request a callback when this socket |
| | * becomes able to be written to witho |
| | ut |
| | * blocking |
| | * |
| | * \param wsi: Websocket connection instance to get callback for |
| | * |
| | * - Which: only this wsi |
| | * - When: when the individual connection becomes writeable |
| | * - What: LWS_CALLBACK_*_WRITEABLE |
| | */ |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_callback_on_writable(struct lws *wsi); | | lws_callback_on_writable(struct lws *wsi); |
| | |
| | /** |
| | * lws_callback_on_writable_all_protocol() - Request a callback for all |
| | * connections on same vhost using the given protocol w |
| | hen it |
| | * becomes possible to write to each socket without |
| | * blocking in turn. |
| | * |
| | * \param context: lws_context |
| | * \param protocol: Protocol whose connections will get callbacks |
| | * |
| | * - Which: connections using this protocol on ANY VHOST |
| | * - When: when the individual connection becomes writeable |
| | * - What: LWS_CALLBACK_*_WRITEABLE |
| | */ |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_callback_on_writable_all_protocol(const struct lws_context *context, | | lws_callback_on_writable_all_protocol(const struct lws_context *context, |
const struct lws_protocols *protocol); | | const struct lws_protocols *protocol); |
| | |
| | /** |
| | * lws_callback_on_writable_all_protocol_vhost() - Request a callback for |
| | * all connections using the given protocol when it |
| | * becomes possible to write to each socket without |
| | * blocking in turn. |
| | * |
| | * \param vhost: Only consider connections on this lws_vhost |
| | * \param protocol: Protocol whose connections will get callbacks |
| | * |
| | * - Which: connections using this protocol on GIVEN VHOST ONLY |
| | * - When: when the individual connection becomes writeable |
| | * - What: LWS_CALLBACK_*_WRITEABLE |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost, |
| | const struct lws_protocols *protocol); |
| | |
| | /** |
| | * lws_callback_all_protocol() - Callback all connections using |
| | * the given protocol with the given reason |
| | * |
| | * \param context: lws_context |
| | * \param protocol: Protocol whose connections will get callbacks |
| | * \param reason: Callback reason index |
| | * |
| | * - Which: connections using this protocol on ALL VHOSTS |
| | * - When: when the individual connection becomes writeable |
| | * - What: reason |
| | */ |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_callback_all_protocol(struct lws_context *context, | | lws_callback_all_protocol(struct lws_context *context, |
const struct lws_protocols *protocol, int reason); | | const struct lws_protocols *protocol, int reason); |
| | |
| | /** |
| | * lws_callback_all_protocol_vhost() - Callback all connections using |
| | * the given protocol with the given reason |
| | * |
| | * \param vh: Vhost whose connections will get callbacks |
| | * \param protocol: Which protocol to match |
| | * \param reason: Callback reason index |
| | * |
| | * - Which: connections using this protocol on GIVEN VHOST ONLY |
| | * - When: now |
| | * - What: reason |
| | */ |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_get_socket_fd(struct lws *wsi); | | lws_callback_all_protocol_vhost(struct lws_vhost *vh, |
| | const struct lws_protocols *protocol, int reason); |
| | |
| | /** |
| | * lws_callback_vhost_protocols() - Callback all protocols enabled on a vho |
| | st |
| | * with the given reason |
| | * |
| | * \param wsi: wsi whose vhost will get callbacks |
| | * \param reason: Callback reason index |
| | * \param in: in argument to callback |
| | * \param len: len argument to callback |
| | * |
| | * - Which: connections using this protocol on same VHOST as wsi ONLY |
| | * - When: now |
| | * - What: reason |
| | */ |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_is_final_fragment(struct lws *wsi); | | lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, int len |
| | ); |
LWS_VISIBLE LWS_EXTERN unsigned char | | |
lws_get_reserved_bits(struct lws *wsi); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_rx_flow_control(struct lws *wsi, int enable); | | lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, |
| | void *user, void *in, size_t len); |
LWS_VISIBLE LWS_EXTERN void | | |
lws_rx_flow_allow_all_protocol(const struct lws_context *context, | | |
const struct lws_protocols *protocol); | | |
| | |
LWS_VISIBLE LWS_EXTERN size_t | | /** |
lws_remaining_packet_payload(struct lws *wsi); | | * lws_get_socket_fd() - returns the socket file descriptor |
| | * |
| | * You will not need this unless you are doing something special |
| | * |
| | * \param wsi: Websocket connection instance |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_get_socket_fd(struct lws *wsi); |
| | |
/* | | /** |
| | * lws_get_peer_write_allowance() - get the amount of data writeable to pee |
| | r |
| | * if known |
| | * |
| | * \param wsi: Websocket connection instance |
| | * |
* if the protocol does not have any guidance, returns -1. Currently only | | * if the protocol does not have any guidance, returns -1. Currently only |
* http2 connections get send window information from this API. But your c
ode | | * http2 connections get send window information from this API. But your c
ode |
* should use it so it can work properly with any protocol. | | * 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 | | * 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 amo
unt | | * reported it has buffer space for. That has NO relationship with the amo
unt |
* of buffer space your OS can accept on this connection for a write action
. | | * 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 interme
diary | | * This number represents the maximum you could send to the peer or interme
diary |
* on this connection right now without it complaining. | | * on this connection right now without the protocol complaining. |
* | | * |
* lws manages accounting for send window updates and payload writes | | * lws manages accounting for send window updates and payload writes |
* automatically, so this number reflects the situation at the peer or | | * automatically, so this number reflects the situation at the peer or |
* intermediary dynamically. | | * intermediary dynamically. |
*/ | | */ |
LWS_VISIBLE LWS_EXTERN size_t | | LWS_VISIBLE LWS_EXTERN size_t |
lws_get_peer_write_allowance(struct lws *wsi); | | lws_get_peer_write_allowance(struct lws *wsi); |
| | ///@} |
| | |
/* deprecated, use lws_client_connect_via_info() */ | | /** |
LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT | | * lws_rx_flow_control() - Enable and disable socket servicing for |
lws_client_connect(struct lws_context *clients, const char *address, | | * received packets. |
int port, int ssl_connection, const char *path, | | * |
const char *host, const char *origin, const char *protoco | | * If the output side of a server process becomes choked, this allows flow |
l, | | * control for the input side. |
int ietf_version_or_minus_one) LWS_WARN_DEPRECATED; | | * |
/* deprecated, use lws_client_connect_via_info() */ | | * \param wsi: Websocket connection instance to get callback for |
LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT | | * \param enable: 0 = disable read servicing for this connection, 1 = |
lws_client_connect_extended(struct lws_context *clients, const char *addres | | enable |
s, | | */ |
int port, int ssl_connection, const char *path, | | LWS_VISIBLE LWS_EXTERN int |
const char *host, const char *origin, | | lws_rx_flow_control(struct lws *wsi, int enable); |
const char *protocol, int ietf_version_or_minus_ | | |
one, | | |
void *userdata) LWS_WARN_DEPRECATED; | | |
| | |
LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT | | /** |
lws_client_connect_via_info(struct lws_client_connect_info * ccinfo); | | * lws_rx_flow_allow_all_protocol() - Allow all connections with this proto |
| | col to receive |
| | * |
| | * When the user server code realizes it can accept more input, it can |
| | * call this to have the RX flow restriction removed from all connections u |
| | sing |
| | * the given protocol. |
| | * \param context: lws_context |
| | * \param protocol: all connections using this protocol will be allowed |
| | to receive |
| | */ |
| | LWS_VISIBLE LWS_EXTERN void |
| | lws_rx_flow_allow_all_protocol(const struct lws_context *context, |
| | const struct lws_protocols *protocol); |
| | |
| | /** |
| | * lws_remaining_packet_payload() - Bytes to come before "overall" |
| | * rx packet is complete |
| | * \param wsi: Websocket instance (available from user callback) |
| | * |
| | * This function is intended to be called from the callback if the |
| | * user code is interested in "complete packets" from the client. |
| | * libwebsockets just passes through payload as it comes and issues a buff |
| | er |
| | * additionally when it hits a built-in limit. The LWS_CALLBACK_RECEIVE |
| | * callback handler can use this API to find out if the buffer it has just |
| | * been given is the last piece of a "complete packet" from the client -- |
| | * when that is the case lws_remaining_packet_payload() will return |
| | * 0. |
| | * |
| | * Many protocols won't care becuse their packets are always small. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN size_t |
| | lws_remaining_packet_payload(struct lws *wsi); |
| | |
| | /** \defgroup sock-adopt Socket adoption helpers |
| | * ##Socket adoption helpers |
| | * |
| | * When integrating with an external app with its own event loop, these can |
| | * be used to accept connections from someone else's listening socket. |
| | * |
| | * When using lws own event loop, these are not needed. |
| | */ |
| | ///@{ |
| | |
| | /** |
| | * lws_adopt_socket() - adopt foreign socket as if listen socket accepted i |
| | t |
| | * \param context: lws context |
| | * \param accept_fd: fd of already-accepted socket to adopt |
| | * |
| | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
| | * returns NULL, having cleaned up any new wsi pieces. |
| | * |
| | * LWS adopts the socket in http serving mode, it's ready to accept an upgr |
| | ade |
| | * to ws or just serve http. |
| | */ |
LWS_VISIBLE LWS_EXTERN struct lws * | | LWS_VISIBLE LWS_EXTERN struct lws * |
lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd); | | lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd); |
| | /** |
| | * lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if lis |
| | ten socket accepted it |
| | * \param context: lws context |
| | * \param accept_fd: fd of already-accepted socket to adopt |
| | * \param readbuf: NULL or pointer to data that must be drained before |
| | reading from |
| | * accept_fd |
| | * \param len: The length of the data held at \param readbuf |
| | * |
| | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
| | * returns NULL, having cleaned up any new wsi pieces. |
| | * |
| | * LWS adopts the socket in http serving mode, it's ready to accept an upgr |
| | ade |
| | * to ws or just serve http. |
| | * |
| | * If your external code did not already read from the socket, you can use |
| | * lws_adopt_socket() instead. |
| | * |
| | * This api is guaranteed to use the data at \param readbuf first, before r |
| | eading from |
| | * the socket. |
| | * |
| | * readbuf is limited to the size of the ah rx buf, currently 2048 bytes. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN struct lws * |
| | lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accep |
| | t_fd, |
| | const char *readbuf, size_t len); |
| | ///@} |
| | |
| | /** \defgroup net Network related helper APIs |
| | * ##Network related helper APIs |
| | * |
| | * These wrap miscellaneous useful network-related functions |
| | */ |
| | ///@{ |
| | |
| | /** |
| | * lws_canonical_hostname() - returns this host's hostname |
| | * |
| | * This is typically used by client code to fill in the host parameter |
| | * when making a client connection. You can only call it after the context |
| | * has been created. |
| | * |
| | * \param context: Websocket context |
| | */ |
LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT | | LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT |
lws_canonical_hostname(struct lws_context *context); | | lws_canonical_hostname(struct lws_context *context); |
| | |
| | /** |
| | * lws_get_peer_addresses() - Get client address information |
| | * \param wsi: Local struct lws associated with |
| | * \param fd: Connection socket descriptor |
| | * \param name: Buffer to take client address name |
| | * \param name_len: Length of client address name buffer |
| | * \param rip: Buffer to take client address IP dotted quad |
| | * \param rip_len: Length of client address IP buffer |
| | * |
| | * This function fills in name and rip with the name and IP of |
| | * the client connected with socket descriptor fd. Names may be |
| | * truncated if there is not enough room. If either cannot be |
| | * determined, they will be returned as valid zero-length strings. |
| | */ |
LWS_VISIBLE LWS_EXTERN void | | LWS_VISIBLE LWS_EXTERN void |
lws_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name, | | lws_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name, |
int name_len, char *rip, int rip_len); | | int name_len, char *rip, int rip_len); |
| | |
| | /** |
| | * lws_get_peer_simple() - Get client address information without RDNS |
| | * |
| | * \param wsi: Local struct lws associated with |
| | * \param name: Buffer to take client address name |
| | * \param namelen: Length of client address name buffer |
| | * |
| | * This provides a 123.123.123.123 type IP address in name from the |
| | * peer that has connected to wsi |
| | */ |
| | LWS_VISIBLE LWS_EXTERN const char * |
| | lws_get_peer_simple(struct lws *wsi, char *name, int namelen); |
| | #ifndef LWS_WITH_ESP8266 |
| | /** |
| | * lws_interface_to_sa() - Convert interface name or IP to sockaddr struct |
| | * |
| | * \param ipv6: Allow IPV6 addresses |
| | * \param ifname: Interface name or IP |
| | * \param addr: struct sockaddr_in * to be written |
| | * \param addrlen: Length of addr |
| | * |
| | * This converts a textual network interface name to a sockaddr usable by |
| | * other network functions |
| | */ |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_get_random(struct lws_context *context, void *buf, int len); | | lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr, |
| | size_t addrlen); |
| | ///@} |
| | #endif |
| | |
| | /** \defgroup misc Miscellaneous APIs |
| | * ##Miscellaneous APIs |
| | * |
| | * Various APIs outside of other categories |
| | */ |
| | ///@{ |
| | |
| | /** |
| | * lws_snprintf(): 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 yo |
| | u |
| | * 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, ...); |
| | |
| | /** |
| | * lws_get_random(): fill a buffer with platform random data |
| | * |
| | * \param context: the lws context |
| | * \param buf: buffer to fill |
| | * \param len: how much to fill |
| | * |
| | * This is intended to be called from the LWS_CALLBACK_RECEIVE callback if |
| | * it's interested to see if the frame it's dealing with was sent in binary |
| | * mode. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_get_random(struct lws_context *context, void *buf, int len); |
| | /** |
| | * lws_daemonize(): fill a buffer with platform random data |
| | * |
| | * \param _lock_path: the filepath to write the lock file |
| | * |
| | * Spawn lws as a background process, taking care of various things |
| | */ |
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
lws_daemonize(const char *_lock_path); | | lws_daemonize(const char *_lock_path); |
| | /** |
| | * lws_get_library_version(): return string describing the version of lws |
| | * |
| | * On unix, also includes the git describe |
| | */ |
| | LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT |
| | lws_get_library_version(void); |
| | |
| | /** |
| | * lws_wsi_user() - get the user data associated with the connection |
| | * \param wsi: lws connection |
| | * |
| | * Not normally needed since it's passed into the callback |
| | */ |
| | LWS_VISIBLE LWS_EXTERN void * |
| | lws_wsi_user(struct lws *wsi); |
| | |
| | /** |
| | * lws_parse_uri: cut up prot:/ads:port/path into pieces |
| | * Notice it does so by dropping '\0' into input string |
| | * and the leading / on the path is consequently lost |
| | * |
| | * \param p: incoming uri string.. will get written to |
| | * \param prot: result pointer for protocol part (https://) |
| | * \param ads: result pointer for address part |
| | * \param port: result pointer for port part |
| | * \param path: result pointer for path part |
| | */ |
| | 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_now_secs(): return seconds since 1970-1-1 |
| | */ |
| | LWS_VISIBLE LWS_EXTERN unsigned long |
| | lws_now_secs(void); |
| | |
| | /** |
| | * lws_get_context - Allow geting lws_context from a Websocket connection |
| | * instance |
| | * |
| | * With this function, users can access context in the callback function. |
| | * Otherwise users may have to declare context as a global variable. |
| | * |
| | * \param wsi: Websocket connection instance |
| | */ |
| | LWS_VISIBLE LWS_EXTERN struct lws_context * LWS_WARN_UNUSED_RESULT |
| | lws_get_context(const struct lws *wsi); |
| | |
| | /** |
| | * lws_get_count_threads(): how many service threads the context uses |
| | * |
| | * \param context: the lws context |
| | * |
| | * By default this is always 1, if you asked for more than lws can handle i |
| | t |
| | * will clip the number of threads. So you can use this to find out how ma |
| | ny |
| | * threads are actually in use. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| | lws_get_count_threads(struct lws_context *context); |
| | |
| | /** |
| | * lws_get_parent() - get parent wsi or NULL |
| | * \param wsi: lws connection |
| | * |
| | * Specialized wsi like cgi stdin/out/err are associated to a parent wsi, |
| | * this allows you to get their parent. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT |
| | lws_get_parent(const struct lws *wsi); |
| | |
| | /** |
| | * lws_get_child() - get child wsi or NULL |
| | * \param wsi: lws connection |
| | * |
| | * Allows you to find a related wsi from the parent wsi. |
| | */ |
| | LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT |
| | lws_get_child(const struct lws *wsi); |
| | |
| | /* |
| | * \deprecated DEPRECATED 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 *wsi, unsigned char *buf, size_t len); |
| | |
| | /** |
| | * lws_set_allocator() - custom allocator support |
| | * |
| | * \param realloc |
| | * |
| | * Allows you to replace the allocator (and deallocator) used by lws |
| | */ |
| | LWS_VISIBLE LWS_EXTERN void |
| | lws_set_allocator(void *(*realloc)(void *ptr, size_t size)); |
| | ///@} |
| | |
| | /** \defgroup wsstatus Websocket status APIs |
| | * ##Websocket connection status APIs |
| | * |
| | * These provide information about ws connection or message status |
| | */ |
| | ///@{ |
| | /** |
| | * lws_send_pipe_choked() - tests if socket is writable or not |
| | * \param wsi: lws connection |
| | * |
| | * Allows you to check if you can write more on the socket |
| | */ |
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
lws_send_pipe_choked(struct lws *wsi); | | lws_send_pipe_choked(struct lws *wsi); |
| | |
| | /** |
| | * lws_is_final_fragment() - tests if last part of ws message |
| | * \param wsi: lws connection |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_is_final_fragment(struct lws *wsi); |
| | |
| | /** |
| | * lws_get_reserved_bits() - access reserved bits of ws frame |
| | * \param wsi: lws connection |
| | */ |
| | LWS_VISIBLE LWS_EXTERN unsigned char |
| | lws_get_reserved_bits(struct lws *wsi); |
| | |
| | /** |
| | * lws_partial_buffered() - find out if lws buffered the last write |
| | * \param wsi: websocket connection to check |
| | * |
| | * Returns 1 if you cannot use lws_write because the last |
| | * write on this connection is still buffered, and can't be cleared without |
| | * returning to the service loop and waiting for the connection to be |
| | * writeable again. |
| | * |
| | * If you will try to do >1 lws_write call inside a single |
| | * WRITEABLE callback, you must check this after every write and bail if |
| | * set, ask for a new writeable callback and continue writing from there. |
| | * |
| | * This is never set at the start of a writeable callback, but any write |
| | * may set it. |
| | */ |
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
lws_partial_buffered(struct lws *wsi); | | lws_partial_buffered(struct lws *wsi); |
| | |
| | /** |
| | * lws_frame_is_binary(): true if the current frame was sent in binary mode |
| | * |
| | * \param wsi: the connection we are inquiring about |
| | * |
| | * This is intended to be called from the LWS_CALLBACK_RECEIVE callback if |
| | * it's interested to see if the frame it's dealing with was sent in binary |
| | * mode. |
| | */ |
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
lws_frame_is_binary(struct lws *wsi); | | lws_frame_is_binary(struct lws *wsi); |
| | |
| | /** |
| | * lws_is_ssl() - Find out if connection is using SSL |
| | * \param wsi: websocket connection to check |
| | * |
| | * Returns 0 if the connection is not using SSL, 1 if using SSL and |
| | * using verified cert, and 2 if using SSL but the cert was not |
| | * checked (appears for client wsi told to skip check on connection) |
| | */ |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_is_ssl(struct lws *wsi); | | lws_is_ssl(struct lws *wsi); |
| | /** |
| | * lws_is_cgi() - find out if this wsi is running a cgi process |
| | * \param wsi: lws connection |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_is_cgi(struct lws *wsi); |
| | ///@} |
| | |
| | /** \defgroup sha SHA and B64 helpers |
| | * ##SHA and B64 helpers |
| | * |
| | * These provide SHA-1 and B64 helper apis |
| | */ |
| | ///@{ |
#ifdef LWS_SHA1_USE_OPENSSL_NAME | | #ifdef LWS_SHA1_USE_OPENSSL_NAME |
#define lws_SHA1 SHA1 | | #define lws_SHA1 SHA1 |
#else | | #else |
| | /** |
| | * lws_SHA1(): make a SHA-1 digest of a buffer |
| | * |
| | * \param d: incoming buffer |
| | * \param n: length of incoming buffer |
| | * \param md: buffer for message digest (must be >= 20 bytes) |
| | * |
| | * Reduces any size buffer into a 20-byte SHA-1 hash. |
| | */ |
LWS_VISIBLE LWS_EXTERN unsigned char * | | LWS_VISIBLE LWS_EXTERN unsigned char * |
lws_SHA1(const unsigned char *d, size_t n, unsigned char *md); | | lws_SHA1(const unsigned char *d, size_t n, unsigned char *md); |
#endif | | #endif |
| | /** |
| | * lws_b64_encode_string(): encode a string into base 64 |
| | * |
| | * \param in: incoming buffer |
| | * \param in_len: length of incoming buffer |
| | * \param out: result buffer |
| | * \param out_size: length of result buffer |
| | * |
| | * Encodes a string using b64 |
| | */ |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_b64_encode_string(const char *in, int in_len, char *out, int out_size); | | lws_b64_encode_string(const char *in, int in_len, char *out, int out_size); |
| | /** |
| | * lws_b64_decode_string(): decode a string from base 64 |
| | * |
| | * \param in: incoming buffer |
| | * \param out: result buffer |
| | * \param out_size: length of result buffer |
| | * |
| | * Decodes a string using b64 |
| | */ |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_b64_decode_string(const char *in, char *out, int out_size); | | lws_b64_decode_string(const char *in, char *out, int out_size); |
| | ///@} |
| | |
LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT | | /*! \defgroup cgi cgi handling |
lws_get_library_version(void); | | |
| | |
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); | | |
| | |
/* | | |
* Access to http headers | | |
* | | * |
* In lws the client http headers are temporarily malloc'd only for the | | * ##CGI handling |
* 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 life | | |
time | | |
* and would then just be taking up space needlessly. | | |
* | | * |
* During LWS_CALLBACK_HTTP when the URI path is delivered is the last tim | | * These functions allow low-level control over stdin/out/err of the cgi. |
e | | |
* 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 termina | | * However for most cases, binding the cgi to http in and out, the default |
ting | | * lws implementation already does the right thing. |
* '\0', however you must allocate for it when using the _copy apis. So t | | |
he | | |
* length reported for a header containing "123" is 3, but you must provid | | |
e | | |
* a buffer of length 4 so that "123\0" may be copied into it, or the copy | | |
* will fail with a nonzero return code. | | |
*/ | | */ |
| | #ifdef LWS_WITH_CGI |
| | enum lws_enum_stdinouterr { |
| | LWS_STDIN = 0, |
| | LWS_STDOUT = 1, |
| | LWS_STDERR = 2, |
| | }; |
| | |
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | enum lws_cgi_hdr_state { |
lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h); | | LCHS_HEADER, |
| | LCHS_CR1, |
| | LCHS_LF1, |
| | LCHS_CR2, |
| | LCHS_LF2, |
| | LHCS_PAYLOAD, |
| | LCHS_SINGLE_0A, |
| | }; |
| | |
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | struct lws_cgi_args { |
lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag | | struct lws **stdwsi; /**< get fd with lws_get_socket_fd() */ |
_idx); | | enum lws_enum_stdinouterr ch; /**< channel index */ |
| | unsigned char *data; /**< for messages with payload */ |
| | enum lws_cgi_hdr_state hdr_state; /**< track where we are in cgi hea |
| | ders */ |
| | int len; /**< length */ |
| | }; |
| | |
/* | | /** |
* copies the whole, aggregated header, even if it was delivered in | | * lws_cgi: spawn network-connected cgi process |
* several actual headers piece by piece | | * |
| | * \param wsi: connection to own the process |
| | * \param exec_array: array of "exec-name" "arg1" ... "argn" NULL |
| | * \param script_uri_path_len: how many chars on the left of the uri are th |
| | e path to the cgi |
| | * \param timeout_secs: seconds script should be allowed to run |
| | * \param mp_cgienv: pvo list with per-vhost cgi options to put in env |
*/ | | */ |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h | | lws_cgi(struct lws *wsi, const char * const *exec_array, |
); | | int script_uri_path_len, int timeout_secs, |
| | const struct lws_protocol_vhost_options *mp_cgienv); |
| | |
/* | | /** |
* copies only fragment frag_idx of a header. Normally this is only useful | | * lws_cgi_write_split_stdout_headers: write cgi output accounting for head |
* to parse URI arguments like ?x=1&y=2, token index WSI_TOKEN_HTTP_URI_ARG | | er part |
S | | * |
* fragment 0 will contain "x=1" and fragment 1 "y=2" | | * \param wsi: connection to own the process |
*/ | | */ |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int |
lws_hdr_copy_fragment(struct lws *wsi, char *dest, int len, | | lws_cgi_write_split_stdout_headers(struct lws *wsi); |
enum lws_token_indexes h, int frag_idx); | | |
| | |
/* get the active file operations struct */ | | |
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_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); | | * lws_cgi_kill: terminate cgi process associated with wsi |
| | * |
| | * \param wsi: connection to own the process |
| | */ |
| | LWS_VISIBLE LWS_EXTERN int |
| | lws_cgi_kill(struct lws *wsi); |
| | #endif |
| | ///@} |
| | |
/* | | /*! \defgroup fops file operation wrapping |
* Wsi-associated File Operations access helpers | | * |
| | * ##File operation wrapping |
* | | * |
* Use these helper functions if you want to access a file from the perspec
tive | | * Use these helper functions if you want to access a file from the perspec
tive |
* of a specific wsi, which is usually the case. If you just want contextl
ess | | * of a specific wsi, which is usually the case. If you just want contextl
ess |
* file access, use the fops callbacks directly with NULL wsi instead of th
ese | | * file access, use the fops callbacks directly with NULL wsi instead of th
ese |
* helpers. | | * helpers. |
* | | * |
* If so, then it calls the platform handler or user overrides where presen
t | | * If so, then it calls the platform handler or user overrides where presen
t |
* (as defined in info->fops) | | * (as defined in info->fops) |
* | | * |
* The advantage from all this is user code can be portable for file operat
ions | | * The advantage from all this is user code can be portable for file operat
ions |
* without having to deal with differences between platforms. | | * without having to deal with differences between platforms. |
*/ | | */ |
| | //@{ |
| | |
| | /** struct lws_plat_file_ops - Platform-specific file operations |
| | * |
| | * These provide platform-agnostic ways to deal with filesystem access in t |
| | he |
| | * library and in the user code. |
| | */ |
| | struct lws_plat_file_ops { |
| | lws_filefd_type (*open)(struct lws *wsi, const char *filename, |
| | unsigned long *filelen, int flags); |
| | /**< Open file (always binary access if plat supports it) |
| | * filelen is filled on exit to be the length of the file |
| | * flags should be set to O_RDONLY or O_RDWR */ |
| | int (*close)(struct lws *wsi, lws_filefd_type fd); |
| | /**< close file */ |
| | unsigned long (*seek_cur)(struct lws *wsi, lws_filefd_type fd, |
| | long offset_from_cur_pos); |
| | /**< seek from current position */ |
| | int (*read)(struct lws *wsi, lws_filefd_type fd, unsigned long *amou |
| | nt, |
| | unsigned char *buf, unsigned long len); |
| | /**< Read from file, on exit *amount is set to amount actually read |
| | */ |
| | int (*write)(struct lws *wsi, lws_filefd_type fd, unsigned long *amo |
| | unt, |
| | unsigned char *buf, unsigned long len); |
| | /**< Write to file, on exit *amount is set to amount actually writte |
| | n */ |
| | |
| | /* Add new things just above here ---^ |
| | * This is part of the ABI, don't needlessly break compatibility */ |
| | }; |
| | |
| | /** |
| | * lws_get_fops() - get current file ops |
| | * |
| | * \param context: context |
| | */ |
| | LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops * LWS_WARN_UNUSED_RESULT |
| | lws_get_fops(struct lws_context *context); |
| | |
| | /** |
| | * lws_plat_file_open() - file open operations |
| | * |
| | * \param wsi: connection doing the opening |
| | * \param filename: filename to open |
| | * \param filelen: length of file (filled in by call) |
| | * \param flags: open flags |
| | */ |
static LWS_INLINE lws_filefd_type LWS_WARN_UNUSED_RESULT | | static LWS_INLINE lws_filefd_type LWS_WARN_UNUSED_RESULT |
lws_plat_file_open(struct lws *wsi, const char *filename, | | lws_plat_file_open(struct lws *wsi, const char *filename, |
unsigned long *filelen, int flags) | | unsigned long *filelen, int flags) |
{ | | { |
return lws_get_fops(lws_get_context(wsi))->open(wsi, filename, | | return lws_get_fops(lws_get_context(wsi))->open(wsi, filename, |
filelen, flags); | | filelen, flags); |
} | | } |
| | |
| | /** |
| | * lws_plat_file_close() - close file |
| | * |
| | * \param wsi: connection opened by |
| | * \param fd: file descriptor |
| | */ |
static LWS_INLINE int | | static LWS_INLINE int |
lws_plat_file_close(struct lws *wsi, lws_filefd_type fd) | | lws_plat_file_close(struct lws *wsi, lws_filefd_type fd) |
{ | | { |
return lws_get_fops(lws_get_context(wsi))->close(wsi, fd); | | return lws_get_fops(lws_get_context(wsi))->close(wsi, fd); |
} | | } |
| | |
| | /** |
| | * lws_plat_file_seek_cur() - close file |
| | * |
| | * \param wsi: connection opened by |
| | * \param fd: file descriptor |
| | * \param offset: position to seek to |
| | */ |
static LWS_INLINE unsigned long | | static LWS_INLINE unsigned long |
lws_plat_file_seek_cur(struct lws *wsi, lws_filefd_type fd, long offset) | | lws_plat_file_seek_cur(struct lws *wsi, lws_filefd_type fd, long offset) |
{ | | { |
return lws_get_fops(lws_get_context(wsi))->seek_cur(wsi, fd, offset)
; | | return lws_get_fops(lws_get_context(wsi))->seek_cur(wsi, fd, offset)
; |
} | | } |
| | /** |
| | * lws_plat_file_read() - read from file |
| | * |
| | * \param wsi: connection opened by |
| | * \param fd: file descriptor |
| | * \param amount: how much to read (rewritten by call) |
| | * \param buf: buffer to write to |
| | * \param len: max length |
| | */ |
static LWS_INLINE int LWS_WARN_UNUSED_RESULT | | static LWS_INLINE int LWS_WARN_UNUSED_RESULT |
lws_plat_file_read(struct lws *wsi, lws_filefd_type fd, unsigned long *amou
nt, | | lws_plat_file_read(struct lws *wsi, lws_filefd_type fd, unsigned long *amou
nt, |
unsigned char *buf, unsigned long len) | | unsigned char *buf, unsigned long len) |
{ | | { |
return lws_get_fops(lws_get_context(wsi))->read(wsi, fd, amount, buf
, | | return lws_get_fops(lws_get_context(wsi))->read(wsi, fd, amount, buf
, |
len); | | len); |
} | | } |
| | /** |
| | * lws_plat_file_write() - write from file |
| | * |
| | * \param wsi: connection opened by |
| | * \param fd: file descriptor |
| | * \param amount: how much to write (rewritten by call) |
| | * \param buf: buffer to read from |
| | * \param len: max length |
| | */ |
static LWS_INLINE int LWS_WARN_UNUSED_RESULT | | static LWS_INLINE int LWS_WARN_UNUSED_RESULT |
lws_plat_file_write(struct lws *wsi, lws_filefd_type fd, unsigned long *amo
unt, | | lws_plat_file_write(struct lws *wsi, lws_filefd_type fd, unsigned long *amo
unt, |
unsigned char *buf, unsigned long len) | | unsigned char *buf, unsigned long len) |
{ | | { |
return lws_get_fops(lws_get_context(wsi))->write(wsi, fd, amount, bu
f, | | return lws_get_fops(lws_get_context(wsi))->write(wsi, fd, amount, bu
f, |
len); | | len); |
} | | } |
| | //@} |
| | |
/* | | /** \defgroup smtp |
* Note: this is not normally needed as a user api. It's provided in case | | * \ingroup lwsapi |
it is | | * ##SMTP related functions |
* useful when integrating with other app poll loop service code. | | * |
| | * These apis let you communicate with a local SMTP server to send email fr |
| | om |
| | * lws. It handles all the SMTP sequencing and protocol actions. |
| | * |
| | * Your system should have postfix, sendmail or another MTA listening on po |
| | rt |
| | * 25 and able to send email using the "mail" commandline app. Usually dis |
| | tro |
| | * MTAs are configured for this by default. |
| | * |
| | * It runs via its own libuv events if initialized (which requires giving i |
| | t |
| | * a libuv loop to attach to). |
| | * |
| | * It operates using three callbacks, on_next() queries if there is a new e |
| | mail |
| | * to send, on_get_body() asks for the body of the email, and on_sent() is |
| | * called after the email is successfully sent. |
| | * |
| | * To use it |
| | * |
| | * - create an lws_email struct |
| | * |
| | * - initialize data, loop, the email_* strings, max_content_size and |
| | * the callbacks |
| | * |
| | * - call lws_email_init() |
| | * |
| | * When you have at least one email to send, call lws_email_check() to |
| | * schedule starting to send it. |
*/ | | */ |
LWS_VISIBLE LWS_EXTERN int | | //@{ |
lws_read(struct lws *wsi, unsigned char *buf, size_t len); | | #ifdef LWS_WITH_SMTP |
| | |
#ifndef LWS_NO_EXTENSIONS | | /** enum lwsgs_smtp_states - where we are in SMTP protocol sequence */ |
/* Deprecated | | enum lwsgs_smtp_states { |
| | LGSSMTP_IDLE, /**< awaiting new email */ |
| | LGSSMTP_CONNECTING, /**< opening tcp connection to MTA */ |
| | LGSSMTP_CONNECTED, /**< tcp connection to MTA is connected */ |
| | LGSSMTP_SENT_HELO, /**< sent the HELO */ |
| | LGSSMTP_SENT_FROM, /**< sent FROM */ |
| | LGSSMTP_SENT_TO, /**< sent TO */ |
| | LGSSMTP_SENT_DATA, /**< sent DATA request */ |
| | LGSSMTP_SENT_BODY, /**< sent the email body */ |
| | LGSSMTP_SENT_QUIT, /**< sent the session quit */ |
| | }; |
| | |
| | /** struct lws_email - abstract context for performing SMTP operations */ |
| | struct lws_email { |
| | void *data; |
| | /**< opaque pointer set by user code and available to the callbacks |
| | */ |
| | uv_loop_t *loop; |
| | /**< the libuv loop we will work on */ |
| | |
| | char email_smtp_ip[32]; /**< Fill before init, eg, "127.0.0.1" */ |
| | char email_helo[32]; /**< Fill before init, eg, "myserver.com" */ |
| | char email_from[100]; /**< Fill before init or on_next */ |
| | char email_to[100]; /**< Fill before init or on_next */ |
| | |
| | unsigned int max_content_size; |
| | /**< largest possible email body size */ |
| | |
| | /* Fill all the callbacks before init */ |
| | |
| | int (*on_next)(struct lws_email *email); |
| | /**< (Fill in before calling lws_email_init) |
| | * called when idle, 0 = another email to send, nonzero is idle. |
| | * If you return 0, all of the email_* char arrays must be set |
| | * to something useful. */ |
| | int (*on_sent)(struct lws_email *email); |
| | /**< (Fill in before calling lws_email_init) |
| | * called when transfer of the email to the SMTP server was |
| | * successful, your callback would remove the current email |
| | * from its queue */ |
| | int (*on_get_body)(struct lws_email *email, char *buf, int len); |
| | /**< (Fill in before calling lws_email_init) |
| | * called when the body part of the queued email is about to be |
| | * sent to the SMTP server. */ |
| | |
| | /* private things */ |
| | uv_timer_t timeout_email; /**< private */ |
| | enum lwsgs_smtp_states estate; /**< private */ |
| | uv_connect_t email_connect_req; /**< private */ |
| | uv_tcp_t email_client; /**< private */ |
| | time_t email_connect_started; /**< private */ |
| | char email_buf[256]; /**< private */ |
| | char *content; /**< private */ |
| | }; |
| | |
| | /** |
| | * lws_email_init() - Initialize a struct lws_email |
* | | * |
* There is no longer a set internal extensions table. The table is provid | | * \param email: struct lws_email to init |
ed | | * \param loop: libuv loop to use |
* by user code along with application-specific settings. See the test | | * \param max_content: max email content size |
* client and server for how to do. | | * |
| | * Prepares a struct lws_email for use ending SMTP |
*/ | | */ |
static LWS_INLINE LWS_WARN_DEPRECATED const struct lws_extension * | | LWS_VISIBLE LWS_EXTERN int |
lws_get_internal_extensions() { return NULL; } | | lws_email_init(struct lws_email *email, uv_loop_t *loop, int max_content); |
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 | | |
| | |
/* | | /** |
* custom allocator support | | * lws_email_check() - Request check for new email |
| | * |
| | * \param email: struct lws_email context to check |
| | * |
| | * Schedules a check for new emails in 1s... call this when you have queued |
| | an |
| | * email for send. |
*/ | | */ |
LWS_VISIBLE LWS_EXTERN void | | LWS_VISIBLE LWS_EXTERN void |
lws_set_allocator(void *(*realloc)(void *ptr, size_t size)); | | lws_email_check(struct lws_email *email); |
| | |
/** | | /** |
* lws_snprintf(): lws_snprintf that truncates the returned length too | | * lws_email_destroy() - stop using the struct lws_email |
* | | * |
* \param str: destination buffer | | * \param email: the struct lws_email context |
* \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 yo | | * Stop sending email using email and free allocations |
u | | |
* reach the limit the reported length doesn't exceed the limit. | | |
*/ | | */ |
LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN void |
lws_snprintf(char *str, size_t size, const char *format, ...); | | lws_email_destroy(struct lws_email *email); |
| | |
| | #endif |
| | //@} |
| | |
#ifdef __cplusplus | | #ifdef __cplusplus |
} | | } |
#endif | | #endif |
| | |
#endif | | #endif |
| | |
End of changes. 246 change blocks. |
1219 lines changed or deleted | | 3566 lines changed or added |
|