diff --git a/win32/include/websockets/libwebsockets.h b/win32/include/websockets/libwebsockets.h index 75b41b28..fdbdc0a3 100644 --- a/win32/include/websockets/libwebsockets.h +++ b/win32/include/websockets/libwebsockets.h @@ -1,7 +1,7 @@ /* * libwebsockets - small server side websockets and web server implementation * - * Copyright (C) 2010-2013 Andy Green + * Copyright (C) 2010-2016 Andy Green * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,28 +23,111 @@ #define LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C #ifdef __cplusplus -extern "C" { #include +#include +#ifdef MBED_OPERATORS +#include "mbed-drivers/mbed.h" +#include "sal-iface-eth/EthernetInterface.h" +#include "sockets/TCPListener.h" +#include "sal-stack-lwip/lwipv4_init.h" + +namespace { +} +using namespace mbed::Sockets::v0; + +struct lws; +struct lws_context; + +class lws_conn { + public: + lws_conn(): + ts(NULL), + wsi(NULL), + writeable(1), + awaiting_on_writeable(0) + { + } + +public: + void set_wsi(struct lws *_wsi) { wsi = _wsi; } + int actual_onRX(Socket *s); + void onRX(Socket *s); + void onError(Socket *s, socket_error_t err); + void onDisconnect(TCPStream *s); + void onSent(Socket *s, uint16_t len); + void serialized_writeable(struct lws *wsi); + +public: + TCPStream *ts; + +public: + struct lws *wsi; + char writeable; + char awaiting_on_writeable; +}; + +class lws_conn_listener : lws_conn { +public: + lws_conn_listener(): + srv(SOCKET_STACK_LWIP_IPV4) + { + srv.setOnError(TCPStream::ErrorHandler_t(this, + &lws_conn_listener::onError)); + } + + void start(const uint16_t port); + +protected: + void onRX(Socket *s); + void onError(Socket *s, socket_error_t err); + void onIncoming(TCPListener *s, void *impl); + void onDisconnect(TCPStream *s); + +public: + TCPListener srv; +}; + #endif - -#ifdef CMAKE_BUILD + +extern "C" { +#else +#include +#endif + +#if _MSC_VER >= 1900 +#pragma comment(lib,"legacy_stdio_definitions.lib") + +FILE * __cdecl __iob_func(void) +{ + FILE __libwebsocket_std_redef_arr[] = { stdin, stdout, stderr }; + return &(__libwebsocket_std_redef_arr[0]); +} +#endif + +#ifdef MBED_OPERATORS +#define LWS_POSIX 0 +#else +#define LWS_POSIX 1 +#endif + #include "lws_config.h" -#endif #if defined(WIN32) || defined(_WIN32) - #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif + #include #include #include -//#include -#include"win32helpers/websock-w32.h" +#include +#include +#include #define strcasecmp stricmp #define getdtablesize() 30000 +#define LWS_INLINE __inline #define LWS_VISIBLE #ifdef LWS_DLL @@ -57,29 +140,44 @@ extern "C" { #define LWS_EXTERN #endif -#else // NOT WIN32 +#define LWS_INVALID_FILE INVALID_HANDLE_VALUE +#define LWS_O_RDONLY _O_RDONLY -#include +#else /* NOT WIN32 */ #include +#define LWS_INLINE inline +#define LWS_O_RDONLY O_RDONLY + +#ifndef MBED_OPERATORS +#include +#include +#define LWS_INVALID_FILE -1 +#else +#define getdtablesize() (20) +#define LWS_INVALID_FILE NULL +#endif + #if defined(__GNUC__) #define LWS_VISIBLE __attribute__((visibility("default"))) #else #define LWS_VISIBLE #endif +#if defined(__ANDROID__) +#define getdtablesize() 1024 +#endif + #endif #ifdef LWS_USE_LIBEV #include #endif /* LWS_USE_LIBEV */ -#include - #ifndef LWS_EXTERN #define LWS_EXTERN extern #endif - + #ifdef _WIN32 #define random rand #else @@ -87,8 +185,19 @@ extern "C" { #include #endif +#ifdef LWS_OPENSSL_SUPPORT +#ifdef USE_WOLFSSL +#ifdef USE_OLD_CYASSL +#include +#else +#include +#endif /* not USE_OLD_CYASSL */ +#else +#include +#endif /* not USE_WOLFSSL */ +#endif + #define CONTEXT_PORT_NO_LISTEN -1 -#define MAX_MUX_RECURSION 2 enum lws_log_levels { LLL_ERR = 1 << 0, @@ -106,6 +215,7 @@ enum lws_log_levels { }; LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...); +LWS_VISIBLE LWS_EXTERN void _lws_logv(int filter, const char *format, va_list vl); /* notice, warn and log are always compiled in */ #define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) @@ -129,131 +239,249 @@ LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len); #else /* no debug */ -#define lwsl_info(...) -#define lwsl_debug(...) -#define lwsl_parser(...) -#define lwsl_header(...) -#define lwsl_ext(...) -#define lwsl_client(...) -#define lwsl_latency(...) +#define lwsl_info(...) {} +#define lwsl_debug(...) {} +#define lwsl_parser(...) {} +#define lwsl_header(...) {} +#define lwsl_ext(...) {} +#define lwsl_client(...) {} +#define lwsl_latency(...) {} #define lwsl_hexdump(a, b) #endif - +struct lws; #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) /* api change list for user code to test against */ #define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_ARG +/* the struct lws_protocols has the id field present */ +#define LWS_FEATURE_PROTOCOLS_HAS_ID_FIELD -enum libwebsocket_context_options { - LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = 2, - LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = 4, - LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = 8, - LWS_SERVER_OPTION_LIBEV = 16, - LWS_SERVER_OPTION_DISABLE_IPV6 = 32, - LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = 64, +/* you can call lws_get_peer_write_allowance */ +#define LWS_FEATURE_PROTOCOLS_HAS_PEER_WRITE_ALLOWANCE + +/* extra parameter introduced in 917f43ab821 */ +#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_LEN + +/* File operations stuff exists */ +#define LWS_FEATURE_FOPS + +/* + * 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 { + LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = (1 << 1), + LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = (1 << 2), + LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = (1 << 3), + LWS_SERVER_OPTION_LIBEV = (1 << 4), + LWS_SERVER_OPTION_DISABLE_IPV6 = (1 << 5), + LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = (1 << 6), + LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED = (1 << 7), + LWS_SERVER_OPTION_VALIDATE_UTF8 = (1 << 8), + LWS_SERVER_OPTION_SSL_ECDH = (1 << 9), + + /****** add new things just above ---^ ******/ }; -enum libwebsocket_callback_reasons { - LWS_CALLBACK_ESTABLISHED, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH, - LWS_CALLBACK_CLIENT_ESTABLISHED, - LWS_CALLBACK_CLOSED, - LWS_CALLBACK_CLOSED_HTTP, - LWS_CALLBACK_RECEIVE, - LWS_CALLBACK_CLIENT_RECEIVE, - LWS_CALLBACK_CLIENT_RECEIVE_PONG, - LWS_CALLBACK_CLIENT_WRITEABLE, - LWS_CALLBACK_SERVER_WRITEABLE, - LWS_CALLBACK_HTTP, - LWS_CALLBACK_HTTP_BODY, - LWS_CALLBACK_HTTP_BODY_COMPLETION, - LWS_CALLBACK_HTTP_FILE_COMPLETION, - LWS_CALLBACK_HTTP_WRITEABLE, - LWS_CALLBACK_FILTER_NETWORK_CONNECTION, - LWS_CALLBACK_FILTER_HTTP_CONNECTION, - LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED, - LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION, - LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS, - LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS, - LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION, - LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER, - LWS_CALLBACK_CONFIRM_EXTENSION_OKAY, - LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED, - LWS_CALLBACK_PROTOCOL_INIT, - LWS_CALLBACK_PROTOCOL_DESTROY, - LWS_CALLBACK_WSI_CREATE, /* always protocol[0] */ - LWS_CALLBACK_WSI_DESTROY, /* always protocol[0] */ - LWS_CALLBACK_GET_THREAD_ID, +/* + * 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 { + LWS_CALLBACK_ESTABLISHED = 0, + LWS_CALLBACK_CLIENT_CONNECTION_ERROR = 1, + LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH = 2, + LWS_CALLBACK_CLIENT_ESTABLISHED = 3, + LWS_CALLBACK_CLOSED = 4, + LWS_CALLBACK_CLOSED_HTTP = 5, + LWS_CALLBACK_RECEIVE = 6, + LWS_CALLBACK_RECEIVE_PONG = 7, + LWS_CALLBACK_CLIENT_RECEIVE = 8, + LWS_CALLBACK_CLIENT_RECEIVE_PONG = 9, + LWS_CALLBACK_CLIENT_WRITEABLE = 10, + LWS_CALLBACK_SERVER_WRITEABLE = 11, + LWS_CALLBACK_HTTP = 12, + LWS_CALLBACK_HTTP_BODY = 13, + LWS_CALLBACK_HTTP_BODY_COMPLETION = 14, + LWS_CALLBACK_HTTP_FILE_COMPLETION = 15, + LWS_CALLBACK_HTTP_WRITEABLE = 16, + LWS_CALLBACK_FILTER_NETWORK_CONNECTION = 17, + LWS_CALLBACK_FILTER_HTTP_CONNECTION = 18, + LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED = 19, + LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION = 20, + LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS = 21, + LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS = 22, + LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION = 23, + LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER = 24, + LWS_CALLBACK_CONFIRM_EXTENSION_OKAY = 25, + LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED = 26, + LWS_CALLBACK_PROTOCOL_INIT = 27, + LWS_CALLBACK_PROTOCOL_DESTROY = 28, + LWS_CALLBACK_WSI_CREATE /* always protocol[0] */ = 29, + LWS_CALLBACK_WSI_DESTROY /* always protocol[0] */ = 30, + LWS_CALLBACK_GET_THREAD_ID = 31, /* external poll() management support */ - LWS_CALLBACK_ADD_POLL_FD, - LWS_CALLBACK_DEL_POLL_FD, - LWS_CALLBACK_CHANGE_MODE_POLL_FD, - LWS_CALLBACK_LOCK_POLL, - LWS_CALLBACK_UNLOCK_POLL, + LWS_CALLBACK_ADD_POLL_FD = 32, + LWS_CALLBACK_DEL_POLL_FD = 33, + LWS_CALLBACK_CHANGE_MODE_POLL_FD = 34, + LWS_CALLBACK_LOCK_POLL = 35, + LWS_CALLBACK_UNLOCK_POLL = 36, + + LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY = 37, + LWS_CALLBACK_WS_PEER_INITIATED_CLOSE = 38, + + LWS_CALLBACK_WS_EXT_DEFAULTS = 39, + + /****** add new things just above ---^ ******/ LWS_CALLBACK_USER = 1000, /* user code can use any including / above */ }; -// argument structure for all external poll related calls -// passed in via 'in' -struct libwebsocket_pollargs { - int fd; // applicable file descriptor - int events; // the new event mask - int prev_events; // the previous event mask -}; -#ifdef _WIN32 -struct libwebsocket_pollfd { - SOCKET fd; +#if defined(_WIN32) +typedef SOCKET lws_sockfd_type; +typedef HANDLE lws_filefd_type; +#define lws_sockfd_valid(sfd) (!!sfd) +struct lws_pollfd { + lws_sockfd_type fd; SHORT events; SHORT revents; }; #else -#define libwebsocket_pollfd pollfd + +#if defined(MBED_OPERATORS) +/* it's a class lws_conn * */ +typedef void * lws_sockfd_type; +typedef void * lws_filefd_type; +#define lws_sockfd_valid(sfd) (!!sfd) +struct pollfd { + lws_sockfd_type fd; + short events; + short revents; +}; +#define POLLIN 0x0001 +#define POLLPRI 0x0002 +#define POLLOUT 0x0004 +#define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 + +struct lws; + +void * mbed3_create_tcp_stream_socket(void); +void mbed3_delete_tcp_stream_socket(void *sockfd); +void mbed3_tcp_stream_bind(void *sock, int port, struct lws *); +void mbed3_tcp_stream_accept(void *sock, struct lws *); +#else +typedef int lws_sockfd_type; +typedef int lws_filefd_type; +#define lws_sockfd_valid(sfd) (sfd >= 0) #endif -enum libwebsocket_extension_callback_reasons { - LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT, - LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT, - LWS_EXT_CALLBACK_CONSTRUCT, - LWS_EXT_CALLBACK_CLIENT_CONSTRUCT, - LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE, - LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION, - LWS_EXT_CALLBACK_DESTROY, - LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING, - LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED, - LWS_EXT_CALLBACK_PACKET_RX_PREPARSE, - LWS_EXT_CALLBACK_PACKET_TX_PRESEND, - LWS_EXT_CALLBACK_PACKET_TX_DO_SEND, - LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX, - LWS_EXT_CALLBACK_FLUSH_PENDING_TX, - LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX, - LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION, - LWS_EXT_CALLBACK_1HZ, - LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE, - LWS_EXT_CALLBACK_IS_WRITEABLE, - LWS_EXT_CALLBACK_PAYLOAD_TX, - LWS_EXT_CALLBACK_PAYLOAD_RX, +#define lws_pollfd pollfd +#endif + +/* argument structure for all external poll related calls + * passed in via 'in' + */ +struct lws_pollargs { + lws_sockfd_type fd; /* applicable socket descriptor */ + int events; /* the new event mask */ + int prev_events; /* the previous event mask */ }; -enum libwebsocket_write_protocol { - LWS_WRITE_TEXT, - LWS_WRITE_BINARY, - LWS_WRITE_CONTINUATION, - LWS_WRITE_HTTP, +/** + * struct lws_plat_file_ops - Platform-specific file operations + * + * These provide platform-agnostic ways to deal with filesystem access in the + * library and in the user code. + * + * @open: Open file (always binary access if plat supports it) + * filelen is filled on exit to be the length of the file + * flags should be set to O_RDONLY or O_RDWR + * @close: Close file + * @seek_cur: Seek from current position + * @read: Read fron file *amount is set on exit to amount read + * @write: Write to file *amount is set on exit as amount written + */ +struct lws_plat_file_ops { + lws_filefd_type (*open)(struct lws *wsi, const char *filename, + unsigned long *filelen, int flags); + int (*close)(struct lws *wsi, lws_filefd_type fd); + unsigned long (*seek_cur)(struct lws *wsi, lws_filefd_type fd, + long offset_from_cur_pos); + int (*read)(struct lws *wsi, lws_filefd_type fd, unsigned long *amount, + unsigned char *buf, unsigned long len); + int (*write)(struct lws *wsi, lws_filefd_type fd, unsigned long *amount, + unsigned char *buf, unsigned long len); + + /* Add new things just above here ---^ + * This is part of the ABI, don't needlessly break compatibilty */ +}; + +/* + * 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_SERVER_CONTEXT_CONSTRUCT = 0, + LWS_EXT_CB_CLIENT_CONTEXT_CONSTRUCT = 1, + LWS_EXT_CB_SERVER_CONTEXT_DESTRUCT = 2, + LWS_EXT_CB_CLIENT_CONTEXT_DESTRUCT = 3, + LWS_EXT_CB_CONSTRUCT = 4, + LWS_EXT_CB_CLIENT_CONSTRUCT = 5, + LWS_EXT_CB_CHECK_OK_TO_REALLY_CLOSE = 6, + LWS_EXT_CB_CHECK_OK_TO_PROPOSE_EXTENSION = 7, + LWS_EXT_CB_DESTROY = 8, + LWS_EXT_CB_DESTROY_ANY_WSI_CLOSING = 9, + LWS_EXT_CB_ANY_WSI_ESTABLISHED = 10, + LWS_EXT_CB_PACKET_RX_PREPARSE = 11, + LWS_EXT_CB_PACKET_TX_PRESEND = 12, + LWS_EXT_CB_PACKET_TX_DO_SEND = 13, + LWS_EXT_CB_HANDSHAKE_REPLY_TX = 14, + LWS_EXT_CB_FLUSH_PENDING_TX = 15, + LWS_EXT_CB_EXTENDED_PAYLOAD_RX = 16, + LWS_EXT_CB_CAN_PROXY_CLIENT_CONNECTION = 17, + LWS_EXT_CB_1HZ = 18, + LWS_EXT_CB_REQUEST_ON_WRITEABLE = 19, + LWS_EXT_CB_IS_WRITEABLE = 20, + LWS_EXT_CB_PAYLOAD_TX = 21, + LWS_EXT_CB_PAYLOAD_RX = 22, + LWS_EXT_CB_OPTION_DEFAULT = 23, + LWS_EXT_CB_OPTION_SET = 24, + LWS_EXT_CB_OPTION_CONFIRM = 25, + + /****** add new things just above ---^ ******/ +}; + +/* + * 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, + LWS_WRITE_BINARY = 1, + LWS_WRITE_CONTINUATION = 2, + LWS_WRITE_HTTP = 3, /* special 04+ opcodes */ - LWS_WRITE_CLOSE, - LWS_WRITE_PING, - LWS_WRITE_PONG, + /* LWS_WRITE_CLOSE is handled by lws_close_reason() */ + LWS_WRITE_PING = 5, + LWS_WRITE_PONG = 6, + + /* Same as write_http but we know this write ends the transaction */ + LWS_WRITE_HTTP_FINAL = 7, + + /* HTTP2 */ + + LWS_WRITE_HTTP_HEADERS = 8, + + /****** add new things just above ---^ ******/ /* flags */ @@ -278,64 +506,111 @@ struct lws_tokens { int token_len; }; +/* + * don't forget to update test server header dump accordingly + * + * these have to be kept in sync with lextable.h / minilex.c + * + * NOTE: These public enums are part of the abi. If you want to add one, + * add it at where specified so existing users are unaffected. + */ enum lws_token_indexes { - WSI_TOKEN_GET_URI, - WSI_TOKEN_POST_URI, - WSI_TOKEN_OPTIONS_URI, - WSI_TOKEN_HOST, - WSI_TOKEN_CONNECTION, - WSI_TOKEN_KEY1, - WSI_TOKEN_KEY2, - WSI_TOKEN_PROTOCOL, - WSI_TOKEN_UPGRADE, - WSI_TOKEN_ORIGIN, - WSI_TOKEN_DRAFT, - WSI_TOKEN_CHALLENGE, + 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, - /* new for 04 */ - WSI_TOKEN_KEY, - WSI_TOKEN_VERSION, - WSI_TOKEN_SWORIGIN, + 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, - /* new for 05 */ - WSI_TOKEN_EXTENSIONS, + 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_PROXY, - /* client receives these */ - WSI_TOKEN_ACCEPT, - WSI_TOKEN_NONCE, - WSI_TOKEN_HTTP, + WSI_TOKEN_PATCH_URI = 73, + WSI_TOKEN_PUT_URI = 74, + WSI_TOKEN_DELETE_URI = 75, - /* http-related */ - WSI_TOKEN_HTTP_ACCEPT, - WSI_TOKEN_HTTP_AC_REQUEST_HEADERS, - WSI_TOKEN_HTTP_IF_MODIFIED_SINCE, - WSI_TOKEN_HTTP_IF_NONE_MATCH, - WSI_TOKEN_HTTP_ACCEPT_ENCODING, - WSI_TOKEN_HTTP_ACCEPT_LANGUAGE, - WSI_TOKEN_HTTP_PRAGMA, - WSI_TOKEN_HTTP_CACHE_CONTROL, - WSI_TOKEN_HTTP_AUTHORIZATION, - WSI_TOKEN_HTTP_COOKIE, - WSI_TOKEN_HTTP_CONTENT_LENGTH, - WSI_TOKEN_HTTP_CONTENT_TYPE, - WSI_TOKEN_HTTP_DATE, - WSI_TOKEN_HTTP_RANGE, - WSI_TOKEN_HTTP_REFERER, - WSI_TOKEN_HTTP_URI_ARGS, - - - WSI_TOKEN_MUXURL, + WSI_TOKEN_HTTP_URI_ARGS = 76, /* use token storage to stash these */ - _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_SENT_PROTOCOLS = 77, + _WSI_TOKEN_CLIENT_PEER_ADDRESS = 78, + _WSI_TOKEN_CLIENT_URI = 79, + _WSI_TOKEN_CLIENT_HOST = 80, + _WSI_TOKEN_CLIENT_ORIGIN = 81, + + /****** add new things just above ---^ ******/ /* always last real token index*/ WSI_TOKEN_COUNT, + /* parser state additions */ WSI_TOKEN_NAME_PART, WSI_TOKEN_SKIPPING, @@ -345,7 +620,7 @@ enum lws_token_indexes { }; struct lws_token_limits { - unsigned short token_limit[WSI_TOKEN_COUNT]; + unsigned short token_limit[WSI_TOKEN_COUNT]; }; /* @@ -437,28 +712,36 @@ struct lws_token_limits { (e.g., the server certificate can't be verified). */ +/* + * NOTE: These public enums are part of the abi. If you want to add one, + * add it at where specified so existing users are unaffected. + */ enum lws_close_status { - LWS_CLOSE_STATUS_NOSTATUS = 0, - LWS_CLOSE_STATUS_NORMAL = 1000, - LWS_CLOSE_STATUS_GOINGAWAY = 1001, - LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002, - LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003, - LWS_CLOSE_STATUS_RESERVED = 1004, - LWS_CLOSE_STATUS_NO_STATUS = 1005, - LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006, - LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007, - LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008, - LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009, - LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010, - LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011, - LWS_CLOSE_STATUS_TLS_FAILURE = 1015, + LWS_CLOSE_STATUS_NOSTATUS = 0, + LWS_CLOSE_STATUS_NORMAL = 1000, + LWS_CLOSE_STATUS_GOINGAWAY = 1001, + LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002, + LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003, + LWS_CLOSE_STATUS_RESERVED = 1004, + LWS_CLOSE_STATUS_NO_STATUS = 1005, + LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006, + LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007, + LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008, + LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009, + LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010, + LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011, + LWS_CLOSE_STATUS_TLS_FAILURE = 1015, + + /****** add new things just above ---^ ******/ + + LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY = 9999, }; enum http_status { - HTTP_STATUS_OK = 200, - HTTP_STATUS_NO_CONTENT = 204, + HTTP_STATUS_OK = 200, + HTTP_STATUS_NO_CONTENT = 204, - HTTP_STATUS_BAD_REQUEST = 400, + HTTP_STATUS_BAD_REQUEST = 400, HTTP_STATUS_UNAUTHORIZED, HTTP_STATUS_PAYMENT_REQUIRED, HTTP_STATUS_FORBIDDEN, @@ -477,7 +760,7 @@ enum http_status { HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE, HTTP_STATUS_EXPECTATION_FAILED, - HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, + HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, HTTP_STATUS_NOT_IMPLEMENTED, HTTP_STATUS_BAD_GATEWAY, HTTP_STATUS_SERVICE_UNAVAILABLE, @@ -485,14 +768,13 @@ enum http_status { HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED, }; -struct libwebsocket; -struct libwebsocket_context; +struct lws; +struct lws_context; /* needed even with extensions disabled for create context */ -struct libwebsocket_extension; +struct lws_extension; /** - * callback_function() - User server actions - * @context: Websockets context + * typedef lws_callback_function() - User server actions * @wsi: Opaque websocket instance pointer * @reason: The reason for the call * @user: Pointer to per-session user data allocated by library @@ -504,16 +786,21 @@ struct libwebsocket_extension; * * For each connection / session there is user data allocated that is * pointed to by "user". You set the size of this user data area when - * the library is initialized with libwebsocket_create_server. + * the library is initialized with lws_create_server. * * You get an opportunity to initialize user data when called back with * LWS_CALLBACK_ESTABLISHED reason. * * LWS_CALLBACK_ESTABLISHED: after the server completes a handshake with - * an incoming client + * an incoming client. If you built the library + * with ssl support, @in is a pointer to the + * ssl struct associated with the connection or + * NULL. * * LWS_CALLBACK_CLIENT_CONNECTION_ERROR: the request client connection has - * been unable to complete a handshake with the remote server + * been unable to complete a handshake with the remote server. If + * in is non-NULL, you can find an error string of length len where + * it points to. * * LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: this is the last chance for the * client user code to examine the http headers @@ -548,7 +835,7 @@ struct libwebsocket_extension; * for example, to send a script to the client * which will then open the websockets connection. * @in points to the URI path requested and - * libwebsockets_serve_http_file() makes it very + * 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 @@ -573,7 +860,7 @@ struct libwebsocket_extension; * * LWS_CALLBACK_CLIENT_WRITEABLE: * LWS_CALLBACK_SERVER_WRITEABLE: If you call - * libwebsocket_callback_on_writable() on a connection, you will + * lws_callback_on_writable() on a connection, you will * get one of these callbacks coming when the connection socket * is able to accept another write packet without blocking. * If it already was able to take another packet without blocking, @@ -591,7 +878,7 @@ struct libwebsocket_extension; * receiving anything. Because this happens immediately after the * network connection from the client, there's no websocket protocol * selected yet so this callback is issued only to protocol 0. - * + * * LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED: A new client just had * been connected, accepted, and instantiated into the pool. This * callback allows setting any relevant property to it. Because this @@ -637,6 +924,15 @@ struct libwebsocket_extension; * verify the validity of certificates returned by clients. @user * is the server's OpenSSL SSL_CTX* * + * LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY: if configured for + * including OpenSSL support but no private key file has been + * specified (ssl_private_key_filepath is NULL), this is called to + * allow the user to set the private key directly via libopenssl + * and perform further operations if required; this might be useful + * in situations where the private key is not directly accessible + * by the OS, for example if it is stored on a smartcard + * @user is the server's OpenSSL SSL_CTX* + * * LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION: if the * libwebsockets context was created with the option * LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this @@ -716,7 +1012,7 @@ struct libwebsocket_extension; * will be integrating libwebsockets sockets into an external polling * array. * - * For these calls, @in points to a struct libwebsocket_pollargs that + * For these calls, @in points to a struct lws_pollargs that * contains @fd, @events and @prev_events members * * LWS_CALLBACK_ADD_POLL_FD: libwebsocket deals with its poll() loop @@ -729,7 +1025,7 @@ struct libwebsocket_extension; * serving case. * This callback happens when a socket needs to be * added to the polling loop: @in points to a struct - * libwebsocket_pollargs; the @fd member of the struct is the file + * lws_pollargs; the @fd member of the struct is the file * descriptor, and @events contains the active events. * * If you are using the internal polling loop (the "service" @@ -737,13 +1033,13 @@ struct libwebsocket_extension; * * LWS_CALLBACK_DEL_POLL_FD: This callback happens when a socket descriptor * needs to be removed from an external polling array. @in is - * again the struct libwebsocket_pollargs containing the @fd member + * again the struct lws_pollargs containing the @fd member * to be removed. If you are using the internal polling * loop, you can just ignore it. * * LWS_CALLBACK_CHANGE_MODE_POLL_FD: This callback happens when * libwebsockets wants to modify the events for a connectiion. - * @in is the struct libwebsocket_pollargs with the @fd to change. + * @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 @@ -753,25 +1049,36 @@ struct libwebsocket_extension; * LWS_CALLBACK_UNLOCK_POLL: These allow the external poll changes driven * by libwebsockets 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_WS_PEER_INITIATED_CLOSE: + * The peer has sent an unsolicited Close WS packet. @in and + * @len are the optional close code (first 2 bytes, network + * order) and the optional additional information which is not + * defined in the standard, and may be a string or non-human- + * readble data. + * If you return 0 lws will echo the close and then close the + * connection. If you return nonzero lws will just close the + * connection. */ -LWS_VISIBLE LWS_EXTERN int callback(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len); +typedef int +lws_callback_function(struct lws *wsi, enum lws_callback_reasons reason, + void *user, void *in, size_t len); -typedef int (callback_function)(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len); - -#ifndef LWS_NO_EXTENSIONS /** - * extension_callback_function() - Hooks to allow extensions to operate + * typedef lws_extension_callback_function() - Hooks to allow extensions to operate * @context: Websockets context * @ext: This extension * @wsi: Opaque websocket instance pointer * @reason: The reason for the call - * @user: Pointer to per-session user data allocated by library + * @user: Pointer to ptr to per-session user data allocated by library * @in: Pointer used for some callback reasons * @len: Length set for some callback reasons * @@ -783,26 +1090,26 @@ typedef int (callback_function)(struct libwebsocket_context *context, * each active extension on each connection. That is what is pointed to * by the @user parameter. * - * LWS_EXT_CALLBACK_CONSTRUCT: called when the server has decided to + * LWS_EXT_CB_CONSTRUCT: called when the server has decided to * select this extension from the list provided by the client, * just before the server will send back the handshake accepting * the connection with this extension active. This gives the * extension a chance to initialize its connection context found * in @user. * - * LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: same as LWS_EXT_CALLBACK_CONSTRUCT + * LWS_EXT_CB_CLIENT_CONSTRUCT: same as LWS_EXT_CB_CONSTRUCT * but called when client is instantiating this extension. Some * extensions will work the same on client and server side and then * you can just merge handlers for both CONSTRUCTS. * - * LWS_EXT_CALLBACK_DESTROY: called when the connection the extension was + * LWS_EXT_CB_DESTROY: called when the connection the extension was * being used on is about to be closed and deallocated. It's the * last chance for the extension to deallocate anything it has * allocated in the user data (pointed to by @user) before the * user data is deleted. This same callback is used whether you * are in client or server instantiation context. * - * LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: when this extension was active on + * LWS_EXT_CB_PACKET_RX_PREPARSE: when this extension was active on * a connection, and a packet of data arrived at the connection, * it is passed to this callback to give the extension a chance to * change the data, eg, decompress it. @user is pointing to the @@ -814,33 +1121,28 @@ typedef int (callback_function)(struct libwebsocket_context *context, * a new buffer allocated in its private user context data and * set the pointed-to lws_tokens members to point to its buffer. * - * LWS_EXT_CALLBACK_PACKET_TX_PRESEND: this works the same way as - * LWS_EXT_CALLBACK_PACKET_RX_PREPARSE above, except it gives the + * LWS_EXT_CB_PACKET_TX_PRESEND: this works the same way as + * LWS_EXT_CB_PACKET_RX_PREPARSE above, except it gives the * extension a chance to change websocket data just before it will * be sent out. Using the same lws_token pointer scheme in @in, * the extension can change the buffer and the length to be * transmitted how it likes. Again if it wants to grow the * buffer safely, it should copy the data into its own buffer and * set the lws_tokens token pointer to it. + * + * LWS_EXT_CB_ARGS_VALIDATE: */ -LWS_VISIBLE LWS_EXTERN int extension_callback(struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len); - -typedef int (extension_callback_function)(struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len); -#endif +typedef int +lws_extension_callback_function(struct lws_context *context, + const struct lws_extension *ext, struct lws *wsi, + enum lws_extension_callback_reasons reason, + void *user, void *in, size_t len); /** - * struct libwebsocket_protocols - List of protocols and handlers server + * struct lws_protocols - List of protocols and handlers server * supports. * @name: Protocol name that must match the one given in the client - * Javascript new WebSocket(url, 'protocol') name + * Javascript new WebSocket(url, 'protocol') name. * @callback: The service callback used for this protocol. It allows the * service action for an entire protocol to be encapsulated in * the protocol-specific callback @@ -853,95 +1155,141 @@ typedef int (extension_callback_function)(struct libwebsocket_context *context, * you support. If the frame size is exceeded, there is no * error, but the buffer will spill to the user callback when * full, which you can detect by using - * libwebsockets_remaining_packet_payload(). Notice that you - * just talk about frame size here, the LWS_SEND_BUFFER_PRE_PADDING + * lws_remaining_packet_payload(). Notice that you + * just talk about frame size here, the LWS_PRE * and post-padding are automatically also allocated on top. - * @no_buffer_all_partial_tx: Leave at zero if you want the library to take - * care of all partial tx for you. It's useful if you only have - * small tx packets and the chance of any truncated send is small - * enough any additional malloc / buffering overhead is less - * painful than writing the code to deal with partial sends. For - * protocols where you stream big blocks, set to nonzero and use - * the return value from libwebsocket_write() to manage how much - * got send yourself. - * @owning_server: the server init call fills in this opaque pointer when - * registering this protocol with the server. - * @protocol_index: which protocol we are starting from zero + * @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. + * @user: User provided context data at the protocol level. + * Accessible via lws_get_protocol(wsi)->user + * This should not be confused with wsi->user, it is not the same. + * The library completely ignores any value in here. * * This structure represents one protocol supported by the server. An - * array of these structures is passed to libwebsocket_create_server() + * array of these structures is passed to lws_create_server() * allows as many protocols as you like to be handled by one server. + * + * The first protocol given has its callback used for user callbacks when + * there is no agreed protocol name, that's true during HTTP part of the + * connection and true if the client did not send a Protocol: header. */ -struct libwebsocket_protocols { +struct lws_protocols { const char *name; - callback_function *callback; + lws_callback_function *callback; size_t per_session_data_size; size_t rx_buffer_size; - int no_buffer_all_partial_tx; + unsigned int id; + void *user; - /* - * below are filled in on server init and can be left uninitialized, - * no need for user to use them directly either - */ - - struct libwebsocket_context *owning_server; - int protocol_index; + /* Add new things just above here ---^ + * This is part of the ABI, don't needlessly break compatibilty */ +}; + +enum lws_ext_options_types { + EXTARG_NONE, + EXTARG_DEC, + EXTARG_OPT_DEC + + /* Add new things just above here ---^ + * This is part of the ABI, don't needlessly break compatibilty */ }; -#ifndef LWS_NO_EXTENSIONS /** - * struct libwebsocket_extension - An extension we know how to cope with + * struct lws_ext_options - Option arguments to the extension. These are + * used in the negotiation at ws upgrade time. + * The helper function lws_ext_parse_options() + * uses these to generate callbacks * - * @name: Formal extension name, eg, "deflate-stream" + * @name: Option name, eg, "server_no_context_takeover" + * @type: What kind of args the option can take + */ +struct lws_ext_options { + const char *name; + enum lws_ext_options_types type; + + /* Add new things just above here ---^ + * This is part of the ABI, don't needlessly break compatibilty */ +}; + +struct lws_ext_option_arg { + int option_index; + const char *start; + int len; +}; + +/** + * struct lws_extension - An extension we know how to cope with + * + * @name: Formal extension name, eg, "permessage-deflate" * @callback: Service callback - * @per_session_data_size: Libwebsockets will auto-malloc this much - * memory for the use of the extension, a pointer - * to it comes in the @user callback parameter - * @per_context_private_data: Optional storage for this extension that - * is per-context, so it can track stuff across - * all sessions, etc, if it wants + * @client_offer: String containing exts and options client offers */ -struct libwebsocket_extension { +struct lws_extension { const char *name; - extension_callback_function *callback; - size_t per_session_data_size; - void *per_context_private_data; + lws_extension_callback_function *callback; + const char *client_offer; + + /* Add new things just above here ---^ + * This is part of the ABI, don't needlessly break compatibilty */ }; -#endif + +/* + * The internal exts are part of the public abi + * If we add more extensions, publish the callback here + */ + +extern int lws_extension_callback_pm_deflate( + struct lws_context *context, const struct lws_extension *ext, + struct lws *wsi, enum lws_extension_callback_reasons reason, + void *user, void *in, size_t len); + /** - * struct lws_context_creation_info: parameters to create context with + * struct lws_context_creation_info - parameters to create context with * - * @port: Port to listen on... you can use 0 to suppress listening on - * any port, that's what you want if you are not running a - * websocket server at all but just using it as a client + * @port: Port to listen on... you can use CONTEXT_PORT_NO_LISTEN to + * suppress listening on any port, that's what you want if you are + * not running a websocket server at all but just using it as a + * client * @iface: NULL to bind the listen socket to all interfaces, or the * interface name, eg, "eth2" * @protocols: Array of structures listing supported protocols and a protocol- * specific callback for each one. The list is ended with an * entry that has a NULL callback pointer. * It's not const because we write the owning_server member - * @extensions: NULL or array of libwebsocket_extension structs listing the + * @extensions: NULL or array of lws_extension structs listing the * extensions this context supports. If you configured with * --without-extensions, you should give NULL here. * @token_limits: NULL or struct lws_token_limits pointer which is initialized - * with a token length limit for each possible WSI_TOKEN_*** + * with a token length limit for each possible WSI_TOKEN_*** * @ssl_cert_filepath: If libwebsockets was compiled to use ssl, and you want * to listen using SSL, set to the filepath to fetch the * server cert from, otherwise NULL for unencrypted - * @ssl_private_key_filepath: filepath to private key if wanting SSL mode, - * else ignored + * @ssl_private_key_filepath: filepath to private key if wanting SSL mode; + * if this is set to NULL but sll_cert_filepath is set, the + * OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY callback is called + * to allow setting of the private key directly via openSSL + * library calls * @ssl_ca_filepath: CA certificate filepath or NULL * @ssl_cipher_list: List of valid ciphers to use (eg, * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" * or you can leave it as NULL to get "DEFAULT" + * @http_proxy_address: If non-NULL, attempts to proxy via the given address. + * If proxy auth is required, use format + * "username:password@server:port" + * @http_proxy_port: If http_proxy_address was non-NULL, uses this port at + * the address * @gid: group id to change to after setting listen socket, or -1. * @uid: user id to change to after setting listen socket, or -1. - * @options: 0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK + * @options: 0, or LWS_SERVER_OPTION_... bitfields * @user: optional user pointer that can be recovered via the context - * pointer using libwebsocket_context_user + * pointer using lws_context_user * @ka_time: 0 for no keepalive, otherwise apply this keepalive timeout to * all libwebsocket sockets, client or server * @ka_probes: if ka_time was nonzero, after the timeout expires how many @@ -949,14 +1297,26 @@ struct libwebsocket_extension { * and killing the connection * @ka_interval: if ka_time was nonzero, how long to wait before each ka_probes * attempt + * @provided_client_ssl_ctx: If non-null, swap out libwebsockets ssl + * implementation for the one provided by provided_ssl_ctx. + * Libwebsockets no longer is responsible for freeing the context + * if this option is selected. + * @max_http_header_data: The max amount of header payload that can be handled + * in an http request (unrecognized header payload is dropped) + * @max_http_header_pool: The max number of connections with http headers that + * can be processed simultaneously (the corresponding memory is + * allocated for the lifetime of the context). If the pool is + * busy new incoming connections must wait for accept until one + * becomes free. */ struct lws_context_creation_info { int port; const char *iface; - struct libwebsocket_protocols *protocols; - struct libwebsocket_extension *extensions; - struct lws_token_limits *token_limits; + const struct lws_protocols *protocols; + const struct lws_extension *extensions; + const struct lws_token_limits *token_limits; + const char *ssl_private_key_password; const char *ssl_cert_filepath; const char *ssl_private_key_filepath; const char *ssl_ca_filepath; @@ -970,204 +1330,365 @@ struct lws_context_creation_info { int ka_time; int ka_probes; int ka_interval; +#ifdef LWS_OPENSSL_SUPPORT + SSL_CTX *provided_client_ssl_ctx; +#else /* maintain structure layout either way */ + void *provided_client_ssl_ctx; +#endif + short max_http_header_data; + short max_http_header_pool; + + /* Add new things just above here ---^ + * This is part of the ABI, don't needlessly break compatibility + * + * The below is to ensure later library versions with new + * members added above will see 0 (default) even if the app + * was not built against the newer headers. + */ + + void *_unused[8]; }; -LWS_VISIBLE LWS_EXTERN -void lws_set_log_level(int level, - void (*log_emit_function)(int level, const char *line)); +/** + * struct lws_client_connect_info - parameters to connect with when using + * lws_client_connect_via_info() + * + * @context: lws context to create connection in + * @address: remote address to connect to + * @port: remote port to connect to + * @ssl_connection: nonzero for ssl + * @path: uri path + * @host: content of host header + * @origin: content of origin header + * @protocol: list of ws protocols + * @ietf_version_or_minus_one: currently leave at 0 or -1 + * @userdata: if non-NULL, use this as wsi user_data instead of malloc it + * @client_exts: array of extensions that may be used on connection + */ + +struct lws_client_connect_info { + struct lws_context *context; + const char *address; + int port; + int ssl_connection; + const char *path; + const char *host; + const char *origin; + const char *protocol; + int ietf_version_or_minus_one; + void *userdata; + const struct lws_extension *client_exts; + + /* Add new things just above here ---^ + * This is part of the ABI, don't needlessly break compatibility + * + * The below is to ensure later library versions with new + * members added above will see 0 (default) even if the app + * was not built against the newer headers. + */ + + void *_unused[4]; +}; + +LWS_VISIBLE LWS_EXTERN void +lws_set_log_level(int level, + void (*log_emit_function)(int level, const char *line)); LWS_VISIBLE LWS_EXTERN void lwsl_emit_syslog(int level, const char *line); -LWS_VISIBLE LWS_EXTERN struct libwebsocket_context * -libwebsocket_create_context(struct lws_context_creation_info *info); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_set_proxy(struct libwebsocket_context *context, const char *proxy); - -LWS_VISIBLE LWS_EXTERN void -libwebsocket_context_destroy(struct libwebsocket_context *context); +LWS_VISIBLE LWS_EXTERN struct lws_context * +lws_create_context(struct lws_context_creation_info *info); LWS_VISIBLE LWS_EXTERN int -libwebsocket_service(struct libwebsocket_context *context, int timeout_ms); +lws_set_proxy(struct lws_context *context, const char *proxy); LWS_VISIBLE LWS_EXTERN void -libwebsocket_cancel_service(struct libwebsocket_context *context); +lws_context_destroy(struct lws_context *context); + +LWS_VISIBLE LWS_EXTERN int +lws_service(struct lws_context *context, int timeout_ms); + +LWS_VISIBLE LWS_EXTERN void +lws_cancel_service(struct lws_context *context); + +LWS_VISIBLE LWS_EXTERN int +lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr, size_t addrlen); + +LWS_VISIBLE LWS_EXTERN const unsigned char * +lws_token_to_string(enum lws_token_indexes token); + +LWS_VISIBLE LWS_EXTERN int +lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name, + const unsigned char *value, int length, + unsigned char **p, unsigned char *end); +LWS_VISIBLE LWS_EXTERN int +lws_finalize_http_header(struct lws *wsi, unsigned char **p, + unsigned char *end); +LWS_VISIBLE LWS_EXTERN int +lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token, + const unsigned char *value, int length, + unsigned char **p, unsigned char *end); +LWS_VISIBLE LWS_EXTERN int +lws_add_http_header_content_length(struct lws *wsi, + unsigned long content_length, + unsigned char **p, unsigned char *end); +LWS_VISIBLE LWS_EXTERN int +lws_add_http_header_status(struct lws *wsi, + unsigned int code, unsigned char **p, + unsigned char *end); + +LWS_EXTERN int +lws_http_transaction_completed(struct lws *wsi); #ifdef LWS_USE_LIBEV +typedef void (lws_ev_signal_cb)(EV_P_ struct ev_signal *w, int revents); + LWS_VISIBLE LWS_EXTERN int -libwebsocket_initloop( - struct libwebsocket_context *context, struct ev_loop *loop); +lws_sigint_cfg(struct lws_context *context, int use_ev_sigint, + lws_ev_signal_cb *cb); + +LWS_VISIBLE LWS_EXTERN int +lws_initloop(struct lws_context *context, struct ev_loop *loop); LWS_VISIBLE void -libwebsocket_sigint_cb( - struct ev_loop *loop, struct ev_signal *watcher, int revents); +lws_sigint_cb(struct ev_loop *loop, struct ev_signal *watcher, int revents); #endif /* LWS_USE_LIBEV */ LWS_VISIBLE LWS_EXTERN int -libwebsocket_service_fd(struct libwebsocket_context *context, - struct libwebsocket_pollfd *pollfd); +lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd); LWS_VISIBLE LWS_EXTERN void * -libwebsocket_context_user(struct libwebsocket_context *context); +lws_context_user(struct lws_context *context); +LWS_VISIBLE LWS_EXTERN void * +lws_wsi_user(struct lws *wsi); + +/* + * NOTE: These public enums are part of the abi. If you want to add one, + * add it at where specified so existing users are unaffected. + */ enum pending_timeout { - NO_PENDING_TIMEOUT = 0, - PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, - PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE, - PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, - PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, - PENDING_TIMEOUT_AWAITING_PING, - PENDING_TIMEOUT_CLOSE_ACK, - PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE, - PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE, - PENDING_TIMEOUT_SSL_ACCEPT, - PENDING_TIMEOUT_HTTP_CONTENT, - PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND, + 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_AWAITING_EXTENSION_CONNECT_RESPONSE = 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, + + /****** add new things just above ---^ ******/ }; LWS_VISIBLE LWS_EXTERN void -libwebsocket_set_timeout(struct libwebsocket *wsi, - enum pending_timeout reason, int secs); +lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs); /* * IMPORTANT NOTICE! * - * When sending with websocket protocol (LWS_WRITE_TEXT or LWS_WRITE_BINARY) - * the send buffer has to have LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE - * buf, and LWS_SEND_BUFFER_POST_PADDING bytes valid AFTER (buf + len). + * When sending with websocket protocol + * + * LWS_WRITE_TEXT, + * LWS_WRITE_BINARY, + * LWS_WRITE_CONTINUATION, + * LWS_WRITE_PING, + * LWS_WRITE_PONG + * + * the send buffer has to have LWS_PRE bytes valid BEFORE + * the buffer pointer you pass to lws_write(). * * This allows us to add protocol info before and after the data, and send as * one packet on the network without payload copying, for maximum efficiency. * - * So for example you need this kind of code to use libwebsocket_write with a + * So for example you need this kind of code to use lws_write with a * 128-byte payload * - * char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING]; + * char buf[LWS_PRE + 128]; * * // fill your part of the buffer... for example here it's all zeros - * memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128); + * memset(&buf[LWS_PRE], 0, 128); * - * libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128, - * LWS_WRITE_TEXT); + * lws_write(wsi, &buf[LWS_PRE], 128, LWS_WRITE_TEXT); * - * When sending LWS_WRITE_HTTP, there is no protocol addition and you can just - * use the whole buffer without taking care of the above. + * When sending HTTP, with + * + * LWS_WRITE_HTTP, + * LWS_WRITE_HTTP_HEADERS + * LWS_WRITE_HTTP_FINAL + * + * there is no protocol data prepended, and don't need to take care about the + * LWS_PRE bytes valid before the buffer pointer. + * + * LWS_PRE is at least the frame nonce + 2 header + 8 length + * LWS_SEND_BUFFER_POST_PADDING is deprecated, it's now 0 and can be left off. + * The example apps no longer use it. + * + * Pad LWS_PRE to the CPU word size, so that word references + * to the address immediately after the padding won't cause an unaligned access + * error. Sometimes for performance reasons the recommended padding is even + * larger than sizeof(void *). */ -/* - * this is the frame nonce plus two header plus 8 length - * there's an additional two for mux extension per mux nesting level - * 2 byte prepend on close will already fit because control frames cannot use - * the big length style - */ +#if !defined(LWS_SIZEOFPTR) +#define LWS_SIZEOFPTR (sizeof (void *)) +#endif +#if !defined(u_int64_t) +#define u_int64_t unsigned long long +#endif -#define LWS_SEND_BUFFER_PRE_PADDING (4 + 10 + (2 * MAX_MUX_RECURSION)) -#define LWS_SEND_BUFFER_POST_PADDING 4 +#if __x86_64__ +#define _LWS_PAD_SIZE 16 /* Intel recommended for best performance */ +#else +#define _LWS_PAD_SIZE LWS_SIZEOFPTR /* Size of a pointer on the target arch */ +#endif +#define _LWS_PAD(n) (((n) % _LWS_PAD_SIZE) ? \ + ((n) + (_LWS_PAD_SIZE - ((n) % _LWS_PAD_SIZE))) : (n)) +#define LWS_PRE _LWS_PAD(4 + 10) +/* used prior to 1.7 and retained for backward compatibility */ +#define LWS_SEND_BUFFER_PRE_PADDING LWS_PRE +#define LWS_SEND_BUFFER_POST_PADDING 0 LWS_VISIBLE LWS_EXTERN int -libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len, - enum libwebsocket_write_protocol protocol); +lws_write(struct lws *wsi, unsigned char *buf, size_t len, + enum lws_write_protocol protocol); + +/** + * lws_close_reason - Set reason and aux data to send with Close packet + * If you are going to return nonzero from the callback + * requesting the connection to close, you can optionally + * call this to set the reason the peer will be told if + * possible. + * + * @wsi: The websocket connection to set the close reason on + * @status: A valid close status from websocket standard + * @buf: NULL or buffer containing up to 124 bytes of auxiliary data + * @len: Length of data in @buf to send + */ +LWS_VISIBLE LWS_EXTERN void +lws_close_reason(struct lws *wsi, enum lws_close_status status, + unsigned char *buf, size_t len); /* helper for case where buffer may be const */ -#define libwebsocket_write_http(wsi, buf, len) \ - libwebsocket_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP) +#define lws_write_http(wsi, buf, len) \ + lws_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP) LWS_VISIBLE LWS_EXTERN int -libwebsockets_serve_http_file(struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *file, - const char *content_type, const char *other_headers); +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 -libwebsockets_serve_http_file_fragment(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int libwebsockets_return_http_status( - struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned int code, - const char *html_body); - -LWS_VISIBLE LWS_EXTERN const struct libwebsocket_protocols * -libwebsockets_get_protocol(struct libwebsocket *wsi); +lws_serve_http_file_fragment(struct lws *wsi); LWS_VISIBLE LWS_EXTERN int -libwebsocket_callback_on_writable(struct libwebsocket_context *context, - struct libwebsocket *wsi); +lws_return_http_status(struct lws *wsi, unsigned int code, + const char *html_body); + +LWS_VISIBLE LWS_EXTERN const struct lws_protocols * +lws_get_protocol(struct lws *wsi); LWS_VISIBLE LWS_EXTERN int -libwebsocket_callback_on_writable_all_protocol( - const struct libwebsocket_protocols *protocol); +lws_callback_on_writable(struct lws *wsi); LWS_VISIBLE LWS_EXTERN int -libwebsocket_callback_all_protocol( - const struct libwebsocket_protocols *protocol, int reason); +lws_callback_on_writable_all_protocol(const struct lws_context *context, + const struct lws_protocols *protocol); LWS_VISIBLE LWS_EXTERN int -libwebsocket_get_socket_fd(struct libwebsocket *wsi); +lws_callback_all_protocol(struct lws_context *context, + const struct lws_protocols *protocol, int reason); LWS_VISIBLE LWS_EXTERN int -libwebsocket_is_final_fragment(struct libwebsocket *wsi); +lws_get_socket_fd(struct lws *wsi); + +LWS_VISIBLE LWS_EXTERN int +lws_is_final_fragment(struct lws *wsi); LWS_VISIBLE LWS_EXTERN unsigned char -libwebsocket_get_reserved_bits(struct libwebsocket *wsi); +lws_get_reserved_bits(struct lws *wsi); LWS_VISIBLE LWS_EXTERN int -libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable); +lws_rx_flow_control(struct lws *wsi, int enable); LWS_VISIBLE LWS_EXTERN void -libwebsocket_rx_flow_allow_all_protocol( - const struct libwebsocket_protocols *protocol); +lws_rx_flow_allow_all_protocol(const struct lws_context *context, + const struct lws_protocols *protocol); LWS_VISIBLE LWS_EXTERN size_t -libwebsockets_remaining_packet_payload(struct libwebsocket *wsi); +lws_remaining_packet_payload(struct lws *wsi); -LWS_VISIBLE LWS_EXTERN struct libwebsocket * -libwebsocket_client_connect(struct libwebsocket_context *clients, - const char *address, - int port, - int ssl_connection, - const char *path, - const char *host, - const char *origin, - const char *protocol, - int ietf_version_or_minus_one); +/* + * if the protocol does not have any guidance, returns -1. Currently only + * http2 connections get send window information from this API. But your code + * should use it so it can work properly with any protocol. + * + * If nonzero return is the amount of payload data the peer or intermediary has + * reported it has buffer space for. That has NO relationship with the amount + * of buffer space your OS can accept on this connection for a write action. + * + * This number represents the maximum you could send to the peer or intermediary + * on this connection right now without it complaining. + * + * lws manages accounting for send window updates and payload writes + * automatically, so this number reflects the situation at the peer or + * intermediary dynamically. + */ +LWS_VISIBLE LWS_EXTERN size_t +lws_get_peer_write_allowance(struct lws *wsi); -LWS_VISIBLE LWS_EXTERN struct libwebsocket * -libwebsocket_client_connect_extended(struct libwebsocket_context *clients, - const char *address, - int port, - int ssl_connection, - const char *path, - const char *host, - const char *origin, - const char *protocol, - int ietf_version_or_minus_one, - void *userdata); +/* deprecated, use lws_client_connect_via_info() */ +LWS_VISIBLE LWS_EXTERN struct lws * +lws_client_connect(struct lws_context *clients, const char *address, + int port, int ssl_connection, const char *path, + const char *host, const char *origin, const char *protocol, + int ietf_version_or_minus_one); +/* deprecated, use lws_client_connect_via_info() */ +LWS_VISIBLE LWS_EXTERN struct lws * +lws_client_connect_extended(struct lws_context *clients, const char *address, + int port, int ssl_connection, const char *path, + const char *host, const char *origin, + const char *protocol, int ietf_version_or_minus_one, + void *userdata); + +LWS_VISIBLE LWS_EXTERN struct lws * +lws_client_connect_via_info(struct lws_client_connect_info * ccinfo); LWS_VISIBLE LWS_EXTERN const char * -libwebsocket_canonical_hostname(struct libwebsocket_context *context); +lws_canonical_hostname(struct lws_context *context); LWS_VISIBLE LWS_EXTERN void -libwebsockets_get_peer_addresses(struct libwebsocket_context *context, - struct libwebsocket *wsi, int fd, char *name, int name_len, - char *rip, int rip_len); +lws_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name, + int name_len, char *rip, int rip_len); LWS_VISIBLE LWS_EXTERN int -libwebsockets_get_random(struct libwebsocket_context *context, - void *buf, int len); +lws_get_random(struct lws_context *context, void *buf, int len); LWS_VISIBLE LWS_EXTERN int lws_daemonize(const char *_lock_path); LWS_VISIBLE LWS_EXTERN int -lws_send_pipe_choked(struct libwebsocket *wsi); +lws_send_pipe_choked(struct lws *wsi); LWS_VISIBLE LWS_EXTERN int -lws_frame_is_binary(struct libwebsocket *wsi); +lws_partial_buffered(struct lws *wsi); +LWS_VISIBLE LWS_EXTERN int +lws_frame_is_binary(struct lws *wsi); + +LWS_VISIBLE LWS_EXTERN int +lws_is_ssl(struct lws *wsi); +#ifdef LWS_SHA1_USE_OPENSSL_NAME +#define lws_SHA1 SHA1 +#else LWS_VISIBLE LWS_EXTERN unsigned char * -libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md); +lws_SHA1(const unsigned char *d, size_t n, unsigned char *md); +#endif LWS_VISIBLE LWS_EXTERN int lws_b64_encode_string(const char *in, int in_len, char *out, int out_size); @@ -1178,29 +1699,131 @@ lws_b64_decode_string(const char *in, char *out, int out_size); LWS_VISIBLE LWS_EXTERN const char * lws_get_library_version(void); -/* access to headers... only valid while headers valid */ +LWS_VISIBLE LWS_EXTERN int +lws_parse_uri(char *p, const char **prot, const char **ads, int *port, + const char **path); + +/* + * Access to http headers + * + * In lws the client http headers are temporarily malloc'd only for the + * duration of the http part of the handshake. It's because in most cases, + * the header content is ignored for the whole rest of the connection lifetime + * and would then just be taking up space needlessly. + * + * During LWS_CALLBACK_HTTP when the URI path is delivered is the last time + * the http headers are still allocated, you can use these apis then to + * look at and copy out interesting header content (cookies, etc) + * + * Notice that the header total length reported does not include a terminating + * '\0', however you must allocate for it when using the _copy apis. So the + * length reported for a header containing "123" is 3, but you must provide + * a buffer of length 4 so that "123\0" may be copied into it, or the copy + * will fail with a nonzero return code. + */ LWS_VISIBLE LWS_EXTERN int -lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_indexes h); +lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h); LWS_VISIBLE LWS_EXTERN int -lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len, - enum lws_token_indexes h); +lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx); + +/* + * copies the whole, aggregated header, even if it was delivered in + * several actual headers piece by piece + */ +LWS_VISIBLE LWS_EXTERN int +lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h); + +/* + * copies only fragment frag_idx of a header. Normally this is only useful + * to parse URI arguments like ?x=1&y=2, oken index WSI_TOKEN_HTTP_URI_ARGS + * fragment 0 will contain "x=1" and fragment 1 "y=2" + */ +LWS_VISIBLE LWS_EXTERN int +lws_hdr_copy_fragment(struct lws *wsi, char *dest, int len, + enum lws_token_indexes h, int frag_idx); + + +/* get the active file operations struct */ +LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops * +lws_get_fops(struct lws_context *context); + +LWS_VISIBLE LWS_EXTERN struct lws_context * +lws_get_context(const struct lws *wsi); + +/* + * Wsi-associated File Operations access helpers + * + * Use these helper functions if you want to access a file from the perspective + * of a specific wsi, which is usually the case. If you just want contextless + * file access, use the fops callbacks directly with NULL wsi instead of these + * helpers. + * + * If so, then it calls the platform handler or user overrides where present + * (as defined in info->fops) + * + * The advantage from all this is user code can be portable for file operations + * without having to deal with differences between platforms. + */ + +static LWS_INLINE lws_filefd_type +lws_plat_file_open(struct lws *wsi, const char *filename, + unsigned long *filelen, int flags) +{ + return lws_get_fops(lws_get_context(wsi))->open(wsi, filename, + filelen, flags); +} + +static LWS_INLINE int +lws_plat_file_close(struct lws *wsi, lws_filefd_type fd) +{ + return lws_get_fops(lws_get_context(wsi))->close(wsi, fd); +} + +static LWS_INLINE unsigned long +lws_plat_file_seek_cur(struct lws *wsi, lws_filefd_type fd, long offset) +{ + return lws_get_fops(lws_get_context(wsi))->seek_cur(wsi, fd, offset); +} + +static LWS_INLINE int +lws_plat_file_read(struct lws *wsi, lws_filefd_type fd, unsigned long *amount, + unsigned char *buf, unsigned long len) +{ + return lws_get_fops(lws_get_context(wsi))->read(wsi, fd, amount, buf, + len); +} + +static LWS_INLINE int +lws_plat_file_write(struct lws *wsi, lws_filefd_type fd, unsigned long *amount, + unsigned char *buf, unsigned long len) +{ + return lws_get_fops(lws_get_context(wsi))->write(wsi, fd, amount, buf, + len); +} /* * Note: this is not normally needed as a user api. It's provided in case it is * useful when integrating with other app poll loop service code. */ - LWS_VISIBLE LWS_EXTERN int -libwebsocket_read(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned char *buf, size_t len); +lws_read(struct lws *wsi, unsigned char *buf, size_t len); #ifndef LWS_NO_EXTENSIONS -LWS_VISIBLE LWS_EXTERN struct libwebsocket_extension *libwebsocket_get_internal_extensions(); +/* deprecated */ +#define lws_get_internal_extensions() NULL +LWS_VISIBLE LWS_EXTERN int +lws_ext_parse_options(const struct lws_extension *ext, struct lws *wsi, + void *ext_user, const struct lws_ext_options *opts, const char *o, int len); #endif +/* + * custom allocator support + */ +LWS_VISIBLE LWS_EXTERN void +lws_set_allocator(void *(*realloc)(void *ptr, size_t size)); + #ifdef __cplusplus } #endif diff --git a/win32/include/websockets/lws_config.h b/win32/include/websockets/lws_config.h new file mode 100644 index 00000000..36a695ee --- /dev/null +++ b/win32/include/websockets/lws_config.h @@ -0,0 +1,74 @@ +/* lws_config.h Generated from lws_config.h.in */ + +#ifndef NDEBUG + #ifndef _DEBUG + #define _DEBUG + #endif +#endif + +/* Define to 1 to use wolfSSL/CyaSSL as a replacement for OpenSSL. + * LWS_OPENSSL_SUPPORT needs to be set also for this to work. */ +/* #undef USE_WOLFSSL */ + +/* Also define to 1 (in addition to USE_WOLFSSL) when using the + (older) CyaSSL library */ +/* #undef USE_OLD_CYASSL */ + +/* The Libwebsocket version */ +#define LWS_LIBRARY_VERSION "1.6.0" + +#define LWS_LIBRARY_VERSION_MAJOR 1 +#define LWS_LIBRARY_VERSION_MINOR 6 +#define LWS_LIBRARY_VERSION_PATCH 0 +/* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */ +#define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR*1000000)+(LWS_LIBRARY_VERSION_MINOR*1000)+LWS_LIBRARY_VERSION_PATCH + +/* The current git commit hash that we're building from */ +/* #undef LWS_BUILD_HASH */ + +/* Build with OpenSSL support */ +/* #undef LWS_OPENSSL_SUPPORT */ + +/* The client should load and trust CA root certs it finds in the OS */ +#define LWS_SSL_CLIENT_USE_OS_CA_CERTS + +/* Sets the path where the client certs should be installed. */ +#define LWS_OPENSSL_CLIENT_CERTS "../share" + +/* Turn off websocket extensions */ +/* #undef LWS_NO_EXTENSIONS */ + +/* Enable libev io loop */ +/* #undef LWS_USE_LIBEV */ + +/* Build with support for ipv6 */ +/* #undef LWS_USE_IPV6 */ + +/* Build with support for HTTP2 */ +/* #undef LWS_USE_HTTP2 */ + +/* Turn on latency measuring code */ +/* #undef LWS_LATENCY */ + +/* Don't build the daemonizeation api */ +#define LWS_NO_DAEMONIZE + +/* Build without server support */ +#define LWS_NO_SERVER + +/* Build without client support */ +/* #undef LWS_NO_CLIENT */ + +/* If we should compile with MinGW support */ +/* #undef LWS_MINGW_SUPPORT */ + +/* Use the BSD getifaddrs that comes with libwebsocket, for uclibc support */ +#define LWS_BUILTIN_GETIFADDRS + +/* use SHA1() not internal libwebsockets_SHA1 */ +/* #undef LWS_SHA1_USE_OPENSSL_NAME */ + +/* SSL server using ECDH certificate */ +/* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */ + + diff --git a/win32/include/websockets/win32helpers/getopt.h b/win32/include/websockets/win32helpers/getopt.h old mode 100644 new mode 100755 index 7137f037..5a88c2df --- a/win32/include/websockets/win32helpers/getopt.h +++ b/win32/include/websockets/win32helpers/getopt.h @@ -1,33 +1,33 @@ -#ifndef __GETOPT_H__ -#define __GETOPT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -extern int opterr; /* if error message should be printed */ -extern int optind; /* index into parent argv vector */ -extern int optopt; /* character checked for validity */ -extern int optreset; /* reset getopt */ -extern char *optarg; /* argument associated with option */ - -struct option -{ - const char *name; - int has_arg; - int *flag; - int val; -}; - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -int getopt(int, char**, char*); -int getopt_long(int, char**, char*, struct option*, int*); - -#ifdef __cplusplus -} -#endif - -#endif /* __GETOPT_H__ */ +#ifndef __GETOPT_H__ +#define __GETOPT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int opterr; /* if error message should be printed */ +extern int optind; /* index into parent argv vector */ +extern int optopt; /* character checked for validity */ +extern int optreset; /* reset getopt */ +extern char *optarg; /* argument associated with option */ + +struct option +{ + const char *name; + int has_arg; + int *flag; + int val; +}; + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +int getopt(int, char**, char*); +int getopt_long(int, char**, char*, struct option*, int*); + +#ifdef __cplusplus +} +#endif + +#endif /* __GETOPT_H__ */ diff --git a/win32/include/websockets/win32helpers/gettimeofday.h b/win32/include/websockets/win32helpers/gettimeofday.h old mode 100644 new mode 100755 diff --git a/win32/include/websockets/win32helpers/websock-w32.h b/win32/include/websockets/win32helpers/websock-w32.h old mode 100644 new mode 100755 diff --git a/win32/libs/websockets.dll b/win32/libs/websockets.dll deleted file mode 100644 index 83fb7ae1..00000000 Binary files a/win32/libs/websockets.dll and /dev/null differ diff --git a/win32/libs/websockets.lib b/win32/libs/websockets.lib index e3f13f63..8aba28ac 100644 Binary files a/win32/libs/websockets.lib and b/win32/libs/websockets.lib differ