libwebsockets.h (3.0.0) | | libwebsockets.h (current) |
| | |
skipping to change at line 69 ¶ | | skipping to change at line 69 ¶ |
#include <stddef.h> | | #include <stddef.h> |
#include <basetsd.h> | | #include <basetsd.h> |
#include <io.h> | | #include <io.h> |
#ifndef _WIN32_WCE | | #ifndef _WIN32_WCE |
#include <fcntl.h> | | #include <fcntl.h> |
#else | | #else |
#define _O_RDONLY 0x0000 | | #define _O_RDONLY 0x0000 |
#define O_RDONLY _O_RDONLY | | #define O_RDONLY _O_RDONLY |
#endif | | #endif |
| | |
// Visual studio older than 2015 and WIN_CE has only _stricmp | | |
#if (defined(_MSC_VER) && _MSC_VER < 1900) || defined(_WIN32_WCE) | | |
#define strcasecmp _stricmp | | |
#elif !defined(__MINGW32__) | | |
#define strcasecmp stricmp | | |
#endif | | |
#define getdtablesize() 30000 | | |
| | |
#define LWS_INLINE __inline | | #define LWS_INLINE __inline |
#define LWS_VISIBLE | | #define LWS_VISIBLE |
#define LWS_WARN_UNUSED_RESULT | | #define LWS_WARN_UNUSED_RESULT |
#define LWS_WARN_DEPRECATED | | #define LWS_WARN_DEPRECATED |
#define LWS_FORMAT(string_index) | | #define LWS_FORMAT(string_index) |
| | |
| | #if !defined(LWS_EXTERN) |
#ifdef LWS_DLL | | #ifdef LWS_DLL |
#ifdef LWS_INTERNAL | | #ifdef LWS_INTERNAL |
#define LWS_EXTERN extern __declspec(dllexport) | | #define LWS_EXTERN extern __declspec(dllexport) |
#else | | #else |
#define LWS_EXTERN extern __declspec(dllimport) | | #define LWS_EXTERN extern __declspec(dllimport) |
#endif | | #endif |
#else | | #else |
#define LWS_EXTERN | | #define LWS_EXTERN |
#endif | | #endif |
| | #endif |
| | |
#define LWS_INVALID_FILE INVALID_HANDLE_VALUE | | #define LWS_INVALID_FILE INVALID_HANDLE_VALUE |
#define LWS_O_RDONLY _O_RDONLY | | #define LWS_O_RDONLY _O_RDONLY |
#define LWS_O_WRONLY _O_WRONLY | | #define LWS_O_WRONLY _O_WRONLY |
#define LWS_O_CREAT _O_CREAT | | #define LWS_O_CREAT _O_CREAT |
#define LWS_O_TRUNC _O_TRUNC | | #define LWS_O_TRUNC _O_TRUNC |
| | |
#ifndef __func__ | | #ifndef __func__ |
#define __func__ __FUNCTION__ | | #define __func__ __FUNCTION__ |
#endif | | #endif |
| | |
#else /* NOT WIN32 */ | | #else /* NOT WIN32 */ |
#include <unistd.h> | | #include <unistd.h> |
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) | | #if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) |
#include <sys/capability.h> | | #include <sys/capability.h> |
#endif | | #endif |
| | |
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__QNX__) | | #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__QNX__) || defi |
| | ned(__OpenBSD__) |
| | #include <sys/socket.h> |
#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 |
#define LWS_O_WRONLY O_WRONLY | | #define LWS_O_WRONLY O_WRONLY |
#define LWS_O_CREAT O_CREAT | | #define LWS_O_CREAT O_CREAT |
#define LWS_O_TRUNC O_TRUNC | | #define LWS_O_TRUNC O_TRUNC |
| | |
#if !defined(LWS_PLAT_OPTEE) && !defined(OPTEE_TA) && !defined(LWS_WITH_ESP
32) | | #if !defined(LWS_PLAT_OPTEE) && !defined(OPTEE_TA) && !defined(LWS_WITH_ESP
32) |
| | |
skipping to change at line 152 ¶ | | skipping to change at line 147 ¶ |
#define LWS_WARN_DEPRECATED __attribute__ ((deprecated)) | | #define LWS_WARN_DEPRECATED __attribute__ ((deprecated)) |
#define LWS_FORMAT(string_index) __attribute__ ((format(printf, string_inde
x, string_index+1))) | | #define LWS_FORMAT(string_index) __attribute__ ((format(printf, string_inde
x, string_index+1))) |
#else | | #else |
#define LWS_VISIBLE | | #define LWS_VISIBLE |
#define LWS_WARN_UNUSED_RESULT | | #define LWS_WARN_UNUSED_RESULT |
#define LWS_WARN_DEPRECATED | | #define LWS_WARN_DEPRECATED |
#define LWS_FORMAT(string_index) | | #define LWS_FORMAT(string_index) |
#endif | | #endif |
| | |
#if defined(__ANDROID__) | | #if defined(__ANDROID__) |
| | #include <netinet/in.h> |
#include <unistd.h> | | #include <unistd.h> |
#define getdtablesize() sysconf(_SC_OPEN_MAX) | | #define getdtablesize() sysconf(_SC_OPEN_MAX) |
#endif | | #endif |
| | |
#endif | | #endif |
| | |
#if defined(LWS_WITH_LIBEV) | | #if defined(LWS_WITH_LIBEV) |
#include <ev.h> | | #include <ev.h> |
#endif /* LWS_WITH_LIBEV */ | | #endif /* LWS_WITH_LIBEV */ |
#ifdef LWS_WITH_LIBUV | | #ifdef LWS_WITH_LIBUV |
#include <uv.h> | | #include <uv.h> |
#ifdef LWS_HAVE_UV_VERSION_H | | #ifdef LWS_HAVE_UV_VERSION_H |
#include <uv-version.h> | | #include <uv-version.h> |
#endif | | #endif |
| | #ifdef LWS_HAVE_NEW_UV_VERSION_H |
| | #include <uv/version.h> |
| | #endif |
#endif /* LWS_WITH_LIBUV */ | | #endif /* LWS_WITH_LIBUV */ |
#if defined(LWS_WITH_LIBEVENT) | | #if defined(LWS_WITH_LIBEVENT) |
#include <event2/event.h> | | #include <event2/event.h> |
#endif /* LWS_WITH_LIBEVENT */ | | #endif /* LWS_WITH_LIBEVENT */ |
| | |
#ifndef LWS_EXTERN | | #ifndef LWS_EXTERN |
#define LWS_EXTERN extern | | #define LWS_EXTERN extern |
#endif | | #endif |
| | |
#ifdef _WIN32 | | #ifdef _WIN32 |
| | |
skipping to change at line 280 ¶ | | skipping to change at line 279 ¶ |
#define lws_pthread_mutex(name) | | #define lws_pthread_mutex(name) |
#define lws_pthread_mutex_init(_a) | | #define lws_pthread_mutex_init(_a) |
#define lws_pthread_mutex_destroy(_a) | | #define lws_pthread_mutex_destroy(_a) |
#define lws_pthread_mutex_lock(_a) | | #define lws_pthread_mutex_lock(_a) |
#define lws_pthread_mutex_unlock(_a) | | #define lws_pthread_mutex_unlock(_a) |
#endif | | #endif |
| | |
#define CONTEXT_PORT_NO_LISTEN -1 | | #define CONTEXT_PORT_NO_LISTEN -1 |
#define CONTEXT_PORT_NO_LISTEN_SERVER -2 | | #define CONTEXT_PORT_NO_LISTEN_SERVER -2 |
| | |
/** \defgroup log Logging | | #include <libwebsockets/lws-logs.h> |
* | | |
* ##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 { | | |
LLL_ERR = 1 << 0, | | |
LLL_WARN = 1 << 1, | | |
LLL_NOTICE = 1 << 2, | | |
LLL_INFO = 1 << 3, | | |
LLL_DEBUG = 1 << 4, | | |
LLL_PARSER = 1 << 5, | | |
LLL_HEADER = 1 << 6, | | |
LLL_EXT = 1 << 7, | | |
LLL_CLIENT = 1 << 8, | | |
LLL_LATENCY = 1 << 9, | | |
LLL_USER = 1 << 10, | | |
| | |
LLL_COUNT = 11 /* set to count of valid flags */ | | |
}; | | |
| | |
LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...) L | | |
WS_FORMAT(2); | | |
LWS_VISIBLE LWS_EXTERN void _lws_logv(int filter, const char *format, va_li | | |
st vl); | | |
/** | | |
* lwsl_timestamp: generate logging timestamp string | | |
* | | |
* \param level: logging level | | |
* \param p: char * buffer to take timestamp | | |
* \param len: length of p | | |
* | | |
* returns length written in p | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lwsl_timestamp(int level, char *p, int len); | | |
| | |
/* these guys are unconditionally included */ | | |
| | |
#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__) | | |
#define lwsl_user(...) _lws_log(LLL_USER, __VA_ARGS__) | | |
| | |
#if !defined(LWS_WITH_NO_LOGS) | | |
/* notice and warn are usually included by being compiled in */ | | |
#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) | | |
#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) | | |
#endif | | |
/* | | |
* weaker logging can be deselected by telling CMake to build in RELEASE m | | |
ode | | |
* that gets rid of the overhead of checking while keeping _warn and _err | | |
* active | | |
*/ | | |
| | |
#ifdef _DEBUG | | |
#if defined(LWS_WITH_NO_LOGS) | | |
/* notice, warn and log are always compiled in */ | | |
#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_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__) | | |
#define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__) | | |
#define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__) | | |
#define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__) | | |
#define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__) | | |
#define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__) | | |
| | |
#else /* no debug */ | | |
#if defined(LWS_WITH_NO_LOGS) | | |
#define lwsl_warn(...) do {} while(0) | | |
#define lwsl_notice(...) do {} while(0) | | |
#endif | | |
#define lwsl_info(...) do {} while(0) | | |
#define lwsl_debug(...) do {} while(0) | | |
#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) | | |
| | |
#endif | | |
| | |
#define lwsl_hexdump_err(...) lwsl_hexdump_level(LLL_ERR, __VA_ARGS__) | | |
#define lwsl_hexdump_warn(...) lwsl_hexdump_level(LLL_WARN, __VA_ARGS__) | | |
#define lwsl_hexdump_notice(...) lwsl_hexdump_level(LLL_NOTICE, __VA_ARGS__ | | |
) | | |
#define lwsl_hexdump_info(...) lwsl_hexdump_level(LLL_INFO, __VA_ARGS__) | | |
#define lwsl_hexdump_debug(...) lwsl_hexdump_level(LLL_DEBUG, __VA_ARGS__) | | |
| | |
/** | | |
* lwsl_hexdump_level() - helper to hexdump a buffer at a selected debug le | | |
vel | | |
* | | |
* \param level: one of LLL_ constants | | |
* \param vbuf: buffer start to dump | | |
* \param len: length of buffer to dump | | |
* | | |
* If \p level is visible, does a nice hexdump -C style dump of \p vbuf for | | |
* \p len bytes. This can be extremely convenient while debugging. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lwsl_hexdump_level(int level, const void *vbuf, size_t len); | | |
| | |
/** | | |
* lwsl_hexdump() - helper to hexdump a buffer (DEBUG builds only) | | |
* | | |
* \param buf: buffer start to dump | | |
* \param len: length of buffer to dump | | |
* | | |
* Calls through to lwsl_hexdump_level(LLL_DEBUG, ... for compatability. | | |
* It's better to use lwsl_hexdump_level(level, ... directly so you can con | | |
trol | | |
* the visibility. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lwsl_hexdump(const void *buf, size_t len); | | |
| | |
/** | | |
* lws_is_be() - returns nonzero if the platform is Big Endian | | |
*/ | | |
static LWS_INLINE int lws_is_be(void) { | | |
const int probe = ~0xff; | | |
| | |
return *(const char *)&probe; | | |
} | | |
| | |
/** | | |
* 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. If stderr is a tty (according to isatty()) then | | |
* the output is coloured according to the log level using ANSI escapes | | |
. | | |
*/ | | |
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); | | |
| | |
/** | | |
* lwsl_visible() - returns true if the log level should be printed | | |
* | | |
* \param level: one of LLL_ log level indexes | | |
* | | |
* This is useful if you have to do work to generate the log content, you | | |
* can skip the work if the log level used to print it is not actually | | |
* enabled at runtime. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lwsl_visible(int level); | | |
| | |
///@} | | |
| | |
#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 | | |
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) | | |
#endif | | |
| | |
typedef int64_t lws_usec_t; | | typedef int64_t lws_usec_t; |
| | |
/* api change list for user code to test against */ | | /* api change list for user code to test against */ |
| | |
#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_ARG | | #define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_ARG |
| | |
/* the struct lws_protocols has the id field present */ | | /* the struct lws_protocols has the id field present */ |
#define LWS_FEATURE_PROTOCOLS_HAS_ID_FIELD | | #define LWS_FEATURE_PROTOCOLS_HAS_ID_FIELD |
| | |
/* you can call lws_get_peer_write_allowance */ | | /* you can call lws_get_peer_write_allowance */ |
#define LWS_FEATURE_PROTOCOLS_HAS_PEER_WRITE_ALLOWANCE | | #define LWS_FEATURE_PROTOCOLS_HAS_PEER_WRITE_ALLOWANCE |
| | |
/* extra parameter introduced in 917f43ab821 */ | | /* extra parameter introduced in 917f43ab821 */ |
#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_LEN | | #define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_LEN |
| | |
/* File operations stuff exists */ | | /* File operations stuff exists */ |
#define LWS_FEATURE_FOPS | | #define LWS_FEATURE_FOPS |
| | |
#if defined(_WIN32) | | #if defined(_WIN32) |
| | #if !defined(LWS_WIN32_HANDLE_TYPES) |
typedef SOCKET lws_sockfd_type; | | typedef SOCKET lws_sockfd_type; |
typedef HANDLE lws_filefd_type; | | typedef HANDLE lws_filefd_type; |
| | #endif |
| | |
struct lws_pollfd { | | struct lws_pollfd { |
lws_sockfd_type fd; /**< file descriptor */ | | lws_sockfd_type fd; /**< file descriptor */ |
SHORT events; /**< which events to respond to */ | | SHORT events; /**< which events to respond to */ |
SHORT revents; /**< which events happened */ | | SHORT revents; /**< which events happened */ |
}; | | }; |
#define LWS_POLLHUP (FD_CLOSE) | | #define LWS_POLLHUP (FD_CLOSE) |
#define LWS_POLLIN (FD_READ | FD_ACCEPT) | | #define LWS_POLLIN (FD_READ | FD_ACCEPT) |
#define LWS_POLLOUT (FD_WRITE) | | #define LWS_POLLOUT (FD_WRITE) |
#else | | #else |
| | |
#if defined(LWS_WITH_ESP32) | | #if defined(LWS_WITH_ESP32) |
| | #include <libwebsockets/lws-esp32.h> |
typedef int lws_sockfd_type; | | |
typedef int lws_filefd_type; | | |
| | |
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 | | |
| | |
#include <freertos/FreeRTOS.h> | | |
#include <freertos/event_groups.h> | | |
#include <string.h> | | |
#include "esp_wifi.h" | | |
#include "esp_system.h" | | |
#include "esp_event.h" | | |
#include "esp_event_loop.h" | | |
#include "nvs.h" | | |
#include "driver/gpio.h" | | |
#include "esp_spi_flash.h" | | |
#include "freertos/timers.h" | | |
| | |
#if !defined(CONFIG_FREERTOS_HZ) | | |
#define CONFIG_FREERTOS_HZ 100 | | |
#endif | | |
| | |
typedef TimerHandle_t uv_timer_t; | | |
typedef void uv_cb_t(uv_timer_t *); | | |
typedef void * uv_handle_t; | | |
| | |
struct timer_mapping { | | |
uv_cb_t *cb; | | |
uv_timer_t *t; | | |
}; | | |
| | |
#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; | | |
*t = NULL; | | |
} | | |
| | |
extern void esp32_uvtimer_cb(TimerHandle_t t); | | |
| | |
static inline void uv_timer_start(uv_timer_t *t, uv_cb_t *cb, int first, in | | |
t rep) | | |
{ | | |
struct timer_mapping *tm = (struct timer_mapping *)malloc(sizeof(*tm | | |
)); | | |
| | |
if (!tm) | | |
return; | | |
| | |
tm->t = t; | | |
tm->cb = cb; | | |
| | |
*t = xTimerCreate("x", pdMS_TO_TICKS(first), !!rep, tm, | | |
(TimerCallbackFunction_t)esp32_uvtimer_cb); | | |
xTimerStart(*t, 0); | | |
} | | |
| | |
static inline void uv_timer_stop(uv_timer_t *t) | | |
{ | | |
xTimerStop(*t, 0); | | |
} | | |
| | |
static inline void uv_close(uv_handle_t *h, void *v) | | |
{ | | |
free(pvTimerGetTimerID((uv_timer_t)h)); | | |
xTimerDelete(*(uv_timer_t *)h, 0); | | |
} | | |
| | |
/* ESP32 helper declarations */ | | |
| | |
#include <mdns.h> | | |
#include <esp_partition.h> | | |
| | |
#define LWS_PLUGIN_STATIC | | |
#define LWS_MAGIC_REBOOT_TYPE_ADS 0x50001ffc | | |
#define LWS_MAGIC_REBOOT_TYPE_REQ_FACTORY 0xb00bcafe | | |
#define LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY 0xfaceb00b | | |
#define LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON 0xf0cedfac | | |
| | |
/* user code provides these */ | | |
| | |
extern void | | |
lws_esp32_identify_physical_device(void); | | |
| | |
/* lws-plat-esp32 provides these */ | | |
| | |
typedef void (*lws_cb_scan_done)(uint16_t count, wifi_ap_record_t *recs, vo | | |
id *arg); | | |
| | |
enum genled_state { | | |
LWSESP32_GENLED__INIT, | | |
LWSESP32_GENLED__LOST_NETWORK, | | |
LWSESP32_GENLED__NO_NETWORK, | | |
LWSESP32_GENLED__CONN_AP, | | |
LWSESP32_GENLED__GOT_IP, | | |
LWSESP32_GENLED__OK, | | |
}; | | |
| | |
struct lws_group_member { | | |
struct lws_group_member *next; | | |
uint64_t last_seen; | | |
char model[16]; | | |
char role[16]; | | |
char host[32]; | | |
char mac[20]; | | |
int width, height; | | |
struct ip4_addr addr; | | |
struct ip6_addr addrv6; | | |
uint8_t flags; | | |
}; | | |
| | |
#define LWS_SYSTEM_GROUP_MEMBER_ADD 1 | | |
#define LWS_SYSTEM_GROUP_MEMBER_CHANGE 2 | | |
#define LWS_SYSTEM_GROUP_MEMBER_REMOVE 3 | | |
| | |
#define LWS_GROUP_FLAG_SELF 1 | | |
| | |
struct lws_esp32 { | | |
char sta_ip[16]; | | |
char sta_mask[16]; | | |
char sta_gw[16]; | | |
char serial[16]; | | |
char opts[16]; | | |
char model[16]; | | |
char group[16]; | | |
char role[16]; | | |
char ssid[4][64]; | | |
char password[4][64]; | | |
char active_ssid[64]; | | |
char access_pw[16]; | | |
char hostname[32]; | | |
char mac[20]; | | |
char le_dns[64]; | | |
char le_email[64]; | | |
char region; | | |
char inet; | | |
char conn_ap; | | |
| | |
enum genled_state genled; | | |
uint64_t genled_t; | | |
| | |
lws_cb_scan_done scan_consumer; | | |
void *scan_consumer_arg; | | |
struct lws_group_member *first; | | |
int extant_group_members; | | |
| | |
char acme; | | |
char upload; | | |
| | |
volatile char button_is_down; | | |
}; | | |
| | |
struct lws_esp32_image { | | |
uint32_t romfs; | | |
uint32_t romfs_len; | | |
uint32_t json; | | |
uint32_t json_len; | | |
}; | | |
| | |
extern struct lws_esp32 lws_esp32; | | |
struct lws_vhost; | | |
| | |
extern esp_err_t | | |
lws_esp32_event_passthru(void *ctx, system_event_t *event); | | |
extern void | | |
lws_esp32_wlan_config(void); | | |
extern void | | |
lws_esp32_wlan_start_ap(void); | | |
extern void | | |
lws_esp32_wlan_start_station(void); | | |
struct lws_context_creation_info; | | |
extern void | | |
lws_esp32_set_creation_defaults(struct lws_context_creation_info *info); | | |
extern struct lws_context * | | |
lws_esp32_init(struct lws_context_creation_info *, struct lws_vhost **pvh); | | |
extern int | | |
lws_esp32_wlan_nvs_get(int retry); | | |
extern esp_err_t | | |
lws_nvs_set_str(nvs_handle handle, const char* key, const char* value); | | |
extern void | | |
lws_esp32_restart_guided(uint32_t type); | | |
extern const esp_partition_t * | | |
lws_esp_ota_get_boot_partition(void); | | |
extern int | | |
lws_esp32_get_image_info(const esp_partition_t *part, struct lws_esp32_imag | | |
e *i, char *json, int json_len); | | |
extern int | | |
lws_esp32_leds_network_indication(void); | | |
| | |
extern uint32_t lws_esp32_get_reboot_type(void); | | |
extern uint16_t lws_esp32_sine_interp(int n); | | |
| | |
/* required in external code by esp32 plat (may just return if no leds) */ | | |
extern void lws_esp32_leds_timer_cb(TimerHandle_t th); | | |
#else | | #else |
typedef int lws_sockfd_type; | | typedef int lws_sockfd_type; |
typedef int lws_filefd_type; | | typedef int lws_filefd_type; |
#endif | | #endif |
| | |
#define lws_pollfd pollfd | | #define lws_pollfd pollfd |
#define LWS_POLLHUP (POLLHUP|POLLERR) | | #define LWS_POLLHUP (POLLHUP|POLLERR) |
#define LWS_POLLIN (POLLIN) | | #define LWS_POLLIN (POLLIN) |
#define LWS_POLLOUT (POLLOUT) | | #define LWS_POLLOUT (POLLOUT) |
#endif | | #endif |
| | |
skipping to change at line 744 ¶ | | skipping to change at line 373 ¶ |
typedef uint32_t lws_fop_flags_t; | | typedef uint32_t lws_fop_flags_t; |
| | |
/** struct lws_pollargs - argument structure for all external poll related
calls | | /** struct lws_pollargs - argument structure for all external poll related
calls |
* passed in via 'in' */ | | * passed in via 'in' */ |
struct lws_pollargs { | | struct lws_pollargs { |
lws_sockfd_type fd; /**< applicable socket descriptor */ | | lws_sockfd_type fd; /**< applicable socket descriptor */ |
int events; /**< the new event mask */ | | int events; /**< the new event mask */ |
int prev_events; /**< the previous event mask */ | | int prev_events; /**< the previous event mask */ |
}; | | }; |
| | |
struct lws_tokens; | | struct lws_extension; /* needed even with ws exts disabled for create conte
xt */ |
struct lws_token_limits; | | 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, | | |
* add it at where specified so existing users are unaffected. | | |
*/ | | |
/** enum lws_close_status - RFC6455 close status codes */ | | |
enum lws_close_status { | | |
LWS_CLOSE_STATUS_NOSTATUS = 0, | | |
LWS_CLOSE_STATUS_NORMAL = 1000, | | |
/**< 1000 indicates a normal closure, meaning that the purpose for | | |
which the connection was established has been fulfilled. */ | | |
LWS_CLOSE_STATUS_GOINGAWAY = 1001, | | |
/**< 1001 indicates that an endpoint is "going away", such as a serv | | |
er | | |
going down or a browser having navigated away from a page. */ | | |
LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002, | | |
/**< 1002 indicates that an endpoint is terminating the connection d | | |
ue | | |
to a protocol error. */ | | |
LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003, | | |
/**< 1003 indicates that an endpoint is terminating the connection | | |
because it has received a type of data it cannot accept (e.g., an | | |
endpoint that understands only text data MAY send this if it | | |
receives a binary message). */ | | |
LWS_CLOSE_STATUS_RESERVED = 1004, | | |
/**< Reserved. The specific meaning might be defined in the future. | | |
*/ | | |
LWS_CLOSE_STATUS_NO_STATUS = 1005, | | |
/**< 1005 is a reserved value and MUST NOT be set as a status code i | | |
n a | | |
Close control frame by an endpoint. It is designated for use in | | |
applications expecting a status code to indicate that no status | | |
code was actually present. */ | | |
LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006, | | |
/**< 1006 is a reserved value and MUST NOT be set as a status code i | | |
n a | | |
Close control frame by an endpoint. It is designated for use in | | |
applications expecting a status code to indicate that the | | |
connection was closed abnormally, e.g., without sending or | | |
receiving a Close control frame. */ | | |
LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007, | | |
/**< 1007 indicates that an endpoint is terminating the connection | | |
because it has received data within a message that was not | | |
consistent with the type of the message (e.g., non-UTF-8 [RFC3629] | | |
data within a text message). */ | | |
LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008, | | |
/**< 1008 indicates that an endpoint is terminating the connection | | |
because it has received a message that violates its policy. This | | |
is a generic status code that can be returned when there is no | | |
other more suitable status code (e.g., 1003 or 1009) or if there | | |
is a need to hide specific details about the policy. */ | | |
LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009, | | |
/**< 1009 indicates that an endpoint is terminating the connection | | |
because it has received a message that is too big for it to | | |
process. */ | | |
LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010, | | |
/**< 1010 indicates that an endpoint (client) is terminating the | | |
connection because it has expected the server to negotiate one or | | |
more extension, but the server didn't return them in the response | | |
message of the WebSocket handshake. The list of extensions that | | |
are needed SHOULD appear in the /reason/ part of the Close frame. | | |
Note that this status code is not used by the server, because it | | |
can fail the WebSocket handshake instead */ | | |
LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011, | | |
/**< 1011 indicates that a server is terminating the connection beca | | |
use | | |
it encountered an unexpected condition that prevented it from | | |
fulfilling the request. */ | | |
LWS_CLOSE_STATUS_TLS_FAILURE = 1015, | | |
/**< 1015 is a reserved value and MUST NOT be set as a status code i | | |
n a | | |
Close control frame by an endpoint. It is designated for use in | | |
applications expecting a status code to indicate that the | | |
connection was closed due to a failure to perform a TLS handshake | | |
(e.g., the server certificate can't be verified). */ | | |
| | |
LWS_CLOSE_STATUS_CLIENT_TRANSACTION_DONE = 2000, | | |
| | |
/****** add new things just above ---^ ******/ | | |
| | |
LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY = 9999, | | |
}; | | |
| | |
/** | | |
* lws_close_reason - Set reason and aux data to send with Close packet | | |
* If you are going to return nonzero from the callback | | |
* requesting the connection to close, you can optionally | | |
* call this to set the reason the peer will be told if | | |
* possible. | | |
* | | |
* \param wsi: The websocket connection to set the close reason on | | |
* \param status: A valid close status from websocket standard | | |
* \param buf: NULL or buffer containing up to 124 bytes of auxiliary data | | |
* \param len: Length of data in \param buf to send | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_close_reason(struct lws *wsi, enum lws_close_status status, | | |
unsigned char *buf, size_t len); | | |
| | |
///@} | | |
| | |
struct lws; | | |
struct lws_context; | | struct lws_context; |
/* needed even with extensions disabled for create context */ | | struct lws_tokens; |
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. | | |
*/ | | |
///@{ | | |
| | |
struct lws_ssl_info { | | |
int where; | | |
int ret; | | |
}; | | |
| | |
enum lws_cert_update_state { | | |
LWS_CUS_IDLE, | | |
LWS_CUS_STARTING, | | |
LWS_CUS_SUCCESS, | | |
LWS_CUS_FAILED, | | |
| | |
LWS_CUS_CREATE_KEYS, | | |
LWS_CUS_REG, | | |
LWS_CUS_AUTH, | | |
LWS_CUS_CHALLENGE, | | |
LWS_CUS_CREATE_REQ, | | |
LWS_CUS_REQ, | | |
LWS_CUS_CONFIRM, | | |
LWS_CUS_ISSUE, | | |
}; | | |
| | |
enum { | | |
LWS_TLS_REQ_ELEMENT_COUNTRY, | | |
LWS_TLS_REQ_ELEMENT_STATE, | | |
LWS_TLS_REQ_ELEMENT_LOCALITY, | | |
LWS_TLS_REQ_ELEMENT_ORGANIZATION, | | |
LWS_TLS_REQ_ELEMENT_COMMON_NAME, | | |
LWS_TLS_REQ_ELEMENT_EMAIL, | | |
| | |
LWS_TLS_REQ_ELEMENT_COUNT, | | |
| | |
LWS_TLS_SET_DIR_URL = LWS_TLS_REQ_ELEMENT_COUNT, | | |
LWS_TLS_SET_AUTH_PATH, | | |
LWS_TLS_SET_CERT_PATH, | | |
LWS_TLS_SET_KEY_PATH, | | |
| | |
LWS_TLS_TOTAL_COUNT | | |
}; | | |
| | |
struct lws_acme_cert_aging_args { | | |
struct lws_vhost *vh; | | |
const char *element_overrides[LWS_TLS_TOTAL_COUNT]; /* NULL = use pv | | |
o */ | | |
}; | | |
| | |
/* | | |
* 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_callback_reasons - reason you're getting a protocol callback * | | |
/ | | |
enum lws_callback_reasons { | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to wsi and protocol binding lifecycle --- | | |
-- | | |
*/ | | |
| | |
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, | | |
/**< One-time call per protocol, per-vhost using it, indicating | | |
* 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_HTTP_BIND_PROTOCOL = 49, | | |
/**< By default, all HTTP handling is done in protocols[0]. | | |
* However you can bind different protocols (by name) to | | |
* different parts of the URL space using callback mounts. This | | |
* callback occurs in the new protocol when a wsi is bound | | |
* to that protocol. Any protocol allocation related to the | | |
* http transaction processing should be created then. | | |
* These specific callbacks are necessary because with HTTP/1.1, | | |
* a single connection may perform at series of different | | |
* transactions at different URLs, thus the lifetime of the | | |
* protocol bind is just for one transaction, not connection. */ | | |
| | |
LWS_CALLBACK_HTTP_DROP_PROTOCOL = 50, | | |
/**< This is called when a transaction is unbound from a protocol. | | |
* It indicates the connection completed its transaction and may | | |
* do something different now. Any protocol allocation related | | |
* to the http transaction processing should be destroyed. */ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to Server TLS ----- | | |
*/ | | |
| | |
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, | | |
/**< if configured for | | |
* including OpenSSL support, this callback allows your user code | | |
* to load extra certificates into the server which allow it to | | |
* verify the validity of certificates returned by clients. user | | |
* is the server's OpenSSL SSL_CTX* and in is the lws_vhost */ | | |
| | |
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_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_SSL_INFO = 67, | | |
/**< SSL connections only. An event you registered an | | |
* interest in at the vhost has occurred on a connection | | |
* using the vhost. in is a pointer to a | | |
* struct lws_ssl_info containing information about the | | |
* event*/ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to Client TLS ----- | | |
*/ | | |
| | |
LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION = 58, | | |
/**< Similar to LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATIO | | |
N | | |
* this callback is called during OpenSSL verification of the cert | | |
* sent from the server to the client. It is sent to protocol[0] | | |
* callback as no protocol has been negotiated on the connection yet | | |
. | | |
* Notice that the wsi is set because lws_client_connect_via_info wa | | |
s | | |
* successful. | | |
* | | |
* 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. | | |
* | | |
* THIS IS NOT RECOMMENDED BUT if a cert validation error shall be | | |
* overruled and cert shall be accepted as ok, | | |
* X509_STORE_CTX_set_error((X509_STORE_CTX*)user, X509_V_OK); must | | |
be | | |
* called and return value must be 0 to mean the cert is OK; | | |
* returning 1 will fail the cert in any case. | | |
* | | |
* This also means that if you don't handle this callback then | | |
* the default callback action of returning 0 will not accept the | | |
* certificate in case of a validation error decided by the SSL lib. | | |
* | | |
* This is expected and secure behaviour when validating certificate | | |
s. | | |
* | | |
* Note: LCCSCF_ALLOW_SELFSIGNED and | | |
* LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK still work without this | | |
* callback being implemented. | | |
*/ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to HTTP Server ----- | | |
*/ | | |
| | |
LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED = 19, | | |
/**< A new client has been accepted by the ws server. 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_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, | | |
/**< the next len bytes data from the http | | |
* request body HTTP connection is now available in in. */ | | |
| | |
LWS_CALLBACK_HTTP_BODY_COMPLETION = 14, | | |
/**< the expected amount of http request body has been delivered */ | | |
| | |
LWS_CALLBACK_HTTP_FILE_COMPLETION = 15, | | |
/**< a file requested to be sent down http link has completed. */ | | |
| | |
LWS_CALLBACK_HTTP_WRITEABLE = 16, | | |
/**< you can write more down the http protocol link now. */ | | |
| | |
LWS_CALLBACK_CLOSED_HTTP = 5, | | |
/**< when a HTTP (non-websocket) session ends */ | | |
| | |
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_ADD_HEADERS = 53, | | |
/**< This gives your user code a chance to add headers to a server | | |
* transaction bound to your protocol. `in` points to a | | |
* `struct lws_process_html_args` describing a buffer and length | | |
* you can add headers into using the normal lws apis. | | |
* | | |
* (see LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER to add headers t | | |
o | | |
* a client transaction) | | |
* | | |
* Only `args->p` and `args->len` are valid, and `args->p` should | | |
* be moved on by the amount of bytes written, if any. Eg | | |
* | | |
* case LWS_CALLBACK_ADD_HEADERS: | | |
* | | |
* struct lws_process_html_args *args = | | |
* (struct lws_process_html_args *)in; | | |
* | | |
* if (lws_add_http_header_by_name(wsi, | | |
* (unsigned char *)"set-cookie:", | | |
* (unsigned char *)cookie, cookie_len, | | |
* (unsigned char **)&args->p, | | |
* (unsigned char *)args->p + args->max_len)) | | |
* return 1; | | |
* | | |
* break; | | |
*/ | | |
| | |
LWS_CALLBACK_CHECK_ACCESS_RIGHTS = 51, | | |
/**< This gives the user code a chance to forbid an http access. | | |
* `in` points to a `struct lws_process_html_args`, which | | |
* describes the URL, and a bit mask describing the type of | | |
* authentication required. If the callback returns nonzero, | | |
* the transaction ends with HTTP_STATUS_UNAUTHORIZED. */ | | |
| | |
LWS_CALLBACK_PROCESS_HTML = 52, | | |
/**< This gives your user code a chance to mangle outgoing | | |
* HTML. `in` points to a `struct lws_process_html_args` | | |
* which describes the buffer containing outgoing HTML. | | |
* The buffer may grow up to `.max_len` (currently +128 | | |
* bytes per buffer). | | |
*/ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to HTTP Client ----- | | |
*/ | | |
| | |
LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP = 44, | | |
/**< The HTTP client connection has succeeded, and is now | | |
* connected to the server */ | | |
| | |
LWS_CALLBACK_CLOSED_CLIENT_HTTP = 45, | | |
/**< The HTTP client connection is closing */ | | |
| | |
LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ = 48, | | |
/**< This is generated by lws_http_client_read() used to drain | | |
* incoming data. In the case the incoming data was chunked, it wil | | |
l | | |
* be split into multiple smaller callbacks for each chunk block, | | |
* removing the chunk headers. If not chunked, it will appear all in | | |
* one callback. */ | | |
| | |
LWS_CALLBACK_RECEIVE_CLIENT_HTTP = 46, | | |
/**< This simply indicates data was received on the HTTP client | | |
* connection. It does NOT drain or provide the data. | | |
* This exists to neatly allow a proxying type situation, | | |
* where this incoming data will go out on another connection. | | |
* If the outgoing connection stalls, we should stall processing | | |
* the incoming data. So a handler for this in that case should | | |
* simply set a flag to indicate there is incoming data ready | | |
* and ask for a writeable callback on the outgoing connection. | | |
* In the writable callback he can check the flag and then get | | |
* and drain the waiting incoming data using lws_http_client_read(). | | |
* This will use callbacks to LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ | | |
* to get and drain the incoming data, where it should be sent | | |
* back out on the outgoing connection. */ | | |
LWS_CALLBACK_COMPLETED_CLIENT_HTTP = 47, | | |
/**< The client transaction completed... at the moment this | | |
* is the same as closing since transaction pipelining on | | |
* client side is not yet supported. */ | | |
| | |
LWS_CALLBACK_CLIENT_HTTP_WRITEABLE = 57, | | |
/**< when doing an HTTP type client connection, you can call | | |
* lws_client_http_body_pending(wsi, 1) from | | |
* LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER to get these callback | | |
s | | |
* sending the HTTP headers. | | |
* | | |
* From this callback, when you have sent everything, you should let | | |
* lws know by calling lws_client_http_body_pending(wsi, 0) | | |
*/ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to Websocket Server ----- | | |
*/ | | |
| | |
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. | | |
* | | |
* b0 of len is set if the connection was made using ws-over-h2 | | |
*/ | | |
| | |
LWS_CALLBACK_CLOSED = 4, | | |
/**< when the websocket session ends */ | | |
| | |
LWS_CALLBACK_SERVER_WRITEABLE = 11, | | |
/**< See LWS_CALLBACK_CLIENT_WRITEABLE */ | | |
| | |
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, | | |
/**< servers receive PONG packets with this callback reason */ | | |
| | |
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-readabl | | |
e | | |
* 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_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_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. */ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to Websocket Client ----- | | |
*/ | | |
| | |
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, | | |
/**< 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, | | |
/**< after your client connection completed the websocket upgrade | | |
* handshake with the remote server */ | | |
| | |
LWS_CALLBACK_CLIENT_CLOSED = 75, | | |
/**< when a client websocket session ends */ | | |
| | |
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. | | |
* | | |
* See LWS_CALLBACK_ADD_HEADERS for adding headers to server | | |
* transactions. | | |
*/ | | |
| | |
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, | | |
/**< clients receive PONG packets with this callback reason */ | | |
| | |
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_CLIENT_CONFIRM_EXTENSION_SUPPORTED = 26, | | |
/**< When a ws 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_WS_EXT_DEFAULTS = 39, | | |
/**< Gives client connections an opportunity to adjust negotiated | | |
* extension defaults. `user` is the extension name that was | | |
* negotiated (eg, "permessage-deflate"). `in` points to a | | |
* buffer and `len` is the buffer size. The user callback can | | |
* set the buffer to a string describing options the extension | | |
* should parse. Or just ignore for defaults. */ | | |
| | |
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. */ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to external poll loop integration ----- | | |
*/ | | |
| | |
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 */ | | |
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, | | |
/**< 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, | | |
/**< 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, | | |
/**< 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, | | |
/**< See LWS_CALLBACK_LOCK_POLL, ignore if using lws internal poll * | | |
/ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to CGI serving ----- | | |
*/ | | |
| | |
LWS_CALLBACK_CGI = 40, | | |
/**< CGI: CGI IO events on stdin / out / err are sent here on | | |
* protocols[0]. The provided `lws_callback_http_dummy()` | | |
* handles this and the callback should be directed there if | | |
* you use CGI. */ | | |
| | |
LWS_CALLBACK_CGI_TERMINATED = 41, | | |
/**< CGI: The related CGI process ended, this is called before | | |
* the wsi is closed. Used to, eg, terminate chunking. | | |
* The provided `lws_callback_http_dummy()` | | |
* handles this and the callback should be directed there if | | |
* you use CGI. The child PID that terminated is in len. */ | | |
| | |
LWS_CALLBACK_CGI_STDIN_DATA = 42, | | |
/**< CGI: Data is, to be sent to the CGI process stdin, eg from | | |
* a POST body. The provided `lws_callback_http_dummy()` | | |
* handles this and the callback should be directed there if | | |
* you use CGI. */ | | |
| | |
LWS_CALLBACK_CGI_STDIN_COMPLETED = 43, | | |
/**< CGI: no more stdin is coming. The provided | | |
* `lws_callback_http_dummy()` handles this and the callback | | |
* should be directed there if you use CGI. */ | | |
| | |
LWS_CALLBACK_CGI_PROCESS_ATTACH = 70, | | |
/**< CGI: Sent when the CGI process is spawned for the wsi. The | | |
* len parameter is the PID of the child process */ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to Generic Sessions ----- | | |
*/ | | |
| | |
LWS_CALLBACK_SESSION_INFO = 54, | | |
/**< This is only generated by user code using generic sessions. | | |
* It's used to get a `struct lws_session_info` filled in by | | |
* generic sessions with information about the logged-in user. | | |
* See the messageboard sample for an example of how to use. */ | | |
| | |
LWS_CALLBACK_GS_EVENT = 55, | | |
/**< Indicates an event happened to the Generic Sessions session. | | |
* `in` contains a `struct lws_gs_event_args` describing the event. | | |
*/ | | |
| | |
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. | | |
*/ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to RAW sockets ----- | | |
*/ | | |
| | |
LWS_CALLBACK_RAW_RX = 59, | | |
/**< RAW mode connection RX */ | | |
| | |
LWS_CALLBACK_RAW_CLOSE = 60, | | |
/**< RAW mode connection is closing */ | | |
| | |
LWS_CALLBACK_RAW_WRITEABLE = 61, | | |
/**< RAW mode connection may be written */ | | |
| | |
LWS_CALLBACK_RAW_ADOPT = 62, | | |
/**< RAW mode connection was adopted (equivalent to 'wsi created') * | | |
/ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to RAW file handles ----- | | |
*/ | | |
| | |
LWS_CALLBACK_RAW_ADOPT_FILE = 63, | | |
/**< RAW mode file was adopted (equivalent to 'wsi created') */ | | |
| | |
LWS_CALLBACK_RAW_RX_FILE = 64, | | |
/**< This is the indication the RAW mode file has something to read. | | |
* This doesn't actually do the read of the file and len is always | | |
* 0... your code should do the read having been informed there is | | |
* something to read now. */ | | |
| | |
LWS_CALLBACK_RAW_WRITEABLE_FILE = 65, | | |
/**< RAW mode file is writeable */ | | |
| | |
LWS_CALLBACK_RAW_CLOSE_FILE = 66, | | |
/**< RAW mode wsi that adopted a file is closing */ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to generic wsi events ----- | | |
*/ | | |
| | |
LWS_CALLBACK_TIMER = 73, | | |
/**< When the time elapsed after a call to | | |
* lws_set_timer_usecs(wsi, usecs) is up, the wsi will get one of | | |
* these callbacks. The deadline can be continuously extended into | | |
the | | |
* future by later calls to lws_set_timer_usecs() before the deadlin | | |
e | | |
* expires, or cancelled by lws_set_timer_usecs(wsi, -1); | | |
* See the note on lws_set_timer_usecs() about which event loops are | | |
* supported. */ | | |
| | |
LWS_CALLBACK_EVENT_WAIT_CANCELLED = 71, | | |
/**< This is sent to every protocol of every vhost in response | | |
* to lws_cancel_service() or lws_cancel_service_pt(). This | | |
* callback is serialized in the lws event loop normally, even | | |
* if the lws_cancel_service[_pt]() call was from a different | | |
* thread. */ | | |
| | |
LWS_CALLBACK_CHILD_CLOSING = 69, | | |
/**< Sent to parent to notify them a child is closing / being | | |
* destroyed. in is the child wsi. | | |
*/ | | |
| | |
LWS_CALLBACK_CHILD_WRITE_VIA_PARENT = 68, | | |
/**< Child has been marked with parent_carries_io attribute, so | | |
* lws_write directs the to this callback at the parent, | | |
* in is a struct lws_write_passthru containing the args | | |
* the lws_write() was called with. | | |
*/ | | |
| | |
/* ----------------------------------------------------------------- | | |
---- | | |
* ----- Callbacks related to TLS certificate management ----- | | |
*/ | | |
| | |
LWS_CALLBACK_VHOST_CERT_AGING = 72, | | |
/**< When a vhost TLS cert has its expiry checked, this callback | | |
* is broadcast to every protocol of every vhost in case the | | |
* protocol wants to take some action with this information. | | |
* \p in is a pointer to a struct lws_acme_cert_aging_args, | | |
* and \p len is the number of days left before it expires, as | | |
* a (ssize_t). In the struct lws_acme_cert_aging_args, vh | | |
* points to the vhost the cert aging information applies to, | | |
* and element_overrides[] is an optional way to update information | | |
* from the pvos... NULL in an index means use the information from | | |
* from the pvo for the cert renewal, non-NULL in the array index | | |
* means use that pointer instead for the index. */ | | |
| | |
LWS_CALLBACK_VHOST_CERT_UPDATE = 74, | | |
/**< When a vhost TLS cert is being updated, progress is | | |
* reported to the vhost in question here, including completion | | |
* and failure. in points to optional JSON, and len represents the | | |
* connection state using enum lws_cert_update_state */ | | |
| | |
/****** add new things just above ---^ ******/ | | |
| | |
LWS_CALLBACK_USER = 1000, | | |
/**< user code can use any including above without fear of clashes | | |
*/ | | |
}; | | |
| | |
/** | | |
* 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 | | |
* | | |
* 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. | | |
*/ | | |
typedef int | | |
lws_callback_function(struct lws *wsi, enum lws_callback_reasons reason, | | |
void *user, void *in, size_t len); | | |
| | |
#define LWS_CB_REASON_AUX_BF__CGI 1 | | |
#define LWS_CB_REASON_AUX_BF__PROXY 2 | | |
#define LWS_CB_REASON_AUX_BF__CGI_CHUNK_END 4 | | |
#define LWS_CB_REASON_AUX_BF__CGI_HEADERS 8 | | |
///@} | | |
| | |
struct lws_vhost; | | struct lws_vhost; |
| | struct lws; |
| | |
/*! \defgroup generic hash | | #include <libwebsockets/lws-ws-close.h> |
* ## Generic Hash related functions | | #include <libwebsockets/lws-callbacks.h> |
* | | #include <libwebsockets/lws-ws-state.h> |
* Lws provides generic hash / digest accessors that abstract the ones | | #include <libwebsockets/lws-ws-ext.h> |
* provided by whatever OpenSSL library you are linking against. | | #include <libwebsockets/lws-protocols-plugins.h> |
* | | #include <libwebsockets/lws-plugin-generic-sessions.h> |
* It lets you use the same code if you build against mbedtls or OpenSSL | | #include <libwebsockets/lws-context-vhost.h> |
* for example. | | #include <libwebsockets/lws-client.h> |
*/ | | #include <libwebsockets/lws-http.h> |
///@{ | | #include <libwebsockets/lws-spa.h> |
| | #include <libwebsockets/lws-purify.h> |
| | #include <libwebsockets/lws-timeout-timer.h> |
| | #include <libwebsockets/lws-service.h> |
| | #include <libwebsockets/lws-write.h> |
| | #include <libwebsockets/lws-writeable.h> |
| | #include <libwebsockets/lws-adopt.h> |
| | #include <libwebsockets/lws-network-helper.h> |
| | #include <libwebsockets/lws-misc.h> |
| | #include <libwebsockets/lws-ring.h> |
| | #include <libwebsockets/lws-sha1-base64.h> |
| | #include <libwebsockets/lws-x509.h> |
| | #include <libwebsockets/lws-cgi.h> |
| | #include <libwebsockets/lws-vfs.h> |
| | #include <libwebsockets/lws-lejp.h> |
| | #include <libwebsockets/lws-stats.h> |
| | #include <libwebsockets/lws-threadpool.h> |
| | |
#if defined(LWS_WITH_TLS) | | #if defined(LWS_WITH_TLS) |
| | |
#if defined(LWS_WITH_MBEDTLS) | | #if defined(LWS_WITH_MBEDTLS) |
#include <mbedtls/sha1.h> | | #include <mbedtls/sha1.h> |
#include <mbedtls/sha256.h> | | #include <mbedtls/sha256.h> |
#include <mbedtls/sha512.h> | | #include <mbedtls/sha512.h> |
#endif | | #endif |
| | |
enum lws_genhash_types { | | #include <libwebsockets/lws-genhash.h> |
LWS_GENHASH_TYPE_SHA1, | | #include <libwebsockets/lws-genrsa.h> |
LWS_GENHASH_TYPE_SHA256, | | #include <libwebsockets/lws-jwk.h> |
LWS_GENHASH_TYPE_SHA384, | | #include <libwebsockets/lws-jws.h> |
LWS_GENHASH_TYPE_SHA512, | | |
}; | | |
| | |
enum lws_genhmac_types { | | |
LWS_GENHMAC_TYPE_SHA256, | | |
LWS_GENHMAC_TYPE_SHA384, | | |
LWS_GENHMAC_TYPE_SHA512, | | |
}; | | |
| | |
#define LWS_GENHASH_LARGEST 64 | | |
| | |
struct lws_genhash_ctx { | | |
uint8_t type; | | |
#if defined(LWS_WITH_MBEDTLS) | | |
union { | | |
mbedtls_sha1_context sha1; | | |
mbedtls_sha256_context sha256; | | |
mbedtls_sha512_context sha512; /* 384 also uses this */ | | |
const mbedtls_md_info_t *hmac; | | |
} u; | | |
#else | | |
const EVP_MD *evp_type; | | |
EVP_MD_CTX *mdctx; | | |
#endif | | |
}; | | |
| | |
struct lws_genhmac_ctx { | | |
uint8_t type; | | |
#if defined(LWS_WITH_MBEDTLS) | | |
const mbedtls_md_info_t *hmac; | | |
mbedtls_md_context_t ctx; | | |
#else | | |
const EVP_MD *evp_type; | | |
EVP_MD_CTX *ctx; | | |
#endif | | |
}; | | |
| | |
/** lws_genhash_size() - get hash size in bytes | | |
* | | |
* \param type: one of LWS_GENHASH_TYPE_... | | |
* | | |
* Returns number of bytes in this type of hash | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN size_t LWS_WARN_UNUSED_RESULT | | |
lws_genhash_size(enum lws_genhash_types type); | | |
| | |
/** lws_genhmac_size() - get hash size in bytes | | |
* | | |
* \param type: one of LWS_GENHASH_TYPE_... | | |
* | | |
* Returns number of bytes in this type of hmac | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN size_t LWS_WARN_UNUSED_RESULT | | |
lws_genhmac_size(enum lws_genhmac_types type); | | |
| | |
/** lws_genhash_init() - prepare your struct lws_genhash_ctx for use | | |
* | | |
* \param ctx: your struct lws_genhash_ctx | | |
* \param type: one of LWS_GENHASH_TYPE_... | | |
* | | |
* Initializes the hash context for the type you requested | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | |
lws_genhash_init(struct lws_genhash_ctx *ctx, enum lws_genhash_types type); | | |
| | |
/** lws_genhash_update() - digest len bytes of the buffer starting at in | | |
* | | |
* \param ctx: your struct lws_genhash_ctx | | |
* \param in: start of the bytes to digest | | |
* \param len: count of bytes to digest | | |
* | | |
* Updates the state of your hash context to reflect digesting len bytes fr | | |
om in | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | |
lws_genhash_update(struct lws_genhash_ctx *ctx, const void *in, size_t len) | | |
; | | |
| | |
/** lws_genhash_destroy() - copy out the result digest and destroy the ctx | | |
* | | |
* \param ctx: your struct lws_genhash_ctx | | |
* \param result: NULL, or where to copy the result hash | | |
* | | |
* Finalizes the hash and copies out the digest. Destroys any allocations | | |
such | | |
* that ctx can safely go out of scope after calling this. | | |
* | | |
* NULL result is supported so that you can destroy the ctx cleanly on erro | | |
r | | |
* conditions, where there is no valid result. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result); | | |
| | |
/** lws_genhmac_init() - prepare your struct lws_genhmac_ctx for use | | |
* | | |
* \param ctx: your struct lws_genhmac_ctx | | |
* \param type: one of LWS_GENHMAC_TYPE_... | | |
* \param key: pointer to the start of the HMAC key | | |
* \param key_len: length of the HMAC key | | |
* | | |
* Initializes the hash context for the type you requested | | |
* | | |
* If the return is nonzero, it failed and there is nothing needing to be | | |
* destroyed. | | |
*/ | | |
int | | |
lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type, | | |
const uint8_t *key, size_t key_len); | | |
| | |
/** lws_genhmac_update() - digest len bytes of the buffer starting at in | | |
* | | |
* \param ctx: your struct lws_genhmac_ctx | | |
* \param in: start of the bytes to digest | | |
* \param len: count of bytes to digest | | |
* | | |
* Updates the state of your hash context to reflect digesting len bytes fr | | |
om in | | |
* | | |
* If the return is nonzero, it failed and needs destroying. | | |
*/ | | |
int | | |
lws_genhmac_update(struct lws_genhmac_ctx *ctx, const void *in, size_t len) | | |
; | | |
| | |
/** lws_genhmac_destroy() - copy out the result digest and destroy the ctx | | |
* | | |
* \param ctx: your struct lws_genhmac_ctx | | |
* \param result: NULL, or where to copy the result hash | | |
* | | |
* Finalizes the hash and copies out the digest. Destroys any allocations | | |
such | | |
* that ctx can safely go out of scope after calling this. | | |
* | | |
* NULL result is supported so that you can destroy the ctx cleanly on erro | | |
r | | |
* conditions, where there is no valid result. | | |
*/ | | |
int | | |
lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result); | | |
///@} | | |
| | |
/*! \defgroup generic RSA | | |
* ## Generic RSA related functions | | |
* | | |
* Lws provides generic RSA functions that abstract the ones | | |
* provided by whatever OpenSSL library you are linking against. | | |
* | | |
* It lets you use the same code if you build against mbedtls or OpenSSL | | |
* for example. | | |
*/ | | |
///@{ | | |
| | |
enum enum_jwk_tok { | | |
JWK_KEY_E, | | |
JWK_KEY_N, | | |
JWK_KEY_D, | | |
JWK_KEY_P, | | |
JWK_KEY_Q, | | |
JWK_KEY_DP, | | |
JWK_KEY_DQ, | | |
JWK_KEY_QI, | | |
JWK_KTY, /* also serves as count of real elements */ | | |
JWK_KEY, | | |
}; | | |
| | |
#define LWS_COUNT_RSA_ELEMENTS JWK_KTY | | |
| | |
struct lws_genrsa_ctx { | | |
#if defined(LWS_WITH_MBEDTLS) | | |
mbedtls_rsa_context *ctx; | | |
#else | | |
BIGNUM *bn[LWS_COUNT_RSA_ELEMENTS]; | | |
RSA *rsa; | | |
#endif | | |
}; | | |
| | |
struct lws_genrsa_element { | | |
uint8_t *buf; | | |
uint16_t len; | | |
}; | | |
| | |
struct lws_genrsa_elements { | | |
struct lws_genrsa_element e[LWS_COUNT_RSA_ELEMENTS]; | | |
}; | | |
| | |
/** lws_jwk_destroy_genrsa_elements() - Free allocations in genrsa_elements | | |
* | | |
* \param el: your struct lws_genrsa_elements | | |
* | | |
* This is a helper for user code making use of struct lws_genrsa_elements | | |
* where the elements are allocated on the heap, it frees any non-NULL | | |
* buf element and sets the buf to NULL. | | |
* | | |
* NB: lws_genrsa_public_... apis do not need this as they take care of the | | |
key | | |
* creation and destruction themselves. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_jwk_destroy_genrsa_elements(struct lws_genrsa_elements *el); | | |
| | |
/** lws_genrsa_public_decrypt_create() - Create RSA public decrypt context | | |
* | | |
* \param ctx: your struct lws_genrsa_ctx | | |
* \param el: struct prepared with key element data | | |
* | | |
* Creates an RSA context with a public key associated with it, formed from | | |
* the key elements in \p el. | | |
* | | |
* Returns 0 for OK or nonzero for error. | | |
* | | |
* This and related APIs operate identically with OpenSSL or mbedTLS backen | | |
ds. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_genrsa_create(struct lws_genrsa_ctx *ctx, struct lws_genrsa_elements *e | | |
l); | | |
| | |
/** lws_genrsa_new_keypair() - Create new RSA keypair | | |
* | | |
* \param context: your struct lws_context (may be used for RNG) | | |
* \param ctx: your struct lws_genrsa_ctx | | |
* \param el: struct to get the new key element data allocated into it | | |
* \param bits: key size, eg, 4096 | | |
* | | |
* Creates a new RSA context and generates a new keypair into it, with \p b | | |
its | | |
* bits. | | |
* | | |
* Returns 0 for OK or nonzero for error. | | |
* | | |
* This and related APIs operate identically with OpenSSL or mbedTLS backen | | |
ds. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_genrsa_new_keypair(struct lws_context *context, struct lws_genrsa_ctx * | | |
ctx, | | |
struct lws_genrsa_elements *el, int bits); | | |
| | |
/** lws_genrsa_public_decrypt() - Perform RSA public decryption | | |
* | | |
* \param ctx: your struct lws_genrsa_ctx | | |
* \param in: encrypted input | | |
* \param in_len: length of encrypted input | | |
* \param out: decrypted output | | |
* \param out_max: size of output buffer | | |
* | | |
* Performs the decryption. | | |
* | | |
* Returns <0 for error, or length of decrypted data. | | |
* | | |
* This and related APIs operate identically with OpenSSL or mbedTLS backen | | |
ds. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_genrsa_public_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in, | | |
size_t in_len, uint8_t *out, size_t out_max); | | |
| | |
/** lws_genrsa_public_verify() - Perform RSA public verification | | |
* | | |
* \param ctx: your struct lws_genrsa_ctx | | |
* \param in: unencrypted payload (usually a recomputed hash) | | |
* \param hash_type: one of LWS_GENHASH_TYPE_ | | |
* \param sig: pointer to the signature we received with the payload | | |
* \param sig_len: length of the signature we are checking in bytes | | |
* | | |
* Returns <0 for error, or 0 if signature matches the payload + key. | | |
* | | |
* This and related APIs operate identically with OpenSSL or mbedTLS backen | | |
ds. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_genrsa_public_verify(struct lws_genrsa_ctx *ctx, const uint8_t *in, | | |
enum lws_genhash_types hash_type, | | |
const uint8_t *sig, size_t sig_len); | | |
| | |
/** lws_genrsa_public_sign() - Create RSA signature | | |
* | | |
* \param ctx: your struct lws_genrsa_ctx | | |
* \param in: precomputed hash | | |
* \param hash_type: one of LWS_GENHASH_TYPE_ | | |
* \param sig: pointer to buffer to take signature | | |
* \param sig_len: length of the buffer (must be >= length of key N) | | |
* | | |
* Returns <0 for error, or 0 for success. | | |
* | | |
* This and related APIs operate identically with OpenSSL or mbedTLS backen | | |
ds. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_genrsa_public_sign(struct lws_genrsa_ctx *ctx, const uint8_t *in, | | |
enum lws_genhash_types hash_type, uint8_t *sig, | | |
size_t sig_len); | | |
| | |
/** lws_genrsa_public_decrypt_destroy() - Destroy RSA public decrypt contex | | |
t | | |
* | | |
* \param ctx: your struct lws_genrsa_ctx | | |
* | | |
* Destroys any allocations related to \p ctx. | | |
* | | |
* This and related APIs operate identically with OpenSSL or mbedTLS backen | | |
ds. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_genrsa_destroy(struct lws_genrsa_ctx *ctx); | | |
| | |
/** lws_genrsa_render_pkey_asn1() - Exports public or private key to ASN1/D | | |
ER | | |
* | | |
* \param ctx: your struct lws_genrsa_ctx | | |
* \param _private: 0 = public part only, 1 = all parts of the key | | |
* \param pkey_asn1: pointer to buffer to take the ASN1 | | |
* \param pkey_asn1_len: max size of the pkey_asn1_len | | |
* | | |
* Returns length of pkey_asn1 written, or -1 for error. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_genrsa_render_pkey_asn1(struct lws_genrsa_ctx *ctx, int _private, | | |
uint8_t *pkey_asn1, size_t pkey_asn1_len); | | |
///@} | | |
| | |
/*! \defgroup jwk JSON Web Keys | | |
* ## JSON Web Keys API | | |
* | | |
* Lws provides an API to parse JSON Web Keys into a struct lws_genrsa_elem | | |
ents. | | |
* | | |
* "oct" and "RSA" type keys are supported. For "oct" keys, they are held | | |
in | | |
* the "e" member of the struct lws_genrsa_elements. | | |
* | | |
* Keys elements are allocated on the heap. You must destroy the allocatio | | |
ns | | |
* in the struct lws_genrsa_elements by calling | | |
* lws_jwk_destroy_genrsa_elements() when you are finished with it. | | |
*/ | | |
///@{ | | |
| | |
struct lws_jwk { | | |
char keytype[5]; /**< "oct" or "RSA" */ | | |
struct lws_genrsa_elements el; /**< OCTet key is in el.e */ | | |
}; | | |
| | |
/** lws_jwk_import() - Create a JSON Web key from the textual representatio | | |
n | | |
* | | |
* \param s: the JWK object to create | | |
* \param in: a single JWK JSON stanza in utf-8 | | |
* \param len: the length of the JWK JSON stanza in bytes | | |
* | | |
* Creates an lws_jwk struct filled with data from the JSON representation. | | |
* "oct" and "rsa" key types are supported. | | |
* | | |
* For "oct" type keys, it is loaded into el.e. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_jwk_import(struct lws_jwk *s, const char *in, size_t len); | | |
| | |
/** lws_jwk_destroy() - Destroy a JSON Web key | | |
* | | |
* \param s: the JWK object to destroy | | |
* | | |
* All allocations in the lws_jwk are destroyed | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_jwk_destroy(struct lws_jwk *s); | | |
| | |
/** lws_jwk_export() - Export a JSON Web key to a textual representation | | |
* | | |
* \param s: the JWK object to export | | |
* \param _private: 0 = just export public parts, 1 = export everything | | |
* \param p: the buffer to write the exported JWK to | | |
* \param len: the length of the buffer \p p in bytes | | |
* | | |
* Returns length of the used part of the buffer if OK, or -1 for error. | | |
* | | |
* Serializes the content of the JWK into a char buffer. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_jwk_export(struct lws_jwk *s, int _private, char *p, size_t len); | | |
| | |
/** lws_jwk_load() - Import a JSON Web key from a file | | |
* | | |
* \param s: the JWK object to load into | | |
* \param filename: filename to load from | | |
* | | |
* Returns 0 for OK or -1 for failure | | |
*/ | | |
LWS_VISIBLE int | | |
lws_jwk_load(struct lws_jwk *s, const char *filename); | | |
| | |
/** lws_jwk_save() - Export a JSON Web key to a file | | |
* | | |
* \param s: the JWK object to save from | | |
* \param filename: filename to save to | | |
* | | |
* Returns 0 for OK or -1 for failure | | |
*/ | | |
LWS_VISIBLE int | | |
lws_jwk_save(struct lws_jwk *s, const char *filename); | | |
| | |
/** lws_jwk_rfc7638_fingerprint() - jwk to RFC7638 compliant fingerprint | | |
* | | |
* \param s: the JWK object to fingerprint | | |
* \param digest32: buffer to take 32-byte digest | | |
* | | |
* Returns 0 for OK or -1 for failure | | |
*/ | | |
LWS_VISIBLE int | | |
lws_jwk_rfc7638_fingerprint(struct lws_jwk *s, char *digest32); | | |
///@} | | |
| | |
/*! \defgroup jws JSON Web Signature | | |
* ## JSON Web Signature API | | |
* | | |
* Lws provides an API to check and create RFC7515 JSON Web Signatures | | |
* | | |
* SHA256/384/512 HMAC, and RSA 256/384/512 are supported. | | |
* | | |
* The API uses your TLS library crypto, but works exactly the same no matt | | |
er | | |
* what you TLS backend is. | | |
*/ | | |
///@{ | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_jws_confirm_sig(const char *in, size_t len, struct lws_jwk *jwk); | | |
| | |
/** | | |
* lws_jws_sign_from_b64() - add b64 sig to b64 hdr + payload | | |
* | | |
* \param b64_hdr: protected header encoded in b64, may be NULL | | |
* \param hdr_len: bytes in b64 coding of protected header | | |
* \param b64_pay: payload encoded in b64 | | |
* \param pay_len: bytes in b64 coding of payload | | |
* \param b64_sig: buffer to write the b64 encoded signature into | | |
* \param sig_len: max bytes we can write at b64_sig | | |
* \param hash_type: one of LWS_GENHASH_TYPE_SHA[256|384|512] | | |
* \param jwk: the struct lws_jwk containing the signing key | | |
* | | |
* This adds a b64-coded JWS signature of the b64-encoded protected header | | |
* and b64-encoded payload, at \p b64_sig. The signature will be as large | | |
* as the N element of the RSA key when the RSA key is used, eg, 512 bytes | | |
for | | |
* a 4096-bit key, and then b64-encoding on top. | | |
* | | |
* In some special cases, there is only payload to sign and no header, in t | | |
hat | | |
* case \p b64_hdr may be NULL, and only the payload will be hashed before | | |
* signing. | | |
* | | |
* Returns the length of the encoded signature written to \p b64_sig, or -1 | | |
. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_jws_sign_from_b64(const char *b64_hdr, size_t hdr_len, const char *b64_ | | |
pay, | | |
size_t pay_len, char *b64_sig, size_t sig_len, | | |
enum lws_genhash_types hash_type, struct lws_jwk *jwk) | | |
; | | |
| | |
/** | | |
* lws_jws_create_packet() - add b64 sig to b64 hdr + payload | | |
* | | |
* \param jwk: the struct lws_jwk containing the signing key | | |
* \param payload: unencoded payload JSON | | |
* \param len: length of unencoded payload JSON | | |
* \param nonce: Nonse string to include in protected header | | |
* \param out: buffer to take signed packet | | |
* \param out_len: size of \p out buffer | | |
* | | |
* This creates a "flattened" JWS packet from the jwk and the plaintext | | |
* payload, and signs it. The packet is written into \p out. | | |
* | | |
* This does the whole packet assembly and signing, calling through to | | |
* lws_jws_sign_from_b64() as part of the process. | | |
* | | |
* Returns the length written to \p out, or -1. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_jws_create_packet(struct lws_jwk *jwk, const char *payload, size_t len, | | |
const char *nonce, char *out, size_t out_len); | | |
| | |
/** | | |
* lws_jws_base64_enc() - encode input data into b64url data | | |
* | | |
* \param in: the incoming plaintext | | |
* \param in_len: the length of the incoming plaintext in bytes | | |
* \param out: the buffer to store the b64url encoded data to | | |
* \param out_max: the length of \p out in bytes | | |
* | | |
* Returns either -1 if problems, or the number of bytes written to \p out. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_jws_base64_enc(const char *in, size_t in_len, char *out, size_t out_max | | |
); | | |
///@} | | |
#endif | | |
| | |
/*! \defgroup extensions Extension related functions | | |
* ##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, | | |
* add it at where specified so existing users are unaffected. | | |
*/ | | |
enum lws_extension_callback_reasons { | | |
LWS_EXT_CB_CONSTRUCT = 4, | | |
LWS_EXT_CB_CLIENT_CONSTRUCT = 5, | | |
LWS_EXT_CB_DESTROY = 8, | | |
LWS_EXT_CB_PACKET_TX_PRESEND = 12, | | |
LWS_EXT_CB_PAYLOAD_TX = 21, | | |
LWS_EXT_CB_PAYLOAD_RX = 22, | | |
LWS_EXT_CB_OPTION_DEFAULT = 23, | | |
LWS_EXT_CB_OPTION_SET = 24, | | |
LWS_EXT_CB_OPTION_CONFIRM = 25, | | |
LWS_EXT_CB_NAMED_OPTION_SET = 26, | | |
| | |
/****** add new things just above ---^ ******/ | | |
}; | | |
| | |
/** enum lws_ext_options_types */ | | |
enum lws_ext_options_types { | | |
EXTARG_NONE, /**< does not take an argument */ | | |
EXTARG_DEC, /**< requires a decimal argument */ | | |
EXTARG_OPT_DEC /**< may have an optional decimal argument */ | | |
| | |
/* Add new things just above here ---^ | | |
* This is part of the ABI, don't needlessly break compatibility */ | | |
}; | | |
| | |
/** struct lws_ext_options - Option arguments to the extension. These ar | | |
e | | |
* used in the negotiation at ws upgrade time. | | |
* The helper function lws_ext_parse_options() | | |
* uses these to generate callbacks */ | | |
struct lws_ext_options { | | |
const char *name; /**< Option name, eg, "server_no_context_takeover" | | |
*/ | | |
enum lws_ext_options_types type; /**< What kind of args the option c | | |
an take */ | | |
| | |
/* Add new things just above here ---^ | | |
* This is part of the ABI, don't needlessly break compatibility */ | | |
}; | | |
| | |
/** struct lws_ext_option_arg */ | | |
struct lws_ext_option_arg { | | |
const char *option_name; /**< may be NULL, option_index used then */ | | |
int option_index; /**< argument ordinal to use if option_name missin | | |
g */ | | |
const char *start; /**< value */ | | |
int len; /**< length of value */ | | |
}; | | |
| | |
/** | | |
* typedef lws_extension_callback_function() - Hooks to allow extensions to | | |
operate | | |
* \param context: Websockets context | | |
* \param ext: This extension | | |
* \param wsi: Opaque websocket instance pointer | | |
* \param reason: The reason for the call | | |
* \param user: Pointer to ptr to per-session user data allocated by | | |
library | | |
* \param in: Pointer used for some callback reasons | | |
* \param len: Length set for some callback reasons | | |
* | | |
* Each extension that is active on a particular connection receives | | |
* callbacks during the connection lifetime to allow the extension to | | |
* operate on websocket data and manage itself. | | |
* | | |
* Libwebsockets takes care of allocating and freeing "user" memory for | | |
* each active extension on each connection. That is what is pointed t | | |
o | | |
* by the user parameter. | | |
* | | |
* LWS_EXT_CB_CONSTRUCT: called when the server has decided to | | |
* select this extension from the list provided by the client, | | |
* just before the server will send back the handshake acceptin | | |
g | | |
* the connection with this extension active. This gives the | | |
* extension a chance to initialize its connection context foun | | |
d | | |
* in user. | | |
* | | |
* LWS_EXT_CB_CLIENT_CONSTRUCT: same as LWS_EXT_CB_CONSTRUCT | | |
* but called when client is instantiating this extension. Som | | |
e | | |
* extensions will work the same on client and server side and | | |
then | | |
* you can just merge handlers for both CONSTRUCTS. | | |
* | | |
* LWS_EXT_CB_DESTROY: called when the connection the extension was | | |
* being used on is about to be closed and deallocated. It's t | | |
he | | |
* last chance for the extension to deallocate anything it has | | |
* allocated in the user data (pointed to by user) before the | | |
* user data is deleted. This same callback is used whether yo | | |
u | | |
* are in client or server instantiation context. | | |
* | | |
* LWS_EXT_CB_PACKET_TX_PRESEND: this works the same way as | | |
* LWS_EXT_CB_PACKET_RX_PREPARSE above, except it gives the | | |
* extension a chance to change websocket data just before it w | | |
ill | | |
* be sent out. Using the same lws_token pointer scheme in in, | | |
* the extension can change the buffer and the length to be | | |
* transmitted how it likes. Again if it wants to grow the | | |
* buffer safely, it should copy the data into its own buffer a | | |
nd | | |
* set the lws_tokens token pointer to it. | | |
* | | |
* LWS_EXT_CB_ARGS_VALIDATE: | | |
*/ | | |
typedef int | | |
lws_extension_callback_function(struct lws_context *context, | | |
const struct lws_extension *ext, struct lws *w | | |
si, | | |
enum lws_extension_callback_reasons reason, | | |
void *user, void *in, size_t len); | | |
| | |
/** struct lws_extension - An extension we support */ | | |
struct lws_extension { | | |
const char *name; /**< Formal extension name, eg, "permessage-deflat | | |
e" */ | | |
lws_extension_callback_function *callback; /**< Service callback */ | | |
const char *client_offer; /**< String containing exts and options cl | | |
ient offers */ | | |
| | |
/* Add new things just above here ---^ | | |
* This is part of the ABI, don't needlessly break compatibility */ | | |
}; | | |
| | |
/** | | |
* lws_set_extension_option(): set extension option if possible | | |
* | | |
* \param wsi: websocket connection | | |
* \param ext_name: name of ext, like "permessage-deflate" | | |
* \param opt_name: name of option, like "rx_buf_size" | | |
* \param opt_val: value to set option to | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_set_extension_option(struct lws *wsi, const char *ext_name, | | |
const char *opt_name, const char *opt_val); | | |
| | |
/** | | |
* 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); | | |
| | |
/** lws_extension_callback_pm_deflate() - extension for RFC7692 | | |
* | | |
* \param context: lws context | | |
* \param ext: related lws_extension struct | | |
* \param wsi: websocket connection | | |
* \param reason: incoming callback reason | | |
* \param user: per-connection extension private data | | |
* \param in: pointer parameter | | |
* \param len: length parameter | | |
* | | |
* Built-in callback implementing RFC7692 permessage-deflate | | |
*/ | | |
LWS_EXTERN | | |
int lws_extension_callback_pm_deflate( | | |
struct lws_context *context, const struct lws_extension *ext, | | |
struct lws *wsi, enum lws_extension_callback_reasons reason, | | |
void *user, void *in, size_t len); | | |
| | |
/* | | |
* The internal exts are part of the public abi | | |
* If we add more extensions, publish the callback here ------v | | |
*/ | | |
///@} | | |
| | |
/*! \defgroup Protocols-and-Plugins Protocols and Plugins | | |
* \ingroup lwsapi | | |
* | | |
* ##Protocol and protocol plugin -related apis | | |
* | | |
* Protocols bind ws protocol names to a custom callback specific to that | | |
* protocol implementaion. | | |
* | | |
* A list of protocols can be passed in at context creation time, but it is | | |
* also legal to leave that NULL and add the protocols and their callback c | | |
ode | | |
* using plugins. | | |
* | | |
* Plugins are much preferable compared to cut and pasting code into an | | |
* application each time, since they can be used standalone. | | |
*/ | | |
///@{ | | |
/** struct lws_protocols - List of protocols and handlers client or ser | | |
ver | | |
* supports. */ | | |
| | |
struct lws_protocols { | | |
const char *name; | | |
/**< Protocol name that must match the one given in the client | | |
* Javascript new WebSocket(url, 'protocol') name. */ | | |
lws_callback_function *callback; | | |
/**< The service callback used for this protocol. It allows the | | |
* service action for an entire protocol to be encapsulated in | | |
* the protocol-specific callback */ | | |
size_t per_session_data_size; | | |
/**< Each new connection using this protocol gets | | |
* this much memory allocated on connection establishment and | | |
* freed on connection takedown. A pointer to this per-connection | | |
* allocation is passed into the callback in the 'user' parameter */ | | |
size_t rx_buffer_size; | | |
/**< lws allocates this much space for rx data and informs callback | | |
* when something came. Due to rx flow control, the callback may no | | |
t | | |
* be able to consume it all without having to return to the event | | |
* loop. That is supported in lws. | | |
* | | |
* If .tx_packet_size is 0, this also controls how much may be sent | | |
at | | |
* once for backwards compatibility. | | |
*/ | | |
unsigned int id; | | |
/**< ignored by lws, but useful to contain user information bound | | |
* to the selected protocol. For example if this protocol was | | |
* called "myprotocol-v2", you might set id to 2, and the user | | |
* code that acts differently according to the version can do so by | | |
* switch (wsi->protocol->id), user code might use some bits as | | |
* capability flags based on selected protocol version, etc. */ | | |
void *user; /**< ignored by lws, but user code can pass a pointer | | |
here it can later access from the protocol callback | | |
*/ | | |
size_t tx_packet_size; | | |
/**< 0 indicates restrict send() size to .rx_buffer_size for backwar | | |
ds- | | |
* compatibility. | | |
* If greater than zero, a single send() is restricted to this amoun | | |
t | | |
* and any remainder is buffered by lws and sent afterwards also in | | |
* these size chunks. Since that is expensive, it's preferable | | |
* to restrict one fragment you are trying to send to match this | | |
* size. | | |
*/ | | |
| | |
/* Add new things just above here ---^ | | |
* This is part of the ABI, don't needlessly break compatibility */ | | |
}; | | |
| | |
/** | | |
* lws_vhost_name_to_protocol() - get vhost's protocol object from its name | | |
* | | |
* \param vh: vhost to search | | |
* \param name: protocol name | | |
* | | |
* Returns NULL or a pointer to the vhost's protocol of the requested name | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN const struct lws_protocols * | | |
lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name); | | |
| | |
/** | | |
* lws_get_protocol() - Returns a protocol pointer from a websocket | | |
* connection. | | |
* \param wsi: pointer to struct websocket you want to know the protocol of | | |
* | | |
* | | |
* Some apis can act on all live connections of a given protocol, | | |
* this is how you can get a pointer to the active protocol if needed. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN const struct lws_protocols * | | |
lws_get_protocol(struct lws *wsi); | | |
| | |
/** lws_protocol_get() - deprecated: use lws_get_protocol */ | | |
LWS_VISIBLE LWS_EXTERN const struct lws_protocols * | | |
lws_protocol_get(struct lws *wsi) LWS_WARN_DEPRECATED; | | |
| | |
/** | | |
* lws_protocol_vh_priv_zalloc() - Allocate and zero down a protocol's per- | | |
vhost | | |
* storage | | |
* \param vhost: vhost the instance is related to | | |
* \param prot: protocol the instance is related to | | |
* \param size: bytes to allocate | | |
* | | |
* Protocols often find it useful to allocate a per-vhost struct, this is a | | |
* helper to be called in the per-vhost init LWS_CALLBACK_PROTOCOL_INIT | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void * | | |
lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_proto | | |
cols *prot, | | |
int size); | | |
| | |
/** | | |
* lws_protocol_vh_priv_get() - retreive a protocol's per-vhost storage | | |
* | | |
* \param vhost: vhost the instance is related to | | |
* \param prot: protocol the instance is related to | | |
* | | |
* Recover a pointer to the allocated per-vhost storage for the protocol cr | | |
eated | | |
* by lws_protocol_vh_priv_zalloc() earlier | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void * | | |
lws_protocol_vh_priv_get(struct lws_vhost *vhost, const struct lws_protocol | | |
s *prot); | | |
| | |
/** | | |
* lws_adjust_protocol_psds - change a vhost protocol's per session data si | | |
ze | | |
* | | |
* \param wsi: a connection with the protocol to change | | |
* \param new_size: the new size of the per session data size for the proto | | |
col | | |
* | | |
* Returns user_space for the wsi, after allocating | | |
* | | |
* This should not be used except to initalize a vhost protocol's per sessi | | |
on | | |
* data size one time, before any connections are accepted. | | |
* | | |
* Sometimes the protocol wraps another protocol and needs to discover and | | |
set | | |
* its per session data size at runtime. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void * | | |
lws_adjust_protocol_psds(struct lws *wsi, size_t new_size); | | |
| | |
/** | | |
* 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); | | |
| | |
/** | | |
* lws_pvo_search() - helper to find a named pvo in a linked-list | | |
* | | |
* \param pvo: the first pvo in the linked-list | | |
* \param name: the name of the pvo to return if found | | |
* | | |
* Returns NULL, or a pointer to the name pvo in the linked-list | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN const struct lws_protocol_vhost_options * | | |
lws_pvo_search(const struct lws_protocol_vhost_options *pvo, const char *na | | |
me); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_protocol_init(struct lws_context *context); | | |
| | |
#ifdef LWS_WITH_PLUGINS | | |
| | |
/* PLUGINS implies LIBUV */ | | |
| | |
#define LWS_PLUGIN_API_MAGIC 180 | | |
| | |
/** struct lws_plugin_capability - how a plugin introduces itself to lws */ | | |
struct lws_plugin_capability { | | |
unsigned int api_magic; /**< caller fills this in, plugin fills rest | | |
*/ | | |
const struct lws_protocols *protocols; /**< array of supported proto | | |
cols provided by plugin */ | | |
int count_protocols; /**< how many protocols */ | | |
const struct lws_extension *extensions; /**< array of extensions pro | | |
vided by plugin */ | | |
int count_extensions; /**< how many extensions */ | | |
}; | | |
| | |
typedef int (*lws_plugin_init_func)(struct lws_context *, | | |
struct lws_plugin_capability *); | | |
typedef int (*lws_plugin_destroy_func)(struct lws_context *); | | |
| | |
/** struct lws_plugin */ | | |
struct lws_plugin { | | |
struct lws_plugin *list; /**< linked list */ | | |
#if (UV_VERSION_MAJOR > 0) | | |
uv_lib_t lib; /**< shared library pointer */ | | |
#else | | |
void *l; /**< so we can compile on ancient libuv */ | | |
#endif | | |
char name[64]; /**< name of the plugin */ | | |
struct lws_plugin_capability caps; /**< plugin capabilities */ | | |
}; | | |
| | |
#endif | | |
| | |
///@} | | |
| | |
/*! \defgroup generic-sessions plugin: generic-sessions | | |
* \ingroup Protocols-and-Plugins | | |
* | | |
* ##Plugin Generic-sessions related | | |
* | | |
* generic-sessions plugin provides a reusable, generic session and login / | | |
* register / forgot password framework including email verification. | | |
*/ | | |
///@{ | | |
| | |
#define LWSGS_EMAIL_CONTENT_SIZE 16384 | | |
/**< Maximum size of email we might send */ | | |
| | |
/* SHA-1 binary and hexified versions */ | | |
/** typedef struct lwsgw_hash_bin */ | | |
typedef struct { unsigned char bin[20]; /**< binary representation of hash | | |
*/} lwsgw_hash_bin; | | |
/** typedef struct lwsgw_hash */ | | |
typedef struct { char id[41]; /**< ascii hex representation of hash */ } lw | | |
sgw_hash; | | |
| | |
/** enum lwsgs_auth_bits */ | | |
enum lwsgs_auth_bits { | | |
LWSGS_AUTH_LOGGED_IN = 1, /**< user is logged in as somebody */ | | |
LWSGS_AUTH_ADMIN = 2, /**< logged in as the admin user */ | | |
LWSGS_AUTH_VERIFIED = 4, /**< user has verified his email */ | | |
LWSGS_AUTH_FORGOT_FLOW = 8, /**< he just completed "forgot passw | | |
ord" flow */ | | |
}; | | |
| | |
/** struct lws_session_info - information about user session status */ | | |
struct lws_session_info { | | |
char username[32]; /**< username logged in as, or empty string */ | | |
char email[100]; /**< email address associated with login, or empty | | |
string */ | | |
char ip[72]; /**< ip address session was started from */ | | |
unsigned int mask; /**< access rights mask associated with session | | |
* see enum lwsgs_auth_bits */ | | |
char session[42]; /**< session id string, usable as opaque uid when | | |
not logged in */ | | |
}; | | |
| | |
/** enum lws_gs_event */ | | |
enum lws_gs_event { | | |
LWSGSE_CREATED, /**< a new user was created */ | | |
LWSGSE_DELETED /**< an existing user was deleted */ | | |
}; | | |
| | |
/** struct lws_gs_event_args */ | | |
struct lws_gs_event_args { | | |
enum lws_gs_event event; /**< which event happened */ | | |
const char *username; /**< which username the event happened to */ | | |
const char *email; /**< the email address of that user */ | | |
}; | | |
| | |
///@} | | |
| | |
/*! \defgroup context-and-vhost context and vhost related functions | | |
* ##Context and Vhost releated functions | | |
* \ingroup lwsapi | | |
* | | |
* | | |
* 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. | | |
*/ | | |
LWS_SERVER_OPTION_JUST_USE_RAW_ORIGIN = (1 << 19), | | |
/**< For backwards-compatibility reasons, by default | | |
* lws prepends "http://" to the origin you give in the client | | |
* connection info struct. If you give this flag when you create | | |
* the context, only the string you give in the client connect | | |
* info for .origin (if any) will be used directly. | | |
*/ | | |
LWS_SERVER_OPTION_FALLBACK_TO_RAW = (1 << 20), | | |
/**< (VH) if invalid http is coming in the first line, */ | | |
LWS_SERVER_OPTION_LIBEVENT = (1 << 21), | | |
/**< (CTX) Use libevent event loop */ | | |
LWS_SERVER_OPTION_ONLY_RAW = (1 << 22), | | |
/**< (VH) All connections to this vhost / port are RAW as soon as | | |
* the connection is accepted, no HTTP is going to be coming. | | |
*/ | | |
LWS_SERVER_OPTION_ALLOW_LISTEN_SHARE = (1 << 23), | | |
/**< (VH) Set to allow multiple listen sockets on one interface + | | |
* address + port. The default is to strictly allow only one | | |
* listen socket at a time. This is automatically selected if you | | |
* have multiple service threads. | | |
*/ | | |
LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX = (1 << 24), | | |
/**< (VH) Force setting up the vhost SSL_CTX, even though the user | | |
* code doesn't explicitly provide a cert in the info struct. It | | |
* implies the user code is going to provide a cert at the | | |
* LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS callback, whi | | |
ch | | |
* provides the vhost SSL_CTX * in the user parameter. | | |
*/ | | |
LWS_SERVER_OPTION_SKIP_PROTOCOL_INIT = (1 << 25), | | |
/**< (VH) You probably don't want this. It forces this vhost to not | | |
* call LWS_CALLBACK_PROTOCOL_INIT on its protocols. It's used in t | | |
he | | |
* special case of a temporary vhost bound to a single protocol. | | |
*/ | | |
LWS_SERVER_OPTION_IGNORE_MISSING_CERT = (1 << 26), | | |
/**< (VH) Don't fail if the vhost TLS cert or key are missing, just | | |
* continue. The vhost won't be able to serve anything, but if for | | |
* example the ACME plugin was configured to fetch a cert, this lets | | |
* you bootstrap your vhost from having no cert to start with. | | |
*/ | | |
| | |
/****** add new things just above ---^ ******/ | | |
}; | | |
| | |
#define lws_check_opt(c, f) (((c) & (f)) == (f)) | | |
| | |
struct lws_plat_file_ops; | | |
| | |
/** struct lws_context_creation_info - parameters to create context and /or | | |
vhost with | | |
* | | |
* This is also used to create vhosts.... if LWS_SERVER_OPTION_EXPLICIT_VHO | | |
STS | | |
* is not given, then for backwards compatibility one vhost is created at | | |
* context-creation time using the info from this struct. | | |
* | | |
* If LWS_SERVER_OPTION_EXPLICIT_VHOSTS is given, then no vhosts are create | | |
d | | |
* at the same time as the context, they are expected to be created afterwa | | |
rds. | | |
*/ | | |
struct lws_context_creation_info { | | |
int port; | | |
/**< VHOST: Port to listen on. Use CONTEXT_PORT_NO_LISTEN to suppres | | |
s | | |
* listening for a client. Use CONTEXT_PORT_NO_LISTEN_SERVER if you | | |
are | | |
* writing a server but you are using \ref sock-adopt instead of the | | |
* built-in listener. | | |
* | | |
* You can also set port to 0, in which case the kernel will pick | | |
* a random port that is not already in use. You can find out what | | |
* port the vhost is listening on using lws_get_vhost_listen_port() | | |
*/ | | |
const char *iface; | | |
/**< VHOST: NULL to bind the listen socket to all interfaces, or the | | |
* interface name, eg, "eth2" | | |
* If options specifies LWS_SERVER_OPTION_UNIX_SOCK, this member is | | |
* the pathname of a UNIX domain socket. you can use the UNIX domain | | |
* sockets in abstract namespace, by prepending an at symbol to the | | |
* socket name. */ | | |
const struct lws_protocols *protocols; | | |
/**< VHOST: Array of structures listing supported protocols and a pr | | |
otocol- | | |
* specific callback for each one. The list is ended with an | | |
* entry that has a NULL callback pointer. */ | | |
const struct lws_extension *extensions; | | |
/**< VHOST: NULL or array of lws_extension structs listing the | | |
* extensions this context supports. */ | | |
const struct lws_token_limits *token_limits; | | |
/**< CONTEXT: NULL or struct lws_token_limits pointer which is initi | | |
alized | | |
* with a token length limit for each possible WSI_TOKEN_ */ | | |
const char *ssl_private_key_password; | | |
/**< VHOST: NULL or the passphrase needed for the private key. (For | | |
* backwards compatibility, this can also be used to pass the client | | |
* cert passphrase when setting up a vhost client SSL context, but i | | |
t is | | |
* preferred to use .client_ssl_private_key_password for that.) */ | | |
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. (For backwards | | |
* compatibility, this can also be used to pass the client certifica | | |
te | | |
* when setting up a vhost client SSL context, but it is preferred t | | |
o | | |
* use .client_ssl_cert_filepath for that.) */ | | |
const char *ssl_private_key_filepath; | | |
/**< VHOST: filepath to private key if wanting SSL mode; | | |
* if this is set to NULL but ssl_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. (For backwards compatibility, this can also be u | | |
sed | | |
* to pass the client cert private key filepath when setting up a | | |
* vhost client SSL context, but it is preferred to use | | |
* .client_ssl_private_key_filepath for that.) */ | | |
const char *ssl_ca_filepath; | | |
/**< VHOST: CA certificate filepath or NULL. (For backwards | | |
* compatibility, this can also be used to pass the client CA | | |
* filepath when setting up a vhost client SSL context, | | |
* but it is preferred to use .client_ssl_ca_filepath for that.) */ | | |
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" (For backwards | | |
* compatibility, this can also be used to pass the client cipher | | |
* list when setting up a vhost client SSL context, | | |
* but it is preferred to use .client_ssl_cipher_list for that.)*/ | | |
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; | | |
/**< VHOST + CONTEXT: optional user pointer that will be associated | | |
* with the context when creating the context (and can be retrieved | | |
by | | |
* lws_context_user(context), or with the vhost when creating the vh | | |
ost | | |
* (and can be retrieved by lws_vhost_user(vhost)). You will need t | | |
o | | |
* use LWS_SERVER_OPTION_EXPLICIT_VHOSTS and create the vhost separa | | |
tely | | |
* if you care about giving the context and vhost different user poi | | |
nter | | |
* values. | | |
*/ | | |
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 */ | | |
#if defined(LWS_WITH_TLS) && !defined(LWS_WITH_MBEDTLS) | | |
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 context | | |
* if this option is selected. */ | | |
#else /* maintain structure layout either way */ | | |
void *provided_client_ssl_ctx; /**< dummy if ssl disabled */ | | |
#endif | | |
| | |
short max_http_header_data; | | |
/**< CONTEXT: The max amount of header payload that can be handled | | |
* in an http request (unrecognized header payload is dropped) */ | | |
short max_http_header_pool; | | |
/**< CONTEXT: The max number of connections with http headers that | | |
* can be processed simultaneously (the corresponding memory is | | |
* allocated and deallocated dynamically as needed). If the pool is | | |
* fully busy new incoming connections must wait for accept until on | | |
e | | |
* becomes free. 0 = allow as many ah as number of availble fds for | | |
* the process */ | | |
| | |
unsigned int count_threads; | | |
/**< CONTEXT: how many contexts to create in an array, 0 = 1 */ | | |
unsigned int fd_limit_per_thread; | | |
/**< CONTEXT: nonzero means restrict each service thread to this | | |
* many fds, 0 means the default which is divide the process fd | | |
* limit by the number of threads. */ | | |
unsigned int timeout_secs; | | |
/**< VHOST: various processes involving network roundtrips in the | | |
* library are protected from hanging forever by timeouts. If | | |
* nonzero, this member lets you set the timeout used in seconds. | | |
* Otherwise a default timeout is used. */ | | |
const char *ecdh_curve; | | |
/**< VHOST: if NULL, defaults to initializing server with "prime256v | | |
1" */ | | |
const char *vhost_name; | | |
/**< VHOST: name of vhost, must match external DNS name used to | | |
* access the site, like "warmcat.com" as it's used to match | | |
* Host: header and / or SNI name for SSL. */ | | |
const char * const *plugin_dirs; | | |
/**< CONTEXT: NULL, or NULL-terminated array of directories to | | |
* scan for lws protocol plugins at context creation time */ | | |
const struct lws_protocol_vhost_options *pvo; | | |
/**< VHOST: pointer to optional linked list of per-vhost | | |
* options made accessible to protocols */ | | |
int keepalive_timeout; | | |
/**< VHOST: (default = 0 = 60s) seconds to allow remote | | |
* client to hold on to an idle HTTP/1.1 connection */ | | |
const char *log_filepath; | | |
/**< VHOST: filepath to append logs to... this is opened before | | |
* any dropping of initial privileges */ | | |
const struct lws_http_mount *mounts; | | |
/**< VHOST: optional linked list of mounts for this vhost */ | | |
const char *server_string; | | |
/**< CONTEXT: string used in HTTP headers to identify server | | |
* software, if NULL, "libwebsockets". */ | | |
unsigned int pt_serv_buf_size; | | |
/**< CONTEXT: 0 = default of 4096. This buffer is used by | | |
* various service related features including file serving, it | | |
* defines the max chunk of file that can be sent at once. | | |
* At the risk of lws having to buffer failed large sends, it | | |
* can be increased to, eg, 128KiB to improve throughput. */ | | |
unsigned int max_http_header_data2; | | |
/**< CONTEXT: if max_http_header_data is 0 and this | | |
* is nonzero, this will be used in place of the default. It's | | |
* like this for compatibility with the original short version, | | |
* this is unsigned int length. */ | | |
long ssl_options_set; | | |
/**< VHOST: Any bits set here will be set as SSL options */ | | |
long ssl_options_clear; | | |
/**< VHOST: Any bits set here will be cleared as SSL options */ | | |
unsigned short ws_ping_pong_interval; | | |
/**< CONTEXT: 0 for none, else interval in seconds between sending | | |
* PINGs on idle websocket connections. When the PING is sent, | | |
* the PONG must come within the normal timeout_secs timeout period | | |
* or the connection will be dropped. | | |
* Any RX or TX traffic on the connection restarts the interval time | | |
r, | | |
* so a connection which always sends or receives something at inter | | |
vals | | |
* less than the interval given here will never send PINGs / expect | | |
* PONGs. Conversely as soon as the ws connection is established, a | | |
n | | |
* idle connection will do the PING / PONG roundtrip as soon as | | |
* ws_ping_pong_interval seconds has passed without traffic | | |
*/ | | |
const struct lws_protocol_vhost_options *headers; | | |
/**< VHOST: pointer to optional linked list of per-vhost | | |
* canned headers that are added to server responses */ | | |
| | |
const struct lws_protocol_vhost_options *reject_service_keywords; | | |
/**< CONTEXT: Optional list of keywords and rejection codes + text. | | |
* | | |
* The keywords are checked for existing in the user agent string. | | |
* | | |
* Eg, "badrobot" "404 Not Found" | | |
*/ | | |
void *external_baggage_free_on_destroy; | | |
/**< CONTEXT: NULL, or pointer to something externally malloc'd, tha | | |
t | | |
* should be freed when the context is destroyed. This allows you t | | |
o | | |
* automatically sync the freeing action to the context destruction | | |
* action, so there is no need for an external free() if the context | | |
* succeeded to create. | | |
*/ | | |
| | |
const char *client_ssl_private_key_password; | | |
/**< VHOST: Client SSL context init: NULL or the passphrase needed | | |
* for the private key */ | | |
const char *client_ssl_cert_filepath; | | |
/**< VHOST: Client SSL context init:T he certificate the client | | |
* should present to the peer on connection */ | | |
const char *client_ssl_private_key_filepath; | | |
/**< VHOST: Client SSL context init: filepath to client private key | | |
* if this is set to NULL but client_ssl_cert_filepath is set, you | | |
* can handle the LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERT | | |
S | | |
* callback of protocols[0] to allow setting of the private key dire | | |
ctly | | |
* via openSSL library calls */ | | |
const char *client_ssl_ca_filepath; | | |
/**< VHOST: Client SSL context init: CA certificate filepath or NULL | | |
*/ | | |
const char *client_ssl_cipher_list; | | |
/**< VHOST: Client SSL context init: List of valid ciphers to use (e | | |
g, | | |
* "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" | | |
* or you can leave it as NULL to get "DEFAULT" */ | | |
| | |
const struct lws_plat_file_ops *fops; | | |
/**< CONTEXT: NULL, or pointer to an array of fops structs, terminat | | |
ed | | |
* by a sentinel with NULL .open. | | |
* | | |
* If NULL, lws provides just the platform file operations struct fo | | |
r | | |
* backwards compatibility. | | |
*/ | | |
int simultaneous_ssl_restriction; | | |
/**< CONTEXT: 0 (no limit) or limit of simultaneous SSL sessions pos | | |
sible.*/ | | |
const char *socks_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 socks_proxy_port; | | |
/**< VHOST: If socks_proxy_address was non-NULL, uses this port */ | | |
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) | | |
cap_value_t caps[4]; | | |
/**< CONTEXT: array holding Linux capabilities you want to | | |
* continue to be available to the server after it transitions | | |
* to a noprivileged user. Usually none are needed but for, eg, | | |
* .bind_iface, CAP_NET_RAW is required. This gives you a way | | |
* to still have the capability but drop root. | | |
*/ | | |
char count_caps; | | |
/**< CONTEXT: count of Linux capabilities in .caps[]. 0 means | | |
* no capabilities will be inherited from root (the default) */ | | |
#endif | | |
int bind_iface; | | |
/**< VHOST: nonzero to strictly bind sockets to the interface name i | | |
n | | |
* .iface (eg, "eth2"), using SO_BIND_TO_DEVICE. | | |
* | | |
* Requires SO_BINDTODEVICE support from your OS and CAP_NET_RAW | | |
* capability. | | |
* | | |
* Notice that common things like access network interface IP from | | |
* your local machine use your lo / loopback interface and will be | | |
* disallowed by this. | | |
*/ | | |
int ssl_info_event_mask; | | |
/**< VHOST: mask of ssl events to be reported on LWS_CALLBACK_SSL_IN | | |
FO | | |
* callback for connections on this vhost. The mask values are of | | |
* the form SSL_CB_ALERT, defined in openssl/ssl.h. The default of | | |
* 0 means no info events will be reported. | | |
*/ | | |
unsigned int timeout_secs_ah_idle; | | |
/**< VHOST: seconds to allow a client to hold an ah without using it | | |
. | | |
* 0 defaults to 10s. */ | | |
unsigned short ip_limit_ah; | | |
/**< CONTEXT: max number of ah a single IP may use simultaneously | | |
* 0 is no limit. This is a soft limit: if the limit is | | |
* reached, connections from that IP will wait in the ah | | |
* waiting list and not be able to acquire an ah until | | |
* a connection belonging to the IP relinquishes one it | | |
* already has. | | |
*/ | | |
unsigned short ip_limit_wsi; | | |
/**< CONTEXT: max number of wsi a single IP may use simultaneously. | | |
* 0 is no limit. This is a hard limit, connections from | | |
* the same IP will simply be dropped once it acquires th | | |
e | | |
* amount of simultaneous wsi / accepted connections | | |
* given here. | | |
*/ | | |
uint32_t http2_settings[7]; | | |
/**< VHOST: if http2_settings[0] is nonzero, the values given in | | |
* http2_settings[1]..[6] are used instead of the lws | | |
* platform default values. | | |
* Just leave all at 0 if you don't care. | | |
*/ | | |
const char *error_document_404; | | |
/**< VHOST: If non-NULL, when asked to serve a non-existent file, | | |
* lws attempts to server this url path instead. Eg, | | |
* "/404.html" */ | | |
const char *alpn; | | |
/**< CONTEXT: If non-NULL, default list of advertised alpn, comma- | | |
* separated | | |
* | | |
* VHOST: If non-NULL, per-vhost list of advertised alpn, comma- | | |
* separated | | |
*/ | | |
void **foreign_loops; | | |
/**< CONTEXT: This is ignored if the context is not being started wi | | |
th | | |
* an event loop, ie, .options has a flag like | | |
* LWS_SERVER_OPTION_LIBUV. | | |
* | | |
* NULL indicates lws should start its own even loop fo | | |
r | | |
* each service thread, and deal with closing the loops | | |
* when the context is destroyed. | | |
* | | |
* Non-NULL means it points to an array of external | | |
* ("foreign") event loops that are to be used in turn | | |
for | | |
* each service thread. In the default case of 1 servi | | |
ce | | |
* thread, it can just point to one foreign event loop. | | |
*/ | | |
void (*signal_cb)(void *event_lib_handle, int signum); | | |
/**< CONTEXT: NULL: default signal handling. Otherwise this receive | | |
s | | |
* the signal handler callback. event_lib_handle is th | | |
e | | |
* native event library signal handle, eg uv_signal_t * | | |
* for libuv. | | |
*/ | | |
| | |
/* Add new things just above here ---^ | | |
* This is part of the ABI, don't needlessly break compatibility | | |
* | | |
* The below is to ensure later library versions with new | | |
* members added above will see 0 (default) even if the app | | |
* was not built against the newer headers. | | |
*/ | | |
struct lws_context **pcontext; | | |
/**< CONTEXT: if non-NULL, at the end of context destroy processing, | | |
* the pointer pointed to by pcontext is written with NULL. You can | | |
* use this to let foreign event loops know that lws context destruc | | |
tion | | |
* is fully completed. | | |
*/ | | |
| | |
void *_unused[4]; /**< dummy */ | | |
}; | | |
| | |
/** | | |
* lws_create_context() - Create the websocket handler | | |
* \param info: pointer to struct with parameters | | |
* | | |
* This function creates the listening socket (if serving) and takes ca | | |
re | | |
* of all initialization in one step. | | |
* | | |
* If option LWS_SERVER_OPTION_EXPLICIT_VHOSTS is given, no vhost is | | |
* created; you're expected to create your own vhosts afterwards using | | |
* lws_create_vhost(). Otherwise a vhost named "default" is also creat | | |
ed | | |
* using the information in the vhost-related members, for compatibilit | | |
y. | | |
* | | |
* After initialization, it returns a struct lws_context * that | | |
* represents this server. After calling, user code needs to take care | | |
* of calling lws_service() with the context pointer to get the | | |
* server's sockets serviced. This must be done in the same process | | |
* context as the initialization call. | | |
* | | |
* The protocol callback functions are called for a handful of events | | |
* including http requests coming in, websocket connections becoming | | |
* established, and data arriving; it's also called periodically to all | | |
ow | | |
* async transmission. | | |
* | | |
* HTTP requests are sent always to the FIRST protocol in protocol, sin | | |
ce | | |
* at that time websocket protocol has not been negotiated. Other | | |
* protocols after the first one never see any HTTP callback 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(const 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); | | |
| | |
typedef int (*lws_reload_func)(void); | | |
| | |
/** | | |
* lws_context_deprecate() - Deprecate the websocket context | | |
* | | |
* \param context: Websocket context | | |
* \param cb: Callback notified when old context listen sockets are closed | | |
* | | |
* This function is used on an existing context before superceding it | | |
* with a new context. | | |
* | | |
* It closes any listen sockets in the context, so new connections are | | |
* not possible. | | |
* | | |
* And it marks the context to be deleted when the number of active | | |
* connections into it falls to zero. | | |
* | | |
* Otherwise if you attach the deprecated context to the replacement | | |
* context when it has been created using lws_context_attach_deprecated | | |
() | | |
* both any deprecated and the new context will service their connectio | | |
ns. | | |
* | | |
* This is aimed at allowing seamless configuration reloads. | | |
* | | |
* The callback cb will be called after the listen sockets are actually | | |
* closed and may be reopened. In the callback the new context should | | |
be | | |
* configured and created. (With libuv, socket close happens async aft | | |
er | | |
* more loop events). | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_context_deprecate(struct lws_context *context, lws_reload_func cb); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_context_is_deprecated(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); | | |
| | |
/** | | |
* lws_set_socks() - Setup socks to lws_context. | | |
* \param vhost: pointer to struct lws_vhost you want set socks for | | |
* \param socks: pointer to c string containing socks in format address:por | | |
t | | |
* | | |
* Returns 0 if socks string was parsed and socks was setup. | | |
* Returns -1 if socks is NULL or has incorrect format. | | |
* | | |
* This is only required if your OS does not provide the socks_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_socks(struct lws_vhost *vhost, const char *socks); | | |
| | |
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_VISIBLE LWS_EXTERN struct lws_vhost * | | |
lws_create_vhost(struct lws_context *context, | | |
const struct lws_context_creation_info *info); | | |
| | |
/** | | |
* lws_vhost_destroy() - Destroy a vhost (virtual server context) | | |
* | | |
* \param vh: pointer to result of lws_create_vhost() | | |
* | | |
* This function destroys a vhost. Normally, if you just want to exit, | | |
* then lws_destroy_context() will take care of everything. If you want | | |
* to destroy an individual vhost and all connections and allocations, you | | |
* can do it with this. | | |
* | | |
* If the vhost has a listen sockets shared by other vhosts, it will be giv | | |
en | | |
* to one of the vhosts sharing it rather than closed. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_vhost_destroy(struct lws_vhost *vh); | | |
| | |
/** | | |
* 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_get_vhost_name() - returns the name of a vhost | | |
* | | |
* \param vhost: which vhost | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN const char * | | |
lws_get_vhost_name(struct lws_vhost *vhost); | | |
| | |
/** | | |
* lws_get_vhost_port() - returns the port a vhost listens on, or -1 | | |
* | | |
* \param vhost: which vhost | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_get_vhost_port(struct lws_vhost *vhost); | | |
| | |
/** | | |
* lws_get_vhost_user() - returns the user pointer for the vhost | | |
* | | |
* \param vhost: which vhost | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void * | | |
lws_get_vhost_user(struct lws_vhost *vhost); | | |
| | |
/** | | |
* lws_get_vhost_iface() - returns the binding for the vhost listen socket | | |
* | | |
* \param vhost: which vhost | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN const char * | | |
lws_get_vhost_iface(struct lws_vhost *vhost); | | |
| | |
/** | | |
* 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 | | |
* \param hide_vhosts: nonzero to not provide per-vhost mount etc informati | | |
on | | |
* | | |
* Generates a JSON description of vhost state into buf | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_json_dump_context(const struct lws_context *context, char *buf, int len | | |
, | | |
int hide_vhosts); | | |
| | |
/** | | |
* lws_vhost_user() - get the user data associated with the vhost | | |
* \param vhost: Websocket vhost | | |
* | | |
* This returns the optional user pointer that can be attached to | | |
* a vhost when it was created. Lws never dereferences this pointer, it on | | |
ly | | |
* sets it when the vhost is created, and returns it using this api. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void * | | |
lws_vhost_user(struct lws_vhost *vhost); | | |
| | |
/** | | |
* 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, /**< http reverse proxy */ | | |
LWSMPRO_HTTPS = 1, /**< https reverse proxy */ | | |
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 */ | | |
| | |
const char *basic_auth_login_file; | | |
/**<NULL, or filepath to use to check basic auth logins against */ | | |
| | |
/* Add new things just above here ---^ | | |
* This is part of the ABI, don't needlessly break compatibility | | |
* | | |
* The below is to ensure later library versions with new | | |
* members added above will see 0 (default) even if the app | | |
* was not built against the newer headers. | | |
*/ | | |
| | |
void *_unused[2]; /**< dummy */ | | |
}; | | |
///@} | | |
///@} | | |
| | |
/*! \defgroup client Client related functions | | |
* ##Client releated functions | | |
* \ingroup lwsapi | | |
* | | |
* */ | | |
///@{ | | |
| | |
/** 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), | | |
LCCSCF_ALLOW_EXPIRED = (1 << 3), | | |
| | |
LCCSCF_PIPELINE = (1 << 16), | | |
/**< Serialize / pipeline multiple client connections | | |
* on a single connection where possible. | | |
* | | |
* HTTP/1.0: possible if Keep-Alive: yes sent by server | | |
* HTTP/1.1: always possible... uses pipelining | | |
* HTTP/2: always possible... uses parallel streams | | |
* */ | | |
}; | | |
| | |
/** struct lws_client_connect_info - parameters to connect with when using | | |
* lws_client_connect_via_info() */ | | |
| | |
struct lws_client_connect_info { | | |
struct lws_context *context; | | |
/**< lws context to create connection in */ | | |
const char *address; | | |
/**< remote address to connect to */ | | |
int port; | | |
/**< remote port to connect to */ | | |
int ssl_connection; | | |
/**< 0, or a combination of LCCSCF_ flags */ | | |
const char *path; | | |
/**< uri path */ | | |
const char *host; | | |
/**< content of host header */ | | |
const char *origin; | | |
/**< content of origin header */ | | |
const char *protocol; | | |
/**< list of ws protocols we could accept */ | | |
int ietf_version_or_minus_one; | | |
/**< deprecated: currently leave at 0 or -1 */ | | |
void *userdata; | | |
/**< if non-NULL, use this as wsi user_data instead of malloc it */ | | |
const void *client_exts; | | |
/**< UNUSED... provide in info.extensions at context creation time * | | |
/ | | |
const char *method; | | |
/**< if non-NULL, do this http method instead of ws[s] upgrade. | | |
* use "GET" to be a simple http client connection. "RAW" gets | | |
* you a connected socket that lws itself will leave alone once | | |
* connected. */ | | |
struct lws *parent_wsi; | | |
/**< if another wsi is responsible for this connection, give it here | | |
. | | |
* this is used to make sure if the parent closes so do any | | |
* child connections first. */ | | |
const char *uri_replace_from; | | |
/**< if non-NULL, when this string is found in URIs in | | |
* text/html content-encoding, it's replaced with uri_replace_to */ | | |
const char *uri_replace_to; | | |
/**< see uri_replace_from */ | | |
struct lws_vhost *vhost; | | |
/**< vhost to bind to (used to determine related SSL_CTX) */ | | |
struct lws **pwsi; | | |
/**< if not NULL, store the new wsi here early in the connection | | |
* process. Although we return the new wsi, the call to create the | | |
* client connection does progress the connection somewhat and may | | |
* meet an error that will result in the connection being scrubbed a | | |
nd | | |
* NULL returned. While the wsi exists though, he may process a | | |
* callback like CLIENT_CONNECTION_ERROR with his wsi: this gives th | | |
e | | |
* user callback a way to identify which wsi it is that faced the er | | |
ror | | |
* even before the new wsi is returned and even if ultimately no wsi | | |
* is returned. | | |
*/ | | |
const char *iface; | | |
/**< NULL to allow routing on any interface, or interface name or IP | | |
* to bind the socket to */ | | |
const char *local_protocol_name; | | |
/**< NULL: .protocol is used both to select the local protocol handl | | |
er | | |
* to bind to and as the list of remote ws protocols we coul | | |
d | | |
* accept. | | |
* non-NULL: this protocol name is used to bind the connection to | | |
* the local protocol handler. .protocol is used for th | | |
e | | |
* list of remote ws protocols we could accept */ | | |
| | |
/* Add new things just above here ---^ | | |
* This is part of the ABI, don't needlessly break compatibility | | |
* | | |
* The below is to ensure later library versions with new | | |
* members added above will see 0 (default) even if the app | | |
* was not built against the newer headers. | | |
*/ | | |
const char *alpn; | | |
/* NULL: allow lws default ALPN list, from vhost if present or from | | |
* list of roles built into lws | | |
* non-NULL: require one from provided comma-separated list of alpn | | |
* tokens | | |
*/ | | |
| | |
void *_unused[4]; /**< dummy */ | | |
}; | | |
| | |
/** | | |
* lws_client_connect_via_info() - Connect to another websocket server | | |
* \param ccinfo: pointer to lws_client_connect_info struct | | |
* | | |
* This function creates a connection to a remote server using the | | |
* information provided in ccinfo. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN struct lws * | | |
lws_client_connect_via_info(struct lws_client_connect_info * ccinfo); | | |
| | |
/** | | |
* lws_client_connect() - Connect to another websocket server | | |
* \deprecated DEPRECATED use lws_client_connect_via_info | | |
* \param clients: Websocket context | | |
* \param address: Remote server address, eg, "myserver.com" | | |
* \param port: Port to connect to on the remote server, eg, 80 | | |
* \param ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// | | |
allow self | | |
* signed certs | | |
* \param path: Websocket path on server | | |
* \param host: Hostname on server | | |
* \param origin: Socket origin name | | |
* \param protocol: Comma-separated list of protocols being asked for fr | | |
om | | |
* the server, or just one. The server will pick the one it | | |
* likes best. If you don't want to specify a protocol, which | | |
is | | |
* legal, use NULL here. | | |
* \param ietf_version_or_minus_one: -1 to ask to connect using the default | | |
, latest | | |
* protocol supported, or the specific protocol ordinal | | |
* | | |
* This function creates a connection to a remote server | | |
*/ | | |
/* deprecated, use lws_client_connect_via_info() */ | | |
LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT | | |
lws_client_connect(struct lws_context *clients, const char *address, | | |
int port, int ssl_connection, const char *path, | | |
const char *host, const char *origin, const char *protoco | | |
l, | | |
int ietf_version_or_minus_one) LWS_WARN_DEPRECATED; | | |
/* deprecated, use lws_client_connect_via_info() */ | | |
/** | | |
* lws_client_connect_extended() - Connect to another websocket server | | |
* \deprecated DEPRECATED use lws_client_connect_via_in | | |
fo | | |
* \param clients: Websocket context | | |
* \param address: Remote server address, eg, "myserver.com" | | |
* \param port: Port to connect to on the remote server, eg, 80 | | |
* \param ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// | | |
allow self | | |
* signed certs | | |
* \param path: Websocket path on server | | |
* \param host: Hostname on server | | |
* \param origin: Socket origin name | | |
* \param protocol: Comma-separated list of protocols being asked for fr | | |
om | | |
* the server, or just one. The server will pick the one it | | |
* likes best. | | |
* \param ietf_version_or_minus_one: -1 to ask to connect using the default | | |
, latest | | |
* protocol supported, or the specific protocol ordinal | | |
* \param userdata: Pre-allocated user data | | |
* | | |
* This function creates a connection to a remote server | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT | | |
lws_client_connect_extended(struct lws_context *clients, const char *addres | | |
s, | | |
int port, int ssl_connection, const char *path, | | |
const char *host, const char *origin, | | |
const char *protocol, int ietf_version_or_minus_ | | |
one, | | |
void *userdata) LWS_WARN_DEPRECATED; | | |
| | |
/** | | |
* lws_init_vhost_client_ssl() - also enable client SSL on an existing vhos | | |
t | | |
* | | |
* \param info: client ssl related info | | |
* \param vhost: which vhost to initialize client ssl operations on | | |
* | | |
* You only need to call this if you plan on using SSL client connections o | | |
n | | |
* the vhost. For non-SSL client connections, it's not necessary to call t | | |
his. | | |
* | | |
* The following members of info are used during the call | | |
* | | |
* - options must have LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT set, | | |
* otherwise the call does nothing | | |
* - provided_client_ssl_ctx must be NULL to get a generated client | | |
* ssl context, otherwise you can pass a prepared one in by settin | | |
g it | | |
* - ssl_cipher_list may be NULL or set to the client valid cipher lis | | |
t | | |
* - ssl_ca_filepath may be NULL or client cert filepath | | |
* - ssl_cert_filepath may be NULL or client cert filepath | | |
* - ssl_private_key_filepath may be NULL or client cert private key | | |
* | | |
* You must create your vhost explicitly if you want to use this, so you ha | | |
ve | | |
* a pointer to the vhost. Create the context first with the option flag | | |
* LWS_SERVER_OPTION_EXPLICIT_VHOSTS and then call lws_create_vhost() with | | |
* the same info struct. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_init_vhost_client_ssl(const struct lws_context_creation_info *info, | | |
struct lws_vhost *vhost); | | |
/** | | |
* lws_http_client_read() - consume waiting received http client data | | |
* | | |
* \param wsi: client connection | | |
* \param buf: pointer to buffer pointer - fill with pointer to your buffer | | |
* \param len: pointer to chunk length - fill with max length of buffer | | |
* | | |
* This is called when the user code is notified client http data has arriv | | |
ed. | | |
* The user code may choose to delay calling it to consume the data, for ex | | |
ample | | |
* waiting until an onward connection is writeable. | | |
* | | |
* For non-chunked connections, up to len bytes of buf are filled with the | | |
* received content. len is set to the actual amount filled before return. | | |
* | | |
* For chunked connections, the linear buffer content contains the chunking | | |
* headers and it cannot be passed in one lump. Instead, this function wil | | |
l | | |
* call back LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ with in pointing to the | | |
* chunk start and len set to the chunk length. There will be as many call | | |
s | | |
* as there are chunks or partial chunks in the buffer. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_http_client_read(struct lws *wsi, char **buf, int *len); | | |
| | |
/** | | |
* lws_http_client_http_response() - get last HTTP response code | | |
* | | |
* \param wsi: client connection | | |
* | | |
* Returns the last server response code, eg, 200 for client http connectio | | |
ns. | | |
* | | |
* You should capture this during the LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP | | |
* callback, because after that the memory reserved for storing the related | | |
* headers is freed and this value is lost. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN unsigned int | | |
lws_http_client_http_response(struct lws *wsi); | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_client_http_body_pending(struct lws *wsi, int something_left_to_send); | | |
| | |
/** | | |
* lws_client_http_body_pending() - control if client connection neeeds to | | |
send body | | |
* | | |
* \param wsi: client connection | | |
* \param something_left_to_send: nonzero if need to send more body, 0 (def | | |
ault) | | |
* if nothing more to send | | |
* | | |
* If you will send payload data with your HTTP client connection, eg, for | | |
POST, | | |
* when you set the related http headers in | | |
* LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER callback you should also cal | | |
l | | |
* this API with something_left_to_send nonzero, and call | | |
* lws_callback_on_writable(wsi); | | |
* | | |
* After sending the headers, lws will call your callback with | | |
* LWS_CALLBACK_CLIENT_HTTP_WRITEABLE reason when writable. You can send t | | |
he | | |
* next part of the http body payload, calling lws_callback_on_writable(wsi | | |
); | | |
* if there is more to come, or lws_client_http_body_pending(wsi, 0); to | | |
* let lws know the last part is sent and the connection can move on. | | |
*/ | | |
| | |
///@} | | |
| | |
/** \defgroup service Built-in service loop entry | | |
* | | |
* ##Built-in service loop entry | | |
* | | |
* If you're not using libev / libuv, these apis are needed to enter the po | | |
ll() | | |
* wait in lws and service any connections with pending events. | | |
*/ | | |
///@{ | | |
| | |
/** | | |
* lws_service() - Service any pending websocket activity | | |
* \param context: Websocket context | | |
* \param timeout_ms: Timeout for poll; 0 means return immediately if noth | | |
ing needed | | |
* service otherwise block and service immediately, returning | | |
* after the timeout if nothing needed service. | | |
* | | |
* This function deals with any pending websocket traffic, for three | | |
* kinds of event. It handles these events on both server and client | | |
* types of connection the same. | | |
* | | |
* 1) Accept new connections to our context's server | | |
* | | |
* 2) Call the receive callback for incoming frame data received by | | |
* server or client connections. | | |
* | | |
* You need to call this service function periodically to all the above | | |
* functions to happen; if your application is single-threaded you can | | |
* just call it in your main event loop. | | |
* | | |
* Alternatively you can fork a new process that asynchronously handles | | |
* calling this service in a loop. In that case you are happy if this | | |
* call blocks your thread until it needs to take care of something and | | |
* would call it with a large nonzero timeout. Your loop then takes no | | |
* CPU while there is nothing happening. | | |
* | | |
* If you are calling it in a single-threaded app, you don't want it to | | |
* wait around blocking other things in your loop from happening, so yo | | |
u | | |
* would call it with a timeout_ms of 0, so it returns immediately if | | |
* nothing is pending, or as soon as it services whatever was pending. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_service(struct lws_context *context, int timeout_ms); | | |
| | |
/** | | |
* lws_service_tsi() - 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. | | |
* \param tsi: Thread service index, starting at 0 | | |
* | | |
* Same as lws_service(), but for a specific thread service index. Only ne | | |
eded | | |
* if you are spawning multiple service threads. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi); | | |
| | |
/** | | |
* lws_cancel_service_pt() - Cancel servicing of pending socket activity | | |
* on one thread | | |
* \param wsi: Cancel service on the thread this wsi is serviced by | | |
* | | |
* Same as lws_cancel_service(), but targets a single service thread, the o | | |
ne | | |
* the wsi belongs to. You probably want to use lws_cancel_service() inste | | |
ad. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_cancel_service_pt(struct lws *wsi); | | |
| | |
/** | | |
* lws_cancel_service() - Cancel wait for new pending socket activity | | |
* \param context: Websocket context | | |
* | | |
* This function creates an immediate "synchronous interrupt" to the lws po | | |
ll() | | |
* wait or event loop. As soon as possible in the serialzed service sequen | | |
cing, | | |
* a LWS_CALLBACK_EVENT_WAIT_CANCELLED callback is sent to every protocol o | | |
n | | |
* every vhost. | | |
* | | |
* lws_cancel_service() may be called from another thread while the context | | |
* exists, and its effect will be immediately serialized. | | |
*/ | | |
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, or NULL to tell lws to do only timeout servicing. | | |
* | | |
* 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. | | |
* | | |
* You should also call this with pollfd = NULL to just allow the | | |
* once-per-second global timeout checks; if less than a second since the l | | |
ast | | |
* check it returns immediately then. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd); | | |
| | |
/** | | |
* lws_service_fd_tsi() - Service polled socket in specific service thread | | |
* \param context: Websocket context | | |
* \param pollfd: The pollfd entry describing the socket fd and which | | |
events | | |
* happened. | | |
* \param tsi: thread service index | | |
* | | |
* Same as lws_service_fd() but used with multiple service threads | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, | | |
int tsi); | | |
| | |
/** | | |
* lws_service_adjust_timeout() - Check for any connection needing forced s | | |
ervice | | |
* \param context: Websocket context | | |
* \param timeout_ms: The original poll timeout value. You can just set t | | |
his | | |
* to 1 if you don't really have a poll timeout. | | |
* \param tsi: thread service index | | |
* | | |
* Under some conditions connections may need service even though there is | | |
no | | |
* pending network action on them, this is "forced service". For default | | |
* poll() and libuv / libev, the library takes care of calling this and | | |
* dealing with it for you. But for external poll() integration, you need | | |
* access to the apis. | | |
* | | |
* If anybody needs "forced service", returned timeout is zero. In that ca | | |
se, | | |
* you can call lws_service_tsi() with a timeout of -1 to only service | | |
* guys who need forced service. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_service_adjust_timeout(struct lws_context *context, int timeout_ms, int | | |
tsi); | | |
| | |
/* Backwards compatibility */ | | |
#define lws_plat_service_tsi lws_service_tsi | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd); | | |
| | |
///@} | | |
| | |
/*! \defgroup http HTTP | | |
| | |
Modules related to handling HTTP | | |
*/ | | |
//@{ | | |
| | |
/*! \defgroup httpft HTTP File transfer | | |
* \ingroup http | | |
| | |
APIs for sending local files in response to HTTP requests | | |
*/ | | |
//@{ | | |
| | |
/** | | |
* lws_get_mimetype() - Determine mimetype to use from filename | | |
* | | |
* \param file: filename | | |
* \param m: NULL, or mount context | | |
* | | |
* This uses a canned list of known filetypes first, if no match and m is | | |
* non-NULL, then tries a list of per-mount file suffix to mimtype mappings | | |
. | | |
* | | |
* Returns either NULL or a pointer to the mimetype matching the file. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN const char * | | |
lws_get_mimetype(const char *file, const struct lws_http_mount *m); | | |
| | |
/** | | |
* lws_serve_http_file() - Send a file back to the client using http | | |
* \param wsi: Websocket instance (available from user callback) | | |
* \param file: The file to issue over http | | |
* \param content_type: The http content type, eg, text/html | | |
* \param other_headers: NULL or pointer to header string | | |
* \param other_headers_len: length of the other headers if non-NULL | | |
* | | |
* This function is intended to be called from the callback in response | | |
* to http requests from the client. It allows the callback to issue | | |
* local files down the http link in a single step. | | |
* | | |
* Returning <0 indicates error and the wsi should be closed. Returnin | | |
g | | |
* >0 indicates the file was completely sent and | | |
* lws_http_transaction_completed() called on the wsi (and close if != | | |
0) | | |
* ==0 indicates the file transfer is started and needs more service la | | |
ter, | | |
* the wsi should be left alone. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_serve_http_file(struct lws *wsi, const char *file, const char *content_ | | |
type, | | |
const char *other_headers, int other_headers_len); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_serve_http_file_fragment(struct lws *wsi); | | |
//@} | | |
| | |
enum http_status { | | |
HTTP_STATUS_CONTINUE = 100, | | |
| | |
HTTP_STATUS_OK = 200, | | |
HTTP_STATUS_NO_CONTENT = 204, | | |
HTTP_STATUS_PARTIAL_CONTENT = 206, | | |
| | |
HTTP_STATUS_MOVED_PERMANENTLY = 301, | | |
HTTP_STATUS_FOUND = 302, | | |
HTTP_STATUS_SEE_OTHER = 303, | | |
HTTP_STATUS_NOT_MODIFIED = 304, | | |
| | |
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, | | |
}; | | |
/*! \defgroup html-chunked-substitution HTML Chunked Substitution | | |
* \ingroup http | | |
* | | |
* ##HTML chunked Substitution | | |
* | | |
* APIs for receiving chunks of text, replacing a set of variable names via | | |
* a callback, and then prepending and appending HTML chunked encoding | | |
* headers. | | |
*/ | | |
//@{ | | |
| | |
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 */ | | |
int chunked; /**< 0 == unchunked, 1 == produce chunk headers (incomp | | |
atible with HTTP/2) */ | | |
}; | | |
| | |
typedef const char *(*lws_process_html_state_cb)(void *data, int index); | | |
| | |
struct lws_process_html_state { | | |
char *start; /**< pointer to start of match */ | | |
char swallow[16]; /**< matched character buffer */ | | |
int pos; /**< position in match */ | | |
void *data; /**< opaque pointer */ | | |
const char * const *vars; /**< list of variable names */ | | |
int count_vars; /**< count of variable names */ | | |
| | |
lws_process_html_state_cb replace; /**< called on match to perform s | | |
ubstitution */ | | |
}; | | |
| | |
/*! lws_chunked_html_process() - generic chunked substitution | | |
* \param args: buffer to process using chunked encoding | | |
* \param s: current processing state | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_chunked_html_process(struct lws_process_html_args *args, | | |
struct lws_process_html_state *s); | | |
//@} | | |
| | |
/** \defgroup HTTP-headers-read HTTP headers: read | | |
* \ingroup http | | |
* | | |
* ##HTTP header releated functions | | |
* | | |
* In lws the client http headers are temporarily stored in a pool, only f | | |
or the | | |
* duration of the http part of the handshake. It's because in most cases | | |
, | | |
* the header content is ignored for the whole rest of the connection life | | |
time | | |
* and would then just be taking up space needlessly. | | |
* | | |
* During LWS_CALLBACK_HTTP when the URI path is delivered is the last tim | | |
e | | |
* the http headers are still allocated, you can use these apis then to | | |
* look at and copy out interesting header content (cookies, etc) | | |
* | | |
* Notice that the header total length reported does not include a termina | | |
ting | | |
* '\0', however you must allocate for it when using the _copy apis. So t | | |
he | | |
* length reported for a header containing "123" is 3, but you must provid | | |
e | | |
* a buffer of length 4 so that "123\0" may be copied into it, or the copy | | |
* will fail with a nonzero return code. | | |
* | | |
* In the special case of URL arguments, like ?x=1&y=2, the arguments are | | |
* stored in a token named for the method, eg, WSI_TOKEN_GET_URI if it | | |
* was a GET or WSI_TOKEN_POST_URI if POST. You can check the total | | |
* length to confirm the method. | | |
* | | |
* For URL arguments, each argument is stored urldecoded in a "fragment", | | |
so | | |
* you can use the fragment-aware api lws_hdr_copy_fragment() to access ea | | |
ch | | |
* argument in turn: the fragments contain urldecoded strings like x=1 or | | |
y=2. | | |
* | | |
* As a convenience, lws has an api that will find the fragment with a | | |
* given name= part, lws_get_urlarg_by_name(). | | |
*/ | | |
///@{ | | |
| | |
/** struct lws_tokens | | |
* you need these to look at headers that have been parsed if using the | | |
* LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum | | |
* list below is absent, .token = NULL and len = 0. Otherwise .token | | |
* points to .len chars containing that header content. | | |
*/ | | |
struct lws_tokens { | | |
char *token; /**< pointer to start of the token */ | | |
int 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, | | |
WSI_TOKEN_X_FORWARDED_FOR = 80, | | |
WSI_TOKEN_CONNECT = 81, | | |
WSI_TOKEN_HEAD_URI = 82, | | |
WSI_TOKEN_TE = 83, | | |
WSI_TOKEN_REPLAY_NONCE = 84, | | |
WSI_TOKEN_COLON_PROTOCOL = 85, | | |
WSI_TOKEN_X_AUTH_TOKEN = 86, | | |
| | |
/****** 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, | | |
_WSI_TOKEN_CLIENT_IFACE, | | |
_WSI_TOKEN_CLIENT_ALPN, | | |
| | |
/* 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: token index | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN const unsigned char * | | |
lws_token_to_string(enum lws_token_indexes token); | | |
| | |
/** | | |
* 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. | | |
*/ | | |
///@{ | | |
| | |
#define LWSAHH_CODE_MASK ((1 << 16) - 1) | | |
#define LWSAHH_FLAG_NO_SERVER_NAME (1 << 30) | | |
| | |
/** | | |
* 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. | | |
* | | |
* Code may additionally take OR'd flags: | | |
* | | |
* LWSAHH_FLAG_NO_SERVER_NAME: don't apply server name header this time | | |
*/ | | |
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_add_http_header_by_name(struct lws *wsi, const unsigned char *name, | | |
const unsigned char *value, int length, | | |
unsigned char **p, unsigned char *end); | | |
/** | | |
* lws_add_http_header_by_token() - append given header and value | | |
* | | |
* \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_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token, | | |
const unsigned char *value, int length, | | |
unsigned char **p, unsigned char *end); | | |
/** | | |
* lws_add_http_header_content_length() - 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_add_http_header_content_length(struct lws *wsi, | | |
lws_filepos_t content_length, | | |
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_finalize_http_header(struct lws *wsi, unsigned char **p, | | |
unsigned char *end); | | |
| | |
/** | | |
* lws_finalize_write_http_header() - Helper finializing and writing http h | | |
eaders | | |
* | | |
* \param wsi: the connection to check | | |
* \param start: pointer to the start of headers in the buffer, eg &buf[LWS | | |
_PRE] | | |
* \param p: pointer to current position in buffer pointer | | |
* \param end: pointer to end of buffer | | |
* | | |
* Terminates the headers correctly accoring to the protocol in use (h1 / h | | |
2) | | |
* and writes the headers. Returns nonzero for error. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | |
lws_finalize_write_http_header(struct lws *wsi, unsigned char *start, | | |
unsigned char **p, unsigned char *end); | | |
| | |
#define LWS_ILLEGAL_HTTP_CONTENT_LEN ((lws_filepos_t)-1ll) | | |
| | |
/** | | |
* lws_add_http_common_headers() - Helper preparing common http headers | | |
* | | |
* \param wsi: the connection to check | | |
* \param code: an HTTP code like 200, 404 etc (see enum http_status) | | |
* \param content_type: the content type, like "text/html" | | |
* \param content_len: the content length, in bytes | | |
* \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. | | |
* | | |
* Code may additionally take OR'd flags: | | |
* | | |
* LWSAHH_FLAG_NO_SERVER_NAME: don't apply server name header this time | | |
* | | |
* This helper just calls public apis to simplify adding headers that are | | |
* commonly needed. If it doesn't fit your case, or you want to add additi | | |
onal | | |
* headers just call the public apis directly yourself for what you want. | | |
* | | |
* You can miss out the content length header by providing the constant | | |
* LWS_ILLEGAL_HTTP_CONTENT_LEN for the content_len. | | |
* | | |
* It does not call lws_finalize_http_header(), to allow you to add further | | |
* headers after calling this. You will need to call that yourself at the | | |
end. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | |
lws_add_http_common_headers(struct lws *wsi, unsigned int code, | | |
const char *content_type, lws_filepos_t content_ | | |
len, | | |
unsigned char **p, 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 | | |
* | | |
* Returns 0 if completed OK or nonzero for urldecode violation (non-hex ch | | |
ars | | |
* where hex required, etc) | | |
*/ | | |
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 out on wsi | | |
* | | |
* \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 | | |
* | | |
* Returns amount written, or < 0 indicating fatal write failure. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | |
lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int | | |
len, | | |
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_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); | | |
| | |
/** | | |
* lws_filename_purify_inplace() - replace scary filename chars with unders | | |
core | | |
* | | |
* \param filename: filename to be purified | | |
* | | |
* Replace scary characters in the filename (it should not be a path) | | |
* with underscore, so it's safe to use. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_filename_purify_inplace(char *filename); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf, | | |
int len); | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_plat_write_file(const char *filename, void *buf, int len); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_plat_read_file(const char *filename, void *buf, int len); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_plat_recommended_rsa_bits(void); | | |
///@} | | |
| | |
/*! \defgroup uv libuv helpers | | |
* | | |
* ##libuv helpers | | |
* | | |
* APIs specific to libuv event loop itegration | | |
*/ | | |
///@{ | | |
#ifdef LWS_WITH_LIBUV | | |
/* | | |
* Any direct libuv allocations in lws protocol handlers must participate i | | |
n the | | |
* lws reference counting scheme. Two apis are provided: | | |
* | | |
* - lws_libuv_static_refcount_add(handle, context) to mark the handle with | | |
* a pointer to the context and increment the global uv object counter | | |
* | | |
* - lws_libuv_static_refcount_del() which should be used as the close call | | |
back | | |
* for your own libuv objects declared in the protocol scope. | | |
* | | |
* Using the apis allows lws to detach itself from a libuv loop completely | | |
* cleanly and at the moment all of its libuv objects have completed close. | | |
*/ | | |
| | |
LWS_VISIBLE LWS_EXTERN uv_loop_t * | | |
lws_uv_getloop(struct lws_context *context, int tsi); | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_libuv_static_refcount_add(uv_handle_t *, struct lws_context *context); | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_libuv_static_refcount_del(uv_handle_t *); | | |
| | |
#endif /* LWS_WITH_LIBUV */ | | |
| | |
#if defined(LWS_WITH_ESP32) | | |
#define lws_libuv_static_refcount_add(_a, _b) | | |
#define lws_libuv_static_refcount_del NULL | | |
#endif | | |
///@} | | |
| | |
/*! \defgroup timeout Connection timeouts | | |
| | |
APIs related to setting connection timeouts | | |
*/ | | |
//@{ | | |
| | |
/* | | |
* 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 pending_timeout { | | |
NO_PENDING_TIMEOUT = 0, | | |
PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE = 1, | | |
PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE = 2, | | |
PENDING_TIMEOUT_ESTABLISH_WITH_SERVER = 3, | | |
PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE = 4, | | |
PENDING_TIMEOUT_AWAITING_PING = 5, | | |
PENDING_TIMEOUT_CLOSE_ACK = 6, | | |
PENDING_TIMEOUT_UNUSED1 = 7, | | |
PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE = 8, | | |
PENDING_TIMEOUT_SSL_ACCEPT = 9, | | |
PENDING_TIMEOUT_HTTP_CONTENT = 10, | | |
PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND = 11, | | |
PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE = 12, | | |
PENDING_TIMEOUT_SHUTDOWN_FLUSH = 13, | | |
PENDING_TIMEOUT_CGI = 14, | | |
PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE = 15, | | |
PENDING_TIMEOUT_WS_PONG_CHECK_SEND_PING = 16, | | |
PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG = 17, | | |
PENDING_TIMEOUT_CLIENT_ISSUE_PAYLOAD = 18, | | |
PENDING_TIMEOUT_AWAITING_SOCKS_GREETING_REPLY = 19, | | |
PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY = 20, | | |
PENDING_TIMEOUT_AWAITING_SOCKS_AUTH_REPLY = 21, | | |
PENDING_TIMEOUT_KILLED_BY_SSL_INFO = 22, | | |
PENDING_TIMEOUT_KILLED_BY_PARENT = 23, | | |
PENDING_TIMEOUT_CLOSE_SEND = 24, | | |
PENDING_TIMEOUT_HOLDING_AH = 25, | | |
PENDING_TIMEOUT_UDP_IDLE = 26, | | |
PENDING_TIMEOUT_CLIENT_CONN_IDLE = 27, | | |
PENDING_TIMEOUT_LAGGING = 28, | | |
| | |
/****** add new things just above ---^ ******/ | | |
| | |
PENDING_TIMEOUT_USER_REASON_BASE = 1000 | | |
}; | | |
| | |
#define LWS_TO_KILL_ASYNC -1 | | |
/**< If LWS_TO_KILL_ASYNC is given as the timeout sec in a lws_set_timeout( | | |
) | | |
* call, then the connection is marked to be killed at the next timeout | | |
* check. This is how you should force-close the wsi being serviced if | | |
* you are doing it outside the callback (where you should close by nonzero | | |
* return). | | |
*/ | | |
#define LWS_TO_KILL_SYNC -2 | | |
/**< If LWS_TO_KILL_SYNC is given as the timeout sec in a lws_set_timeout() | | |
* call, then the connection is closed before returning (which may delete | | |
* the wsi). This should only be used where the wsi being closed is not th | | |
e | | |
* wsi currently being serviced. | | |
*/ | | |
/** | | |
* 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. You may set to LWS_TO_KILL_ASYNC | | |
to | | |
* force the connection to timeout at the next opportunity, or | | |
* LWS_TO_KILL_SYNC to close it synchronously if you know the | | |
* wsi is not the one currently being serviced. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs); | | |
| | |
#define LWS_SET_TIMER_USEC_CANCEL ((lws_usec_t)-1ll) | | |
#define LWS_USEC_PER_SEC (1000000ll) | | |
| | |
/** | | |
* lws_set_timer_usecs() - schedules a callback on the wsi in the future | | |
* | | |
* \param wsi: Websocket connection instance | | |
* \param usecs: LWS_SET_TIMER_USEC_CANCEL removes any existing scheduled | | |
* callback, otherwise number of microseconds in the future | | |
* the callback will occur at. | | |
* | | |
* NOTE: event loop support for this: | | |
* | | |
* default poll() loop: yes | | |
* libuv event loop: yes | | |
* libev: not implemented (patch welcome) | | |
* libevent: not implemented (patch welcome) | | |
* | | |
* After the deadline expires, the wsi will get a callback of type | | |
* LWS_CALLBACK_TIMER and the timer is exhausted. The deadline may be | | |
* continuously deferred by further calls to lws_set_timer_usecs() with a l | | |
ater | | |
* deadline, or cancelled by lws_set_timer_usecs(wsi, -1). | | |
* | | |
* If the timer should repeat, lws_set_timer_usecs() must be called again f | | |
rom | | |
* LWS_CALLBACK_TIMER. | | |
* | | |
* Accuracy depends on the platform and the load on the event loop or syste | | |
m... | | |
* all that's guaranteed is the callback will come after the requested wait | | |
* period. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_set_timer_usecs(struct lws *wsi, lws_usec_t usecs); | | |
| | |
/* | | |
* lws_timed_callback_vh_protocol() - calls back a protocol on a vhost afte | | |
r | | |
* the specified delay | | |
* | | |
* \param vh: the vhost to call back | | |
* \param protocol: the protocol to call back | | |
* \param reason: callback reason | | |
* \param secs: how many seconds in the future to do the callback. | | |
Set to | | |
* -1 to cancel the timer callback. | | |
* | | |
* Callback the specified protocol with a fake wsi pointing to the specifie | | |
d | | |
* vhost and protocol, with the specified reason, at the specified time in | | |
the | | |
* future. | | |
* | | |
* Returns 0 if OK. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_timed_callback_vh_protocol(struct lws_vhost *vh, | | |
const struct lws_protocols *prot, | | |
int reason, int secs); | | |
///@} | | |
| | |
/*! \defgroup sending-data Sending data | | |
| | |
APIs related to writing data on a connection | | |
*/ | | |
//@{ | | |
#if !defined(LWS_SIZEOFPTR) | | |
#define LWS_SIZEOFPTR ((int)sizeof (void *)) | | |
#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)) | | |
/* last 2 is for lws-meta */ | | |
#define LWS_PRE _LWS_PAD(4 + 10 + 2) | | |
/* 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 | | |
| | |
#define LWS_WRITE_RAW LWS_WRITE_HTTP | | |
| | |
/* | | |
* 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) | | |
*/ | | |
LWS_WRITE_HTTP_HEADERS_CONTINUATION = 9, | | |
/**< Continuation of http/2 headers | | |
*/ | | |
| | |
/****** 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_H2_STREAM_END = 0x80, | | |
/**< Flag indicates this packet should go out with STREAM_END if h2 | | |
* STREAM_END is allowed on DATA or HEADERS. | | |
*/ | | |
| | |
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 */ | | |
}; | | |
| | |
/* used with LWS_CALLBACK_CHILD_WRITE_VIA_PARENT */ | | |
| | |
struct lws_write_passthru { | | |
struct lws *wsi; | | |
unsigned char *buf; | | |
size_t len; | | |
enum lws_write_protocol wp; | | |
}; | | |
| | |
/** | | |
* 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! | | |
* | | |
* When sending with websocket protocol | | |
* | | |
* LWS_WRITE_TEXT, | | |
* LWS_WRITE_BINARY, | | |
* LWS_WRITE_CONTINUATION, | | |
* LWS_WRITE_PING, | | |
* LWS_WRITE_PONG | | |
* | | |
* the send buffer has to have LWS_PRE bytes valid BEFORE | | |
* the buffer pointer you pass to lws_write(). | | |
* | | |
* This allows us to add protocol info before and after the data, and send | | |
as | | |
* one packet on the network without payload copying, for maximum efficienc | | |
y. | | |
* | | |
* So for example you need this kind of code to use lws_write with a | | |
* 128-byte payload | | |
* | | |
* char buf[LWS_PRE + 128]; | | |
* | | |
* // fill your part of the buffer... for example here it's all zeros | | |
* memset(&buf[LWS_PRE], 0, 128); | | |
* | | |
* lws_write(wsi, &buf[LWS_PRE], 128, LWS_WRITE_TEXT); | | |
* | | |
* When sending HTTP, with | | |
* | | |
* LWS_WRITE_HTTP, | | |
* LWS_WRITE_HTTP_HEADERS | | |
* LWS_WRITE_HTTP_FINAL | | |
* | | |
* there is no protocol data prepended, and don't need to take care about t | | |
he | | |
* LWS_PRE bytes valid before the buffer pointer. | | |
* | | |
* LWS_PRE is at least the frame nonce + 2 header + 8 length | | |
* LWS_SEND_BUFFER_POST_PADDING is deprecated, it's now 0 and can be left o | | |
ff. | | |
* The example apps no longer use it. | | |
* | | |
* Pad LWS_PRE to the CPU word size, so that word references | | |
* to the address immediately after the padding won't cause an unaligned ac | | |
cess | | |
* error. Sometimes for performance reasons the recommended padding is even | | |
* 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 the | | |
* number of bytes sent. | | |
* | | |
* Truncated Writes | | |
* ================ | | |
* | | |
* The OS may not accept everything you asked to write on the connection. | | |
* | | |
* Posix defines POLLOUT indication from poll() to show that the connection | | |
* will accept more write data, but it doesn't specifiy how much. It may j | | |
ust | | |
* accept one byte of whatever you wanted to send. | | |
* | | |
* LWS will buffer the remainder automatically, and send it out autonomousl | | |
y. | | |
* | | |
* During that time, WRITABLE callbacks will be suppressed. | | |
* | | |
* This is to handle corner cases where unexpectedly the OS refuses what we | | |
* usually expect it to accept. You should try to send in chunks that are | | |
* almost always accepted in order to avoid the inefficiency of the bufferi | | |
ng. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_write(struct lws *wsi, unsigned char *buf, size_t len, | | |
enum lws_write_protocol protocol); | | |
| | |
/* helper for case where buffer may be const */ | | |
#define lws_write_http(wsi, buf, len) \ | | |
lws_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP) | | |
| | |
/* helper for multi-frame ws message flags */ | | |
static inline int | | |
lws_write_ws_flags(int initial, int is_start, int is_end) | | |
{ | | |
int r; | | |
| | |
if (is_start) | | |
r = initial; | | |
else | | |
r = LWS_WRITE_CONTINUATION; | | |
| | |
if (!is_end) | | |
r |= LWS_WRITE_NO_FIN; | | |
| | |
return r; | | |
} | | |
///@} | | |
| | |
/** \defgroup callback-when-writeable Callback when writeable | | |
* | | |
* ##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_callback_on_writable(struct lws *wsi); | | |
| | |
/** | | |
* lws_callback_on_writable_all_protocol() - Request a callback for all | | |
* connections using the given protocol when 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_callback_on_writable_all_protocol(const struct lws_context *context, | | |
const struct lws_protocols *protocol); | | |
| | |
/** | | |
* lws_callback_on_writable_all_protocol_vhost() - Request a callback for | | |
* all connections on same vhost using the given protoc | | |
ol | | |
* when it becomes possible to write to each socket wit | | |
hout | | |
* blocking in turn. | | |
* | | |
* \param vhost: Only consider connections on this lws_vhost | | |
* \param protocol: Protocol whose connections will get callbacks | | |
* | | |
* - Which: connections using this protocol on GIVEN VHOST ONLY | | |
* - When: when the individual connection becomes writeable | | |
* - What: LWS_CALLBACK_*_WRITEABLE | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost, | | |
const struct lws_protocols *protocol); | | |
| | |
/** | | |
* lws_callback_all_protocol() - Callback all connections using | | |
* the given protocol with the given reason | | |
* | | |
* \param context: lws_context | | |
* \param protocol: Protocol whose connections will get callbacks | | |
* \param reason: Callback reason index | | |
* | | |
* - Which: connections using this protocol on ALL VHOSTS | | |
* - When: before returning | | |
* - What: reason | | |
* | | |
* This isn't normally what you want... normally any update of connection- | | |
* specific information can wait until a network-related callback like rx, | | |
* writable, or close. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_callback_all_protocol(struct lws_context *context, | | |
const struct lws_protocols *protocol, int reason); | | |
| | |
/** | | |
* lws_callback_all_protocol_vhost() - Callback all connections using | | |
* the given protocol with the given reason. This is | | |
* deprecated since v2.4: use lws_callback_all_protocol | | |
_vhost_args | | |
* | | |
* \param vh: Vhost whose connections will get callbacks | | |
* \param protocol: Which protocol to match. NULL means all. | | |
* \param reason: Callback reason index | | |
* | | |
* - Which: connections using this protocol on GIVEN VHOST ONLY | | |
* - When: now | | |
* - What: reason | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_callback_all_protocol_vhost(struct lws_vhost *vh, | | |
const struct lws_protocols *protocol, int reason) | | |
LWS_WARN_DEPRECATED; | | |
| | |
/** | | |
* lws_callback_all_protocol_vhost_args() - Callback all connections using | | |
* the given protocol with the given reason and args | | |
* | | |
* \param vh: Vhost whose connections will get callbacks | | |
* \param protocol: Which protocol to match. NULL means all. | | |
* \param reason: Callback reason index | | |
* \param argp: Callback "in" parameter | | |
* \param len: Callback "len" parameter | | |
* | | |
* - Which: connections using this protocol on GIVEN VHOST ONLY | | |
* - When: now | | |
* - What: reason | | |
*/ | | |
LWS_VISIBLE int | | |
lws_callback_all_protocol_vhost_args(struct lws_vhost *vh, | | |
const struct lws_protocols *protocol, int reason, | | |
void *argp, size_t len); | | |
| | |
/** | | |
* 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 | | |
* | | |
* This is deprecated since v2.5, use lws_callback_vhost_protocols_vhost() | | |
* which takes the pointer to the vhost directly without using or needing t | | |
he | | |
* wsi. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, int len | | |
) | | |
LWS_WARN_DEPRECATED; | | |
| | |
/** | | |
* lws_callback_vhost_protocols_vhost() - Callback all protocols enabled on | | |
a vhost | | |
* with the given reason | | |
* | | |
* \param vh: vhost that 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_callback_vhost_protocols_vhost(struct lws_vhost *vh, int reason, void * | | |
in, | | |
size_t len); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, | | |
void *user, void *in, size_t len); | | |
| | |
/** | | |
* lws_get_socket_fd() - returns the socket file descriptor | | |
* | | |
* This is needed to use sendto() on UDP raw sockets | | |
* | | |
* \param wsi: Websocket connection instance | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN lws_sockfd_type | | |
lws_get_socket_fd(struct lws *wsi); | | |
| | |
/** | | |
* lws_get_peer_write_allowance() - get the amount of data writeable to pee | | |
r | | |
* if known | | |
* | | |
* \param wsi: Websocket connection instance | | |
* | | |
* if the protocol does not have any guidance, returns -1. Currently only | | |
* http2 connections get send window information from this API. But your c | | |
ode | | |
* should use it so it can work properly with any protocol. | | |
* | | |
* If nonzero return is the amount of payload data the peer or intermediary | | |
has | | |
* reported it has buffer space for. That has NO relationship with the amo | | |
unt | | |
* 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 | | |
* on this connection right now without the protocol complaining. | | |
* | | |
* lws manages accounting for send window updates and payload writes | | |
* automatically, so this number reflects the situation at the peer or | | |
* intermediary dynamically. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN lws_fileofs_t | | |
lws_get_peer_write_allowance(struct lws *wsi); | | |
///@} | | |
| | |
enum { | | |
/* | | |
* Flags for enable and disable rxflow with reason bitmap and with | | |
* backwards-compatible single bool | | |
*/ | | |
LWS_RXFLOW_REASON_USER_BOOL = (1 << 0), | | |
LWS_RXFLOW_REASON_HTTP_RXBUFFER = (1 << 6), | | |
LWS_RXFLOW_REASON_H2_PPS_PENDING = (1 << 7), | | |
| | |
LWS_RXFLOW_REASON_APPLIES = (1 << 14), | | |
LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT = (1 << 13), | | |
LWS_RXFLOW_REASON_APPLIES_ENABLE = LWS_RXFLOW_REASON_APPLIES | | |
| | | |
LWS_RXFLOW_REASON_APPLIES_ | | |
ENABLE_BIT, | | |
LWS_RXFLOW_REASON_APPLIES_DISABLE = LWS_RXFLOW_REASON_APPLIES, | | |
LWS_RXFLOW_REASON_FLAG_PROCESS_NOW = (1 << 12), | | |
| | |
}; | | |
| | |
/** | | |
* lws_rx_flow_control() - Enable and disable socket servicing for | | |
* received packets. | | |
* | | |
* If the output side of a server process becomes choked, this allows flow | | |
* control for the input side. | | |
* | | |
* \param wsi: Websocket connection instance to get callback for | | |
* \param enable: 0 = disable read servicing for this connection, 1 = | | |
enable | | |
* | | |
* If you need more than one additive reason for rxflow control, you can gi | | |
ve | | |
* iLWS_RXFLOW_REASON_APPLIES_ENABLE or _DISABLE together with one or more | | |
of | | |
* b5..b0 set to idicate which bits to enable or disable. If any bits are | | |
* enabled, rx on the connection is suppressed. | | |
* | | |
* LWS_RXFLOW_REASON_FLAG_PROCESS_NOW flag may also be given to force any | | |
change | | |
* in rxflowbstatus to benapplied immediately, this should be used when you | | |
are | | |
* changing a wsi flow control state from outside a callback on that wsi. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_rx_flow_control(struct lws *wsi, int enable); | | |
| | |
/** | | |
* 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 fragment is complete | | |
* \param wsi: Websocket instance (available from user callback) | | |
* | | |
* This tracks how many bytes are left in the current ws fragment, accordin | | |
g | | |
* to the ws length given in the fragment header. | | |
* | | |
* If the message was in a single fragment, and there is no compression, th | | |
is | | |
* is the same as "how much data is left to read for this message". | | |
* | | |
* However, if the message is being sent in multiple fragments, this will | | |
* reflect the unread amount of the current **fragment**, not the message. | | |
With | | |
* ws, it is legal to not know the length of the message before it complete | | |
s. | | |
* | | |
* Additionally if the message is sent via the negotiated permessage-deflat | | |
e | | |
* extension, this number only tells the amount of **compressed** data left | | |
to | | |
* be read, since that is the only information available at the ws layer. | | |
*/ | | |
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 | | |
* for the default vhost of context. | | |
* | | |
* \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_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd); | | |
/** | | |
* lws_adopt_socket_vhost() - adopt foreign socket as if listen socket acce | | |
pted it | | |
* for vhost | | |
* | | |
* \param vh: lws vhost | | |
* \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_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd); | | |
| | |
typedef enum { | | |
LWS_ADOPT_RAW_FILE_DESC = 0, /* convenience constant */ | | |
LWS_ADOPT_HTTP = 1, /* flag: absent implies RAW */ | | |
LWS_ADOPT_SOCKET = 2, /* flag: absent implies file descr * | | |
/ | | |
LWS_ADOPT_ALLOW_SSL = 4, /* flag: if set requires LWS_ADOPT_S | | |
OCKET */ | | |
LWS_ADOPT_WS_PARENTIO = 8, /* flag: ws mode parent handles IO | | |
* if given must be only flag | | |
* wsi put directly into ws mode * | | |
/ | | |
LWS_ADOPT_FLAG_UDP = 16, /* flag: socket is UDP */ | | |
| | |
LWS_ADOPT_RAW_SOCKET_UDP = LWS_ADOPT_SOCKET | LWS_ADOPT_FLAG_UDP, | | |
} lws_adoption_type; | | |
| | |
typedef union { | | |
lws_sockfd_type sockfd; | | |
lws_filefd_type filefd; | | |
} lws_sock_file_fd_type; | | |
| | |
#if !defined(LWS_WITH_ESP32) | | |
struct lws_udp { | | |
struct sockaddr sa; | | |
socklen_t salen; | | |
| | |
struct sockaddr sa_pending; | | |
socklen_t salen_pending; | | |
}; | | |
#endif | | |
| | |
/* | | |
* lws_adopt_descriptor_vhost() - adopt foreign socket or file descriptor | | |
* if socket descriptor, should already have been accepted from listen socke | | |
t | | |
* | | |
* \param vhost: lws vhost | | |
* \param type: OR-ed combinations of lws_adoption_type flags | | |
* \param fd: union with either .sockfd or .filefd set | | |
* \param vh_prot_name: NULL or vh protocol name to bind raw connection to | | |
* \param parent: NULL or struct lws to attach new_wsi to as a child | | |
* | | |
* Either returns new wsi bound to accept_fd, or closes accept_fd and | | |
* returns NULL, having cleaned up any new wsi pieces. | | |
* | | |
* If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, i | | |
t's | | |
* ready to accept an upgrade to ws or just serve http. | | |
* | | |
* parent may be NULL, if given it should be an existing wsi that will becom | | |
e the | | |
* parent of the new wsi created by this call. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN struct lws * | | |
lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type, | | |
lws_sock_file_fd_type fd, const char *vh_prot_nam | | |
e, | | |
struct lws *parent); | | |
| | |
/** | | |
* lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if lis | | |
ten socket accepted it | | |
* for the default vhost of context. | | |
* \param context: lws context | | |
* \param accept_fd: fd of already-accepted socket to adopt | | |
* \param readbuf: NULL or pointer to data that must be drained before | | |
reading from | | |
* accept_fd | | |
* \param len: The length of the data held at \param readbuf | | |
* | | |
* Either returns new wsi bound to accept_fd, or closes accept_fd and | | |
* returns NULL, having cleaned up any new wsi pieces. | | |
* | | |
* LWS adopts the socket in http serving mode, it's ready to accept an upgr | | |
ade | | |
* to ws or just serve http. | | |
* | | |
* If your external code did not already read from the socket, you can use | | |
* lws_adopt_socket() instead. | | |
* | | |
* This api is guaranteed to use the data at \param readbuf first, before r | | |
eading from | | |
* the socket. | | |
* | | |
* readbuf is limited to the size of the ah rx buf, currently 2048 bytes. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN struct lws * | | |
lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accep | | |
t_fd, | | |
const char *readbuf, size_t len); | | |
/** | | |
* lws_adopt_socket_vhost_readbuf() - adopt foreign socket and first rx as | | |
if listen socket | | |
* accepted it for vhost. | | |
* \param vhost: lws vhost | | |
* \param accept_fd: fd of already-accepted socket to adopt | | |
* \param readbuf: NULL or pointer to data that must be drained before | | |
reading from | | |
* accept_fd | | |
* \param len: The length of the data held at \param readbuf | | |
* | | |
* Either returns new wsi bound to accept_fd, or closes accept_fd and | | |
* returns NULL, having cleaned up any new wsi pieces. | | |
* | | |
* LWS adopts the socket in http serving mode, it's ready to accept an upgr | | |
ade | | |
* to ws or just serve http. | | |
* | | |
* If your external code did not already read from the socket, you can use | | |
* lws_adopt_socket() instead. | | |
* | | |
* This api is guaranteed to use the data at \param readbuf first, before r | | |
eading from | | |
* the socket. | | |
* | | |
* readbuf is limited to the size of the ah rx buf, currently 2048 bytes. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN struct lws * | | |
lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost, lws_sockfd_type acc | | |
ept_fd, | | |
const char *readbuf, size_t len); | | |
| | |
#define LWS_CAUDP_BIND 1 | | |
| | |
/** | | |
* lws_create_adopt_udp() - create, bind and adopt a UDP socket | | |
* | | |
* \param vhost: lws vhost | | |
* \param port: UDP port to bind to, -1 means unbound | | |
* \param flags: 0 or LWS_CAUDP_NO_BIND | | |
* \param protocol_name: Name of protocol on vhost to bind wsi to | | |
* \param parent_wsi: NULL or parent wsi new wsi will be a child of | | |
* | | |
* Either returns new wsi bound to accept_fd, or closes accept_fd and | | |
* returns NULL, having cleaned up any new wsi pieces. | | |
* */ | | |
LWS_VISIBLE LWS_EXTERN struct lws * | | |
lws_create_adopt_udp(struct lws_vhost *vhost, int port, int flags, | | |
const char *protocol_name, struct lws *parent_wsi); | | |
///@} | | |
| | |
/** \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_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_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name, | | |
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); | | |
| | |
#define LWS_ITOSA_NOT_EXIST -1 | | |
#define LWS_ITOSA_NOT_USABLE -2 | | |
#define LWS_ITOSA_USABLE 0 | | |
#if !defined(LWS_WITH_ESP32) | | |
/** | | |
* 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. | | |
* | | |
* If the network interface doesn't exist, it will return LWS_ITOSA_NOT_EXI | | |
ST. | | |
* | | |
* If the network interface is not usable, eg ethernet cable is removed, it | | |
* may logically exist but not have any IP address. As such it will return | | |
* LWS_ITOSA_NOT_USABLE. | | |
* | | |
* If the network interface exists and is usable, it will return | | |
* LWS_ITOSA_USABLE. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
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_start_foreach_ll(): linkedlist iterator helper start | | |
* | | |
* \param type: type of iteration, eg, struct xyz * | | |
* \param it: iterator var name to create | | |
* \param start: start of list | | |
* | | |
* This helper creates an iterator and starts a while (it) { | | |
* loop. The iterator runs through the linked list starting at start and | | |
* ends when it gets a NULL. | | |
* The while loop should be terminated using lws_start_foreach_ll(). | | |
*/ | | |
#define lws_start_foreach_ll(type, it, start)\ | | |
{ \ | | |
type it = start; \ | | |
while (it) { | | |
| | |
/** | | |
* lws_end_foreach_ll(): linkedlist iterator helper end | | |
* | | |
* \param it: same iterator var name given when starting | | |
* \param nxt: member name in the iterator pointing to next list element | | |
* | | |
* This helper is the partner for lws_start_foreach_ll() that ends the | | |
* while loop. | | |
*/ | | |
| | |
#define lws_end_foreach_ll(it, nxt) \ | | |
it = it->nxt; \ | | |
} \ | | |
} | | |
| | |
/** | | |
* lws_start_foreach_llp(): linkedlist pointer iterator helper start | | |
* | | |
* \param type: type of iteration, eg, struct xyz ** | | |
* \param it: iterator var name to create | | |
* \param start: start of list | | |
* | | |
* This helper creates an iterator and starts a while (it) { | | |
* loop. The iterator runs through the linked list starting at the | | |
* address of start and ends when it gets a NULL. | | |
* The while loop should be terminated using lws_start_foreach_llp(). | | |
* | | |
* This helper variant iterates using a pointer to the previous linked-list | | |
* element. That allows you to easily delete list members by rewriting the | | |
* previous pointer to the element's next pointer. | | |
*/ | | |
#define lws_start_foreach_llp(type, it, start)\ | | |
{ \ | | |
type it = &(start); \ | | |
while (*(it)) { | | |
| | |
#define lws_start_foreach_llp_safe(type, it, start, nxt)\ | | |
{ \ | | |
type it = &(start); \ | | |
type next; \ | | |
while (*(it)) { \ | | |
next = &((*(it))->nxt); \ | | |
| | |
/** | | |
* lws_end_foreach_llp(): linkedlist pointer iterator helper end | | |
* | | |
* \param it: same iterator var name given when starting | | |
* \param nxt: member name in the iterator pointing to next list element | | |
* | | |
* This helper is the partner for lws_start_foreach_llp() that ends the | | |
* while loop. | | |
*/ | | |
| | |
#define lws_end_foreach_llp(it, nxt) \ | | |
it = &(*(it))->nxt; \ | | |
} \ | | |
} | | |
| | |
#define lws_end_foreach_llp_safe(it) \ | | |
it = next; \ | | |
} \ | | |
} | | |
| | |
#define lws_ll_fwd_insert(\ | | |
___new_object, /* pointer to new object */ \ | | |
___m_list, /* member for next list object ptr */ \ | | |
___list_head /* list head */ \ | | |
) {\ | | |
___new_object->___m_list = ___list_head; \ | | |
___list_head = ___new_object; \ | | |
} | | |
| | |
#define lws_ll_fwd_remove(\ | | |
___type, /* type of listed object */ \ | | |
___m_list, /* member for next list object ptr */ \ | | |
___target, /* object to remove from list */ \ | | |
___list_head /* list head */ \ | | |
) { \ | | |
lws_start_foreach_llp(___type **, ___ppss, ___list_head) { | | |
\ | | |
if (*___ppss == ___target) { \ | | |
*___ppss = ___target->___m_list; \ | | |
break; \ | | |
} \ | | |
} lws_end_foreach_llp(___ppss, ___m_list); \ | | |
} | | |
| | |
/* | | |
* doubly linked-list | | |
*/ | | |
| | |
struct lws_dll { /* abstract */ | | |
struct lws_dll *prev; | | |
struct lws_dll *next; | | |
}; | | |
| | |
/* | | |
* these all point to the composed list objects... you have to use the | | |
* lws_container_of() helper to recover the start of the containing struct | | |
*/ | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_dll_add_front(struct lws_dll *d, struct lws_dll *phead); | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_dll_remove(struct lws_dll *d); | | |
| | |
struct lws_dll_lws { /* typed as struct lws * */ | | |
struct lws_dll_lws *prev; | | |
struct lws_dll_lws *next; | | |
}; | | |
| | |
#define lws_dll_is_null(___dll) (!(___dll)->prev && !(___dll)->next) | | |
| | |
static inline void | | |
lws_dll_lws_add_front(struct lws_dll_lws *_a, struct lws_dll_lws *_head) | | |
{ | | |
lws_dll_add_front((struct lws_dll *)_a, (struct lws_dll *)_head); | | |
} | | |
| | |
static inline void | | |
lws_dll_lws_remove(struct lws_dll_lws *_a) | | |
{ | | |
lws_dll_remove((struct lws_dll *)_a); | | |
} | | |
| | |
/* | | |
* these are safe against the current container object getting deleted, | | |
* since the hold his next in a temp and go to that next. ___tmp is | | |
* the temp. | | |
*/ | | |
| | |
#define lws_start_foreach_dll_safe(___type, ___it, ___tmp, ___start) \ | | |
{ \ | | |
___type ___it = ___start; \ | | |
while (___it) { \ | | |
___type ___tmp = (___it)->next; | | |
| | |
#define lws_end_foreach_dll_safe(___it, ___tmp) \ | | |
___it = ___tmp; \ | | |
} \ | | |
} | | |
| | |
#define lws_start_foreach_dll(___type, ___it, ___start) \ | | |
{ \ | | |
___type ___it = ___start; \ | | |
while (___it) { | | |
| | |
#define lws_end_foreach_dll(___it) \ | | |
___it = (___it)->next; \ | | |
} \ | | |
} | | |
| | |
struct lws_buflist; | | |
| | |
/** | | |
* lws_buflist_append_segment(): add buffer to buflist at head | | |
* | | |
* \param head: list head | | |
* \param buf: buffer to stash | | |
* \param len: length of buffer to stash | | |
* | | |
* Returns -1 on OOM, 1 if this was the first segment on the list, and 0 if | | |
* it was a subsequent segment. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf, | | |
size_t len); | | |
/** | | |
* lws_buflist_next_segment_len(): number of bytes left in current segment | | |
* | | |
* \param head: list head | | |
* \param buf: if non-NULL, *buf is written with the address of the start o | | |
f | | |
* the remaining data in the segment | | |
* | | |
* Returns the number of bytes left in the current segment. 0 indicates | | |
* that the buflist is empty (there are no segments on the buflist). | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN size_t | | |
lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf); | | |
/** | | |
* lws_buflist_use_segment(): remove len bytes from the current segment | | |
* | | |
* \param head: list head | | |
* \param len: number of bytes to mark as used | | |
* | | |
* If len is less than the remaining length of the current segment, the pos | | |
ition | | |
* in the current segment is simply advanced and it returns. | | |
* | | |
* If len uses up the remaining length of the current segment, then the seg | | |
ment | | |
* is deleted and the list head moves to the next segment if any. | | |
* | | |
* Returns the number of bytes left in the current segment. 0 indicates | | |
* that the buflist is empty (there are no segments on the buflist). | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_buflist_use_segment(struct lws_buflist **head, size_t len); | | |
/** | | |
* lws_buflist_destroy_all_segments(): free all segments on the list | | |
* | | |
* \param head: list head | | |
* | | |
* This frees everything on the list unconditionally. *head is always | | |
* NULL after this. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_buflist_destroy_all_segments(struct lws_buflist **head); | | |
| | |
void | | |
lws_buflist_describe(struct lws_buflist **head, void *id); | | |
| | |
/** | | |
* lws_ptr_diff(): helper to report distance between pointers as an int | | |
* | | |
* \param head: the pointer with the larger address | | |
* \param tail: the pointer with the smaller address | | |
* | | |
* This helper gives you an int representing the number of bytes further | | |
* forward the first pointer is compared to the second pointer. | | |
*/ | | |
#define lws_ptr_diff(head, tail) \ | | |
((int)((char *)(head) - (char *)(tail))) | | |
| | |
/** | | |
* 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_FORMAT(3) | | |
; | | |
| | |
/** | | |
* lws_strncpy(): strncpy that guarantees NUL on truncated copy | | |
* | | |
* \param dest: destination buffer | | |
* \param src: source buffer | | |
* \param size: bytes left in destination buffer | | |
* | | |
* 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 char * | | |
lws_strncpy(char *dest, const char *src, size_t size); | | |
| | |
/** | | |
* 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(): make current process run in the background | | |
* | | |
* \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_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_wsi_set_user() - set the user data associated with the client connec | | |
tion | | |
* \param wsi: lws connection | | |
* \param user: user data | | |
* | | |
* By default lws allocates this and it's not legal to externally set it | | |
* yourself. However client connections may have it set externally when th | | |
e | | |
* connection is created... if so, this api can be used to modify it at | | |
* runtime additionally. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_set_wsi_user(struct lws *wsi, void *user); | | |
| | |
/** | | |
* 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_cmdline_option(): simple commandline parser | | |
* | | |
* \param argc: count of argument strings | | |
* \param argv: argument strings | | |
* \param val: string to find | | |
* | | |
* Returns NULL if the string \p val is not found in the arguments. | | |
* | | |
* If it is found, then it returns a pointer to the next character after \p | | |
val. | | |
* So if \p val is "-d", then for the commandlines "myapp -d15" and | | |
* "myapp -d 15", in both cases the return will point to the "15". | | |
* | | |
* In the case there is no argument, like "myapp -d", the return will | | |
* either point to the '\\0' at the end of -d, or to the start of the | | |
* next argument, ie, will be non-NULL. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN const char * | | |
lws_cmdline_option(int argc, const char **argv, const char *val); | | |
| | |
/** | | |
* lws_now_secs(): return seconds since 1970-1-1 | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN unsigned long | | |
lws_now_secs(void); | | |
| | |
/** | | |
* lws_compare_time_t(): return relationship between two time_t | | |
* | | |
* \param context: struct lws_context | | |
* \param t1: time_t 1 | | |
* \param t2: time_t 2 | | |
* | | |
* returns <0 if t2 > t1; >0 if t1 > t2; or == 0 if t1 == t2. | | |
* | | |
* This is aware of clock discontiguities that may have affected either t1 | | |
or | | |
* t2 and adapts the comparison for them. | | |
* | | |
* For the discontiguity detection to work, you must avoid any arithmetic o | | |
n | | |
* the times being compared. For example to have a timeout that triggers | | |
* 15s from when it was set, store the time it was set and compare like | | |
* `if (lws_compare_time_t(context, now, set_time) > 15)` | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_compare_time_t(struct lws_context *context, time_t t1, time_t t2); | | |
| | |
/** | | |
* lws_get_context - Allow getting 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_vhost_listen_port - Find out the port number a vhost is listenin | | |
g on | | |
* | | |
* In the case you passed 0 for the port number at context creation time, y | | |
ou | | |
* can discover the port number that was actually chosen for the vhost usin | | |
g | | |
* this api. | | |
* | | |
* \param vhost: Vhost to get listen port from | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT | | |
lws_get_vhost_listen_port(struct lws_vhost *vhost); | | |
| | |
/** | | |
* 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); | | |
| | |
/** | | |
* lws_get_udp() - get wsi's udp struct | | |
* | | |
* \param wsi: lws connection | | |
* | | |
* Returns NULL or pointer to the wsi's UDP-specific information | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN const struct lws_udp * LWS_WARN_UNUSED_RESULT | | |
lws_get_udp(const struct lws *wsi); | | |
| | |
/** | | |
* lws_parent_carries_io() - mark wsi as needing to send messages via paren | | |
t | | |
* | | |
* \param wsi: child lws connection | | |
*/ | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_set_parent_carries_io(struct lws *wsi); | | |
| | |
LWS_VISIBLE LWS_EXTERN void * | | |
lws_get_opaque_parent_data(const struct lws *wsi); | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_set_opaque_parent_data(struct lws *wsi, void *data); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_get_child_pending_on_writable(const struct lws *wsi); | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_clear_child_pending_on_writable(struct lws *wsi); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_get_close_length(struct lws *wsi); | | |
| | |
LWS_VISIBLE LWS_EXTERN unsigned char * | | |
lws_get_close_payload(struct lws *wsi); | | |
| | |
/** | | |
* lws_get_network_wsi() - Returns wsi that has the tcp connection for this | | |
wsi | | |
* | | |
* \param wsi: wsi you have | | |
* | | |
* Returns wsi that has the tcp connection (which may be the incoming wsi) | | |
* | | |
* HTTP/1 connections will always return the incoming wsi | | |
* HTTP/2 connections may return a different wsi that has the tcp connectio | | |
n | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN | | |
struct lws *lws_get_network_wsi(struct lws *wsi); | | |
| | |
/** | | |
* 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, const char *reas | | |
on)); | | |
///@} | | |
| | |
/** \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_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_is_first_fragment() - tests if first part of ws message | | |
* | | |
* \param wsi: lws connection | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_is_first_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_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_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_is_ssl(struct lws *wsi); | | |
/** | | |
* lws_is_cgi() - find out if this wsi is running a cgi process | | |
* \param wsi: lws connection | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_is_cgi(struct lws *wsi); | | |
| | |
struct lws_wifi_scan { /* generic wlan scan item */ | | |
struct lws_wifi_scan *next; | | |
char ssid[32]; | | |
int32_t rssi; /* divide by .count to get db */ | | |
uint8_t bssid[6]; | | |
uint8_t count; | | |
uint8_t channel; | | |
uint8_t authmode; | | |
}; | | |
| | |
#if defined(LWS_WITH_TLS) && !defined(LWS_WITH_MBEDTLS) | | |
/** | | |
* lws_get_ssl() - Return wsi's SSL context structure | | |
* \param wsi: websocket connection | | |
* | | |
* Returns pointer to the SSL library's context structure | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN SSL* | | |
lws_get_ssl(struct lws *wsi); | | |
#endif | | |
| | |
enum lws_tls_cert_info { | | |
LWS_TLS_CERT_INFO_VALIDITY_FROM, | | |
/**< fills .time with the time_t the cert validity started from */ | | |
LWS_TLS_CERT_INFO_VALIDITY_TO, | | |
/**< fills .time with the time_t the cert validity ends at */ | | |
LWS_TLS_CERT_INFO_COMMON_NAME, | | |
/**< fills up to len bytes of .ns.name with the cert common name */ | | |
LWS_TLS_CERT_INFO_ISSUER_NAME, | | |
/**< fills up to len bytes of .ns.name with the cert issuer name */ | | |
LWS_TLS_CERT_INFO_USAGE, | | |
/**< fills verified with a bitfield asserting the valid uses */ | | |
LWS_TLS_CERT_INFO_VERIFIED, | | |
/**< fills .verified with a bool representing peer cert validity, | | |
* call returns -1 if no cert */ | | |
LWS_TLS_CERT_INFO_OPAQUE_PUBLIC_KEY, | | |
/**< the certificate's public key, as an opaque bytestream. These | | |
* opaque bytestreams can only be compared with each other using the | | |
* same tls backend, ie, OpenSSL or mbedTLS. The different backends | | |
* produce different, incompatible representations for the same cert | | |
. | | |
*/ | | |
}; | | |
| | |
union lws_tls_cert_info_results { | | |
unsigned int verified; | | |
time_t time; | | |
unsigned int usage; | | |
struct { | | |
int len; | | |
/* KEEP LAST... notice the [64] is only there because | | |
* name[] is not allowed in a union. The actual length of | | |
* name[] is arbitrary and is passed into the api using the | | |
* len parameter. Eg | | |
* | | |
* char big[1024]; | | |
* union lws_tls_cert_info_results *buf = | | |
* (union lws_tls_cert_info_results *)big; | | |
* | | |
* lws_tls_peer_cert_info(wsi, type, buf, sizeof(big) - | | |
* sizeof(*buf) + sizeof(buf->ns.name | | |
)); | | |
*/ | | |
char name[64]; | | |
} ns; | | |
}; | | |
| | |
/** | | |
* lws_tls_peer_cert_info() - get information from the peer's TLS cert | | |
* | | |
* \param wsi: the connection to query | | |
* \param type: one of LWS_TLS_CERT_INFO_ | | |
* \param buf: pointer to union to take result | | |
* \param len: when result is a string, the true length of buf->ns.name[] | | |
* | | |
* lws_tls_peer_cert_info() lets you get hold of information from the peer | | |
* certificate. | | |
* | | |
* Return 0 if there is a result in \p buf, or -1 indicating there was no c | | |
ert | | |
* or another problem. | | |
* | | |
* This function works the same no matter if the TLS backend is OpenSSL or | | |
* mbedTLS. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type, | | |
union lws_tls_cert_info_results *buf, size_t len); | | |
| | |
/** | | |
* lws_tls_vhost_cert_info() - get information from the vhost's own TLS cer | | |
t | | |
* | | |
* \param vhost: the vhost to query | | |
* \param type: one of LWS_TLS_CERT_INFO_ | | |
* \param buf: pointer to union to take result | | |
* \param len: when result is a string, the true length of buf->ns.name[] | | |
* | | |
* lws_tls_vhost_cert_info() lets you get hold of information from the vhos | | |
t | | |
* certificate. | | |
* | | |
* Return 0 if there is a result in \p buf, or -1 indicating there was no c | | |
ert | | |
* or another problem. | | |
* | | |
* This function works the same no matter if the TLS backend is OpenSSL or | | |
* mbedTLS. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info typ | | |
e, | | |
union lws_tls_cert_info_results *buf, size_t len); | | |
| | |
/** | | |
* lws_tls_acme_sni_cert_create() - creates a temp selfsigned cert | | |
* and attaches to a vhost | | |
* | | |
* \param vhost: the vhost to acquire the selfsigned cert | | |
* \param san_a: SAN written into the certificate | | |
* \param san_b: second SAN written into the certificate | | |
* | | |
* | | |
* Returns 0 if created and attached to the vhost. Returns -1 if problems | | |
and | | |
* frees all allocations before returning. | | |
* | | |
* On success, any allocations are destroyed at vhost destruction automatic | | |
ally. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a, | | |
const char *san_b); | | |
| | |
/** | | |
* lws_tls_acme_sni_csr_create() - creates a CSR and related private key PE | | |
M | | |
* | | |
* \param context: lws_context used for random | | |
* \param elements: array of LWS_TLS_REQ_ELEMENT_COUNT const char * | | |
* \param csr: buffer that will get the b64URL(ASN-1 CSR) | | |
* \param csr_len: max length of the csr buffer | | |
* \param privkey_pem: pointer to pointer allocated to hold the privkey_pem | | |
* \param privkey_len: pointer to size_t set to the length of the privkey_p | | |
em | | |
* | | |
* Creates a CSR according to the information in \p elements, and a private | | |
* RSA key used to sign the CSR. | | |
* | | |
* The outputs are the b64URL(ASN-1 CSR) into csr, and the PEM private key | | |
into | | |
* privkey_pem. | | |
* | | |
* Notice that \p elements points to an array of const char *s pointing to | | |
the | | |
* information listed in the enum above. If an entry is NULL or an empty | | |
* string, the element is set to "none" in the CSR. | | |
* | | |
* Returns 0 on success or nonzero for failure. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_tls_acme_sni_csr_create(struct lws_context *context, const char *elemen | | |
ts[], | | |
uint8_t *csr, size_t csr_len, char **privkey_pem | | |
, | | |
size_t *privkey_len); | | |
| | |
/** | | |
* lws_tls_cert_updated() - update every vhost using the given cert path | | |
* | | |
* \param context: our lws_context | | |
* \param certpath: the filepath to the certificate | | |
* \param keypath: the filepath to the private key of the certificate | | |
* \param mem_cert: copy of the cert in memory | | |
* \param len_mem_cert: length of the copy of the cert in memory | | |
* \param mem_privkey: copy of the private key in memory | | |
* \param len_mem_privkey: length of the copy of the private key in memory | | |
* | | |
* Checks every vhost to see if it is the using certificate described by th | | |
e | | |
* the given filepaths. If so, it attempts to update the vhost ssl_ctx to | | |
use | | |
* the new certificate. | | |
* | | |
* Returns 0 on success or nonzero for failure. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_tls_cert_updated(struct lws_context *context, const char *certpath, | | |
const char *keypath, | | |
const char *mem_cert, size_t len_mem_cert, | | |
const char *mem_privkey, size_t len_mem_privkey); | | |
///@} | | |
| | |
/** \defgroup lws_ring LWS Ringbuffer APIs | | |
* ##lws_ring: generic ringbuffer struct | | |
* | | |
* Provides an abstract ringbuffer api supporting one head and one or an | | |
* unlimited number of tails. | | |
* | | |
* All of the members are opaque and manipulated by lws_ring_...() apis. | | |
* | | |
* The lws_ring and its buffer is allocated at runtime on the heap, using | | |
* | | |
* - lws_ring_create() | | |
* - lws_ring_destroy() | | |
* | | |
* It may contain any type, the size of the "element" stored in the ring | | |
* buffer and the number of elements is given at creation time. | | |
* | | |
* When you create the ringbuffer, you can optionally provide an element | | |
* destroy callback that frees any allocations inside the element. This is | | |
then | | |
* automatically called for elements with no tail behind them, ie, elements | | |
* which don't have any pending consumer are auto-freed. | | |
* | | |
* Whole elements may be inserted into the ringbuffer and removed from it, | | |
using | | |
* | | |
* - lws_ring_insert() | | |
* - lws_ring_consume() | | |
* | | |
* You can find out how many whole elements are free or waiting using | | |
* | | |
* - lws_ring_get_count_free_elements() | | |
* - lws_ring_get_count_waiting_elements() | | |
* | | |
* In addition there are special purpose optional byte-centric apis | | |
* | | |
* - lws_ring_next_linear_insert_range() | | |
* - lws_ring_bump_head() | | |
* | | |
* which let you, eg, read() directly into the ringbuffer without needing | | |
* an intermediate bounce buffer. | | |
* | | |
* The accessors understand that the ring wraps, and optimizes insertion a | | |
nd | | |
* consumption into one or two memcpy()s depending on if the head or tail | | |
* wraps. | | |
* | | |
* lws_ring only supports a single head, but optionally multiple tails wit | | |
h | | |
* an API to inform it when the "oldest" tail has moved on. You can give | | |
* NULL where-ever an api asks for a tail pointer, and it will use an inte | | |
rnal | | |
* single tail pointer for convenience. | | |
* | | |
* The "oldest tail", which is the only tail if you give it NULL instead o | | |
f | | |
* some other tail, is used to track which elements in the ringbuffer are | | |
* still unread by anyone. | | |
* | | |
* - lws_ring_update_oldest_tail() | | |
*/ | | |
///@{ | | |
struct lws_ring; | | |
| | |
/** | | |
* lws_ring_create(): create a new ringbuffer | | |
* | | |
* \param element_len: the size in bytes of one element in the ringbuffer | | |
* \param count: the number of elements the ringbuffer can contain | | |
* \param destroy_element: NULL, or callback to be called for each element | | |
* that is removed from the ringbuffer due to the | | |
* oldest tail moving beyond it | | |
* | | |
* Creates the ringbuffer and allocates the storage. Returns the new | | |
* lws_ring *, or NULL if the allocation failed. | | |
* | | |
* If non-NULL, destroy_element will get called back for every element that | | |
is | | |
* retired from the ringbuffer after the oldest tail has gone past it, and | | |
for | | |
* any element still left in the ringbuffer when it is destroyed. It repla | | |
ces | | |
* all other element destruction code in your user code. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN struct lws_ring * | | |
lws_ring_create(size_t element_len, size_t count, | | |
void (*destroy_element)(void *element)); | | |
| | |
/** | | |
* lws_ring_destroy(): destroy a previously created ringbuffer | | |
* | | |
* \param ring: the struct lws_ring to destroy | | |
* | | |
* Destroys the ringbuffer allocation and the struct lws_ring itself. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_ring_destroy(struct lws_ring *ring); | | |
| | |
/** | | |
* lws_ring_get_count_free_elements(): return how many elements can fit | | |
* in the free space | | |
* | | |
* \param ring: the struct lws_ring to report on | | |
* | | |
* Returns how much room is left in the ringbuffer for whole element insert | | |
ion. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN size_t | | |
lws_ring_get_count_free_elements(struct lws_ring *ring); | | |
| | |
/** | | |
* lws_ring_get_count_waiting_elements(): return how many elements can be | | |
consumed | | |
* | | |
* \param ring: the struct lws_ring to report on | | |
* \param tail: a pointer to the tail struct to use, or NULL for single tai | | |
l | | |
* | | |
* Returns how many elements are waiting to be consumed from the perspectiv | | |
e | | |
* of the tail pointer given. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN size_t | | |
lws_ring_get_count_waiting_elements(struct lws_ring *ring, uint32_t *tail); | | |
| | |
/** | | |
* lws_ring_insert(): attempt to insert up to max_count elements from src | | |
* | | |
* \param ring: the struct lws_ring to report on | | |
* \param src: the array of elements to be inserted | | |
* \param max_count: the number of available elements at src | | |
* | | |
* Attempts to insert as many of the elements at src as possible, up to the | | |
* maximum max_count. Returns the number of elements actually inserted. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN size_t | | |
lws_ring_insert(struct lws_ring *ring, const void *src, size_t max_count); | | |
| | |
/** | | |
* lws_ring_consume(): attempt to copy out and remove up to max_count elem | | |
ents | | |
* to src | | |
* | | |
* \param ring: the struct lws_ring to report on | | |
* \param tail: a pointer to the tail struct to use, or NULL for single tai | | |
l | | |
* \param dest: the array of elements to be inserted. or NULL for no copy | | |
* \param max_count: the number of available elements at src | | |
* | | |
* Attempts to copy out as many waiting elements as possible into dest, fro | | |
m | | |
* the perspective of the given tail, up to max_count. If dest is NULL, th | | |
e | | |
* copying out is not done but the elements are logically consumed as usual | | |
. | | |
* NULL dest is useful in combination with lws_ring_get_element(), where yo | | |
u | | |
* can use the element direct from the ringbuffer and then call this with N | | |
ULL | | |
* dest to logically consume it. | | |
* | | |
* Increments the tail position according to how many elements could be | | |
* consumed. | | |
* | | |
* Returns the number of elements consumed. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN size_t | | |
lws_ring_consume(struct lws_ring *ring, uint32_t *tail, void *dest, | | |
size_t max_count); | | |
| | |
/** | | |
* lws_ring_get_element(): get a pointer to the next waiting element for t | | |
ail | | |
* | | |
* \param ring: the struct lws_ring to report on | | |
* \param tail: a pointer to the tail struct to use, or NULL for single tai | | |
l | | |
* | | |
* Points to the next element that tail would consume, directly in the | | |
* ringbuffer. This lets you write() or otherwise use the element without | | |
* having to copy it out somewhere first. | | |
* | | |
* After calling this, you must call lws_ring_consume(ring, &tail, NULL, 1) | | |
* which will logically consume the element you used up and increment your | | |
* tail (tail may also be NULL there if you use a single tail). | | |
* | | |
* Returns NULL if no waiting element, or a const void * pointing to it. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN const void * | | |
lws_ring_get_element(struct lws_ring *ring, uint32_t *tail); | | |
| | |
/** | | |
* lws_ring_update_oldest_tail(): free up elements older than tail for reu | | |
se | | |
* | | |
* \param ring: the struct lws_ring to report on | | |
* \param tail: a pointer to the tail struct to use, or NULL for single tai | | |
l | | |
* | | |
* If you are using multiple tails, you must use this API to inform the | | |
* lws_ring when none of the tails still need elements in the fifo any more | | |
, | | |
* by updating it when the "oldest" tail has moved on. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_ring_update_oldest_tail(struct lws_ring *ring, uint32_t tail); | | |
| | |
/** | | |
* lws_ring_get_oldest_tail(): get current oldest available data index | | |
* | | |
* \param ring: the struct lws_ring to report on | | |
* | | |
* If you are initializing a new ringbuffer consumer, you can set its tail | | |
to | | |
* this to start it from the oldest ringbuffer entry still available. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN uint32_t | | |
lws_ring_get_oldest_tail(struct lws_ring *ring); | | |
| | |
/** | | |
* lws_ring_next_linear_insert_range(): used to write directly into the ri | | |
ng | | |
* | | |
* \param ring: the struct lws_ring to report on | | |
* \param start: pointer to a void * set to the start of the next ringbuffe | | |
r area | | |
* \param bytes: pointer to a size_t set to the max length you may use from | | |
*start | | |
* | | |
* This provides a low-level, bytewise access directly into the ringbuffer | | |
* allowing direct insertion of data without having to use a bounce buffer. | | |
* | | |
* The api reports the position and length of the next linear range that ca | | |
n | | |
* be written in the ringbuffer, ie, up to the point it would wrap, and set | | |
s | | |
* *start and *bytes accordingly. You can then, eg, directly read() into | | |
* *start for up to *bytes, and use lws_ring_bump_head() to update the lws_ | | |
ring | | |
* with what you have done. | | |
* | | |
* Returns nonzero if no insertion is currently possible. | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_ring_next_linear_insert_range(struct lws_ring *ring, void **start, | | |
size_t *bytes); | | |
| | |
/** | | |
* lws_ring_bump_head(): used to write directly into the ring | | |
* | | |
* \param ring: the struct lws_ring to operate on | | |
* \param bytes: the number of bytes you inserted at the current head | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_ring_bump_head(struct lws_ring *ring, size_t bytes); | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_ring_dump(struct lws_ring *ring, uint32_t *tail); | | |
| | |
/* | | |
* This is a helper that combines the common pattern of needing to consume | | |
* some ringbuffer elements, move the consumer tail on, and check if that | | |
* has moved any ringbuffer elements out of scope, because it was the last | | |
* consumer that had not already consumed them. | | |
* | | |
* Elements that go out of scope because the oldest tail is now after them | | |
* get garbage-collected by calling the destroy_element callback on them | | |
* defined when the ringbuffer was created. | | |
*/ | | |
| | |
#define lws_ring_consume_and_update_oldest_tail(\ | | |
___ring, /* the lws_ring object */ \ | | |
___type, /* type of objects with tails */ \ | | |
___ptail, /* ptr to tail of obj with tail doing consuming | | |
*/ \ | | |
___count, /* count of payload objects being consumed */ \ | | |
___list_head, /* head of list of objects with tails */ \ | | |
___mtail, /* member name of tail in ___type */ \ | | |
___mlist /* member name of next list member ptr in ___type | | |
*/ \ | | |
) { \ | | |
int ___n, ___m; \ | | |
\ | | |
___n = lws_ring_get_oldest_tail(___ring) == *(___ptail); \ | | |
lws_ring_consume(___ring, ___ptail, NULL, ___count); \ | | |
if (___n) { \ | | |
uint32_t ___oldest; \ | | |
___n = 0; \ | | |
___oldest = *(___ptail); \ | | |
lws_start_foreach_llp(___type **, ___ppss, ___list_head) { \ | | |
___m = lws_ring_get_count_waiting_elements( \ | | |
___ring, &(*___ppss)->tail); \ | | |
if (___m >= ___n) { \ | | |
___n = ___m; \ | | |
___oldest = (*___ppss)->tail; \ | | |
} \ | | |
} lws_end_foreach_llp(___ppss, ___mlist); \ | | |
\ | | |
lws_ring_update_oldest_tail(___ring, ___oldest); \ | | |
} \ | | |
} | | |
| | |
/* | | |
* This does the same as the lws_ring_consume_and_update_oldest_tail() | | |
* helper, but for the simpler case there is only one consumer, so one | | |
* tail, and that tail is always the oldest tail. | | |
*/ | | |
| | |
#define lws_ring_consume_single_tail(\ | | |
___ring, /* the lws_ring object */ \ | | |
___ptail, /* ptr to tail of obj with tail doing consuming */ | | |
\ | | |
___count /* count of payload objects being consumed */ \ | | |
) { \ | | |
lws_ring_consume(___ring, ___ptail, NULL, ___count); \ | | |
lws_ring_update_oldest_tail(___ring, *(___ptail)); \ | | |
} | | |
///@} | | |
| | |
/** \defgroup sha SHA and B64 helpers | | |
* ##SHA and B64 helpers | | |
* | | |
* These provide SHA-1 and B64 helper apis | | |
*/ | | |
///@{ | | |
#ifdef LWS_SHA1_USE_OPENSSL_NAME | | |
#define lws_SHA1 SHA1 | | |
#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_SHA1(const unsigned char *d, size_t n, unsigned char *md); | | |
#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_b64_encode_string(const char *in, int in_len, char *out, int out_size); | | |
/** | | |
* lws_b64_encode_string_url(): 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 with the "URL" variant (+ -> -, and / -> _) | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_b64_encode_string_url(const char *in, int in_len, char *out, int out_si | | |
ze); | | |
/** | | |
* 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 NUL-terminated string using b64 | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_b64_decode_string(const char *in, char *out, int out_size); | | |
/** | | |
* lws_b64_decode_string_len(): decode a string from base 64 | | |
* | | |
* \param in: incoming buffer | | |
* \param in_len: length of incoming buffer | | |
* \param out: result buffer | | |
* \param out_size: length of result buffer | | |
* | | |
* Decodes a range of chars using b64 | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_b64_decode_string_len(const char *in, int in_len, char *out, int out_si | | |
ze); | | |
///@} | | |
| | |
/*! \defgroup cgi cgi handling | | |
* | | |
* ##CGI handling | | |
* | | |
* These functions allow low-level control over stdin/out/err of the cgi. | | |
* | | |
* However for most cases, binding the cgi to http in and out, the default | | |
* lws implementation already does the right thing. | | |
*/ | | |
| | |
enum lws_enum_stdinouterr { | | |
LWS_STDIN = 0, | | |
LWS_STDOUT = 1, | | |
LWS_STDERR = 2, | | |
}; | | |
| | |
enum lws_cgi_hdr_state { | | |
LCHS_HEADER, | | |
LCHS_CR1, | | |
LCHS_LF1, | | |
LCHS_CR2, | | |
LCHS_LF2, | | |
LHCS_RESPONSE, | | |
LHCS_DUMP_HEADERS, | | |
LHCS_PAYLOAD, | | |
LCHS_SINGLE_0A, | | |
}; | | |
| | |
struct lws_cgi_args { | | |
struct lws **stdwsi; /**< get fd with lws_get_socket_fd() */ | | |
enum lws_enum_stdinouterr ch; /**< channel index */ | | |
unsigned char *data; /**< for messages with payload */ | | |
enum lws_cgi_hdr_state hdr_state; /**< track where we are in cgi hea | | |
ders */ | | |
int len; /**< length */ | | |
}; | | |
| | |
#ifdef LWS_WITH_CGI | | |
/** | | |
* 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, or -1 to spawn without URL-related env vars | | |
* \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_cgi(struct lws *wsi, const char * const *exec_array, | | |
int script_uri_path_len, int timeout_secs, | | |
const struct lws_protocol_vhost_options *mp_cgienv); | | |
| | |
/** | | |
* 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_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_cgi_kill(struct lws *wsi); | | |
| | |
/** | | |
* lws_cgi_get_stdwsi: get wsi for stdin, stdout, or stderr | | |
* | | |
* \param wsi: parent wsi that has cgi | | |
* \param ch: which of LWS_STDIN, LWS_STDOUT or LWS_STDERR | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN struct lws * | | |
lws_cgi_get_stdwsi(struct lws *wsi, enum lws_enum_stdinouterr ch); | | |
| | |
#endif | | |
///@} | | |
| | |
/*! \defgroup fops file operation wrapping | | |
* | | |
* ##File operation wrapping | | |
* | | |
* 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 | | |
* file access, use the fops callbacks directly with NULL wsi instead of th | | |
ese | | |
* helpers. | | |
* | | |
* If so, then it calls the platform handler or user overrides where presen | | |
t | | |
* (as defined in info->fops) | | |
* | | |
* The advantage from all this is user code can be portable for file operat | | |
ions | | |
* 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. | | |
*/ | | |
| | |
#if defined(LWS_WITH_ESP32) | | |
/* sdk preprocessor defs? compiler issue? gets confused with member names * | | |
/ | | |
#define LWS_FOP_OPEN _open | | |
#define LWS_FOP_CLOSE _close | | |
#define LWS_FOP_SEEK_CUR _seek_cur | | |
#define LWS_FOP_READ _read | | |
#define LWS_FOP_WRITE _write | | |
#else | | |
#define LWS_FOP_OPEN open | | |
#define LWS_FOP_CLOSE close | | |
#define LWS_FOP_SEEK_CUR seek_cur | | |
#define LWS_FOP_READ read | | |
#define LWS_FOP_WRITE write | | |
#endif | | |
| | |
#define LWS_FOP_FLAGS_MASK ((1 << 23) - 1) | | |
#define LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP (1 << 24) | | |
#define LWS_FOP_FLAG_COMPR_IS_GZIP (1 << 25) | | |
#define LWS_FOP_FLAG_MOD_TIME_VALID (1 << 26) | | |
#define LWS_FOP_FLAG_VIRTUAL (1 << 27) | | |
| | |
struct lws_plat_file_ops; | | |
| | |
struct lws_fop_fd { | | |
lws_filefd_type fd; | | |
/**< real file descriptor related to the file... */ | | |
const struct lws_plat_file_ops *fops; | | |
/**< fops that apply to this fop_fd */ | | |
void *filesystem_priv; | | |
/**< ignored by lws; owned by the fops handlers */ | | |
lws_filepos_t pos; | | |
/**< generic "position in file" */ | | |
lws_filepos_t len; | | |
/**< generic "length of file" */ | | |
lws_fop_flags_t flags; | | |
/**< copy of the returned flags */ | | |
uint32_t mod_time; | | |
/**< optional "modification time of file", only valid if .open() | | |
* set the LWS_FOP_FLAG_MOD_TIME_VALID flag */ | | |
}; | | |
typedef struct lws_fop_fd *lws_fop_fd_t; | | |
| | |
struct lws_fops_index { | | |
const char *sig; /* NULL or vfs signature, eg, ".zip/" */ | | |
uint8_t len; /* length of above string */ | | |
}; | | |
| | |
struct lws_plat_file_ops { | | |
lws_fop_fd_t (*LWS_FOP_OPEN)(const struct lws_plat_file_ops *fops, | | |
const char *filename, const char *vpath | | |
, | | |
lws_fop_flags_t *flags); | | |
/**< Open file (always binary access if plat supports it) | | |
* vpath may be NULL, or if the fops understands it, the point at wh | | |
ich | | |
* the filename's virtual part starts. | | |
* *flags & LWS_FOP_FLAGS_MASK should be set to O_RDONLY or O_RDWR. | | |
* If the file may be gzip-compressed, | | |
* LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP is set. If it actually is | | |
* gzip-compressed, then the open handler should OR | | |
* LWS_FOP_FLAG_COMPR_IS_GZIP on to *flags before returning. | | |
*/ | | |
int (*LWS_FOP_CLOSE)(lws_fop_fd_t *fop_fd); | | |
/**< close file AND set the pointer to NULL */ | | |
lws_fileofs_t (*LWS_FOP_SEEK_CUR)(lws_fop_fd_t fop_fd, | | |
lws_fileofs_t offset_from_cur_pos) | | |
; | | |
/**< seek from current position */ | | |
int (*LWS_FOP_READ)(lws_fop_fd_t fop_fd, lws_filepos_t *amount, | | |
uint8_t *buf, lws_filepos_t len); | | |
/**< Read from file, on exit *amount is set to amount actually read | | |
*/ | | |
int (*LWS_FOP_WRITE)(lws_fop_fd_t fop_fd, lws_filepos_t *amount, | | |
uint8_t *buf, lws_filepos_t len); | | |
/**< Write to file, on exit *amount is set to amount actually writte | | |
n */ | | |
| | |
struct lws_fops_index fi[3]; | | |
/**< vfs path signatures implying use of this fops */ | | |
| | |
const struct lws_plat_file_ops *next; | | |
/**< NULL or next fops in list */ | | |
| | |
/* 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_VISIBLE LWS_EXTERN void | | |
lws_set_fops(struct lws_context *context, const struct lws_plat_file_ops *f | | |
ops); | | |
/** | | |
* lws_vfs_tell() - get current file position | | |
* | | |
* \param fop_fd: fop_fd we are asking about | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN lws_filepos_t LWS_WARN_UNUSED_RESULT | | |
lws_vfs_tell(lws_fop_fd_t fop_fd); | | |
/** | | |
* lws_vfs_get_length() - get current file total length in bytes | | |
* | | |
* \param fop_fd: fop_fd we are asking about | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN lws_filepos_t LWS_WARN_UNUSED_RESULT | | |
lws_vfs_get_length(lws_fop_fd_t fop_fd); | | |
/** | | |
* lws_vfs_get_mod_time() - get time file last modified | | |
* | | |
* \param fop_fd: fop_fd we are asking about | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN uint32_t LWS_WARN_UNUSED_RESULT | | |
lws_vfs_get_mod_time(lws_fop_fd_t fop_fd); | | |
/** | | |
* lws_vfs_file_seek_set() - seek relative to start of file | | |
* | | |
* \param fop_fd: fop_fd we are seeking in | | |
* \param offset: offset from start of file | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN lws_fileofs_t | | |
lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset); | | |
/** | | |
* lws_vfs_file_seek_end() - seek relative to end of file | | |
* | | |
* \param fop_fd: fop_fd we are seeking in | | |
* \param offset: offset from start of file | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN lws_fileofs_t | | |
lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset); | | |
| | |
extern struct lws_plat_file_ops fops_zip; | | |
| | |
/** | | |
* lws_plat_file_open() - open vfs filepath | | |
* | | |
* \param fops: file ops struct that applies to this descriptor | | |
* \param vfs_path: filename to open | | |
* \param flags: pointer to open flags | | |
* | | |
* The vfs_path is scanned for known fops signatures, and the open directed | | |
* to any matching fops open. | | |
* | | |
* User code should use this api to perform vfs opens. | | |
* | | |
* returns semi-opaque handle | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN lws_fop_fd_t LWS_WARN_UNUSED_RESULT | | |
lws_vfs_file_open(const struct lws_plat_file_ops *fops, const char *vfs_pat | | |
h, | | |
lws_fop_flags_t *flags); | | |
| | |
/** | | |
* lws_plat_file_close() - close file | | |
* | | |
* \param fop_fd: file handle to close | | |
*/ | | |
static LWS_INLINE int | | |
lws_vfs_file_close(lws_fop_fd_t *fop_fd) | | |
{ | | |
return (*fop_fd)->fops->LWS_FOP_CLOSE(fop_fd); | | |
} | | |
| | |
/** | | |
* lws_plat_file_seek_cur() - close file | | |
* | | |
* | | |
* \param fop_fd: file handle | | |
* \param offset: position to seek to | | |
*/ | | |
static LWS_INLINE lws_fileofs_t | | |
lws_vfs_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset) | | |
{ | | |
return fop_fd->fops->LWS_FOP_SEEK_CUR(fop_fd, offset); | | |
} | | |
/** | | |
* lws_plat_file_read() - read from file | | |
* | | |
* \param fop_fd: file handle | | |
* \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 | | |
lws_vfs_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, | | |
uint8_t *buf, lws_filepos_t len) | | |
{ | | |
return fop_fd->fops->LWS_FOP_READ(fop_fd, amount, buf, len); | | |
} | | |
/** | | |
* lws_plat_file_write() - write from file | | |
* | | |
* \param fop_fd: file handle | | |
* \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 | | |
lws_vfs_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount, | | |
uint8_t *buf, lws_filepos_t len) | | |
{ | | |
return fop_fd->fops->LWS_FOP_WRITE(fop_fd, amount, buf, len); | | |
} | | |
| | |
/* these are the platform file operations implementations... they can | | |
* be called directly and used in fops arrays | | |
*/ | | |
| | |
LWS_VISIBLE LWS_EXTERN lws_fop_fd_t | | |
_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filen | | |
ame, | | |
const char *vpath, lws_fop_flags_t *flags); | | |
LWS_VISIBLE LWS_EXTERN int | | |
_lws_plat_file_close(lws_fop_fd_t *fop_fd); | | |
LWS_VISIBLE LWS_EXTERN lws_fileofs_t | | |
_lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset); | | |
LWS_VISIBLE LWS_EXTERN int | | |
_lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, | | |
uint8_t *buf, lws_filepos_t len); | | |
LWS_VISIBLE LWS_EXTERN int | | |
_lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount, | | |
uint8_t *buf, lws_filepos_t len); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_alloc_vfs_file(struct lws_context *context, const char *filename, | | |
uint8_t **buf, lws_filepos_t *amount); | | |
//@} | | |
| | |
/** \defgroup smtp SMTP related functions | | |
* ##SMTP related functions | | |
* \ingroup lwsapi | | |
* | | |
* 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. | | |
*/ | | |
//@{ | | |
#ifdef LWS_WITH_SMTP | | |
| | |
/** enum lwsgs_smtp_states - where we are in SMTP protocol sequence */ | | |
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 | | |
* | | |
* \param email: struct lws_email to init | | |
* \param loop: libuv loop to use | | |
* \param max_content: max email content size | | |
* | | |
* Prepares a struct lws_email for use ending SMTP | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN int | | |
lws_email_init(struct lws_email *email, uv_loop_t *loop, int max_content); | | |
| | |
/** | | |
* 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_email_check(struct lws_email *email); | | |
/** | | |
* lws_email_destroy() - stop using the struct lws_email | | |
* | | |
* \param email: the struct lws_email context | | |
* | | |
* Stop sending email using email and free allocations | | |
*/ | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_email_destroy(struct lws_email *email); | | |
| | |
#endif | | |
//@} | | |
| | |
/** \defgroup lejp JSON parser | | |
* ##JSON parsing related functions | | |
* \ingroup lwsapi | | |
* | | |
* LEJP is an extremely lightweight JSON stream parser included in lws. | | |
*/ | | |
//@{ | | |
struct lejp_ctx; | | |
| | |
#ifndef ARRAY_SIZE | | |
#define ARRAY_SIZE(_x) (sizeof(_x) / sizeof(_x[0])) | | |
#endif | | |
#define LWS_ARRAY_SIZE(_x) (sizeof(_x) / sizeof(_x[0])) | | |
#define LEJP_FLAG_WS_KEEP 64 | | |
#define LEJP_FLAG_WS_COMMENTLINE 32 | | |
| | |
enum lejp_states { | | |
LEJP_IDLE = 0, | | |
LEJP_MEMBERS = 1, | | |
LEJP_M_P = 2, | | |
LEJP_MP_STRING = LEJP_FLAG_WS_KEEP | 3, | | |
LEJP_MP_STRING_ESC = LEJP_FLAG_WS_KEEP | 4, | | |
LEJP_MP_STRING_ESC_U1 = LEJP_FLAG_WS_KEEP | 5, | | |
LEJP_MP_STRING_ESC_U2 = LEJP_FLAG_WS_KEEP | 6, | | |
LEJP_MP_STRING_ESC_U3 = LEJP_FLAG_WS_KEEP | 7, | | |
LEJP_MP_STRING_ESC_U4 = LEJP_FLAG_WS_KEEP | 8, | | |
LEJP_MP_DELIM = 9, | | |
LEJP_MP_VALUE = 10, | | |
LEJP_MP_VALUE_NUM_INT = LEJP_FLAG_WS_KEEP | 11, | | |
LEJP_MP_VALUE_NUM_EXP = LEJP_FLAG_WS_KEEP | 12, | | |
LEJP_MP_VALUE_TOK = LEJP_FLAG_WS_KEEP | 13, | | |
LEJP_MP_COMMA_OR_END = 14, | | |
LEJP_MP_ARRAY_END = 15, | | |
}; | | |
| | |
enum lejp_reasons { | | |
LEJP_CONTINUE = -1, | | |
LEJP_REJECT_IDLE_NO_BRACE = -2, | | |
LEJP_REJECT_MEMBERS_NO_CLOSE = -3, | | |
LEJP_REJECT_MP_NO_OPEN_QUOTE = -4, | | |
LEJP_REJECT_MP_STRING_UNDERRUN = -5, | | |
LEJP_REJECT_MP_ILLEGAL_CTRL = -6, | | |
LEJP_REJECT_MP_STRING_ESC_ILLEGAL_ESC = -7, | | |
LEJP_REJECT_ILLEGAL_HEX = -8, | | |
LEJP_REJECT_MP_DELIM_MISSING_COLON = -9, | | |
LEJP_REJECT_MP_DELIM_BAD_VALUE_START = -10, | | |
LEJP_REJECT_MP_VAL_NUM_INT_NO_FRAC = -11, | | |
LEJP_REJECT_MP_VAL_NUM_FORMAT = -12, | | |
LEJP_REJECT_MP_VAL_NUM_EXP_BAD_EXP = -13, | | |
LEJP_REJECT_MP_VAL_TOK_UNKNOWN = -14, | | |
LEJP_REJECT_MP_C_OR_E_UNDERF = -15, | | |
LEJP_REJECT_MP_C_OR_E_NOTARRAY = -16, | | |
LEJP_REJECT_MP_ARRAY_END_MISSING = -17, | | |
LEJP_REJECT_STACK_OVERFLOW = -18, | | |
LEJP_REJECT_MP_DELIM_ISTACK = -19, | | |
LEJP_REJECT_NUM_TOO_LONG = -20, | | |
LEJP_REJECT_MP_C_OR_E_NEITHER = -21, | | |
LEJP_REJECT_UNKNOWN = -22, | | |
LEJP_REJECT_CALLBACK = -23 | | |
}; | | |
| | |
#define LEJP_FLAG_CB_IS_VALUE 64 | | |
| | |
enum lejp_callbacks { | | |
LEJPCB_CONSTRUCTED = 0, | | |
LEJPCB_DESTRUCTED = 1, | | |
| | |
LEJPCB_START = 2, | | |
LEJPCB_COMPLETE = 3, | | |
LEJPCB_FAILED = 4, | | |
| | |
LEJPCB_PAIR_NAME = 5, | | |
| | |
LEJPCB_VAL_TRUE = LEJP_FLAG_CB_IS_VALUE | 6, | | |
LEJPCB_VAL_FALSE = LEJP_FLAG_CB_IS_VALUE | 7, | | |
LEJPCB_VAL_NULL = LEJP_FLAG_CB_IS_VALUE | 8, | | |
LEJPCB_VAL_NUM_INT = LEJP_FLAG_CB_IS_VALUE | 9, | | |
LEJPCB_VAL_NUM_FLOAT = LEJP_FLAG_CB_IS_VALUE | 10, | | |
LEJPCB_VAL_STR_START = 11, /* notice handle separately */ | | |
LEJPCB_VAL_STR_CHUNK = LEJP_FLAG_CB_IS_VALUE | 12, | | |
LEJPCB_VAL_STR_END = LEJP_FLAG_CB_IS_VALUE | 13, | | |
| | |
LEJPCB_ARRAY_START = 14, | | |
LEJPCB_ARRAY_END = 15, | | |
| | |
LEJPCB_OBJECT_START = 16, | | |
LEJPCB_OBJECT_END = 17 | | |
}; | | |
| | |
/** | | |
* _lejp_callback() - User parser actions | | |
* \param ctx: LEJP context | | |
* \param reason: Callback reason | | |
* | | |
* Your user callback is associated with the context at construction ti | | |
me, | | |
* and receives calls as the parsing progresses. | | |
* | | |
* All of the callbacks may be ignored and just return 0. | | |
* | | |
* The reasons it might get called, found in @reason, are: | | |
* | | |
* LEJPCB_CONSTRUCTED: The context was just constructed... you might want | | |
to | | |
* perform one-time allocation for the life of the context. | | |
* | | |
* LEJPCB_DESTRUCTED: The context is being destructed... if you made any | | |
* allocations at construction-time, you can free them now | | |
* | | |
* LEJPCB_START: Parsing is beginning at the first byte of input | | |
* | | |
* LEJPCB_COMPLETE: Parsing has completed successfully. You'll get a 0 | | |
or | | |
* positive return code from lejp_parse indicating the | | |
* amount of unused bytes left in the input buffer | | |
* | | |
* LEJPCB_FAILED: Parsing failed. You'll get a negative error code | | |
* returned from lejp_parse | | |
* | | |
* LEJPCB_PAIR_NAME: When a "name":"value" pair has had the name parsed, | | |
* this callback occurs. You can find the new name at | | |
* the end of ctx->path[] | | |
* | | |
* LEJPCB_VAL_TRUE: The "true" value appeared | | |
* | | |
* LEJPCB_VAL_FALSE: The "false" value appeared | | |
* | | |
* LEJPCB_VAL_NULL: The "null" value appeared | | |
* | | |
* LEJPCB_VAL_NUM_INT: A string representing an integer is in ctx-> | | |
buf | | |
* | | |
* LEJPCB_VAL_NUM_FLOAT: A string representing a float is in ctx->buf | | |
* | | |
* LEJPCB_VAL_STR_START: We are starting to parse a string, no data yet | | |
* | | |
* LEJPCB_VAL_STR_CHUNK: We parsed LEJP_STRING_CHUNK -1 bytes of string da | | |
ta in | | |
* ctx->buf, which is as much as we can buffer, so we a | | |
re | | |
* spilling it. If all your strings are less than | | |
* LEJP_STRING_CHUNK - 1 bytes, you will never see this | | |
* callback. | | |
* | | |
* LEJPCB_VAL_STR_END: String parsing has completed, the last chunk | | |
of the | | |
* string is in ctx->buf. | | |
* | | |
* LEJPCB_ARRAY_START: An array started | | |
* | | |
* LEJPCB_ARRAY_END: An array ended | | |
* | | |
* LEJPCB_OBJECT_START: An object started | | |
* | | |
* LEJPCB_OBJECT_END: An object ended | | |
*/ | | |
LWS_EXTERN signed char _lejp_callback(struct lejp_ctx *ctx, char reason); | | |
| | |
typedef signed char (*lejp_callback)(struct lejp_ctx *ctx, char reason); | | |
| | |
#ifndef LEJP_MAX_DEPTH | | |
#define LEJP_MAX_DEPTH 12 | | |
#endif | | |
#ifndef LEJP_MAX_INDEX_DEPTH | | |
#define LEJP_MAX_INDEX_DEPTH 5 | | |
#endif | | |
#ifndef LEJP_MAX_PATH | | |
#define LEJP_MAX_PATH 128 | | |
#endif | | |
#ifndef LEJP_STRING_CHUNK | | |
/* must be >= 30 to assemble floats */ | | |
#define LEJP_STRING_CHUNK 255 | | |
#endif | | |
| | |
enum num_flags { | | |
LEJP_SEEN_MINUS = (1 << 0), | | |
LEJP_SEEN_POINT = (1 << 1), | | |
LEJP_SEEN_POST_POINT = (1 << 2), | | |
LEJP_SEEN_EXP = (1 << 3) | | |
}; | | |
| | |
struct _lejp_stack { | | |
char s; /* lejp_state stack*/ | | |
char p; /* path length */ | | |
char i; /* index array length */ | | |
char b; /* user bitfield */ | | |
}; | | |
| | |
struct lejp_ctx { | | |
| | |
/* sorted by type for most compact alignment | | |
* | | |
* pointers | | |
*/ | | |
| | |
signed char (*callback)(struct lejp_ctx *ctx, char reason); | | |
void *user; | | |
const char * const *paths; | | |
| | |
/* arrays */ | | |
| | |
struct _lejp_stack st[LEJP_MAX_DEPTH]; | | |
uint16_t i[LEJP_MAX_INDEX_DEPTH]; /* index array */ | | |
uint16_t wild[LEJP_MAX_INDEX_DEPTH]; /* index array */ | | |
char path[LEJP_MAX_PATH]; | | |
char buf[LEJP_STRING_CHUNK]; | | |
| | |
/* int */ | | |
| | |
uint32_t line; | | |
| | |
/* short */ | | |
| | |
uint16_t uni; | | |
| | |
/* char */ | | |
| | |
uint8_t npos; | | |
uint8_t dcount; | | |
uint8_t f; | | |
uint8_t sp; /* stack head */ | | |
uint8_t ipos; /* index stack depth */ | | |
uint8_t ppos; | | |
uint8_t count_paths; | | |
uint8_t path_match; | | |
uint8_t path_match_len; | | |
uint8_t wildcount; | | |
}; | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lejp_construct(struct lejp_ctx *ctx, | | |
signed char (*callback)(struct lejp_ctx *ctx, char reason), | | |
void *user, const char * const *paths, unsigned char paths_co | | |
unt); | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lejp_destruct(struct lejp_ctx *ctx); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len); | | |
| | |
LWS_VISIBLE LWS_EXTERN void | | |
lejp_change_callback(struct lejp_ctx *ctx, | | |
signed char (*callback)(struct lejp_ctx *ctx, char reas | | |
on)); | | |
| | |
LWS_VISIBLE LWS_EXTERN int | | |
lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len); | | |
//@} | | |
| | |
/* | | |
* Stats are all uint64_t numbers that start at 0. | | |
* Index names here have the convention | | |
* | | |
* _C_ counter | | |
* _B_ byte count | | |
* _MS_ millisecond count | | |
*/ | | |
| | |
enum { | | |
LWSSTATS_C_CONNECTIONS, /**< count incoming connections */ | | |
LWSSTATS_C_API_CLOSE, /**< count calls to close api */ | | |
LWSSTATS_C_API_READ, /**< count calls to read from socket api */ | | |
LWSSTATS_C_API_LWS_WRITE, /**< count calls to lws_write API */ | | |
LWSSTATS_C_API_WRITE, /**< count calls to write API */ | | |
LWSSTATS_C_WRITE_PARTIALS, /**< count of partial writes */ | | |
LWSSTATS_C_WRITEABLE_CB_REQ, /**< count of writable callback request | | |
s */ | | |
LWSSTATS_C_WRITEABLE_CB_EFF_REQ, /**< count of effective writable ca | | |
llback requests */ | | |
LWSSTATS_C_WRITEABLE_CB, /**< count of writable callbacks */ | | |
LWSSTATS_C_SSL_CONNECTIONS_FAILED, /**< count of failed SSL connecti | | |
ons */ | | |
LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED, /**< count of accepted SSL conn | | |
ections */ | | |
LWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN, /**< count of SSL_accept() a | | |
ttempts */ | | |
LWSSTATS_C_SSL_CONNS_HAD_RX, /**< count of accepted SSL conns that h | | |
ave had some RX */ | | |
LWSSTATS_C_TIMEOUTS, /**< count of timed-out connections */ | | |
LWSSTATS_C_SERVICE_ENTRY, /**< count of entries to lws service loop | | |
*/ | | |
LWSSTATS_B_READ, /**< aggregate bytes read */ | | |
LWSSTATS_B_WRITE, /**< aggregate bytes written */ | | |
LWSSTATS_B_PARTIALS_ACCEPTED_PARTS, /**< aggreate of size of accepte | | |
d write data from new partials */ | | |
LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY, /**< aggregate delay in | | |
accepting connection */ | | |
LWSSTATS_MS_WRITABLE_DELAY, /**< aggregate delay between asking for | | |
writable and getting cb */ | | |
LWSSTATS_MS_WORST_WRITABLE_DELAY, /**< single worst delay between as | | |
king for writable and getting cb */ | | |
LWSSTATS_MS_SSL_RX_DELAY, /**< aggregate delay between ssl accept co | | |
mplete and first RX */ | | |
LWSSTATS_C_PEER_LIMIT_AH_DENIED, /**< number of times we would have | | |
given an ah but for the peer limit */ | | |
LWSSTATS_C_PEER_LIMIT_WSI_DENIED, /**< number of times we would have | | |
given a wsi but for the peer limit */ | | |
| | |
/* Add new things just above here ---^ | | |
* This is part of the ABI, don't needlessly break compatibility */ | | |
LWSSTATS_SIZE | | |
}; | | |
| | |
#if defined(LWS_WITH_STATS) | | |
| | |
LWS_VISIBLE LWS_EXTERN uint64_t | | |
lws_stats_get(struct lws_context *context, int index); | | |
LWS_VISIBLE LWS_EXTERN void | | |
lws_stats_log_dump(struct lws_context *context); | | |
#else | | |
static LWS_INLINE uint64_t | | |
lws_stats_get(struct lws_context *context, int index) { (void)context; (voi | | |
d)index; return 0; } | | |
static LWS_INLINE void | | |
lws_stats_log_dump(struct lws_context *context) { (void)context; } | | |
#endif | | #endif |
| | |
#ifdef __cplusplus | | #ifdef __cplusplus |
} | | } |
#endif | | #endif |
| | |
#endif | | #endif |
| | |
End of changes. 18 change blocks. |
7477 lines changed or deleted | | 46 lines changed or added |
|