| libwebsockets.h (2.0.3) | | libwebsockets.h (current) | |
| | | | |
| 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 | |
| | | | |
| skipping to change at line 166 ¶ | | skipping to change at line 168 ¶ | |
| #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 204 ¶ | | 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 231 ¶ | | skipping to change at line 236 ¶ | |
| #include <cyassl/openssl/ssl.h> | | #include <cyassl/openssl/ssl.h> | |
| #include <cyassl/error-ssl.h> | | #include <cyassl/error-ssl.h> | |
| #else | | #else | |
| #include <wolfssl/openssl/ssl.h> | | #include <wolfssl/openssl/ssl.h> | |
| #include <wolfssl/error-ssl.h> | | #include <wolfssl/error-ssl.h> | |
| #endif /* not USE_OLD_CYASSL */ | | #endif /* not USE_OLD_CYASSL */ | |
| #else | | #else | |
| #if defined(LWS_USE_POLARSSL) | | #if defined(LWS_USE_POLARSSL) | |
| #include <polarssl/ssl.h> | | #include <polarssl/ssl.h> | |
| struct lws_polarssl_context { | | struct lws_polarssl_context { | |
|
| x509_crt ca; | | x509_crt ca; /**< ca */ | |
| x509_crt certificate; | | x509_crt certificate; /**< cert */ | |
| rsa_context key; | | rsa_context key; /**< key */ | |
| }; | | }; | |
| typedef struct lws_polarssl_context SSL_CTX; | | typedef struct lws_polarssl_context SSL_CTX; | |
| typedef ssl_context SSL; | | typedef ssl_context SSL; | |
| #else | | #else | |
| #if defined(LWS_USE_MBEDTLS) | | #if defined(LWS_USE_MBEDTLS) | |
| #include <mbedtls/ssl.h> | | #include <mbedtls/ssl.h> | |
| #else | | #else | |
| #include <openssl/ssl.h> | | #include <openssl/ssl.h> | |
| #include <openssl/err.h> | | #include <openssl/err.h> | |
| #endif /* not USE_MBEDTLS */ | | #endif /* not USE_MBEDTLS */ | |
| #endif /* not USE_POLARSSL */ | | #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 | | LWS_VISIBLE LWS_EXTERN int | |
| lwsl_timestamp(int level, char *p, int len); | | 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> | | #include <stddef.h> | |
| | | | |
| #ifndef lws_container_of | | #ifndef lws_container_of | |
| #define lws_container_of(P,T,M) ((T *)((char *)(P) - offsetof(T, M))
) | | #define lws_container_of(P,T,M) ((T *)((char *)(P) - offsetof(T, M))
) | |
| #endif | | #endif | |
| | | | |
| struct lws; | | struct lws; | |
| #ifndef ARRAY_SIZE | | #ifndef ARRAY_SIZE | |
| #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) | | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) | |
| #endif | | #endif | |
| | | | |
| skipping to change at line 330 ¶ | | skipping to change at line 407 ¶ | |
| | | | |
| /* 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 { | |
| (1 << 12), | | LWS_CLOSE_STATUS_NOSTATUS = 0, | |
| LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = (1 << 2), | | LWS_CLOSE_STATUS_NORMAL = 1000, | |
| LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = (1 << 3) | | | /**< 1000 indicates a normal closure, meaning that the purpose for | |
| (1 << 12), | | which the connection was established has been fulfilled. */ | |
| LWS_SERVER_OPTION_LIBEV = (1 << 4), | | LWS_CLOSE_STATUS_GOINGAWAY = 1001, | |
| LWS_SERVER_OPTION_DISABLE_IPV6 = (1 << 5), | | /**< 1001 indicates that an endpoint is "going away", such as a serv | |
| LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = (1 << 6), | | er | |
| LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED = (1 << 7), | | going down or a browser having navigated away from a page. */ | |
| LWS_SERVER_OPTION_VALIDATE_UTF8 = (1 << 8), | | LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002, | |
| LWS_SERVER_OPTION_SSL_ECDH = (1 << 9) | | | /**< 1002 indicates that an endpoint is terminating the connection d | |
| (1 << 12), | | ue | |
| LWS_SERVER_OPTION_LIBUV = (1 << 10), | | to a protocol error. */ | |
| LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS = (1 << 11) | | LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003, | |
| | | | /**< 1003 indicates that an endpoint is terminating the connection | |
| (1 << 3) | | | because it has received a type of data it cannot accept (e.g., an | |
| (1 << 12), | | endpoint that understands only text data MAY send this if it | |
| LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT = (1 << 12), | | receives a binary message). */ | |
| LWS_SERVER_OPTION_EXPLICIT_VHOSTS = (1 << 13), | | LWS_CLOSE_STATUS_RESERVED = 1004, | |
| LWS_SERVER_OPTION_UNIX_SOCK = (1 << 14), | | /**< Reserved. The specific meaning might be defined in the future. | |
| LWS_SERVER_OPTION_STS = (1 << 15), | | */ | |
| | | 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, | |
| }; | | }; | |
| | | | |
|
| #define lws_check_opt(c, f) (((c) & (f)) == (f)) | | /** | |
| | | * 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, | |
|
| | | /**< */ | |
| | | | |
| LWS_CALLBACK_CGI = 40, | | LWS_CALLBACK_CGI = 40, | |
|
| | | /**< */ | |
| LWS_CALLBACK_CGI_TERMINATED = 41, | | LWS_CALLBACK_CGI_TERMINATED = 41, | |
|
| | | /**< */ | |
| LWS_CALLBACK_CGI_STDIN_DATA = 42, | | LWS_CALLBACK_CGI_STDIN_DATA = 42, | |
|
| | | /**< */ | |
| LWS_CALLBACK_CGI_STDIN_COMPLETED = 43, | | LWS_CALLBACK_CGI_STDIN_COMPLETED = 43, | |
|
| | | /**< */ | |
| LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP = 44, | | LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP = 44, | |
|
| | | /**< */ | |
| LWS_CALLBACK_CLOSED_CLIENT_HTTP = 45, | | LWS_CALLBACK_CLOSED_CLIENT_HTTP = 45, | |
|
| | | /**< */ | |
| LWS_CALLBACK_RECEIVE_CLIENT_HTTP = 46, | | LWS_CALLBACK_RECEIVE_CLIENT_HTTP = 46, | |
|
| | | /**< */ | |
| LWS_CALLBACK_COMPLETED_CLIENT_HTTP = 47, | | LWS_CALLBACK_COMPLETED_CLIENT_HTTP = 47, | |
|
| | | /**< */ | |
| LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ = 48, | | LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ = 48, | |
|
| | | /**< */ | |
| | | LWS_CALLBACK_HTTP_BIND_PROTOCOL = 49, | |
| | | /**< */ | |
| | | LWS_CALLBACK_HTTP_DROP_PROTOCOL = 50, | |
| | | /**< */ | |
| | | LWS_CALLBACK_CHECK_ACCESS_RIGHTS = 51, | |
| | | /**< */ | |
| | | LWS_CALLBACK_PROCESS_HTML = 52, | |
| | | /**< */ | |
| | | LWS_CALLBACK_ADD_HEADERS = 53, | |
| | | /**< */ | |
| | | LWS_CALLBACK_SESSION_INFO = 54, | |
| | | /**< */ | |
| | | | |
|
| /****** add new things just above ---^ ******/ | | LWS_CALLBACK_GS_EVENT = 55, | |
| | | /**< */ | |
| LWS_CALLBACK_USER = 1000, /* user code can use any including / above | | LWS_CALLBACK_HTTP_PMO = 56, | |
| */ | | /**< per-mount options for this connection, called before | |
| }; | | * the normal LWS_CALLBACK_HTTP when the mount has per-mount | |
| | | * options | |
| #if defined(_WIN32) | | */ | |
| typedef SOCKET lws_sockfd_type; | | LWS_CALLBACK_CLIENT_HTTP_WRITEABLE = 57, | |
| typedef HANDLE lws_filefd_type; | | /**< when doing an HTTP type client connection, you can call | |
| #define lws_sockfd_valid(sfd) (!!sfd) | | * lws_client_http_body_pending(wsi, 1) from | |
| struct lws_pollfd { | | * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER to get these callback | |
| lws_sockfd_type fd; | | s | |
| SHORT events; | | * sending the HTTP headers. | |
| SHORT revents; | | * | |
| }; | | * From this callback, when you have sent everything, you should let | |
| #else | | * lws know by calling lws_client_http_body_pending(wsi, 0) | |
| | | */ | |
| #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; | | | |
| short events; | | | |
| short revents; | | | |
| }; | | | |
| #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 | | | |
| typedef int lws_sockfd_type; | | | |
| typedef int lws_filefd_type; | | | |
| #define lws_sockfd_valid(sfd) (sfd >= 0) | | | |
| #endif | | | |
| | | | |
|
| #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 543 ¶ | | skipping to change at line 1086 ¶ | |
| 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, | | LWS_EXT_CB_NAMED_OPTION_SET = 26, | |
| | | | |
| /****** add new things just above ---^ ******/ | | /****** add new things just above ---^ ******/ | |
| }; | | }; | |
| | | | |
|
| /* | | /** enum lws_ext_options_types */ | |
| * NOTE: These public enums are part of the abi. If you want to add one, | | enum lws_ext_options_types { | |
| * add it at where specified so existing users are unaffected. | | EXTARG_NONE, /**< does not take an argument */ | |
| */ | | EXTARG_DEC, /**< requires a decimal argument */ | |
| enum lws_write_protocol { | | EXTARG_OPT_DEC /**< may have an optional decimal argument */ | |
| LWS_WRITE_TEXT = 0, | | | |
| LWS_WRITE_BINARY = 1, | | | |
| LWS_WRITE_CONTINUATION = 2, | | | |
| LWS_WRITE_HTTP = 3, | | | |
| | | | |
| /* special 04+ opcodes */ | | | |
| | | | |
| /* LWS_WRITE_CLOSE is handled by lws_close_reason() */ | | | |
| LWS_WRITE_PING = 5, | | | |
| LWS_WRITE_PONG = 6, | | | |
| | | | |
| /* Same as write_http but we know this write ends the transaction */ | | | |
| LWS_WRITE_HTTP_FINAL = 7, | | | |
| | | | |
| /* HTTP2 */ | | | |
| | | | |
| LWS_WRITE_HTTP_HEADERS = 8, | | | |
| | | | |
| /****** add new things just above ---^ ******/ | | | |
| | | | |
| /* flags */ | | | |
| | | | |
| LWS_WRITE_NO_FIN = 0x40, | | | |
| /* | | | |
| * client packet payload goes out on wire unmunged | | | |
| * only useful for security tests since normal servers cannot | | | |
| * decode the content if used | | | |
| */ | | | |
| LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80 | | | |
| }; | | | |
| | | | |
| /* | | | |
| * 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 | | | |
| * list below is absent, .token = NULL and token_len = 0. Otherwise .token | | | |
| * points to .token_len chars containing that header content. | | | |
| */ | | | |
| | | | |
| struct lws_tokens { | | | |
| char *token; | | | |
| int token_len; | | | |
| }; | | | |
| | | | |
| /* | | | |
| * 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, | | | |
| * add it at where specified so existing users are unaffected. | | | |
| */ | | | |
| enum lws_token_indexes { | | | |
| WSI_TOKEN_GET_URI = 0, | | | |
| WSI_TOKEN_POST_URI = 1, | | | |
| WSI_TOKEN_OPTIONS_URI = 2, | | | |
| WSI_TOKEN_HOST = 3, | | | |
| WSI_TOKEN_CONNECTION = 4, | | | |
| WSI_TOKEN_UPGRADE = 5, | | | |
| WSI_TOKEN_ORIGIN = 6, | | | |
| WSI_TOKEN_DRAFT = 7, | | | |
| WSI_TOKEN_CHALLENGE = 8, | | | |
| WSI_TOKEN_EXTENSIONS = 9, | | | |
| WSI_TOKEN_KEY1 = 10, | | | |
| WSI_TOKEN_KEY2 = 11, | | | |
| WSI_TOKEN_PROTOCOL = 12, | | | |
| WSI_TOKEN_ACCEPT = 13, | | | |
| WSI_TOKEN_NONCE = 14, | | | |
| WSI_TOKEN_HTTP = 15, | | | |
| WSI_TOKEN_HTTP2_SETTINGS = 16, | | | |
| WSI_TOKEN_HTTP_ACCEPT = 17, | | | |
| WSI_TOKEN_HTTP_AC_REQUEST_HEADERS = 18, | | | |
| WSI_TOKEN_HTTP_IF_MODIFIED_SINCE = 19, | | | |
| WSI_TOKEN_HTTP_IF_NONE_MATCH = 20, | | | |
| WSI_TOKEN_HTTP_ACCEPT_ENCODING = 21, | | | |
| WSI_TOKEN_HTTP_ACCEPT_LANGUAGE = 22, | | | |
| WSI_TOKEN_HTTP_PRAGMA = 23, | | | |
| WSI_TOKEN_HTTP_CACHE_CONTROL = 24, | | | |
| WSI_TOKEN_HTTP_AUTHORIZATION = 25, | | | |
| WSI_TOKEN_HTTP_COOKIE = 26, | | | |
| WSI_TOKEN_HTTP_CONTENT_LENGTH = 27, | | | |
| WSI_TOKEN_HTTP_CONTENT_TYPE = 28, | | | |
| WSI_TOKEN_HTTP_DATE = 29, | | | |
| WSI_TOKEN_HTTP_RANGE = 30, | | | |
| WSI_TOKEN_HTTP_REFERER = 31, | | | |
| WSI_TOKEN_KEY = 32, | | | |
| WSI_TOKEN_VERSION = 33, | | | |
| WSI_TOKEN_SWORIGIN = 34, | | | |
| | | | |
| WSI_TOKEN_HTTP_COLON_AUTHORITY = 35, | | | |
| WSI_TOKEN_HTTP_COLON_METHOD = 36, | | | |
| WSI_TOKEN_HTTP_COLON_PATH = 37, | | | |
| WSI_TOKEN_HTTP_COLON_SCHEME = 38, | | | |
| WSI_TOKEN_HTTP_COLON_STATUS = 39, | | | |
| | | | |
| WSI_TOKEN_HTTP_ACCEPT_CHARSET = 40, | | | |
| WSI_TOKEN_HTTP_ACCEPT_RANGES = 41, | | | |
| WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN = 42, | | | |
| WSI_TOKEN_HTTP_AGE = 43, | | | |
| WSI_TOKEN_HTTP_ALLOW = 44, | | | |
| WSI_TOKEN_HTTP_CONTENT_DISPOSITION = 45, | | | |
| WSI_TOKEN_HTTP_CONTENT_ENCODING = 46, | | | |
| WSI_TOKEN_HTTP_CONTENT_LANGUAGE = 47, | | | |
| WSI_TOKEN_HTTP_CONTENT_LOCATION = 48, | | | |
| WSI_TOKEN_HTTP_CONTENT_RANGE = 49, | | | |
| WSI_TOKEN_HTTP_ETAG = 50, | | | |
| WSI_TOKEN_HTTP_EXPECT = 51, | | | |
| WSI_TOKEN_HTTP_EXPIRES = 52, | | | |
| WSI_TOKEN_HTTP_FROM = 53, | | | |
| WSI_TOKEN_HTTP_IF_MATCH = 54, | | | |
| WSI_TOKEN_HTTP_IF_RANGE = 55, | | | |
| WSI_TOKEN_HTTP_IF_UNMODIFIED_SINCE = 56, | | | |
| WSI_TOKEN_HTTP_LAST_MODIFIED = 57, | | | |
| WSI_TOKEN_HTTP_LINK = 58, | | | |
| WSI_TOKEN_HTTP_LOCATION = 59, | | | |
| WSI_TOKEN_HTTP_MAX_FORWARDS = 60, | | | |
| WSI_TOKEN_HTTP_PROXY_AUTHENTICATE = 61, | | | |
| WSI_TOKEN_HTTP_PROXY_AUTHORIZATION = 62, | | | |
| WSI_TOKEN_HTTP_REFRESH = 63, | | | |
| WSI_TOKEN_HTTP_RETRY_AFTER = 64, | | | |
| WSI_TOKEN_HTTP_SERVER = 65, | | | |
| WSI_TOKEN_HTTP_SET_COOKIE = 66, | | | |
| WSI_TOKEN_HTTP_STRICT_TRANSPORT_SECURITY = 67, | | | |
| WSI_TOKEN_HTTP_TRANSFER_ENCODING = 68, | | | |
| WSI_TOKEN_HTTP_USER_AGENT = 69, | | | |
| WSI_TOKEN_HTTP_VARY = 70, | | | |
| WSI_TOKEN_HTTP_VIA = 71, | | | |
| WSI_TOKEN_HTTP_WWW_AUTHENTICATE = 72, | | | |
| | | | |
| WSI_TOKEN_PATCH_URI = 73, | | | |
| WSI_TOKEN_PUT_URI = 74, | | | |
| WSI_TOKEN_DELETE_URI = 75, | | | |
| | | | |
| WSI_TOKEN_HTTP_URI_ARGS = 76, | | | |
| WSI_TOKEN_PROXY = 77, | | | |
| WSI_TOKEN_HTTP_X_REAL_IP = 78, | | | |
| WSI_TOKEN_HTTP1_0 = 79, | | | |
| | | | |
| /****** add new things just above ---^ ******/ | | | |
| | | | |
| /* use token storage to stash these internally, not for | | | |
| * user use */ | | | |
| | | | |
| _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, | | | |
| _WSI_TOKEN_CLIENT_PEER_ADDRESS, | | | |
| _WSI_TOKEN_CLIENT_URI, | | | |
| _WSI_TOKEN_CLIENT_HOST, | | | |
| _WSI_TOKEN_CLIENT_ORIGIN, | | | |
| _WSI_TOKEN_CLIENT_METHOD, | | | |
| | | | |
| /* always last real token index*/ | | | |
| WSI_TOKEN_COUNT, | | | |
| | | | |
| /* parser state additions, no storage associated */ | | | |
| WSI_TOKEN_NAME_PART, | | | |
| WSI_TOKEN_SKIPPING, | | | |
| WSI_TOKEN_SKIPPING_SAW_CR, | | | |
| WSI_PARSING_COMPLETE, | | | |
| WSI_INIT_TOKEN_MUXURL, | | | |
| }; | | | |
| | | | |
|
| struct lws_token_limits { | | /* Add new things just above here ---^ | |
| unsigned short token_limit[WSI_TOKEN_COUNT]; | | * This is part of the ABI, don't needlessly break compatibility */ | |
| }; | | }; | |
| | | | |
|
| /* | | /** struct lws_ext_options - Option arguments to the extension. These ar | |
| * From RFC 6455 | | e | |
| 1000 | | * used in the negotiation at ws upgrade time. | |
| | | * The helper function lws_ext_parse_options() | |
| 1000 indicates a normal closure, meaning that the purpose for | | * uses these to generate callbacks */ | |
| which the connection was established has been fulfilled. | | struct lws_ext_options { | |
| | | const char *name; /**< Option name, eg, "server_no_context_takeover" | |
| 1001 | | */ | |
| | | enum lws_ext_options_types type; /**< What kind of args the option c | |
| 1001 indicates that an endpoint is "going away", such as a server | | an take */ | |
| 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_CLOSE_STATUS_NOSTATUS = 0, | | | |
| LWS_CLOSE_STATUS_NORMAL = 1000, | | | |
| LWS_CLOSE_STATUS_GOINGAWAY = 1001, | | | |
| LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002, | | | |
| LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003, | | | |
| LWS_CLOSE_STATUS_RESERVED = 1004, | | | |
| LWS_CLOSE_STATUS_NO_STATUS = 1005, | | | |
| LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006, | | | |
| LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007, | | | |
| LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008, | | | |
| LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009, | | | |
| LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010, | | | |
| LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011, | | | |
| LWS_CLOSE_STATUS_TLS_FAILURE = 1015, | | | |
| | | | |
| /****** add new things just above ---^ ******/ | | | |
| | | | |
|
| LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY = 9999, | | /* Add new things just above here ---^ | |
| | | * This is part of the ABI, don't needlessly break compatibility */ | |
| }; | | }; | |
| | | | |
|
| enum http_status { | | /** struct lws_ext_option_arg */ | |
| HTTP_STATUS_OK = 200, | | struct lws_ext_option_arg { | |
| HTTP_STATUS_NO_CONTENT = 204, | | const char *option_name; /**< may be NULL, option_index used then */ | |
| | | int option_index; /**< argument ordinal to use if option_name missin | |
| HTTP_STATUS_MOVED_PERMANENTLY = 301, | | g */ | |
| HTTP_STATUS_FOUND = 302, | | const char *start; /**< value */ | |
| HTTP_STATUS_SEE_OTHER = 303, | | int len; /**< length of value */ | |
| | | | |
| 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 | | | |
| * @wsi: Opaque websocket instance pointer | | | |
| * @reason: The reason for the call | | | |
| * @user: Pointer to per-session user data allocated by library | | | |
| * @in: Pointer used for some callback reasons | | | |
| * @len: Length set for some callback reasons | | | |
| * | | | |
| * This callback is the way the user controls what is served. All the | | | |
| * protocol detail is hidden and handled by the library. | | | |
| * | | | |
| * 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 | | | |
| he | | | |
| * client connection, it can be found at *in an | | | |
| d | | | |
| * is len bytes long | | | |
| * | | | |
| * LWS_CALLBACK_HTTP: an http request has come from a client that is no | | | |
| t | | | |
| * asking to upgrade the connection to a websoc | | | |
| ket | | | |
| * one. This is a chance to serve http content | | | |
| , | | | |
| * for example, to send a script to the client | | | |
| * which will then open the websockets connecti | | | |
| on. | | | |
| * @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 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 | | | |
| * request body HTTP connection is now available in @in. | | | |
| * | | | |
| * LWS_CALLBACK_HTTP_BODY_COMPLETION: the expected amount of http reque | | | |
| st | | | |
| * body has been delivered | | | |
| * | | | |
| * LWS_CALLBACK_HTTP_WRITEABLE: you can write more down the http protoc | | | |
| ol | | | |
| * link now. | | | |
| * | | | |
| * LWS_CALLBACK_HTTP_FILE_COMPLETION: a file requested to be send down | | | |
| * http link has completed. | | | |
| * | | | |
| * LWS_CALLBACK_CLIENT_WRITEABLE: | | | |
| * LWS_CALLBACK_SERVER_WRITEABLE: If you call | | | |
| * lws_callback_on_writable() on a connection, you will | | | |
| * 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 blocki | | | |
| ng, | | | |
| * you'll get this callback at the next call to the service loo | | | |
| p | | | |
| * 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 | | | |
| 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 | | | |
| * been connected, accepted, and instantiated into the pool. Th | | | |
| is | | | |
| * 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 | | | |
| * been received and parsed from the client, but the response i | | | |
| s | | | |
| * 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 | | | |
| as | | | |
| * been received and parsed from the client, but the response i | | | |
| 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 | | | |
| * 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 | | | |
| or | | | |
| * including OpenSSL support, this callback allows your user co | | | |
| de | | | |
| * 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 | | | |
| or | | | |
| * including OpenSSL support, this callback allows your user co | | | |
| de | | | |
| * to load extra certifcates into the server which allow it to | | | |
| * verify the validity of certificates returned by clients. @u | | | |
| ser | | | |
| * is the server's OpenSSL SSL_CTX* | | | |
| * | | | |
| * LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY: if configured for | | | |
| * including OpenSSL support but no private key file has been | | | |
| * specified (ssl_private_key_filepath is NULL), this is called | | | |
| to | | | |
| * allow the user to set the private key directly via libopenss | | | |
| l | | | |
| * 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 | | | |
| * libwebsockets context was created with the option | | | |
| * LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then th | | | |
| is | | | |
| * callback is generated during OpenSSL verification of the cer | | | |
| t | | | |
| * 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 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 | | | |
| * 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 buffe | | | |
| r, | | | |
| * 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; | | | |
| * | | | |
| * 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 handshook yet. | | | |
| * | | | |
| * LWS_CALLBACK_CONFIRM_EXTENSION_OKAY: 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 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 | | | |
| t | | | |
| * connection is being prepared to start a handshake to a serve | | | |
| r, | | | |
| * 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 | | | |
| * do initial setup / allocations etc | | | |
| * | | | |
| * LWS_CALLBACK_PROTOCOL_DESTROY: One-time call per protocol indicatin | | | |
| g | | | |
| * this protocol won't get used at all after this callback, the | | | |
| * context is getting destroyed. Take the opportunity to | | | |
| * deallocate everything that was allocated by the protocol. | | | |
| * | | | |
| * LWS_CALLBACK_WSI_CREATE: outermost (earliest) wsi create notificatio | | | |
| n | | | |
| * | | | |
| * LWS_CALLBACK_WSI_DESTROY: outermost (latest) wsi destroy notificatio | | | |
| n | | | |
| * | | | |
| * The next five reasons are optional and only need taking care of if y | | | |
| ou | | | |
| * will be integrating libwebsockets sockets into an external polling | | | |
| * array. | | | |
| * | | | |
| * For these calls, @in points to a struct lws_pollargs that | | | |
| * contains @fd, @events and @prev_events members | | | |
| * | | | |
| * LWS_CALLBACK_ADD_POLL_FD: libwebsocket deals with its poll() loop | | | |
| * internally, but in the case you are integrating with another | | | |
| * server you will need to have libwebsocket 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, th | | | |
| e | | | |
| * 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 polling loop (the "service" | | | |
| * callback), you can just ignore these callbacks. | | | |
| * | | | |
| * LWS_CALLBACK_DEL_POLL_FD: This callback happens when a socket descri | | | |
| ptor | | | |
| * 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: This callback happens when | | | |
| * libwebsockets wants to modify the events for a connectiion. | | | |
| * @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 ign | | | |
| ore | | | |
| * it. | | | |
| * | | | |
| * LWS_CALLBACK_LOCK_POLL: | | | |
| * 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: | | | |
| * The peer has sent an unsolicited Close WS packet. @in and | | | |
| * @len are the optional close code (first 2 bytes, network | | | |
| * order) and the optional additional information which is not | | | |
| * defined in the standard, and may be a string or non-human- | | | |
| * readble data. | | | |
| * If you return 0 lws will echo the close and then close the | | | |
| * connection. If you return nonzero lws will just close the | | | |
| * connection. | | | |
| */ | | | |
| 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
operate | | * typedef lws_extension_callback_function() - Hooks to allow extensions to
operate | |
|
| * @context: Websockets context | | * \param context: Websockets context | |
| * @ext: This extension | | * \param ext: This extension | |
| * @wsi: Opaque websocket instance pointer | | * \param wsi: Opaque websocket instance pointer | |
| * @reason: The reason for the call | | * \param reason: The reason for the call | |
| * @user: Pointer to ptr to per-session user data allocated by library | | * \param user: Pointer to ptr to per-session user data allocated by | |
| * @in: Pointer used for some callback reasons | | library | |
| * @len: Length set for some callback reasons | | * \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 | | * Each extension that is active on a particular connection receives | |
| * callbacks during the connection lifetime to allow the extension to | | * callbacks during the connection lifetime to allow the extension to | |
| * operate on websocket data and manage itself. | | * operate on websocket data and manage itself. | |
| * | | * | |
| * Libwebsockets takes care of allocating and freeing "user" memory for | | * Libwebsockets takes care of allocating and freeing "user" memory for | |
| * each active extension on each connection. That is what is pointed t
o | | * each active extension on each connection. That is what is pointed t
o | |
|
| * by the @user parameter. | | * by the user parameter. | |
| * | | * | |
| * LWS_EXT_CB_CONSTRUCT: called when the server has decided to | | * LWS_EXT_CB_CONSTRUCT: called when the server has decided to | |
| * select this extension from the list provided by the client, | | * select this extension from the list provided by the client, | |
| * just before the server will send back the handshake acceptin
g | | * just before the server will send back the handshake acceptin
g | |
| * the connection with this extension active. This gives the | | * the connection with this extension active. This gives the | |
| * extension a chance to initialize its connection context foun
d | | * extension a chance to initialize its connection context foun
d | |
|
| * in @user. | | * in user. | |
| * | | * | |
| * LWS_EXT_CB_CLIENT_CONSTRUCT: same as LWS_EXT_CB_CONSTRUCT | | * LWS_EXT_CB_CLIENT_CONSTRUCT: same as LWS_EXT_CB_CONSTRUCT | |
| * but called when client is instantiating this extension. Som
e | | * but called when client is instantiating this extension. Som
e | |
| * extensions will work the same on client and server side and
then | | * extensions will work the same on client and server side and
then | |
| * you can just merge handlers for both CONSTRUCTS. | | * you can just merge handlers for both CONSTRUCTS. | |
| * | | * | |
| * LWS_EXT_CB_DESTROY: called when the connection the extension was | | * LWS_EXT_CB_DESTROY: called when the connection the extension was | |
| * being used on is about to be closed and deallocated. It's t
he | | * being used on is about to be closed and deallocated. It's t
he | |
| * last chance for the extension to deallocate anything it has | | * last chance for the extension to deallocate anything it has | |
|
| * allocated in the user data (pointed to by @user) before the | | * allocated in the user data (pointed to by user) before the | |
| * user data is deleted. This same callback is used whether yo
u | | * user data is deleted. This same callback is used whether yo
u | |
| * are in client or server instantiation context. | | * are in client or server instantiation context. | |
| * | | * | |
| * LWS_EXT_CB_PACKET_RX_PREPARSE: when this extension was active on | | * LWS_EXT_CB_PACKET_RX_PREPARSE: when this extension was active on | |
| * a connection, and a packet of data arrived at the connection
, | | * a connection, and a packet of data arrived at the connection
, | |
| * it is passed to this callback to give the extension a chance
to | | * it is passed to this callback to give the extension a chance
to | |
|
| * change the data, eg, decompress it. @user is pointing to th | | * change the data, eg, decompress it. user is pointing to the | |
| e | | * extension's private connection context data, in is pointing | |
| * extension's private connection context data, @in is pointing | | | |
| * to an lws_tokens struct, it consists of a char * pointer cal
led | | * to an lws_tokens struct, it consists of a char * pointer cal
led | |
| * token, and an int called token_len. At entry, these are | | * token, and an int called token_len. At entry, these are | |
| * set to point to the received buffer and set to the content | | * set to point to the received buffer and set to the content | |
| * length. If the extension will grow the content, it should u
se | | * length. If the extension will grow the content, it should u
se | |
| * a new buffer allocated in its private user context data and | | * a new buffer allocated in its private user context data and | |
| * set the pointed-to lws_tokens members to point to its buffer
. | | * 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_TX_PRESEND: this works the same way as | |
| * LWS_EXT_CB_PACKET_RX_PREPARSE above, except it gives the | | * LWS_EXT_CB_PACKET_RX_PREPARSE above, except it gives the | |
| * extension a chance to change websocket data just before it w
ill | | * extension a chance to change websocket data just before it w
ill | |
|
| * be sent out. Using the same lws_token pointer scheme in @in
, | | * be sent out. Using the same lws_token pointer scheme in in, | |
| * the extension can change the buffer and the length to be | | * the extension can change the buffer and the length to be | |
| * transmitted how it likes. Again if it wants to grow the | | * transmitted how it likes. Again if it wants to grow the | |
| * buffer safely, it should copy the data into its own buffer a
nd | | * buffer safely, it should copy the data into its own buffer a
nd | |
| * set the lws_tokens token pointer to it. | | * set the lws_tokens token pointer to it. | |
| * | | * | |
| * LWS_EXT_CB_ARGS_VALIDATE: | | * LWS_EXT_CB_ARGS_VALIDATE: | |
| */ | | */ | |
| typedef int | | typedef int | |
| lws_extension_callback_function(struct lws_context *context, | | lws_extension_callback_function(struct lws_context *context, | |
| const struct lws_extension *ext, struct lws *w
si, | | const struct lws_extension *ext, struct lws *w
si, | |
| enum lws_extension_callback_reasons reason, | | enum lws_extension_callback_reasons reason, | |
| void *user, void *in, size_t len); | | 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 */ | |
| | | }; | |
| | | | |
| /** | | /** | |
|
| * struct lws_protocols - List of protocols and handlers server | | * lws_set_extension_option(): set extension option if possible | |
| * supports. | | | |
| * @name: Protocol name that must match the one given in the client | | | |
| * Javascript new WebSocket(url, 'protocol') name. | | | |
| * @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 | | | |
| * @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 | | * \param wsi: websocket connection | |
| * array of these structures is passed to lws_create_server() | | * \param ext_name: name of ext, like "permessage-deflate" | |
| * allows as many protocols as you like to be handled by one server. | | * \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 | |
| * | | * | |
|
| * The first protocol given has its callback used for user callbacks wh | | * \Deprecated There is no longer a set internal extensions table. The tab | |
| en | | le is provided | |
| * there is no agreed protocol name, that's true during HTTP part of th | | * by user code along with application-specific settings. See the test | |
| e | | * client and server for how to do. | |
| * connection and true if the client did not send a Protocol: header. | | */ | |
| | | 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 { | | struct lws_protocols { | |
| const char *name; | | const char *name; | |
|
| | | /**< Protocol name that must match the one given in the client | |
| | | * Javascript new WebSocket(url, 'protocol') name. */ | |
| lws_callback_function *callback; | | 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; | | 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; | | 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; | | unsigned int id; | |
|
| void *user; | | /**< 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 ---^ | | /* Add new things just above here ---^ | |
| * This is part of the ABI, don't needlessly break compatibility */ | | * This is part of the ABI, don't needlessly break compatibility */ | |
| }; | | }; | |
| | | | |
|
| enum lws_ext_options_types { | | struct lws_vhost; | |
| 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_vhost_name_to_protocol() - get vhost's protocol object from its name | |
| 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 vh: vhost to search | |
| " | | * \param name: protocol name | |
| * @type: What kind of args the option can take | | * | |
| | | * Returns NULL or a pointer to the vhost's protocol of the requested name | |
| */ | | */ | |
|
| struct lws_ext_options { | | LWS_VISIBLE LWS_EXTERN const struct lws_protocols * | |
| const char *name; | | lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name); | |
| enum lws_ext_options_types type; | | | |
| | | | |
|
| /* Add new things just above here ---^ | | /** | |
| * This is part of the ABI, don't needlessly break compatibility */ | | * 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); | |
| | | | |
|
| struct lws_ext_option_arg { | | /** lws_protocol_get() - deprecated: use lws_get_protocol */ | |
| const char *option_name; /* may be NULL, option_index used then */ | | LWS_VISIBLE LWS_EXTERN const struct lws_protocols * | |
| int option_index; | | lws_protocol_get(struct lws *wsi) LWS_WARN_DEPRECATED; | |
| const char *start; | | | |
| int len; | | | |
| }; | | | |
| | | | |
| /** | | /** | |
|
| * struct lws_extension - An extension we know how to cope with | | * 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 | |
| * | | * | |
|
| * @name: Formal extension name, eg, "permessage-defla | | * Protocols often find it useful to allocate a per-vhost struct, this is a | |
| te" | | * helper to be called in the per-vhost init LWS_CALLBACK_PROTOCOL_INIT | |
| * @callback: Service callback | | | |
| * @client_offer: String containing exts and options client of | | | |
| fers | | | |
| */ | | */ | |
|
| | | LWS_VISIBLE LWS_EXTERN void * | |
| | | lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_proto | |
| | | cols *prot, | |
| | | int size); | |
| | | | |
|
| struct lws_extension { | | /** | |
| const char *name; | | * lws_protocol_vh_priv_get() - retreive a protocol's per-vhost storage | |
| lws_extension_callback_function *callback; | | * | |
| const char *client_offer; | | * \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); | |
| | | | |
|
| /* Add new things just above here ---^ | | /** | |
| * This is part of the ABI, don't needlessly break compatibility */ | | * 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 | | #ifdef LWS_WITH_PLUGINS | |
| | | | |
| /* PLUGINS implies LIBUV */ | | /* PLUGINS implies LIBUV */ | |
| | | | |
| #define LWS_PLUGIN_API_MAGIC 180 | | #define LWS_PLUGIN_API_MAGIC 180 | |
| | | | |
|
| | | /** struct lws_plugin_capability - how a plugin introduces itself to lws */ | |
| struct lws_plugin_capability { | | struct lws_plugin_capability { | |
|
| unsigned int api_magic; /* caller fills this in, plugin fills rest * | | unsigned int api_magic; /**< caller fills this in, plugin fills rest | |
| / | | */ | |
| const struct lws_protocols *protocols; | | const struct lws_protocols *protocols; /**< array of supported proto | |
| int count_protocols; | | cols provided by plugin */ | |
| const struct lws_extension *extensions; | | int count_protocols; /**< how many protocols */ | |
| int count_extensions; | | 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 *, | | typedef int (*lws_plugin_init_func)(struct lws_context *, | |
| struct lws_plugin_capability *); | | struct lws_plugin_capability *); | |
| typedef int (*lws_plugin_destroy_func)(struct lws_context *); | | typedef int (*lws_plugin_destroy_func)(struct lws_context *); | |
|
| | | | |
| | | /** struct lws_plugin */ | |
| struct lws_plugin { | | struct lws_plugin { | |
|
| struct lws_plugin *list; | | struct lws_plugin *list; /**< linked list */ | |
| #if (UV_VERSION_MAJOR > 0) | | #if (UV_VERSION_MAJOR > 0) | |
|
| uv_lib_t lib; | | uv_lib_t lib; /**< shared library pointer */ | |
| #else | | #else | |
|
| void *l; | | void *l; /**< so we can compile on ancient libuv */ | |
| #endif | | #endif | |
|
| char name[64]; | | char name[64]; /**< name of the plugin */ | |
| struct lws_plugin_capability caps; | | struct lws_plugin_capability caps; /**< plugin capabilities */ | |
| }; | | }; | |
| | | | |
| #endif | | #endif | |
| | | | |
|
| /* | | ///@} | |
| * The internal exts are part of the public abi | | | |
| * If we add more extensions, publish the callback here ------v | | /*! \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. | |
| */ | | */ | |
|
| | | ///@{ | |
| | | | |
|
| LWS_EXTERN | | #define LWSGS_EMAIL_CONTENT_SIZE 16384 | |
| int lws_extension_callback_pm_deflate( | | /**< Maximum size of email we might send */ | |
| 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); | | | |
| | | | |
|
| LWS_VISIBLE LWS_EXTERN int | | /* SHA-1 binary and hexified versions */ | |
| lws_set_extension_option(struct lws *wsi, const char *ext_name, | | /** typedef struct lwsgw_hash_bin */ | |
| const char *opt_name, const char *opt_val); | | 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; | |
| | | | |
|
| struct lws_protocol_vhost_options { | | /** enum lwsgs_auth_bits */ | |
| const struct lws_protocol_vhost_options *next; | | enum lwsgs_auth_bits { | |
| const struct lws_protocol_vhost_options *options; | | LWSGS_AUTH_LOGGED_IN = 1, /**< user is logged in as somebody */ | |
| const char *name; | | LWSGS_AUTH_ADMIN = 2, /**< logged in as the admin user */ | |
| const char *value; | | LWSGS_AUTH_VERIFIED = 4, /**< user has verified his email */ | |
| | | LWSGS_AUTH_FORGOT_FLOW = 8, /**< he just completed "forgot passw | |
| | | ord" flow */ | |
| }; | | }; | |
| | | | |
|
| struct lws_http_mount { | | /** struct lws_session_info - information about user session status */ | |
| struct lws_http_mount *mount_next; | | struct lws_session_info { | |
| const char *mountpoint; /* mountpoint in http pathspace, eg, "/" */ | | char username[32]; /**< username logged in as, or empty string */ | |
| const char *origin; /* path to be mounted, eg, "/var/www/warmcat.com | | char email[100]; /**< email address associated with login, or empty | |
| " */ | | string */ | |
| const char *def; /* default target, eg, "index.html" */ | | 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 */ | |
| | | }; | |
| | | | |
|
| const struct lws_protocol_vhost_options *cgienv; | | /** enum lws_gs_event */ | |
| const struct lws_protocol_vhost_options *extra_mimetypes; | | enum lws_gs_event { | |
| | | LWSGSE_CREATED, /**< a new user was created */ | |
| | | LWSGSE_DELETED /**< an existing user was deleted */ | |
| | | }; | |
| | | | |
|
| int cgi_timeout; | | /** struct lws_gs_event_args */ | |
| int cache_max_age; | | 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 */ | |
| | | }; | |
| | | | |
|
| unsigned int cache_reusable:1; | | ///@} | |
| unsigned int cache_revalidate:1; | | | |
| unsigned int cache_intermediaries:1; | | | |
| | | | |
|
| unsigned char origin_protocol; | | /*! \defgroup context-and-vhost | |
| unsigned char mountpoint_len; | | * \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, | |
| | | * add it at where specified so existing users are unaffected. | |
| | | */ | |
| | | | |
| | | /** 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. | |
| | | */ | |
| | | | |
| | | /****** add new things just above ---^ ******/ | |
| }; | | }; | |
| | | | |
|
| /** | | #define lws_check_opt(c, f) (((c) & (f)) == (f)) | |
| * struct lws_context_creation_info - parameters to create context with | | | |
| | | /** 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 | | * 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 | | * is not given, then for backwards compatibility one vhost is created at | |
| * context-creation time using the info from this struct. | | * context-creation time using the info from this struct. | |
| * | | * | |
| * If LWS_SERVER_OPTION_EXPLICIT_VHOSTS is given, then no vhosts are create
d | | * 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. | | * at the same time as the context, they are expected to be created afterwa
rds. | |
|
| * | | | |
| * @port: VHOST: Port to listen on... you can use CONTEXT_PORT_NO_LIST | | | |
| EN 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 | | | |
| * @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 membe | | | |
| r is | | | |
| * the pathname of a UNIX domain socket. you can use the UNIX d | | | |
| omain | | | |
| * sockets in abstract namespace, by prepending an @ symbole to | | | |
| the | | | |
| * socket name. | | | |
| * @protocols: VHOST: Array of structures listing supported protocols and a | | | |
| protocol- | | | |
| * 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: VHOST: 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: CONTEXT: NULL or struct lws_token_limits pointer which is | | | |
| initialized | | | |
| * with a token length limit for each possible WSI_TOKEN_*** | | | |
| * @ssl_cert_filepath: VHOST: If libwebsockets was compiled to use ssl, and | | | |
| you want | | | |
| * to listen using SSL, set to the filepath to fetch th | | | |
| e | | | |
| * server cert from, otherwise NULL for unencrypted | | | |
| * @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 cal | | | |
| led | | | |
| * to allow setting of the private key directly via ope | | | |
| nSSL | | | |
| * library calls | | | |
| * @ssl_ca_filepath: VHOST: CA certificate filepath or NULL | | | |
| * @ssl_cipher_list: VHOST: 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: VHOST: If non-NULL, attempts to proxy via the given | | | |
| address. | | | |
| * If proxy auth is required, use format | | | |
| * "username:password@server:port" | | | |
| * @http_proxy_port: VHOST: If http_proxy_address was non-NULL, uses this | | | |
| port at | | | |
| * the address | | | |
| * @gid: CONTEXT: group id to change to after setting listen socket, | | | |
| or -1. | | | |
| * @uid: CONTEXT: user id to change to after setting listen socket, o | | | |
| r -1. | | | |
| * @options: VHOST + CONTEXT: 0, or LWS_SERVER_OPTION_... bitfields | | | |
| * @user: CONTEXT: optional user pointer that can be recovered via the | | | |
| context | | | |
| * pointer using lws_context_user | | | |
| * @ka_time: CONTEXT: 0 for no keepalive, otherwise apply this keepalive | | | |
| timeout to | | | |
| * all libwebsocket sockets, client or server | | | |
| * @ka_probes: CONTEXT: if ka_time was nonzero, after the timeout expires h | | | |
| ow many | | | |
| * times to try to get a response from the peer before giving u | | | |
| p | | | |
| * and killing the connection | | | |
| * @ka_interval: CONTEXT: if ka_time was nonzero, how long to wait before e | | | |
| ach ka_probes | | | |
| * attempt | | | |
| * @provided_client_ssl_ctx: CONTEXT: If non-null, swap out libwebsockets s | | | |
| sl | | | |
| * 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: CONTEXT: The max amount of header payload that ca | | | |
| n be handled | | | |
| * in an http request (unrecognized header payload is dropped) | | | |
| * @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. | | | |
| * @count_threads: CONTEXT: how many contexts to create in an array, 0 = 1 | | | |
| * @fd_limit_per_thread: CONTEXT: nonzero means restrict each service threa | | | |
| d to this | | | |
| * many fds, 0 means the default which is divide the process fd | | | |
| * limit by the number of threads. | | | |
| * @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 second | | | |
| s. | | | |
| * Otherwise a default timeout is used. | | | |
| * @ecdh_curve: VHOST: if NULL, defaults to initializing server with "prime | | | |
| 256v1" | | | |
| * @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. | | | |
| * @plugin_dirs: CONTEXT: NULL, or NULL-terminated array of directories to | | | |
| * scan for lws protocol plugins at context creation time | | | |
| * @pvo: VHOST: pointer to optional linked list of per-vhost | | | |
| * options made accessible to protocols | | | |
| * @keepalive_timeout: VHOST: (default = 0 = 60s) seconds to allow remote | | | |
| * client to hold on to an idle HTTP/1.1 connection | | | |
| * @log_filepath: VHOST: filepath to append logs to... this is opened befor | | | |
| e | | | |
| * any dropping of initial privileges | | | |
| * @mounts: VHOST: optional linked list of mounts for this vhost | | | |
| * @server_string: CONTEXT: string used in HTTP headers to identify server | | | |
| * software, if NULL, "libwebsockets". | | | |
| */ | | */ | |
|
| | | | |
| struct lws_context_creation_info { | | struct lws_context_creation_info { | |
|
| int port; /* VH */ | | int port; | |
| const char *iface; /* VH */ | | /**< VHOST: Port to listen on... you can use CONTEXT_PORT_NO_LISTEN | |
| const struct lws_protocols *protocols; /* VH */ | | to | |
| const struct lws_extension *extensions; /* VH */ | | * suppress listening on any port, that's what you want if you are | |
| const struct lws_token_limits *token_limits; /* context */ | | * not running a websocket server at all but just using it as a | |
| const char *ssl_private_key_password; /* VH */ | | * client */ | |
| const char *ssl_cert_filepath; /* VH */ | | const char *iface; | |
| const char *ssl_private_key_filepath; /* VH */ | | /**< VHOST: NULL to bind the listen socket to all interfaces, or the | |
| const char *ssl_ca_filepath; /* VH */ | | * interface name, eg, "eth2" | |
| const char *ssl_cipher_list; /* VH */ | | * If options specifies LWS_SERVER_OPTION_UNIX_SOCK, this member is | |
| const char *http_proxy_address; /* VH */ | | * the pathname of a UNIX domain socket. you can use the UNIX domain | |
| unsigned int http_proxy_port; /* VH */ | | * sockets in abstract namespace, by prepending an at symbol to the | |
| int gid; /* context */ | | * socket name. */ | |
| int uid; /* context */ | | const struct lws_protocols *protocols; | |
| unsigned int options; /* VH + context */ | | /**< VHOST: Array of structures listing supported protocols and a pr | |
| void *user; /* context */ | | otocol- | |
| int ka_time; /* context */ | | * specific callback for each one. The list is ended with an | |
| int ka_probes; /* context */ | | * entry that has a NULL callback pointer. */ | |
| int ka_interval; /* context */ | | 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 | | #ifdef LWS_OPENSSL_SUPPORT | |
|
| SSL_CTX *provided_client_ssl_ctx; /* context */ | | 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 */ | | #else /* maintain structure layout either way */ | |
|
| void *provided_client_ssl_ctx; | | void *provided_client_ssl_ctx; /**< dummy if ssl disabled */ | |
| #endif | | #endif | |
| | | | |
|
| short max_http_header_data; /* context */ | | short max_http_header_data; | |
| short max_http_header_pool; /* context */ | | /**< 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. */ | |
| | | | |
|
| unsigned int count_threads; /* context */ | | unsigned int count_threads; | |
| unsigned int fd_limit_per_thread; /* context */ | | /**< CONTEXT: how many contexts to create in an array, 0 = 1 */ | |
| unsigned int timeout_secs; /* VH */ | | unsigned int fd_limit_per_thread; | |
| const char *ecdh_curve; /* VH */ | | /**< CONTEXT: nonzero means restrict each service thread to this | |
| const char *vhost_name; /* VH */ | | * many fds, 0 means the default which is divide the process fd | |
| const char * const *plugin_dirs; /* context */ | | * limit by the number of threads. */ | |
| const struct lws_protocol_vhost_options *pvo; /* VH */ | | unsigned int timeout_secs; | |
| int keepalive_timeout; /* VH */ | | /**< VHOST: various processes involving network roundtrips in the | |
| const char *log_filepath; /* VH */ | | * library are protected from hanging forever by timeouts. If | |
| const struct lws_http_mount *mounts; /* VH */ | | * nonzero, this member lets you set the timeout used in seconds. | |
| const char *server_string; /* context */ | | * 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 */ | |
| | | | |
| /* Add new things just above here ---^ | | /* Add new things just above here ---^ | |
| * This is part of the ABI, don't needlessly break compatibility | | * This is part of the ABI, don't needlessly break compatibility | |
| * | | * | |
| * The below is to ensure later library versions with new | | * The below is to ensure later library versions with new | |
| * members added above will see 0 (default) even if the app | | * members added above will see 0 (default) even if the app | |
| * was not built against the newer headers. | | * was not built against the newer headers. | |
| */ | | */ | |
| | | | |
|
| void *_unused[8]; | | void *_unused[8]; /**< dummy */ | |
| }; | | }; | |
| | | | |
| /** | | /** | |
|
| * struct lws_client_connect_info - parameters to connect with when using | | * lws_create_context() - Create the websocket handler | |
| * lws_client_connect_via_info() | | * \param info: pointer to struct with parameters | |
| * | | * | |
|
| * @context: lws context to create connection in | | * This function creates the listening socket (if serving) and takes ca | |
| * @address: remote address to connect to | | re | |
| * @port: remote port to connect to | | * of all initialization in one step. | |
| * @ssl_connection: nonzero for ssl | | * | |
| * @path: uri path | | * If option LWS_SERVER_OPTION_EXPLICIT_VHOSTS is given, no vhost is | |
| * @host: content of host header | | * created; you're expected to create your own vhosts afterwards using | |
| * @origin: content of origin header | | * lws_create_vhost(). Otherwise a vhost named "default" is also creat | |
| * @protocol: list of ws protocols | | ed | |
| * @ietf_version_or_minus_one: currently leave at 0 or -1 | | * using the information in the vhost-related members, for compatibilit | |
| * @userdata: if non-NULL, use this as wsi user_data instead of malloc it | | y. | |
| * @client_exts: array of extensions that may be used on connection | | * | |
| * @method: if non-NULL, do this http method instead of ws[s] upgrade. | | * After initialization, it returns a struct lws_context * that | |
| * use "GET" to be a simple http client connection | | * represents this server. After calling, user code needs to take care | |
| * @parent_wsi: if another wsi is responsible for this connection, g | | * of calling lws_service() with the context pointer to get the | |
| ive it here. | | * server's sockets serviced. This must be done in the same process | |
| * this is used to make sure if the parent closes so do any | | * context as the initialization call. | |
| * child connections first. | | * | |
| * @uri_replace_from: if non-NULL, when this string is found in URIs in | | * The protocol callback functions are called for a handful of events | |
| * text/html content-encoding, it's replaced with @uri_replace_ | | * including http requests coming in, websocket connections becoming | |
| to | | * established, and data arriving; it's also called periodically to all | |
| * @uri_replace_to: see above | | ow | |
| * @vhost: vhost to bind to (used to determine related SSL_CTX) | | * 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 | |
| | | */ | |
| | | 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_client_connect_info { | |
| struct lws_context *context; | | struct lws_context *context; | |
|
| | | /**< lws context to create connection in */ | |
| const char *address; | | const char *address; | |
|
| | | /**< remote address to connect to */ | |
| int port; | | int port; | |
|
| | | /**< remote port to connect to */ | |
| int ssl_connection; | | int ssl_connection; | |
|
| | | /**< nonzero for ssl */ | |
| const char *path; | | const char *path; | |
|
| | | /**< uri path */ | |
| const char *host; | | const char *host; | |
|
| | | /**< content of host header */ | |
| const char *origin; | | const char *origin; | |
|
| | | /**< content of origin header */ | |
| const char *protocol; | | const char *protocol; | |
|
| | | /**< list of ws protocols we could accept */ | |
| int ietf_version_or_minus_one; | | int ietf_version_or_minus_one; | |
|
| | | /**< deprecated: currently leave at 0 or -1 */ | |
| void *userdata; | | void *userdata; | |
|
| | | /**< if non-NULL, use this as wsi user_data instead of malloc it */ | |
| const struct lws_extension *client_exts; | | const struct lws_extension *client_exts; | |
|
| | | /**< array of extensions that may be used on connection */ | |
| const char *method; | | 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; | | 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; | | 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; | | const char *uri_replace_to; | |
|
| | | /**< see uri_replace_from */ | |
| struct lws_vhost *vhost; | | 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 ---^ | | /* Add new things just above here ---^ | |
| * This is part of the ABI, don't needlessly break compatibility | | * This is part of the ABI, don't needlessly break compatibility | |
| * | | * | |
| * The below is to ensure later library versions with new | | * The below is to ensure later library versions with new | |
| * members added above will see 0 (default) even if the app | | * members added above will see 0 (default) even if the app | |
| * was not built against the newer headers. | | * was not built against the newer headers. | |
| */ | | */ | |
| | | | |
|
| void *_unused[4]; | | void *_unused[4]; /**< dummy */ | |
| }; | | }; | |
| | | | |
|
| enum { | | /** | |
| LWSMPRO_HTTP, | | * lws_client_connect_via_info() - Connect to another websocket server | |
| LWSMPRO_HTTPS, | | * \param ccinfo: pointer to lws_client_connect_info struct | |
| LWSMPRO_FILE, | | * | |
| LWSMPRO_CGI, | | * This function creates a connection to a remote server using the | |
| LWSMPRO_REDIR_HTTP, | | * information provided in ccinfo. | |
| LWSMPRO_REDIR_HTTPS, | | */ | |
| }; | | 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_VISIBLE LWS_EXTERN int | |
|
| lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len); | | lws_init_vhost_client_ssl(const struct lws_context_creation_info *info, | |
| | | struct lws_vhost *vhost); | |
| | | | |
| LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int | |
|
| lws_json_dump_context(const struct lws_context *context, char *buf, int len
); | | lws_http_client_read(struct lws *wsi, char **buf, int *len); | |
| | | | |
| LWS_VISIBLE LWS_EXTERN void | | LWS_VISIBLE LWS_EXTERN void | |
|
| lws_set_log_level(int level, | | lws_client_http_body_pending(struct lws *wsi, int something_left_to_send); | |
| void (*log_emit_function)(int level, const char *line)); | | | |
| | | | |
|
| LWS_VISIBLE LWS_EXTERN void | | /** | |
| lwsl_emit_syslog(int level, const char *line); | | * 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. | |
| | | */ | |
| | | | |
|
| LWS_VISIBLE LWS_EXTERN struct lws_context * | | ///@} | |
| lws_create_context(struct lws_context_creation_info *info); | | | |
| | | | |
|
| struct lws_vhost; | | /** \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_EXTERN LWS_VISIBLE struct lws_vhost * | | /** | |
| lws_create_vhost(struct lws_context *context, | | * lws_service() - Service any pending websocket activity | |
| struct lws_context_creation_info *info); | | * \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_VISIBLE LWS_EXTERN struct lws_vhost * | | /** | |
| lws_vhost_get(struct lws *wsi); | | * 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_VISIBLE LWS_EXTERN const struct lws_protocols * | | /** | |
| lws_protocol_get(struct lws *wsi); | | * 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_VISIBLE LWS_EXTERN void * | | /** | |
| lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_proto | | * lws_cancel_service() - Cancel wait for new pending socket activity | |
| cols *prot, | | * \param context: Websocket context | |
| int size); | | * | |
| LWS_VISIBLE LWS_EXTERN void * | | * This function let a call to lws_service() waiting for a timeout | |
| lws_protocol_vh_priv_get(struct lws_vhost *vhost, const struct lws_protocol | | * immediately return. | |
| s *prot); | | * | |
| | | * 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_VISIBLE LWS_EXTERN int | |
|
| lws_finalize_startup(struct lws_context *context); | | 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_VISIBLE LWS_EXTERN int | |
|
| lws_set_proxy(struct lws_vhost *vhost, const char *proxy); | | lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, | |
| | | int tsi); | |
| | | | |
|
| LWS_VISIBLE LWS_EXTERN void | | ///@} | |
| lws_context_destroy(struct lws_context *context); | | | |
| | | | |
|
| LWS_VISIBLE LWS_EXTERN int | | /*! \defgroup http HTTP | |
| lws_service(struct lws_context *context, int timeout_ms); | | | |
| | | 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_VISIBLE LWS_EXTERN int | |
|
| lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi); | | 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 void | | /*! \defgroup html-chunked-substitution HTML Chunked Substitution | |
| lws_cancel_service_pt(struct lws *wsi); | | * \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. | |
| | | */ | |
| | | //@{ | |
| | | | |
|
| LWS_VISIBLE LWS_EXTERN void | | enum http_status { | |
| lws_cancel_service(struct lws_context *context); | | 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_VISIBLE LWS_EXTERN int | |
|
| lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr, | | lws_chunked_html_process(struct lws_process_html_args *args, | |
| size_t addrlen); | | 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 | |
| | | * LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum | |
| | | * list below is absent, .token = NULL and token_len = 0. Otherwise .token | |
| | | * points to .token_len chars containing that header content. | |
| | | */ | |
| | | struct lws_tokens { | |
| | | char *token; /**< pointer to start of the token */ | |
| | | 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 | |
| | | * | |
| | | * 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_token_indexes { | |
| | | WSI_TOKEN_GET_URI = 0, | |
| | | WSI_TOKEN_POST_URI = 1, | |
| | | WSI_TOKEN_OPTIONS_URI = 2, | |
| | | WSI_TOKEN_HOST = 3, | |
| | | WSI_TOKEN_CONNECTION = 4, | |
| | | WSI_TOKEN_UPGRADE = 5, | |
| | | WSI_TOKEN_ORIGIN = 6, | |
| | | WSI_TOKEN_DRAFT = 7, | |
| | | WSI_TOKEN_CHALLENGE = 8, | |
| | | WSI_TOKEN_EXTENSIONS = 9, | |
| | | WSI_TOKEN_KEY1 = 10, | |
| | | WSI_TOKEN_KEY2 = 11, | |
| | | WSI_TOKEN_PROTOCOL = 12, | |
| | | WSI_TOKEN_ACCEPT = 13, | |
| | | WSI_TOKEN_NONCE = 14, | |
| | | WSI_TOKEN_HTTP = 15, | |
| | | WSI_TOKEN_HTTP2_SETTINGS = 16, | |
| | | WSI_TOKEN_HTTP_ACCEPT = 17, | |
| | | WSI_TOKEN_HTTP_AC_REQUEST_HEADERS = 18, | |
| | | WSI_TOKEN_HTTP_IF_MODIFIED_SINCE = 19, | |
| | | WSI_TOKEN_HTTP_IF_NONE_MATCH = 20, | |
| | | WSI_TOKEN_HTTP_ACCEPT_ENCODING = 21, | |
| | | WSI_TOKEN_HTTP_ACCEPT_LANGUAGE = 22, | |
| | | WSI_TOKEN_HTTP_PRAGMA = 23, | |
| | | WSI_TOKEN_HTTP_CACHE_CONTROL = 24, | |
| | | WSI_TOKEN_HTTP_AUTHORIZATION = 25, | |
| | | WSI_TOKEN_HTTP_COOKIE = 26, | |
| | | WSI_TOKEN_HTTP_CONTENT_LENGTH = 27, | |
| | | WSI_TOKEN_HTTP_CONTENT_TYPE = 28, | |
| | | WSI_TOKEN_HTTP_DATE = 29, | |
| | | WSI_TOKEN_HTTP_RANGE = 30, | |
| | | WSI_TOKEN_HTTP_REFERER = 31, | |
| | | WSI_TOKEN_KEY = 32, | |
| | | WSI_TOKEN_VERSION = 33, | |
| | | WSI_TOKEN_SWORIGIN = 34, | |
| | | | |
| | | WSI_TOKEN_HTTP_COLON_AUTHORITY = 35, | |
| | | WSI_TOKEN_HTTP_COLON_METHOD = 36, | |
| | | WSI_TOKEN_HTTP_COLON_PATH = 37, | |
| | | WSI_TOKEN_HTTP_COLON_SCHEME = 38, | |
| | | WSI_TOKEN_HTTP_COLON_STATUS = 39, | |
| | | | |
| | | WSI_TOKEN_HTTP_ACCEPT_CHARSET = 40, | |
| | | WSI_TOKEN_HTTP_ACCEPT_RANGES = 41, | |
| | | WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN = 42, | |
| | | WSI_TOKEN_HTTP_AGE = 43, | |
| | | WSI_TOKEN_HTTP_ALLOW = 44, | |
| | | WSI_TOKEN_HTTP_CONTENT_DISPOSITION = 45, | |
| | | WSI_TOKEN_HTTP_CONTENT_ENCODING = 46, | |
| | | WSI_TOKEN_HTTP_CONTENT_LANGUAGE = 47, | |
| | | WSI_TOKEN_HTTP_CONTENT_LOCATION = 48, | |
| | | WSI_TOKEN_HTTP_CONTENT_RANGE = 49, | |
| | | WSI_TOKEN_HTTP_ETAG = 50, | |
| | | WSI_TOKEN_HTTP_EXPECT = 51, | |
| | | WSI_TOKEN_HTTP_EXPIRES = 52, | |
| | | WSI_TOKEN_HTTP_FROM = 53, | |
| | | WSI_TOKEN_HTTP_IF_MATCH = 54, | |
| | | WSI_TOKEN_HTTP_IF_RANGE = 55, | |
| | | WSI_TOKEN_HTTP_IF_UNMODIFIED_SINCE = 56, | |
| | | WSI_TOKEN_HTTP_LAST_MODIFIED = 57, | |
| | | WSI_TOKEN_HTTP_LINK = 58, | |
| | | WSI_TOKEN_HTTP_LOCATION = 59, | |
| | | WSI_TOKEN_HTTP_MAX_FORWARDS = 60, | |
| | | WSI_TOKEN_HTTP_PROXY_AUTHENTICATE = 61, | |
| | | WSI_TOKEN_HTTP_PROXY_AUTHORIZATION = 62, | |
| | | WSI_TOKEN_HTTP_REFRESH = 63, | |
| | | WSI_TOKEN_HTTP_RETRY_AFTER = 64, | |
| | | WSI_TOKEN_HTTP_SERVER = 65, | |
| | | WSI_TOKEN_HTTP_SET_COOKIE = 66, | |
| | | WSI_TOKEN_HTTP_STRICT_TRANSPORT_SECURITY = 67, | |
| | | WSI_TOKEN_HTTP_TRANSFER_ENCODING = 68, | |
| | | WSI_TOKEN_HTTP_USER_AGENT = 69, | |
| | | WSI_TOKEN_HTTP_VARY = 70, | |
| | | WSI_TOKEN_HTTP_VIA = 71, | |
| | | WSI_TOKEN_HTTP_WWW_AUTHENTICATE = 72, | |
| | | | |
| | | WSI_TOKEN_PATCH_URI = 73, | |
| | | WSI_TOKEN_PUT_URI = 74, | |
| | | WSI_TOKEN_DELETE_URI = 75, | |
| | | | |
| | | WSI_TOKEN_HTTP_URI_ARGS = 76, | |
| | | WSI_TOKEN_PROXY = 77, | |
| | | WSI_TOKEN_HTTP_X_REAL_IP = 78, | |
| | | WSI_TOKEN_HTTP1_0 = 79, | |
| | | | |
| | | /****** add new things just above ---^ ******/ | |
| | | | |
| | | /* use token storage to stash these internally, not for | |
| | | * user use */ | |
| | | | |
| | | _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, | |
| | | _WSI_TOKEN_CLIENT_PEER_ADDRESS, | |
| | | _WSI_TOKEN_CLIENT_URI, | |
| | | _WSI_TOKEN_CLIENT_HOST, | |
| | | _WSI_TOKEN_CLIENT_ORIGIN, | |
| | | _WSI_TOKEN_CLIENT_METHOD, | |
| | | | |
| | | /* always last real token index*/ | |
| | | WSI_TOKEN_COUNT, | |
| | | | |
| | | /* parser state additions, no storage associated */ | |
| | | WSI_TOKEN_NAME_PART, | |
| | | WSI_TOKEN_SKIPPING, | |
| | | WSI_TOKEN_SKIPPING_SAW_CR, | |
| | | WSI_PARSING_COMPLETE, | |
| | | WSI_INIT_TOKEN_MUXURL, | |
| | | }; | |
| | | | |
| | | struct lws_token_limits { | |
| | | unsigned short token_limit[WSI_TOKEN_COUNT]; /**< max chars for this | |
| | | token */ | |
| | | }; | |
| | | | |
| | | /** | |
| | | * lws_token_to_string() - returns a textual representation of a hdr token | |
| | | index | |
| | | * | |
| | | * \param: token index | |
| | | */ | |
| LWS_VISIBLE LWS_EXTERN const unsigned char * | | LWS_VISIBLE LWS_EXTERN const unsigned char * | |
| lws_token_to_string(enum lws_token_indexes token); | | lws_token_to_string(enum lws_token_indexes token); | |
| | | | |
|
| /* all the below must be LWS_WARN_UNUSED_RESULT as they can run short */ | | /** | |
| | | * lws_hdr_total_length: report length of all fragments of a header totalle | |
| | | d up | |
| | | * The returned length does not include the space for a | |
| | | * terminating '\0' | |
| | | * | |
| | | * \param wsi: websocket connection | |
| | | * \param h: which header index we are interested in | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | |
| | | 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' | |
| | | * | |
| | | * \param wsi: websocket connection | |
| | | * \param h: which header index we are interested in | |
| | | * \param frag_idx: which fragment of h we want to get the length of | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | |
| | | lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag | |
| | | _idx); | |
| | | | |
| | | /** | |
| | | * lws_hdr_copy() - 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. | |
| | | * | |
| | | * \param wsi: websocket connection | |
| | | * \param dest: destination buffer | |
| | | * \param len: length of destination buffer | |
| | | * \param h: which header index we are interested in | |
| | | * | |
| | | * copies the whole, aggregated header, even if it was delivered in | |
| | | * several actual headers piece by piece | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN int | |
| | | lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h | |
| | | ); | |
| | | | |
| | | /** | |
| | | * 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. | |
| | | * | |
| | | * \param wsi: websocket connection | |
| | | * \param dest: destination buffer | |
| | | * \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 | |
| | | * | |
| | | * Normally this is only useful | |
| | | * 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 | |
| | | * | |
| | | * Returns NULL if not found or a pointer inside buf to just after the | |
| | | * name= part. | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN const char * | |
| | | lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int le | |
| | | n); | |
| | | ///@} | |
| | | | |
| | | /*! \defgroup HTTP-headers-create HTTP headers: create | |
| | | * | |
| | | * ## HTTP headers: Create | |
| | | * | |
| | | * These apis allow you to create HTTP response headers in a way compatible | |
| | | with | |
| | | * both HTTP/1.x and HTTP/2. | |
| | | * | |
| | | * They each append to a buffer taking care about the buffer end, which is | |
| | | * passed in as a pointer. When data is written to the buffer, the current | |
| | | * position p is updated accordingly. | |
| | | * | |
| | | * All of these apis are LWS_WARN_UNUSED_RESULT as they can run out of spac | |
| | | e | |
| | | * and fail with nonzero return. | |
| | | */ | |
| | | ///@{ | |
| | | /** | |
| | | * lws_add_http_header_status() - add the HTTP response status code | |
| | | * | |
| | | * \param wsi: the connection to check | |
| | | * \param code: an HTTP code like 200, 404 etc (see enum http_status) | |
| | | * \param p: pointer to current position in buffer pointer | |
| | | * \param end: pointer to end of buffer | |
| | | * | |
| | | * Adds the initial response code, so should be called first | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | |
| | | lws_add_http_header_status(struct lws *wsi, | |
| | | unsigned int code, unsigned char **p, | |
| | | unsigned char *end); | |
| | | /** | |
| | | * lws_add_http_header_by_name() - append named header and value | |
| | | * | |
| | | * \param wsi: the connection to check | |
| | | * \param name: the hdr name, like "my-header" | |
| | | * \param value: the value after the = for this header | |
| | | * \param length: the length of the value | |
| | | * \param p: pointer to current position in buffer pointer | |
| | | * \param end: pointer to end of buffer | |
| | | * | |
| | | * Appends name: value to the headers | |
| | | */ | |
| LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | |
| lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name, | | lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name, | |
| const unsigned char *value, int length, | | const unsigned char *value, int length, | |
| unsigned char **p, unsigned char *end); | | unsigned char **p, unsigned char *end); | |
|
| LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | /** | |
| lws_finalize_http_header(struct lws *wsi, unsigned char **p, | | * lws_add_http_header_by_token() - append given header and value | |
| unsigned char *end); | | * | |
| | | * \param wsi: the connection to check | |
| | | * \param token: the token index for the hdr | |
| | | * \param value: the value after the = for this header | |
| | | * \param length: the length of the value | |
| | | * \param p: pointer to current position in buffer pointer | |
| | | * \param end: pointer to end of buffer | |
| | | * | |
| | | * 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_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | |
| lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token, | | lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token, | |
| const unsigned char *value, int length, | | const unsigned char *value, int length, | |
| unsigned char **p, unsigned char *end); | | unsigned char **p, unsigned char *end); | |
|
| | | /** | |
| | | * lws_add_http_header_by_name() - append content-length helper | |
| | | * | |
| | | * \param wsi: the connection to check | |
| | | * \param content_length: the content length to use | |
| | | * \param p: pointer to current position in buffer pointer | |
| | | * \param end: pointer to end of buffer | |
| | | * | |
| | | * Appends content-length: content_length to the headers | |
| | | */ | |
| LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | |
| lws_add_http_header_content_length(struct lws *wsi, | | lws_add_http_header_content_length(struct lws *wsi, | |
| unsigned long content_length, | | unsigned long content_length, | |
| unsigned char **p, unsigned char *end); | | unsigned char **p, unsigned char *end); | |
|
| | | /** | |
| | | * lws_finalize_http_header() - terminate header block | |
| | | * | |
| | | * \param wsi: the connection to check | |
| | | * \param p: pointer to current position in buffer pointer | |
| | | * \param end: pointer to end of buffer | |
| | | * | |
| | | * Indicates no more headers will be added | |
| | | */ | |
| LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | |
|
| lws_add_http_header_status(struct lws *wsi, | | lws_finalize_http_header(struct lws *wsi, unsigned char **p, | |
| unsigned int code, unsigned char **p, | | unsigned char *end); | |
| unsigned char *end); | | ///@} | |
| | | | |
| | | /** \defgroup form-parsing Form Parsing | |
| | | * \ingroup http | |
| | | * ##POSTed form parsing functions | |
| | | * | |
| | | * These lws_spa (stateful post arguments) apis let you parse and urldecode | |
| | | * POSTed form arguments, both using simple urlencoded and multipart transf | |
| | | er | |
| | | * encoding. | |
| | | * | |
| | | * It's capable of handling file uploads as well a named input parsing, | |
| | | * and the apis are the same for both form upload styles. | |
| | | * | |
| | | * You feed it a list of parameter names and it creates pointers to the | |
| | | * urldecoded arguments: file upload parameters pass the file data in chunk | |
| | | s to | |
| | | * a user-supplied callback as they come. | |
| | | * | |
| | | * Since it's stateful, it handles the incoming data needing more than one | |
| | | * 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 | |
| | | * | |
| | | * \param data: opt_data pointer set in lws_spa_create | |
| | | * \param name: name of the form field being uploaded | |
| | | * \param filename: original filename from client | |
| | | * \param buf: start of data to receive | |
| | | * \param len: length of data to receive | |
| | | * \param state: information about how this call relates to file | |
| | | * | |
| | | * Notice name and filename shouldn't be trusted, as they are passed from | |
| | | * 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 | |
| | | * | |
| | | * \param wsi: lws connection (used to find Content Type) | |
| | | * \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. | |
| | | * | |
| | | * Creates a urldecode parser and initializes it. | |
| | | * | |
| | | * opt_cb can be NULL if you just want normal name=value parsing, however | |
| | | * 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 | |
| | | * | |
| | | * \param spa: the parser object previously created | |
| | | * \param in: incoming, urlencoded data | |
| | | * \param len: count of bytes valid at \param in | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN int | |
| | | lws_spa_process(struct lws_spa *spa, const char *in, int len); | |
| | | | |
| | | /** | |
| | | * lws_spa_finalize() - indicate incoming data completed | |
| | | * | |
| | | * \param spa: the parser object previously created | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN int | |
| | | lws_spa_finalize(struct lws_spa *spa); | |
| | | | |
| | | /** | |
| | | * lws_spa_get_length() - return length of parameter value | |
| | | * | |
| | | * \param spa: the parser object previously created | |
| | | * \param n: parameter ordinal to return length of value for | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN int | |
| | | lws_spa_get_length(struct lws_spa *spa, int n); | |
| | | | |
| | | /** | |
| | | * 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 | |
| | | * | |
| | | * \param spa: the parser object previously created | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN int | |
| | | lws_spa_destroy(struct lws_spa *spa); | |
| | | ///@} | |
| | | | |
| | | /*! \defgroup urlendec Urlencode and Urldecode | |
| | | * \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. | |
| | | */ | |
| | | //@{ | |
| | | | |
| | | /** | |
| | | * lws_urlencode() - like strncpy but with urlencoding | |
| | | * | |
| | | * \param escaped: output buffer | |
| | | * \param string: input buffer ('/0' terminated) | |
| | | * \param len: output buffer max length | |
| | | * | |
| | | * Because urlencoding expands the output string, it's not | |
| | | * possible to do it in-place, ie, with escaped == string | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN const char * | |
| | | lws_urlencode(char *escaped, const char *string, int len); | |
| | | | |
| | | /* | |
| | | * URLDECODE 1 / 2 | |
| | | * | |
| | | * This simple urldecode only operates until the first '\0' and requires th | |
| | | e | |
| | | * data to exist all at once | |
| | | */ | |
| | | /** | |
| | | * lws_urldecode() - like strncpy but with urldecoding | |
| | | * | |
| | | * \param string: output buffer | |
| | | * \param escaped: input buffer ('\0' terminated) | |
| | | * \param len: output buffer max length | |
| | | * | |
| | | * This is only useful for '\0' terminated strings | |
| | | * | |
| | | * Since urldecoding only shrinks the output string, it is possible to | |
| | | * do it in-place, ie, string == escaped | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN int | |
| | | lws_urldecode(char *string, const char *escaped, int len); | |
| | | ///@} | |
| | | /** | |
| | | * lws_return_http_status() - Return simple http status | |
| | | * \param wsi: Websocket instance (available from user callback) | |
| | | * \param code: Status index, eg, 404 | |
| | | * \param html_body: User-readable HTML description < 1KB, or NUL | |
| | | L | |
| | | * | |
| | | * Helper to report HTTP errors back to the client cleanly and | |
| | | * consistently | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN int | |
| | | lws_return_http_status(struct lws *wsi, unsigned int code, | |
| | | const char *html_body); | |
| | | | |
| | | /** | |
| | | * lws_http_redirect() - write http redirect into buffer | |
| | | * | |
| | | * \param wsi: websocket connection | |
| | | * \param code: HTTP response code (eg, 301) | |
| | | * \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 | |
| | | */ | |
| LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | |
| lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int
len, | | lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int
len, | |
| unsigned char **p, unsigned char *end); | | unsigned char **p, unsigned char *end); | |
| | | | |
|
| | | /** | |
| | | * lws_http_transaction_completed() - wait for new http transaction or clos | |
| | | e | |
| | | * \param wsi: websocket connection | |
| | | * | |
| | | * Returns 1 if the HTTP connection must close now | |
| | | * Returns 0 and resets connection to wait for new HTTP header / | |
| | | * transaction if possible | |
| | | */ | |
| LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | |
| lws_http_transaction_completed(struct lws *wsi); | | lws_http_transaction_completed(struct lws *wsi); | |
|
| | | ///@} | |
| | | | |
| | | /*! \defgroup pur Sanitize / purify SQL and JSON helpers | |
| | | * | |
| | | * ##Sanitize / purify SQL and JSON helpers | |
| | | * | |
| | | * APIs for escaping untrusted JSON and SQL safely before use | |
| | | */ | |
| | | //@{ | |
| | | | |
| | | /** | |
| | | * lws_sql_purify() - like strncpy but with escaping for sql quotes | |
| | | * | |
| | | * \param escaped: output buffer | |
| | | * \param string: input buffer ('/0' terminated) | |
| | | * \param len: output buffer max length | |
| | | * | |
| | | * Because escaping expands the output string, it's not | |
| | | * possible to do it in-place, ie, with escaped == string | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN const char * | |
| | | lws_sql_purify(char *escaped, const char *string, int len); | |
| | | | |
| | | /** | |
| | | * lws_json_purify() - like strncpy but with escaping for json chars | |
| | | * | |
| | | * \param escaped: output buffer | |
| | | * \param string: input buffer ('/0' terminated) | |
| | | * \param len: output buffer max length | |
| | | * | |
| | | * Because escaping expands the output string, it's not | |
| | | * possible to do it in-place, ie, with escaped == string | |
| | | */ | |
| | | LWS_VISIBLE LWS_EXTERN const char * | |
| | | lws_json_purify(char *escaped, const char *string, int len); | |
| | | ///@} | |
| | | | |
| | | /*! \defgroup ev libev helpers | |
| | | * | |
| | | * ##libev helpers | |
| | | * | |
| | | * APIs specific to libev event loop itegration | |
| | | */ | |
| | | ///@{ | |
| | | | |
| #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 LWS_EXTERN 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 */ | |
| | | | |
|
| | | ///@} | |
| | | | |
| | | /*! \defgroup uv libuv helpers | |
| | | * | |
| | | * ##libuv helpers | |
| | | * | |
| | | * APIs specific to libuv event loop itegration | |
| | | */ | |
| | | ///@{ | |
| #ifdef LWS_USE_LIBUV | | #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, | |
| uv_signal_cb 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 LWS_EXTERN 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, 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 LWS_EXTERN void | | LWS_VISIBLE LWS_EXTERN void | |
| lws_uv_sigint_cb(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, | |
| | | | |
| skipping to change at line 1773 ¶ | | skipping to change at line 3063 ¶ | |
| 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_CGI = 14, | |
| PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE = 15, | | 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 1824 ¶ | | skipping to change at line 3214 ¶ | |
| * 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 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 | | | |
| | | | |
| 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_VISIBLE LWS_EXTERN int | |
| lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost, | | lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost, | |
| const struct lws_protocols *protocol); | | 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_callback_all_protocol_vhost(struct lws_vhost *vh, | | lws_callback_all_protocol_vhost(struct lws_vhost *vh, | |
| const struct lws_protocols *protocol, int reason); | | 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_get_socket_fd(struct lws *wsi); | | lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, int len
); | |
| | | | |
| LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int | |
|
| lws_is_final_fragment(struct lws *wsi); | | lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, | |
| | | void *user, void *in, size_t len); | |
| LWS_VISIBLE LWS_EXTERN unsigned char | | | |
| lws_get_reserved_bits(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_VISIBLE LWS_EXTERN int | |
|
| lws_rx_flow_control(struct lws *wsi, int enable); | | lws_get_socket_fd(struct lws *wsi); | |
| | | | |
| 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_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_VISIBLE LWS_EXTERN struct lws * | |
| lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accep
t_fd, | | lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accep
t_fd, | |
| const char *readbuf, size_t len); | | 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_VISIBLE LWS_EXTERN int | |
| lws_is_cgi(struct lws *wsi); | | 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. | | | |
| */ | | | |
| | | | |
| LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | | |
| lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h); | | | |
| | | | |
| LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | | |
| lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag | | | |
| _idx); | | | |
| | | | |
| /* | | | |
| * copies the whole, aggregated header, even if it was delivered in | | | |
| * several actual headers piece by piece | | | |
| */ | | | |
| LWS_VISIBLE LWS_EXTERN int | | | |
| lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h | | | |
| ); | | | |
| | | | |
| /* | | | |
| * copies only fragment frag_idx of a header. Normally this is only useful | | | |
| * to parse URI arguments like ?x=1&y=2, token index WSI_TOKEN_HTTP_URI_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); | | | |
| | | | |
| /* 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_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT | | | |
| lws_get_parent(const struct lws *wsi); | | | |
| | | | |
| LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT | | | |
| lws_get_child(const struct lws *wsi); | | | |
| | | | |
| #ifdef LWS_WITH_CGI | | #ifdef LWS_WITH_CGI | |
| enum lws_enum_stdinouterr { | | enum lws_enum_stdinouterr { | |
| LWS_STDIN = 0, | | LWS_STDIN = 0, | |
| LWS_STDOUT = 1, | | LWS_STDOUT = 1, | |
| LWS_STDERR = 2, | | LWS_STDERR = 2, | |
| }; | | }; | |
| | | | |
| enum lws_cgi_hdr_state { | | enum lws_cgi_hdr_state { | |
| LCHS_HEADER, | | LCHS_HEADER, | |
| LCHS_CR1, | | LCHS_CR1, | |
| LCHS_LF1, | | LCHS_LF1, | |
| LCHS_CR2, | | LCHS_CR2, | |
| LCHS_LF2, | | LCHS_LF2, | |
| LHCS_PAYLOAD, | | LHCS_PAYLOAD, | |
| LCHS_SINGLE_0A, | | LCHS_SINGLE_0A, | |
| }; | | }; | |
| | | | |
| struct lws_cgi_args { | | struct lws_cgi_args { | |
|
| struct lws **stdwsi; /* get fd with lws_get_socket_fd() */ | | struct lws **stdwsi; /**< get fd with lws_get_socket_fd() */ | |
| enum lws_enum_stdinouterr ch; | | enum lws_enum_stdinouterr ch; /**< channel index */ | |
| unsigned char *data; /* for messages with payload */ | | unsigned char *data; /**< for messages with payload */ | |
| enum lws_cgi_hdr_state hdr_state; | | enum lws_cgi_hdr_state hdr_state; /**< track where we are in cgi hea | |
| int len; | | ders */ | |
| | | int len; /**< length */ | |
| }; | | }; | |
| | | | |
|
| | | /** | |
| | | * lws_cgi: spawn network-connected cgi process | |
| | | * | |
| | | * \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_cgi(struct lws *wsi, const char * const *exec_array, | | lws_cgi(struct lws *wsi, const char * const *exec_array, | |
| int script_uri_path_len, int timeout_secs, | | int script_uri_path_len, int timeout_secs, | |
| const struct lws_protocol_vhost_options *mp_cgienv); | | const struct lws_protocol_vhost_options *mp_cgienv); | |
| | | | |
|
| | | /** | |
| | | * lws_cgi_write_split_stdout_headers: write cgi output accounting for head | |
| | | er part | |
| | | * | |
| | | * \param wsi: connection to own the process | |
| | | */ | |
| LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int | |
| lws_cgi_write_split_stdout_headers(struct lws *wsi); | | lws_cgi_write_split_stdout_headers(struct lws *wsi); | |
| | | | |
|
| | | /** | |
| | | * lws_cgi_kill: terminate cgi process associated with wsi | |
| | | * | |
| | | * \param wsi: connection to own the process | |
| | | */ | |
| LWS_VISIBLE LWS_EXTERN int | | LWS_VISIBLE LWS_EXTERN int | |
| lws_cgi_kill(struct lws *wsi); | | lws_cgi_kill(struct lws *wsi); | |
| #endif | | #endif | |
|
| | | ///@} | |
| | | | |
|
| LWS_VISIBLE LWS_EXTERN int | | /*! \defgroup fops file operation wrapping | |
| lws_http_client_read(struct lws *wsi, char **buf, int *len); | | * | |
| | | * ##File operation wrapping | |
| /* | | | |
| * Wsi-associated File Operations access helpers | | | |
| * | | * | |
| * 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. 267 change blocks. |
| 1393 lines changed or deleted | | 3388 lines changed or added | |
|