lws_snprintf
[platform/upstream/libwebsockets.git] / lib / libwebsockets.h
index fc4fd02..a330ba1 100644 (file)
@@ -35,8 +35,9 @@ namespace {
 }
 using namespace mbed::Sockets::v0;
 
+
+struct sockaddr_in;
 struct lws;
-struct lws_context;
 
 class lws_conn {
        public:
@@ -95,6 +96,7 @@ extern "C" {
 #endif
 
 #ifdef MBED_OPERATORS
+struct sockaddr_in;
 #define LWS_POSIX 0
 #else
 #define LWS_POSIX 1
@@ -112,13 +114,24 @@ extern "C" {
 #include <stddef.h>
 #include <stdint.h>
 #include <basetsd.h>
+#ifndef _WIN32_WCE
 #include <fcntl.h>
+#else
+#define _O_RDONLY      0x0000
+#define O_RDONLY       _O_RDONLY
+#endif
 
+#ifdef _WIN32_WCE
+#define strcasecmp _stricmp
+#else
 #define strcasecmp stricmp
+#endif
 #define getdtablesize() 30000
 
 #define LWS_INLINE __inline
 #define LWS_VISIBLE
+#define LWS_WARN_UNUSED_RESULT
+#define LWS_WARN_DEPRECATED
 
 #ifdef LWS_DLL
 #ifdef LWS_INTERNAL
@@ -133,9 +146,15 @@ extern "C" {
 #define LWS_INVALID_FILE INVALID_HANDLE_VALUE
 #define LWS_O_RDONLY _O_RDONLY
 
+#define lws_snprintf _snprintf
+
 #else /* NOT WIN32 */
 #include <unistd.h>
 
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+#include <netinet/in.h>
+#endif
+
 #define LWS_INLINE inline
 #define LWS_O_RDONLY O_RDONLY
 
@@ -149,13 +168,25 @@ extern "C" {
 #endif
 
 #if defined(__GNUC__)
+
+/* warn_unused_result attribute only supported by GCC 3.4 or later */
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define LWS_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define LWS_WARN_UNUSED_RESULT
+#endif
+
 #define LWS_VISIBLE __attribute__((visibility("default")))
+#define LWS_WARN_DEPRECATED __attribute__ ((deprecated))
 #else
 #define LWS_VISIBLE
+#define LWS_WARN_UNUSED_RESULT
+#define LWS_WARN_DEPRECATED
 #endif
 
 #if defined(__ANDROID__)
-#define getdtablesize() 1024
+#include <unistd.h>
+#define getdtablesize() sysconf(_SC_OPEN_MAX)
 #endif
 
 #endif
@@ -163,6 +194,9 @@ extern "C" {
 #ifdef LWS_USE_LIBEV
 #include <ev.h>
 #endif /* LWS_USE_LIBEV */
+#ifdef LWS_USE_LIBUV
+#include <uv.h>
+#endif /* LWS_USE_LIBUV */
 
 #ifndef LWS_EXTERN
 #define LWS_EXTERN extern
@@ -272,6 +306,7 @@ enum lws_context_options {
        LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED                = (1 << 7),
        LWS_SERVER_OPTION_VALIDATE_UTF8                         = (1 << 8),
        LWS_SERVER_OPTION_SSL_ECDH                              = (1 << 9),
+       LWS_SERVER_OPTION_LIBUV                                 = (1 << 10),
 
        /****** add new things just above ---^ ******/
 };
@@ -410,7 +445,7 @@ struct lws_plat_file_ops {
                     unsigned char *buf, unsigned long len);
 
        /* Add new things just above here ---^
-        * This is part of the ABI, don't needlessly break compatibilty */
+        * This is part of the ABI, don't needlessly break compatibility */
 };
 
 /*
@@ -425,7 +460,7 @@ enum lws_extension_callback_reasons {
        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_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,
@@ -497,8 +532,6 @@ struct lws_tokens {
 };
 
 /*
- * 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,
@@ -580,28 +613,30 @@ enum lws_token_indexes {
        WSI_TOKEN_HTTP_VARY                                     = 70,
        WSI_TOKEN_HTTP_VIA                                      = 71,
        WSI_TOKEN_HTTP_WWW_AUTHENTICATE                         = 72,
-       WSI_TOKEN_PROXY,
 
        WSI_TOKEN_PATCH_URI                                     = 73,
        WSI_TOKEN_PUT_URI                                       = 74,
        WSI_TOKEN_DELETE_URI                                    = 75,
 
        WSI_TOKEN_HTTP_URI_ARGS                                 = 76,
+       WSI_TOKEN_PROXY                                         = 77,
+       WSI_TOKEN_HTTP_X_REAL_IP                                = 78,
 
-       /* use token storage to stash these */
+       /****** add new things just above ---^ ******/
 
-       _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,
+       /* use token storage to stash these internally, not for
+        * user use */
 
-       /****** add new things just above ---^ ******/
+       _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
+       _WSI_TOKEN_CLIENT_PEER_ADDRESS,
+       _WSI_TOKEN_CLIENT_URI,
+       _WSI_TOKEN_CLIENT_HOST,
+       _WSI_TOKEN_CLIENT_ORIGIN,
 
        /* always last real token index*/
        WSI_TOKEN_COUNT,
 
-       /* parser state additions */
+       /* parser state additions, no storage associated */
        WSI_TOKEN_NAME_PART,
        WSI_TOKEN_SKIPPING,
        WSI_TOKEN_SKIPPING_SAW_CR,
@@ -1177,7 +1212,7 @@ struct lws_protocols {
        void *user;
 
        /* Add new things just above here ---^
-        * This is part of the ABI, don't needlessly break compatibilty */
+        * This is part of the ABI, don't needlessly break compatibility */
 };
 
 enum lws_ext_options_types {
@@ -1186,7 +1221,7 @@ enum lws_ext_options_types {
        EXTARG_OPT_DEC
 
        /* Add new things just above here ---^
-        * This is part of the ABI, don't needlessly break compatibilty */
+        * This is part of the ABI, don't needlessly break compatibility */
 };
 
 /**
@@ -1203,7 +1238,7 @@ struct lws_ext_options {
        enum lws_ext_options_types type;
 
        /* Add new things just above here ---^
-        * This is part of the ABI, don't needlessly break compatibilty */
+        * This is part of the ABI, don't needlessly break compatibility */
 };
 
 struct lws_ext_option_arg {
@@ -1226,12 +1261,12 @@ struct lws_extension {
        const char *client_offer;
 
        /* Add new things just above here ---^
-        * This is part of the ABI, don't needlessly break compatibilty */
+        * This is part of the ABI, don't needlessly break compatibility */
 };
 
-/* 
+/*
  * The internal exts are part of the public abi
- * If we add more extensions, publish the callback here
+ * If we add more extensions, publish the callback here  ------v
  */
 
 extern int lws_extension_callback_pm_deflate(
@@ -1298,6 +1333,14 @@ extern int lws_extension_callback_pm_deflate(
  *             allocated for the lifetime of the context).  If the pool is
  *             busy new incoming connections must wait for accept until one
  *             becomes free.
+ * @count_threads: how many contexts to create in an array, 0 = 1
+ * @fd_limit_per_thread: nonzero means restrict each service thread to this
+ *             many fds, 0 means the default which is divide the process fd
+ *             limit by the number of threads.
+ * @timeout_secs: various processes involving network roundtrips in the
+ *             library are protected from hanging forever by timeouts.  If
+ *             nonzero, this member lets you set the timeout used in seconds.
+ *             Otherwise a default timeout is used.
  */
 
 struct lws_context_creation_info {
@@ -1329,6 +1372,10 @@ struct lws_context_creation_info {
        short max_http_header_data;
        short max_http_header_pool;
 
+       unsigned int count_threads;
+       unsigned int fd_limit_per_thread;
+       unsigned int timeout_secs;
+
        /* Add new things just above here ---^
         * This is part of the ABI, don't needlessly break compatibility
         *
@@ -1340,6 +1387,23 @@ struct lws_context_creation_info {
        void *_unused[8];
 };
 
+/**
+ * struct lws_client_connect_info - parameters to connect with when using
+ *                                 lws_client_connect_via_info()
+ *
+ * @context:   lws context to create connection in
+ * @address:   remote address to connect to
+ * @port:      remote port to connect to
+ * @ssl_connection: nonzero for ssl
+ * @path:      uri path
+ * @host:      content of host header
+ * @origin:    content of origin header
+ * @protocol:  list of ws protocols
+ * @ietf_version_or_minus_one: currently leave at 0 or -1
+ * @userdata:  if non-NULL, use this as wsi user_data instead of malloc it
+ * @client_exts: array of extensions that may be used on connection
+ */
+
 struct lws_client_connect_info {
        struct lws_context *context;
        const char *address;
@@ -1352,10 +1416,18 @@ struct lws_client_connect_info {
        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));
@@ -1375,9 +1447,19 @@ lws_context_destroy(struct lws_context *context);
 LWS_VISIBLE LWS_EXTERN int
 lws_service(struct lws_context *context, int timeout_ms);
 
+LWS_VISIBLE LWS_EXTERN int
+lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_cancel_service_pt(struct lws *wsi);
+
 LWS_VISIBLE LWS_EXTERN void
 lws_cancel_service(struct lws_context *context);
 
+LWS_VISIBLE LWS_EXTERN int
+lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr,
+                   size_t addrlen);
+
 LWS_VISIBLE LWS_EXTERN const unsigned char *
 lws_token_to_string(enum lws_token_indexes token);
 
@@ -1401,26 +1483,53 @@ lws_add_http_header_status(struct lws *wsi,
                           unsigned int code, unsigned char **p,
                           unsigned char *end);
 
-LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_http_transaction_completed(struct lws *wsi);
 
 #ifdef LWS_USE_LIBEV
-typedef void (lws_ev_signal_cb)(EV_P_ struct ev_signal *w, int revents);
+typedef void (lws_ev_signal_cb_t)(EV_P_ struct ev_signal *w, int revents);
 
 LWS_VISIBLE LWS_EXTERN int
-lws_sigint_cfg(struct lws_context *context, int use_ev_sigint,
-              lws_ev_signal_cb *cb);
+lws_ev_sigint_cfg(struct lws_context *context, int use_ev_sigint,
+                 lws_ev_signal_cb_t *cb);
 
 LWS_VISIBLE LWS_EXTERN int
-lws_initloop(struct lws_context *context, struct ev_loop *loop);
+lws_ev_initloop(struct lws_context *context, struct ev_loop *loop, int tsi);
 
 LWS_VISIBLE void
-lws_sigint_cb(struct ev_loop *loop, struct ev_signal *watcher, int revents);
+lws_ev_sigint_cb(struct ev_loop *loop, struct ev_signal *watcher, int revents);
 #endif /* LWS_USE_LIBEV */
 
+#ifdef LWS_USE_LIBUV
+typedef void (lws_uv_signal_cb_t)(uv_loop_t *l, uv_signal_t *w, int signum);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_uv_sigint_cfg(struct lws_context *context, int use_uv_sigint,
+                 lws_uv_signal_cb_t *cb);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_libuv_run(const struct lws_context *context, int tsi);
+
+LWS_VISIBLE void
+lws_libuv_stop(struct lws_context *context);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, uv_signal_cb cb, int tsi);
+
+LWS_VISIBLE LWS_EXTERN uv_loop_t *
+lws_uv_getloop(struct lws_context *context, int tsi);
+
+LWS_VISIBLE void
+lws_uv_sigint_cb(uv_loop_t *loop, uv_signal_t *watcher, int signum);
+#endif /* LWS_USE_LIBUV */
+
 LWS_VISIBLE LWS_EXTERN int
 lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd);
 
+LWS_VISIBLE LWS_EXTERN int
+lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd,
+                  int tsi);
+
 LWS_VISIBLE LWS_EXTERN void *
 lws_context_user(struct lws_context *context);
 
@@ -1445,6 +1554,7 @@ enum pending_timeout {
        PENDING_TIMEOUT_HTTP_CONTENT                            = 10,
        PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND                 = 11,
        PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE                  = 12,
+       PENDING_TIMEOUT_SHUTDOWN_FLUSH                          = 13,
 
        /****** add new things just above ---^ ******/
 };
@@ -1603,24 +1713,27 @@ lws_remaining_packet_payload(struct lws *wsi);
 LWS_VISIBLE LWS_EXTERN size_t
 lws_get_peer_write_allowance(struct lws *wsi);
 
-/* deprecated, use lws_client_connect_info() */
-LWS_VISIBLE LWS_EXTERN struct lws *
+/* deprecated, use lws_client_connect_via_info() */
+LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
 lws_client_connect(struct lws_context *clients, const char *address,
                   int port, int ssl_connection, const char *path,
                   const char *host, const char *origin, const char *protocol,
-                  int ietf_version_or_minus_one);
-/* deprecated, use lws_client_connect_info() */
-LWS_VISIBLE LWS_EXTERN struct lws *
+                  int ietf_version_or_minus_one) LWS_WARN_DEPRECATED;
+/* deprecated, use lws_client_connect_via_info() */
+LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
 lws_client_connect_extended(struct lws_context *clients, const char *address,
                            int port, int ssl_connection, const char *path,
                            const char *host, const char *origin,
                            const char *protocol, int ietf_version_or_minus_one,
-                           void *userdata);
+                           void *userdata) LWS_WARN_DEPRECATED;
 
-LWS_VISIBLE LWS_EXTERN struct lws *
+LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
 lws_client_connect_via_info(struct lws_client_connect_info * ccinfo);
 
-LWS_VISIBLE LWS_EXTERN const char *
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd);
+
+LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT
 lws_canonical_hostname(struct lws_context *context);
 
 
@@ -1631,16 +1744,16 @@ lws_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name,
 LWS_VISIBLE LWS_EXTERN int
 lws_get_random(struct lws_context *context, void *buf, int len);
 
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_daemonize(const char *_lock_path);
 
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_send_pipe_choked(struct lws *wsi);
 
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_partial_buffered(struct lws *wsi);
 
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_frame_is_binary(struct lws *wsi);
 
 LWS_VISIBLE LWS_EXTERN int
@@ -1658,9 +1771,13 @@ lws_b64_encode_string(const char *in, int in_len, char *out, int out_size);
 LWS_VISIBLE LWS_EXTERN int
 lws_b64_decode_string(const char *in, char *out, int out_size);
 
-LWS_VISIBLE LWS_EXTERN const char *
+LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT
 lws_get_library_version(void);
 
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_parse_uri(char *p, const char **prot, const char **ads, int *port,
+             const char **path);
+
 /*
  *  Access to http headers
  *
@@ -1680,10 +1797,10 @@ lws_get_library_version(void);
  *  will fail with a nonzero return code.
  */
 
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h);
 
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx);
 
 /*
@@ -1695,7 +1812,7 @@ 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
+ * to parse URI arguments like ?x=1&y=2, token index WSI_TOKEN_HTTP_URI_ARGS
  * fragment 0 will contain "x=1" and fragment 1 "y=2"
  */
 LWS_VISIBLE LWS_EXTERN int
@@ -1704,12 +1821,15 @@ lws_hdr_copy_fragment(struct lws *wsi, char *dest, int len,
 
 
 /* get the active file operations struct */
-LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops *
+LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops * LWS_WARN_UNUSED_RESULT
 lws_get_fops(struct lws_context *context);
 
-LWS_VISIBLE LWS_EXTERN struct lws_context *
+LWS_VISIBLE LWS_EXTERN struct lws_context * LWS_WARN_UNUSED_RESULT
 lws_get_context(const struct lws *wsi);
 
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_get_count_threads(struct lws_context *context);
+
 /*
  * Wsi-associated File Operations access helpers
  *
@@ -1725,7 +1845,7 @@ lws_get_context(const struct lws *wsi);
  * without having to deal with differences between platforms.
  */
 
-static LWS_INLINE lws_filefd_type
+static LWS_INLINE lws_filefd_type LWS_WARN_UNUSED_RESULT
 lws_plat_file_open(struct lws *wsi, const char *filename,
                   unsigned long *filelen, int flags)
 {
@@ -1745,7 +1865,7 @@ 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
+static LWS_INLINE int LWS_WARN_UNUSED_RESULT
 lws_plat_file_read(struct lws *wsi, lws_filefd_type fd, unsigned long *amount,
                   unsigned char *buf, unsigned long len)
 {
@@ -1753,7 +1873,7 @@ lws_plat_file_read(struct lws *wsi, lws_filefd_type fd, unsigned long *amount,
                                                        len);
 }
 
-static LWS_INLINE int
+static LWS_INLINE int LWS_WARN_UNUSED_RESULT
 lws_plat_file_write(struct lws *wsi, lws_filefd_type fd, unsigned long *amount,
                    unsigned char *buf, unsigned long len)
 {
@@ -1769,11 +1889,18 @@ LWS_VISIBLE LWS_EXTERN int
 lws_read(struct lws *wsi, unsigned char *buf, size_t len);
 
 #ifndef LWS_NO_EXTENSIONS
-/* deprecated */
-#define lws_get_internal_extensions() NULL
-LWS_VISIBLE LWS_EXTERN int
+/* Deprecated
+ *
+ * There is no longer a set internal extensions table.  The table is provided
+ * by user code along with application-specific settings.  See the test
+ * client and server for how to do.
+ */
+static LWS_INLINE LWS_WARN_DEPRECATED const struct lws_extension *
+lws_get_internal_extensions() { return NULL; }
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_ext_parse_options(const struct lws_extension *ext, struct lws *wsi,
-                      void *ext_user, const struct lws_ext_options *opts, const char *o, int len);
+                      void *ext_user, const struct lws_ext_options *opts,
+                      const char *o, int len);
 #endif
 
 /*
@@ -1782,6 +1909,20 @@ lws_ext_parse_options(const struct lws_extension *ext, struct lws *wsi,
 LWS_VISIBLE LWS_EXTERN void
 lws_set_allocator(void *(*realloc)(void *ptr, size_t size));
 
+/**
+ * lws_snprintf(): lws_snprintf that truncates the returned length too
+ *
+ * \param str: destination buffer
+ * \param size: bytes left in destination buffer
+ * \param format: format string
+ * \param ...: args for format
+ *
+ * This lets you correctly truncate buffers by concatenating lengths, if you
+ * reach the limit the reported length doesn't exceed the limit.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_snprintf(char *str, size_t size, const char *format, ...);
+
 #ifdef __cplusplus
 }
 #endif