Andy Green | a0da8a8 | 2010-11-08 17:12:19 +0000 | [diff] [blame] | 1 | /* |
| 2 | * libwebsockets - small server side websockets and web server implementation |
Andy Green | e77ddd8 | 2010-11-13 10:03:47 +0000 | [diff] [blame] | 3 | * |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 4 | * Copyright (C) 2010-2016 Andy Green <andy@warmcat.com> |
Andy Green | a0da8a8 | 2010-11-08 17:12:19 +0000 | [diff] [blame] | 5 | * |
| 6 | * This library is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU Lesser General Public |
| 8 | * License as published by the Free Software Foundation: |
| 9 | * version 2.1 of the License. |
| 10 | * |
| 11 | * This library is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | * Lesser General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU Lesser General Public |
| 17 | * License along with this library; if not, write to the Free Software |
| 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
| 19 | * MA 02110-1301 USA |
| 20 | */ |
| 21 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 22 | /** @file */ |
| 23 | |
Markus Elfring | 7521233 | 2013-10-26 20:23:00 +0800 | [diff] [blame] | 24 | #ifndef LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C |
| 25 | #define LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C |
Andy Green | ab990e4 | 2010-10-31 12:42:52 +0000 | [diff] [blame] | 26 | |
Andy Green | a11fe94 | 2011-09-25 10:30:26 +0100 | [diff] [blame] | 27 | #ifdef __cplusplus |
Paulo Roberto Urio | 4144e83 | 2012-06-04 09:04:33 +0800 | [diff] [blame] | 28 | #include <cstddef> |
José Luis Millán | 080e6dd | 2014-12-16 12:54:33 +0100 | [diff] [blame] | 29 | #include <cstdarg> |
Andy Green | 0aed7a0 | 2017-02-22 09:50:11 +0800 | [diff] [blame] | 30 | # |
Neil Horman | fc98f9a | 2014-12-13 14:15:48 +0800 | [diff] [blame] | 31 | extern "C" { |
Johan Simonsson | bb87ac8 | 2015-01-04 11:15:23 +0000 | [diff] [blame] | 32 | #else |
| 33 | #include <stdarg.h> |
Andy Green | a11fe94 | 2011-09-25 10:30:26 +0100 | [diff] [blame] | 34 | #endif |
wonder-mice | 41802c7 | 2015-04-22 00:16:57 -0700 | [diff] [blame] | 35 | |
Andy Green | 09f3947 | 2017-07-21 19:25:41 +0800 | [diff] [blame] | 36 | #include "lws_config.h" |
| 37 | |
| 38 | /* |
| 39 | * CARE: everything using cmake defines needs to be below here |
| 40 | */ |
Andy Green | 7262e14 | 2017-07-07 08:32:04 +0800 | [diff] [blame] | 41 | |
Andy Green | 0aed7a0 | 2017-02-22 09:50:11 +0800 | [diff] [blame] | 42 | #if defined(LWS_WITH_ESP8266) |
Andy Green | 5086597 | 2016-01-20 17:35:18 +0800 | [diff] [blame] | 43 | struct sockaddr_in; |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 44 | #define LWS_POSIX 0 |
| 45 | #else |
| 46 | #define LWS_POSIX 1 |
| 47 | #endif |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 48 | |
Andy Green | 09f3947 | 2017-07-21 19:25:41 +0800 | [diff] [blame] | 49 | #if defined(LWS_HAS_INTPTR_T) |
| 50 | #include <stdint.h> |
| 51 | #define lws_intptr_t intptr_t |
| 52 | #else |
| 53 | typedef unsigned long long lws_intptr_t; |
| 54 | #endif |
Andy Green | a11fe94 | 2011-09-25 10:30:26 +0100 | [diff] [blame] | 55 | |
Andreas Pakulat | 68bd4bd | 2013-10-28 15:18:04 +0100 | [diff] [blame] | 56 | #if defined(WIN32) || defined(_WIN32) |
Peter Hinz | 56885f3 | 2011-03-02 22:03:47 +0000 | [diff] [blame] | 57 | #ifndef WIN32_LEAN_AND_MEAN |
| 58 | #define WIN32_LEAN_AND_MEAN |
| 59 | #endif |
Andy Green | 00c6d15 | 2015-12-17 07:54:44 +0800 | [diff] [blame] | 60 | |
Peter Hinz | 56885f3 | 2011-03-02 22:03:47 +0000 | [diff] [blame] | 61 | #include <winsock2.h> |
| 62 | #include <ws2tcpip.h> |
Paulo Roberto Urio | 4144e83 | 2012-06-04 09:04:33 +0800 | [diff] [blame] | 63 | #include <stddef.h> |
pmcdona | 0a0a7eb | 2013-12-18 10:17:25 +0800 | [diff] [blame] | 64 | #include <basetsd.h> |
Ondraco | 442ae80 | 2016-02-29 18:48:55 +0800 | [diff] [blame] | 65 | #ifndef _WIN32_WCE |
Andy Green | 21da561 | 2015-12-10 13:21:07 +0800 | [diff] [blame] | 66 | #include <fcntl.h> |
Ondraco | 442ae80 | 2016-02-29 18:48:55 +0800 | [diff] [blame] | 67 | #else |
| 68 | #define _O_RDONLY 0x0000 |
| 69 | #define O_RDONLY _O_RDONLY |
| 70 | #endif |
Peter Hinz | 56885f3 | 2011-03-02 22:03:47 +0000 | [diff] [blame] | 71 | |
OndraCo | 624b23d | 2016-05-05 12:57:11 +0200 | [diff] [blame] | 72 | // Visual studio older than 2015 and WIN_CE has only _stricmp |
| 73 | #if (defined(_MSC_VER) && _MSC_VER < 1900) || defined(_WIN32_WCE) |
Ondraco | 442ae80 | 2016-02-29 18:48:55 +0800 | [diff] [blame] | 74 | #define strcasecmp _stricmp |
Rainer Poisel | d2cef15 | 2016-11-07 21:36:05 +0100 | [diff] [blame] | 75 | #elif !defined(__MINGW32__) |
Oleg Golosovskiy | 2ef7505 | 2011-10-04 20:20:14 +0800 | [diff] [blame] | 76 | #define strcasecmp stricmp |
Ondraco | 442ae80 | 2016-02-29 18:48:55 +0800 | [diff] [blame] | 77 | #endif |
Andy Green | dfb2304 | 2013-01-17 12:26:48 +0800 | [diff] [blame] | 78 | #define getdtablesize() 30000 |
Oleg Golosovskiy | 2ef7505 | 2011-10-04 20:20:14 +0800 | [diff] [blame] | 79 | |
Andy Green | 8a97c06 | 2015-12-16 15:02:47 +0800 | [diff] [blame] | 80 | #define LWS_INLINE __inline |
Andy Green | 3661d7b | 2013-04-26 07:37:16 +0800 | [diff] [blame] | 81 | #define LWS_VISIBLE |
Andy Green | cb17ad8 | 2016-01-21 10:56:20 +0800 | [diff] [blame] | 82 | #define LWS_WARN_UNUSED_RESULT |
Andy Green | 4939a70 | 2016-02-02 09:02:24 +0800 | [diff] [blame] | 83 | #define LWS_WARN_DEPRECATED |
Martin Milata | be1f0a3 | 2017-02-04 13:09:00 +0100 | [diff] [blame] | 84 | #define LWS_FORMAT(string_index) |
Andy Green | 3661d7b | 2013-04-26 07:37:16 +0800 | [diff] [blame] | 85 | |
David Galeano | 9454e21 | 2011-09-26 12:17:20 +0100 | [diff] [blame] | 86 | #ifdef LWS_DLL |
| 87 | #ifdef LWS_INTERNAL |
| 88 | #define LWS_EXTERN extern __declspec(dllexport) |
| 89 | #else |
| 90 | #define LWS_EXTERN extern __declspec(dllimport) |
| 91 | #endif |
Andy Green | 3661d7b | 2013-04-26 07:37:16 +0800 | [diff] [blame] | 92 | #else |
| 93 | #define LWS_EXTERN |
David Galeano | 9454e21 | 2011-09-26 12:17:20 +0100 | [diff] [blame] | 94 | #endif |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 95 | |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 96 | #define LWS_INVALID_FILE INVALID_HANDLE_VALUE |
Andy Green | cca0d7d | 2015-12-10 13:03:10 +0800 | [diff] [blame] | 97 | #define LWS_O_RDONLY _O_RDONLY |
Joel Winarske | 991f6ec | 2017-04-19 14:55:21 -0700 | [diff] [blame] | 98 | #define LWS_O_WRONLY _O_WRONLY |
| 99 | #define LWS_O_CREAT _O_CREAT |
| 100 | #define LWS_O_TRUNC _O_TRUNC |
David Galeano | 9454e21 | 2011-09-26 12:17:20 +0100 | [diff] [blame] | 101 | |
Rainer Poisel | d2cef15 | 2016-11-07 21:36:05 +0100 | [diff] [blame] | 102 | #if !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER < 1900) /* Visual Studio 2015 already defines this in <stdio.h> */ |
Andy Green | a496700 | 2016-09-15 02:22:57 +0800 | [diff] [blame] | 103 | #define lws_snprintf _snprintf |
Lucas Terra | 1759e32 | 2016-04-18 16:15:37 -0300 | [diff] [blame] | 104 | #endif |
Meir Yanovich | efcf496 | 2016-04-08 16:11:27 +0800 | [diff] [blame] | 105 | |
Andy Green | bf31c1b | 2016-05-13 08:20:12 +0800 | [diff] [blame] | 106 | #ifndef __func__ |
| 107 | #define __func__ __FUNCTION__ |
| 108 | #endif |
| 109 | |
Renyaow | 4ae029c | 2017-04-05 01:55:38 +0800 | [diff] [blame] | 110 | #if !defined(__MINGW32__) &&(!defined(_MSC_VER) || _MSC_VER < 1900) && !defined(snprintf) |
| 111 | #define snprintf(buf,len, format,...) _snprintf_s(buf, len,len, format, __VA_ARGS__) |
| 112 | #endif |
| 113 | |
Andy Green | 510c3c8 | 2015-12-10 07:50:51 +0800 | [diff] [blame] | 114 | #else /* NOT WIN32 */ |
Andy Green | dfb2304 | 2013-01-17 12:26:48 +0800 | [diff] [blame] | 115 | #include <unistd.h> |
Andy Green | 156363f | 2017-06-07 06:10:02 +0800 | [diff] [blame] | 116 | #if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) |
| 117 | #include <sys/capability.h> |
| 118 | #endif |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 119 | |
hgrundy | d02028b | 2016-04-21 17:20:10 +0800 | [diff] [blame] | 120 | #if defined(__NetBSD__) || defined(__FreeBSD__) |
Andy Green | c049589 | 2016-02-27 09:34:28 +0800 | [diff] [blame] | 121 | #include <netinet/in.h> |
| 122 | #endif |
| 123 | |
Andy Green | 8a97c06 | 2015-12-16 15:02:47 +0800 | [diff] [blame] | 124 | #define LWS_INLINE inline |
Andy Green | cca0d7d | 2015-12-10 13:03:10 +0800 | [diff] [blame] | 125 | #define LWS_O_RDONLY O_RDONLY |
Joel Winarske | 991f6ec | 2017-04-19 14:55:21 -0700 | [diff] [blame] | 126 | #define LWS_O_WRONLY O_WRONLY |
| 127 | #define LWS_O_CREAT O_CREAT |
| 128 | #define LWS_O_TRUNC O_TRUNC |
Andy Green | 5f2a815 | 2015-11-02 08:21:08 +0800 | [diff] [blame] | 129 | |
Andy Green | 0aed7a0 | 2017-02-22 09:50:11 +0800 | [diff] [blame] | 130 | #if !defined(LWS_WITH_ESP8266) && !defined(OPTEE_TA) && !defined(LWS_WITH_ESP32) |
Andy Green | 5f2a815 | 2015-11-02 08:21:08 +0800 | [diff] [blame] | 131 | #include <poll.h> |
Andy Green | 7e37d10 | 2015-01-28 21:03:49 +0800 | [diff] [blame] | 132 | #include <netdb.h> |
Andy Green | 1fa7685 | 2015-12-14 11:17:16 +0800 | [diff] [blame] | 133 | #define LWS_INVALID_FILE -1 |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 134 | #else |
Andy Green | 102d40e | 2017-03-11 11:51:06 +0800 | [diff] [blame] | 135 | #define getdtablesize() (30) |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 136 | #if defined(LWS_WITH_ESP32) |
Andy Green | 1fa7685 | 2015-12-14 11:17:16 +0800 | [diff] [blame] | 137 | #define LWS_INVALID_FILE NULL |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 138 | #else |
| 139 | #define LWS_INVALID_FILE NULL |
| 140 | #endif |
Andy Green | 5f2a815 | 2015-11-02 08:21:08 +0800 | [diff] [blame] | 141 | #endif |
Peter Pentchev | 9a4fef7 | 2013-03-30 09:52:21 +0800 | [diff] [blame] | 142 | |
| 143 | #if defined(__GNUC__) |
Patrick Farrell | 72e0e2a | 2016-04-05 16:59:07 -0400 | [diff] [blame] | 144 | |
| 145 | /* warn_unused_result attribute only supported by GCC 3.4 or later */ |
| 146 | #if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) |
| 147 | #define LWS_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) |
| 148 | #else |
| 149 | #define LWS_WARN_UNUSED_RESULT |
| 150 | #endif |
| 151 | |
Peter Pentchev | 9a4fef7 | 2013-03-30 09:52:21 +0800 | [diff] [blame] | 152 | #define LWS_VISIBLE __attribute__((visibility("default"))) |
Andy Green | 4939a70 | 2016-02-02 09:02:24 +0800 | [diff] [blame] | 153 | #define LWS_WARN_DEPRECATED __attribute__ ((deprecated)) |
Martin Milata | be1f0a3 | 2017-02-04 13:09:00 +0100 | [diff] [blame] | 154 | #define LWS_FORMAT(string_index) __attribute__ ((format(printf, string_index, string_index+1))) |
Peter Pentchev | 9a4fef7 | 2013-03-30 09:52:21 +0800 | [diff] [blame] | 155 | #else |
| 156 | #define LWS_VISIBLE |
Andy Green | e99a83c | 2016-01-20 16:56:06 +0800 | [diff] [blame] | 157 | #define LWS_WARN_UNUSED_RESULT |
Andy Green | 4939a70 | 2016-02-02 09:02:24 +0800 | [diff] [blame] | 158 | #define LWS_WARN_DEPRECATED |
Martin Milata | be1f0a3 | 2017-02-04 13:09:00 +0100 | [diff] [blame] | 159 | #define LWS_FORMAT(string_index) |
Peter Pentchev | 9a4fef7 | 2013-03-30 09:52:21 +0800 | [diff] [blame] | 160 | #endif |
| 161 | |
Krishnaraj R Bhat | 1662c62 | 2015-10-28 21:02:04 +0530 | [diff] [blame] | 162 | #if defined(__ANDROID__) |
Dan Albert | cd5e7bf | 2016-02-11 16:13:27 -0800 | [diff] [blame] | 163 | #include <unistd.h> |
| 164 | #define getdtablesize() sysconf(_SC_OPEN_MAX) |
Krishnaraj R Bhat | 1662c62 | 2015-10-28 21:02:04 +0530 | [diff] [blame] | 165 | #endif |
| 166 | |
Peter Hinz | 56885f3 | 2011-03-02 22:03:47 +0000 | [diff] [blame] | 167 | #endif |
Andy Green | 9f99034 | 2011-02-12 11:57:45 +0000 | [diff] [blame] | 168 | |
Andrew Canaday | 9769f4f | 2014-03-23 13:25:07 +0800 | [diff] [blame] | 169 | #ifdef LWS_USE_LIBEV |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 170 | #include <ev.h> |
Andrew Canaday | 9769f4f | 2014-03-23 13:25:07 +0800 | [diff] [blame] | 171 | #endif /* LWS_USE_LIBEV */ |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 172 | #ifdef LWS_USE_LIBUV |
| 173 | #include <uv.h> |
Andy Green | 4cfe81d | 2016-10-05 13:49:46 +0800 | [diff] [blame] | 174 | #ifdef LWS_HAVE_UV_VERSION_H |
| 175 | #include <uv-version.h> |
| 176 | #endif |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 177 | #endif /* LWS_USE_LIBUV */ |
Aditya Tirumala | ec50eba | 2017-03-15 19:41:11 +0530 | [diff] [blame] | 178 | #ifdef LWS_USE_LIBEVENT |
| 179 | #include <event2/event.h> |
| 180 | #endif /* LWS_USE_LIBEVENT */ |
Andrew Canaday | 9769f4f | 2014-03-23 13:25:07 +0800 | [diff] [blame] | 181 | |
David Galeano | 9454e21 | 2011-09-26 12:17:20 +0100 | [diff] [blame] | 182 | #ifndef LWS_EXTERN |
| 183 | #define LWS_EXTERN extern |
| 184 | #endif |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 185 | |
Andy Green | 158e804 | 2014-04-02 14:25:10 +0800 | [diff] [blame] | 186 | #ifdef _WIN32 |
| 187 | #define random rand |
| 188 | #else |
Andy Green | 51c96d8 | 2017-01-17 07:01:02 +0800 | [diff] [blame] | 189 | #if !defined(OPTEE_TA) |
Andy Green | 158e804 | 2014-04-02 14:25:10 +0800 | [diff] [blame] | 190 | #include <sys/time.h> |
| 191 | #include <unistd.h> |
| 192 | #endif |
Andy Green | 51c96d8 | 2017-01-17 07:01:02 +0800 | [diff] [blame] | 193 | #endif |
David Galeano | 9454e21 | 2011-09-26 12:17:20 +0100 | [diff] [blame] | 194 | |
joseph.urciuoli | 4d9c8fc | 2014-10-16 08:53:19 +0800 | [diff] [blame] | 195 | #ifdef LWS_OPENSSL_SUPPORT |
Andy Green | 1a3f177 | 2016-03-28 19:58:02 +0800 | [diff] [blame] | 196 | |
Alexander Bruines | c3bcb89 | 2015-08-08 18:54:49 +0200 | [diff] [blame] | 197 | #ifdef USE_WOLFSSL |
ABruines | 80a7068 | 2015-08-09 22:56:32 +0200 | [diff] [blame] | 198 | #ifdef USE_OLD_CYASSL |
| 199 | #include <cyassl/openssl/ssl.h> |
Andy Green | 1a3f177 | 2016-03-28 19:58:02 +0800 | [diff] [blame] | 200 | #include <cyassl/error-ssl.h> |
ABruines | 80a7068 | 2015-08-09 22:56:32 +0200 | [diff] [blame] | 201 | #else |
Alexander Bruines | c3bcb89 | 2015-08-08 18:54:49 +0200 | [diff] [blame] | 202 | #include <wolfssl/openssl/ssl.h> |
Andy Green | 1a3f177 | 2016-03-28 19:58:02 +0800 | [diff] [blame] | 203 | #include <wolfssl/error-ssl.h> |
ABruines | 80a7068 | 2015-08-09 22:56:32 +0200 | [diff] [blame] | 204 | #endif /* not USE_OLD_CYASSL */ |
joseph.urciuoli | 4d9c8fc | 2014-10-16 08:53:19 +0800 | [diff] [blame] | 205 | #else |
| 206 | #include <openssl/ssl.h> |
Juraj Vijtiuk | 41909ea | 2017-08-28 20:22:20 +0800 | [diff] [blame] | 207 | #if !defined(LWS_USE_MBEDTLS) |
Andy Green | 451cee5 | 2016-04-17 11:28:43 +0800 | [diff] [blame] | 208 | #include <openssl/err.h> |
Andy Green | 3a09c3b | 2017-03-08 11:11:41 +0800 | [diff] [blame] | 209 | #endif |
Alexander Bruines | c3bcb89 | 2015-08-08 18:54:49 +0200 | [diff] [blame] | 210 | #endif /* not USE_WOLFSSL */ |
joseph.urciuoli | 4d9c8fc | 2014-10-16 08:53:19 +0800 | [diff] [blame] | 211 | #endif |
| 212 | |
Andy Green | 1a3f177 | 2016-03-28 19:58:02 +0800 | [diff] [blame] | 213 | |
Andrew Canaday | 9769f4f | 2014-03-23 13:25:07 +0800 | [diff] [blame] | 214 | #define CONTEXT_PORT_NO_LISTEN -1 |
Alan Conway | f3ad954 | 2016-12-21 09:32:44 +0800 | [diff] [blame] | 215 | #define CONTEXT_PORT_NO_LISTEN_SERVER -2 |
Andy Green | bfb051f | 2011-02-09 08:49:14 +0000 | [diff] [blame] | 216 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 217 | /** \defgroup log Logging |
| 218 | * |
| 219 | * ##Logging |
| 220 | * |
| 221 | * Lws provides flexible and filterable logging facilities, which can be |
| 222 | * used inside lws and in user code. |
| 223 | * |
| 224 | * Log categories may be individually filtered bitwise, and directed to built-in |
| 225 | * sinks for syslog-compatible logging, or a user-defined function. |
| 226 | */ |
| 227 | ///@{ |
| 228 | |
Andy Green | 43db045 | 2013-01-10 19:50:35 +0800 | [diff] [blame] | 229 | enum lws_log_levels { |
| 230 | LLL_ERR = 1 << 0, |
| 231 | LLL_WARN = 1 << 1, |
Andy Green | 7c19c34 | 2013-01-19 12:18:07 +0800 | [diff] [blame] | 232 | LLL_NOTICE = 1 << 2, |
| 233 | LLL_INFO = 1 << 3, |
| 234 | LLL_DEBUG = 1 << 4, |
| 235 | LLL_PARSER = 1 << 5, |
| 236 | LLL_HEADER = 1 << 6, |
| 237 | LLL_EXT = 1 << 7, |
| 238 | LLL_CLIENT = 1 << 8, |
Andy Green | d636e35 | 2013-01-29 12:36:17 +0800 | [diff] [blame] | 239 | LLL_LATENCY = 1 << 9, |
Andy Green | c220864 | 2017-01-31 10:50:15 +0800 | [diff] [blame] | 240 | LLL_USER = 1 << 10, |
Andy Green | 43db045 | 2013-01-10 19:50:35 +0800 | [diff] [blame] | 241 | |
Andy Green | c220864 | 2017-01-31 10:50:15 +0800 | [diff] [blame] | 242 | LLL_COUNT = 11 /* set to count of valid flags */ |
Andy Green | 43db045 | 2013-01-10 19:50:35 +0800 | [diff] [blame] | 243 | }; |
| 244 | |
Martin Milata | be1f0a3 | 2017-02-04 13:09:00 +0100 | [diff] [blame] | 245 | LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...) LWS_FORMAT(2); |
Neal Horman | 98e491f | 2014-12-10 18:50:28 -0600 | [diff] [blame] | 246 | LWS_VISIBLE LWS_EXTERN void _lws_logv(int filter, const char *format, va_list vl); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 247 | /** |
| 248 | * lwsl_timestamp: generate logging timestamp string |
| 249 | * |
| 250 | * \param level: logging level |
| 251 | * \param p: char * buffer to take timestamp |
| 252 | * \param len: length of p |
| 253 | * |
| 254 | * returns length written in p |
| 255 | */ |
Andy Green | d61bed3 | 2016-02-25 15:01:55 +0800 | [diff] [blame] | 256 | LWS_VISIBLE LWS_EXTERN int |
| 257 | lwsl_timestamp(int level, char *p, int len); |
Andy Green | 69e4364 | 2013-01-19 11:58:07 +0800 | [diff] [blame] | 258 | |
Andy Green | c220864 | 2017-01-31 10:50:15 +0800 | [diff] [blame] | 259 | /* these guys are unconditionally included */ |
| 260 | |
Andy Green | 69e4364 | 2013-01-19 11:58:07 +0800 | [diff] [blame] | 261 | #define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__) |
Andy Green | c220864 | 2017-01-31 10:50:15 +0800 | [diff] [blame] | 262 | #define lwsl_user(...) _lws_log(LLL_USER, __VA_ARGS__) |
Andy Green | 7acf76c | 2016-07-23 14:18:25 +0800 | [diff] [blame] | 263 | |
| 264 | #if !defined(LWS_WITH_NO_LOGS) |
Andy Green | c220864 | 2017-01-31 10:50:15 +0800 | [diff] [blame] | 265 | /* notice and warn are usually included by being compiled in */ |
Andy Green | 7acf76c | 2016-07-23 14:18:25 +0800 | [diff] [blame] | 266 | #define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) |
| 267 | #define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) |
| 268 | #endif |
Andy Green | 69e4364 | 2013-01-19 11:58:07 +0800 | [diff] [blame] | 269 | /* |
Andy Green | c220864 | 2017-01-31 10:50:15 +0800 | [diff] [blame] | 270 | * weaker logging can be deselected by telling CMake to build in RELEASE mode |
Andy Green | 69e4364 | 2013-01-19 11:58:07 +0800 | [diff] [blame] | 271 | * that gets rid of the overhead of checking while keeping _warn and _err |
| 272 | * active |
| 273 | */ |
Andy Green | d636e35 | 2013-01-29 12:36:17 +0800 | [diff] [blame] | 274 | |
Andy Green | 7acf76c | 2016-07-23 14:18:25 +0800 | [diff] [blame] | 275 | #if defined(LWS_WITH_ESP8266) |
| 276 | #undef _DEBUG |
| 277 | #endif |
| 278 | |
| 279 | #ifdef _DEBUG |
| 280 | #if defined(LWS_WITH_NO_LOGS) |
| 281 | /* notice, warn and log are always compiled in */ |
Andy Green | 7acf76c | 2016-07-23 14:18:25 +0800 | [diff] [blame] | 282 | #define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) |
| 283 | #define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) |
| 284 | #endif |
Andy Green | 69e4364 | 2013-01-19 11:58:07 +0800 | [diff] [blame] | 285 | #define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__) |
| 286 | #define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__) |
| 287 | #define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__) |
| 288 | #define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__) |
Andy Green | d636e35 | 2013-01-29 12:36:17 +0800 | [diff] [blame] | 289 | #define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__) |
Andy Green | 69e4364 | 2013-01-19 11:58:07 +0800 | [diff] [blame] | 290 | #define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__) |
Andy Green | d636e35 | 2013-01-29 12:36:17 +0800 | [diff] [blame] | 291 | #define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__) |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 292 | /** |
| 293 | * lwsl_hexdump() - helper to hexdump a buffer (DEBUG builds only) |
| 294 | * |
| 295 | * \param buf: buffer start to dump |
| 296 | * \param len: length of buffer to dump |
| 297 | */ |
Peter Pentchev | 9a4fef7 | 2013-03-30 09:52:21 +0800 | [diff] [blame] | 298 | LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len); |
Andy Green | d636e35 | 2013-01-29 12:36:17 +0800 | [diff] [blame] | 299 | |
Andy Green | 69e4364 | 2013-01-19 11:58:07 +0800 | [diff] [blame] | 300 | #else /* no debug */ |
Andy Green | 7acf76c | 2016-07-23 14:18:25 +0800 | [diff] [blame] | 301 | #if defined(LWS_WITH_NO_LOGS) |
Andy Green | 7acf76c | 2016-07-23 14:18:25 +0800 | [diff] [blame] | 302 | #define lwsl_warn(...) do {} while(0) |
| 303 | #define lwsl_notice(...) do {} while(0) |
| 304 | #endif |
| 305 | #define lwsl_info(...) do {} while(0) |
| 306 | #define lwsl_debug(...) do {} while(0) |
| 307 | #define lwsl_parser(...) do {} while(0) |
| 308 | #define lwsl_header(...) do {} while(0) |
| 309 | #define lwsl_ext(...) do {} while(0) |
| 310 | #define lwsl_client(...) do {} while(0) |
| 311 | #define lwsl_latency(...) do {} while(0) |
Andy Green | 69e4364 | 2013-01-19 11:58:07 +0800 | [diff] [blame] | 312 | #define lwsl_hexdump(a, b) |
Andy Green | d636e35 | 2013-01-29 12:36:17 +0800 | [diff] [blame] | 313 | |
Andy Green | 69e4364 | 2013-01-19 11:58:07 +0800 | [diff] [blame] | 314 | #endif |
Andy Green | 0207705 | 2016-04-06 16:15:40 +0800 | [diff] [blame] | 315 | |
paularmitt | 422f56c | 2017-03-31 19:55:42 +0800 | [diff] [blame] | 316 | static LWS_INLINE int lws_is_be(void) { |
| 317 | const int probe = ~0xff; |
| 318 | |
| 319 | return *(const char *)&probe; |
| 320 | } |
| 321 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 322 | /** |
| 323 | * lws_set_log_level() - Set the logging bitfield |
| 324 | * \param level: OR together the LLL_ debug contexts you want output from |
| 325 | * \param log_emit_function: NULL to leave it as it is, or a user-supplied |
| 326 | * function to perform log string emission instead of |
| 327 | * the default stderr one. |
| 328 | * |
| 329 | * log level defaults to "err", "warn" and "notice" contexts enabled and |
| 330 | * emission on stderr. |
| 331 | */ |
| 332 | LWS_VISIBLE LWS_EXTERN void |
| 333 | lws_set_log_level(int level, |
| 334 | void (*log_emit_function)(int level, const char *line)); |
| 335 | |
| 336 | /** |
| 337 | * lwsl_emit_syslog() - helper log emit function writes to system log |
| 338 | * |
| 339 | * \param level: one of LLL_ log level indexes |
| 340 | * \param line: log string |
| 341 | * |
| 342 | * You use this by passing the function pointer to lws_set_log_level(), to set |
| 343 | * it as the log emit function, it is not called directly. |
| 344 | */ |
| 345 | LWS_VISIBLE LWS_EXTERN void |
| 346 | lwsl_emit_syslog(int level, const char *line); |
| 347 | |
Andy Green | c8b2091 | 2017-02-09 09:11:17 +0800 | [diff] [blame] | 348 | /** |
| 349 | * lwsl_visible() - returns true if the log level should be printed |
| 350 | * |
| 351 | * \param level: one of LLL_ log level indexes |
| 352 | * |
| 353 | * This is useful if you have to do work to generate the log content, you |
| 354 | * can skip the work if the log level used to print it is not actually |
| 355 | * enabled at runtime. |
| 356 | */ |
| 357 | LWS_VISIBLE LWS_EXTERN int |
| 358 | lwsl_visible(int level); |
| 359 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 360 | ///@} |
| 361 | |
| 362 | |
Andy Green | 0207705 | 2016-04-06 16:15:40 +0800 | [diff] [blame] | 363 | #include <stddef.h> |
| 364 | |
| 365 | #ifndef lws_container_of |
| 366 | #define lws_container_of(P,T,M) ((T *)((char *)(P) - offsetof(T, M))) |
| 367 | #endif |
| 368 | |
| 369 | |
Andy Green | 891628b | 2015-12-11 13:12:58 +0800 | [diff] [blame] | 370 | struct lws; |
Andy Green | 57513b7 | 2016-06-06 20:35:23 +0800 | [diff] [blame] | 371 | #ifndef ARRAY_SIZE |
Andy Green | 4e7a133 | 2013-11-11 07:30:33 +0800 | [diff] [blame] | 372 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) |
Andy Green | 57513b7 | 2016-06-06 20:35:23 +0800 | [diff] [blame] | 373 | #endif |
Andy Green | 4e7a133 | 2013-11-11 07:30:33 +0800 | [diff] [blame] | 374 | |
Andy Green | 6ea337a | 2014-04-21 08:27:19 +0900 | [diff] [blame] | 375 | /* api change list for user code to test against */ |
| 376 | |
| 377 | #define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_ARG |
| 378 | |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame] | 379 | /* the struct lws_protocols has the id field present */ |
Michael Haberler | a2d3bf1 | 2014-08-11 14:36:57 +0200 | [diff] [blame] | 380 | #define LWS_FEATURE_PROTOCOLS_HAS_ID_FIELD |
| 381 | |
Andy Green | 97ee57f | 2014-10-29 09:39:08 +0800 | [diff] [blame] | 382 | /* you can call lws_get_peer_write_allowance */ |
| 383 | #define LWS_FEATURE_PROTOCOLS_HAS_PEER_WRITE_ALLOWANCE |
Andy Green | 6ea337a | 2014-04-21 08:27:19 +0900 | [diff] [blame] | 384 | |
Michael Haberler | 49d0ce1 | 2014-12-01 14:05:51 +0100 | [diff] [blame] | 385 | /* extra parameter introduced in 917f43ab821 */ |
| 386 | #define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_LEN |
| 387 | |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 388 | /* File operations stuff exists */ |
| 389 | #define LWS_FEATURE_FOPS |
| 390 | |
Michael Haberler | cb73306 | 2014-02-15 20:15:55 +0800 | [diff] [blame] | 391 | |
Andy Green | 375a193 | 2015-12-16 19:51:12 +0800 | [diff] [blame] | 392 | #if defined(_WIN32) |
Andy Green | 3b19386 | 2015-11-02 13:13:44 +0800 | [diff] [blame] | 393 | typedef SOCKET lws_sockfd_type; |
SoapyMan | 11260da | 2015-12-10 07:52:31 +0800 | [diff] [blame] | 394 | typedef HANDLE lws_filefd_type; |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 395 | #define lws_sockfd_valid(sfd) (!!sfd) |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame] | 396 | struct lws_pollfd { |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 397 | lws_sockfd_type fd; /**< file descriptor */ |
| 398 | SHORT events; /**< which events to respond to */ |
| 399 | SHORT revents; /**< which events happened */ |
Patrick Gansterer | 73882e4 | 2014-03-29 08:25:58 +0100 | [diff] [blame] | 400 | }; |
Andy Green | 2b304a9 | 2016-07-11 07:28:23 +0800 | [diff] [blame] | 401 | #define LWS_POLLHUP (FD_CLOSE) |
| 402 | #define LWS_POLLIN (FD_READ | FD_ACCEPT) |
| 403 | #define LWS_POLLOUT (FD_WRITE) |
Patrick Gansterer | 73882e4 | 2014-03-29 08:25:58 +0100 | [diff] [blame] | 404 | #else |
Andy Green | 3b19386 | 2015-11-02 13:13:44 +0800 | [diff] [blame] | 405 | |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 406 | |
Andy Green | 7acf76c | 2016-07-23 14:18:25 +0800 | [diff] [blame] | 407 | #if defined(LWS_WITH_ESP8266) |
| 408 | |
| 409 | #include <user_interface.h> |
| 410 | #include <espconn.h> |
| 411 | |
| 412 | typedef struct espconn * lws_sockfd_type; |
| 413 | typedef void * lws_filefd_type; |
| 414 | #define lws_sockfd_valid(sfd) (!!sfd) |
| 415 | struct pollfd { |
| 416 | lws_sockfd_type fd; /**< fd related to */ |
| 417 | short events; /**< which POLL... events to respond to */ |
| 418 | short revents; /**< which POLL... events occurred */ |
| 419 | }; |
| 420 | #define POLLIN 0x0001 |
| 421 | #define POLLPRI 0x0002 |
| 422 | #define POLLOUT 0x0004 |
| 423 | #define POLLERR 0x0008 |
| 424 | #define POLLHUP 0x0010 |
| 425 | #define POLLNVAL 0x0020 |
| 426 | |
| 427 | struct lws_vhost; |
| 428 | |
| 429 | lws_sockfd_type esp8266_create_tcp_listen_socket(struct lws_vhost *vh); |
| 430 | void esp8266_tcp_stream_accept(lws_sockfd_type fd, struct lws *wsi); |
| 431 | |
| 432 | #include <os_type.h> |
| 433 | #include <osapi.h> |
| 434 | #include "ets_sys.h" |
| 435 | |
Martin Milata | be1f0a3 | 2017-02-04 13:09:00 +0100 | [diff] [blame] | 436 | int ets_snprintf(char *str, size_t size, const char *format, ...) LWS_FORMAT(3); |
Andy Green | 7acf76c | 2016-07-23 14:18:25 +0800 | [diff] [blame] | 437 | #define snprintf ets_snprintf |
| 438 | |
| 439 | typedef os_timer_t uv_timer_t; |
| 440 | typedef void uv_cb_t(uv_timer_t *); |
| 441 | |
| 442 | void os_timer_disarm(void *); |
| 443 | void os_timer_setfn(os_timer_t *, os_timer_func_t *, void *); |
| 444 | |
| 445 | void ets_timer_arm_new(os_timer_t *, int, int, int); |
| 446 | |
| 447 | //void os_timer_arm(os_timer_t *, int, int); |
| 448 | |
| 449 | #define UV_VERSION_MAJOR 1 |
| 450 | |
| 451 | #define lws_uv_getloop(a, b) (NULL) |
| 452 | |
| 453 | static inline void uv_timer_init(void *l, uv_timer_t *t) |
| 454 | { |
| 455 | (void)l; |
| 456 | memset(t, 0, sizeof(*t)); |
| 457 | os_timer_disarm(t); |
| 458 | } |
| 459 | |
| 460 | static inline void uv_timer_start(uv_timer_t *t, uv_cb_t *cb, int first, int rep) |
| 461 | { |
| 462 | os_timer_setfn(t, (os_timer_func_t *)cb, t); |
| 463 | /* ms, repeat */ |
| 464 | os_timer_arm(t, first, !!rep); |
| 465 | } |
| 466 | |
| 467 | static inline void uv_timer_stop(uv_timer_t *t) |
| 468 | { |
| 469 | os_timer_disarm(t); |
| 470 | } |
| 471 | |
| 472 | #else |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 473 | #if defined(LWS_WITH_ESP32) |
| 474 | |
| 475 | typedef int lws_sockfd_type; |
Andy Green | 3a09c3b | 2017-03-08 11:11:41 +0800 | [diff] [blame] | 476 | typedef int lws_filefd_type; |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 477 | #define lws_sockfd_valid(sfd) (sfd >= 0) |
| 478 | struct pollfd { |
| 479 | lws_sockfd_type fd; /**< fd related to */ |
| 480 | short events; /**< which POLL... events to respond to */ |
| 481 | short revents; /**< which POLL... events occurred */ |
| 482 | }; |
| 483 | #define POLLIN 0x0001 |
| 484 | #define POLLPRI 0x0002 |
| 485 | #define POLLOUT 0x0004 |
| 486 | #define POLLERR 0x0008 |
| 487 | #define POLLHUP 0x0010 |
| 488 | #define POLLNVAL 0x0020 |
| 489 | |
Andy Green | e0572d3 | 2017-03-10 14:29:21 +0800 | [diff] [blame] | 490 | #include <freertos/FreeRTOS.h> |
| 491 | #include <freertos/event_groups.h> |
| 492 | #include <string.h> |
| 493 | #include "esp_wifi.h" |
| 494 | #include "esp_system.h" |
| 495 | #include "esp_event.h" |
| 496 | #include "esp_event_loop.h" |
| 497 | #include "nvs.h" |
| 498 | #include "driver/gpio.h" |
| 499 | #include "esp_spi_flash.h" |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 500 | #include "freertos/timers.h" |
| 501 | |
| 502 | #if !defined(CONFIG_FREERTOS_HZ) |
| 503 | #define CONFIG_FREERTOS_HZ 100 |
| 504 | #endif |
| 505 | |
| 506 | typedef TimerHandle_t uv_timer_t; |
| 507 | typedef void uv_cb_t(uv_timer_t *); |
| 508 | typedef void * uv_handle_t; |
| 509 | |
| 510 | struct timer_mapping { |
| 511 | uv_cb_t *cb; |
| 512 | uv_timer_t *t; |
| 513 | }; |
| 514 | |
| 515 | #define UV_VERSION_MAJOR 1 |
| 516 | |
| 517 | #define lws_uv_getloop(a, b) (NULL) |
| 518 | |
| 519 | static inline void uv_timer_init(void *l, uv_timer_t *t) |
| 520 | { |
| 521 | (void)l; |
| 522 | *t = NULL; |
| 523 | } |
| 524 | |
| 525 | extern void esp32_uvtimer_cb(TimerHandle_t t); |
| 526 | |
| 527 | static inline void uv_timer_start(uv_timer_t *t, uv_cb_t *cb, int first, int rep) |
| 528 | { |
Andy Green | 3cf570e | 2017-05-16 19:35:55 +0800 | [diff] [blame] | 529 | struct timer_mapping *tm = (struct timer_mapping *)malloc(sizeof(*tm)); |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 530 | |
| 531 | if (!tm) |
| 532 | return; |
| 533 | |
| 534 | tm->t = t; |
| 535 | tm->cb = cb; |
| 536 | |
| 537 | *t = xTimerCreate("x", pdMS_TO_TICKS(first), !!rep, tm, |
| 538 | (TimerCallbackFunction_t)esp32_uvtimer_cb); |
| 539 | xTimerStart(*t, 0); |
| 540 | } |
| 541 | |
| 542 | static inline void uv_timer_stop(uv_timer_t *t) |
| 543 | { |
| 544 | xTimerStop(*t, 0); |
| 545 | } |
| 546 | |
| 547 | static inline void uv_close(uv_handle_t *h, void *v) |
| 548 | { |
| 549 | free(pvTimerGetTimerID((uv_timer_t)h)); |
| 550 | xTimerDelete(*(uv_timer_t *)h, 0); |
| 551 | } |
| 552 | |
Andy Green | e0572d3 | 2017-03-10 14:29:21 +0800 | [diff] [blame] | 553 | /* ESP32 helper declarations */ |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 554 | |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 555 | #include <mdns.h> |
| 556 | #include <esp_partition.h> |
| 557 | |
Andy Green | e0572d3 | 2017-03-10 14:29:21 +0800 | [diff] [blame] | 558 | #define LWS_PLUGIN_STATIC |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 559 | #define LWS_MAGIC_REBOOT_TYPE_ADS 0x50001ffc |
| 560 | #define LWS_MAGIC_REBOOT_TYPE_REQ_FACTORY 0xb00bcafe |
| 561 | #define LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY 0xfaceb00b |
| 562 | #define LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON 0xf0cedfac |
| 563 | |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 564 | |
Andy Green | e0572d3 | 2017-03-10 14:29:21 +0800 | [diff] [blame] | 565 | /* user code provides these */ |
| 566 | |
Andy Green | e0572d3 | 2017-03-10 14:29:21 +0800 | [diff] [blame] | 567 | extern void |
| 568 | lws_esp32_identify_physical_device(void); |
| 569 | |
| 570 | /* lws-plat-esp32 provides these */ |
| 571 | |
Andy Green | b2f8bc5 | 2017-05-13 10:26:59 +0800 | [diff] [blame] | 572 | typedef void (*lws_cb_scan_done)(uint16_t count, wifi_ap_record_t *recs, void *arg); |
Andy Green | e0572d3 | 2017-03-10 14:29:21 +0800 | [diff] [blame] | 573 | |
Andy Green | c28f436 | 2017-05-21 07:33:09 +0800 | [diff] [blame] | 574 | enum genled_state { |
| 575 | LWSESP32_GENLED__INIT, |
| 576 | LWSESP32_GENLED__LOST_NETWORK, |
| 577 | LWSESP32_GENLED__NO_NETWORK, |
| 578 | LWSESP32_GENLED__CONN_AP, |
| 579 | LWSESP32_GENLED__GOT_IP, |
| 580 | LWSESP32_GENLED__OK, |
| 581 | }; |
| 582 | |
Andy Green | b778cc5 | 2017-05-14 14:55:15 +0800 | [diff] [blame] | 583 | struct lws_group_member { |
| 584 | struct lws_group_member *next; |
| 585 | uint64_t last_seen; |
| 586 | char model[16]; |
| 587 | char role[16]; |
| 588 | char host[32]; |
Andy Green | 3cf570e | 2017-05-16 19:35:55 +0800 | [diff] [blame] | 589 | char mac[20]; |
| 590 | int width, height; |
Andy Green | b778cc5 | 2017-05-14 14:55:15 +0800 | [diff] [blame] | 591 | struct ip4_addr addr; |
| 592 | struct ip6_addr addrv6; |
Andy Green | 3cf570e | 2017-05-16 19:35:55 +0800 | [diff] [blame] | 593 | uint8_t flags; |
Andy Green | b778cc5 | 2017-05-14 14:55:15 +0800 | [diff] [blame] | 594 | }; |
| 595 | |
Andy Green | 3cf570e | 2017-05-16 19:35:55 +0800 | [diff] [blame] | 596 | #define LWS_SYSTEM_GROUP_MEMBER_ADD 1 |
| 597 | #define LWS_SYSTEM_GROUP_MEMBER_CHANGE 2 |
| 598 | #define LWS_SYSTEM_GROUP_MEMBER_REMOVE 3 |
| 599 | |
| 600 | #define LWS_GROUP_FLAG_SELF 1 |
| 601 | |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 602 | struct lws_esp32 { |
| 603 | char sta_ip[16]; |
| 604 | char sta_mask[16]; |
| 605 | char sta_gw[16]; |
| 606 | char serial[16]; |
| 607 | char opts[16]; |
| 608 | char model[16]; |
Andy Green | 54236bd | 2017-05-11 15:02:01 +0800 | [diff] [blame] | 609 | char group[16]; |
| 610 | char role[16]; |
Andy Green | b2f8bc5 | 2017-05-13 10:26:59 +0800 | [diff] [blame] | 611 | char ssid[4][16]; |
| 612 | char password[4][32]; |
Andy Green | 54236bd | 2017-05-11 15:02:01 +0800 | [diff] [blame] | 613 | char active_ssid[32]; |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 614 | char access_pw[16]; |
Andy Green | b778cc5 | 2017-05-14 14:55:15 +0800 | [diff] [blame] | 615 | char hostname[32]; |
Andy Green | 3cf570e | 2017-05-16 19:35:55 +0800 | [diff] [blame] | 616 | char mac[20]; |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 617 | mdns_server_t *mdns; |
| 618 | char region; |
| 619 | char inet; |
Andy Green | c28f436 | 2017-05-21 07:33:09 +0800 | [diff] [blame] | 620 | char conn_ap; |
| 621 | |
| 622 | enum genled_state genled; |
| 623 | uint64_t genled_t; |
| 624 | |
Andy Green | b2f8bc5 | 2017-05-13 10:26:59 +0800 | [diff] [blame] | 625 | lws_cb_scan_done scan_consumer; |
| 626 | void *scan_consumer_arg; |
Andy Green | b778cc5 | 2017-05-14 14:55:15 +0800 | [diff] [blame] | 627 | struct lws_group_member *first; |
| 628 | int extant_group_members; |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 629 | }; |
| 630 | |
| 631 | struct lws_esp32_image { |
| 632 | uint32_t romfs; |
| 633 | uint32_t romfs_len; |
| 634 | uint32_t json; |
| 635 | uint32_t json_len; |
| 636 | }; |
| 637 | |
| 638 | extern struct lws_esp32 lws_esp32; |
Andy Green | 219a367 | 2017-08-05 10:59:51 +0800 | [diff] [blame] | 639 | struct lws_vhost; |
Andy Green | e0572d3 | 2017-03-10 14:29:21 +0800 | [diff] [blame] | 640 | |
| 641 | extern esp_err_t |
| 642 | lws_esp32_event_passthru(void *ctx, system_event_t *event); |
| 643 | extern void |
| 644 | lws_esp32_wlan_config(void); |
| 645 | extern void |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 646 | lws_esp32_wlan_start_ap(void); |
| 647 | extern void |
| 648 | lws_esp32_wlan_start_station(void); |
Andy Green | e0572d3 | 2017-03-10 14:29:21 +0800 | [diff] [blame] | 649 | struct lws_context_creation_info; |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 650 | extern void |
| 651 | lws_esp32_set_creation_defaults(struct lws_context_creation_info *info); |
Andy Green | e0572d3 | 2017-03-10 14:29:21 +0800 | [diff] [blame] | 652 | extern struct lws_context * |
Andy Green | 219a367 | 2017-08-05 10:59:51 +0800 | [diff] [blame] | 653 | lws_esp32_init(struct lws_context_creation_info *, struct lws_vhost **pvh); |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 654 | extern int |
| 655 | lws_esp32_wlan_nvs_get(int retry); |
Andy Green | b2f8bc5 | 2017-05-13 10:26:59 +0800 | [diff] [blame] | 656 | extern esp_err_t |
| 657 | lws_nvs_set_str(nvs_handle handle, const char* key, const char* value); |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 658 | extern void |
| 659 | lws_esp32_restart_guided(uint32_t type); |
| 660 | extern const esp_partition_t * |
| 661 | lws_esp_ota_get_boot_partition(void); |
| 662 | extern int |
| 663 | lws_esp32_get_image_info(const esp_partition_t *part, struct lws_esp32_image *i, char *json, int json_len); |
Andy Green | c28f436 | 2017-05-21 07:33:09 +0800 | [diff] [blame] | 664 | extern int |
| 665 | lws_esp32_leds_network_indication(void); |
| 666 | |
Andy Green | 30195eb | 2017-04-03 11:56:33 +0800 | [diff] [blame] | 667 | extern uint32_t lws_esp32_get_reboot_type(void); |
Andy Green | 2790d5b | 2017-05-07 13:24:48 +0800 | [diff] [blame] | 668 | extern uint16_t lws_esp32_sine_interp(int n); |
| 669 | |
| 670 | /* required in external code by esp32 plat (may just return if no leds) */ |
| 671 | extern void lws_esp32_leds_timer_cb(TimerHandle_t th); |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 672 | #else |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 673 | typedef int lws_sockfd_type; |
SoapyMan | 11260da | 2015-12-10 07:52:31 +0800 | [diff] [blame] | 674 | typedef int lws_filefd_type; |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 675 | #define lws_sockfd_valid(sfd) (sfd >= 0) |
Andy Green | 3b19386 | 2015-11-02 13:13:44 +0800 | [diff] [blame] | 676 | #endif |
Andy Green | 7acf76c | 2016-07-23 14:18:25 +0800 | [diff] [blame] | 677 | #endif |
Andy Green | 3b19386 | 2015-11-02 13:13:44 +0800 | [diff] [blame] | 678 | |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame] | 679 | #define lws_pollfd pollfd |
Andy Green | 2b304a9 | 2016-07-11 07:28:23 +0800 | [diff] [blame] | 680 | #define LWS_POLLHUP (POLLHUP|POLLERR) |
| 681 | #define LWS_POLLIN (POLLIN) |
| 682 | #define LWS_POLLOUT (POLLOUT) |
Patrick Gansterer | 73882e4 | 2014-03-29 08:25:58 +0100 | [diff] [blame] | 683 | #endif |
Michael Haberler | cb73306 | 2014-02-15 20:15:55 +0800 | [diff] [blame] | 684 | |
Andy Green | 37053b3 | 2017-06-07 07:46:51 +0800 | [diff] [blame] | 685 | |
| 686 | #if (defined(WIN32) || defined(_WIN32)) && !defined(__MINGW32__) |
| 687 | /* ... */ |
WebsocketUser | 0be9e98 | 2017-06-09 20:20:42 +0800 | [diff] [blame] | 688 | #define ssize_t SSIZE_T |
Andy Green | 37053b3 | 2017-06-07 07:46:51 +0800 | [diff] [blame] | 689 | #endif |
WebsocketUser | 0be9e98 | 2017-06-09 20:20:42 +0800 | [diff] [blame] | 690 | |
| 691 | #if defined(WIN32) && defined(LWS_HAVE__STAT32I64) |
| 692 | #include <sys/types.h> |
| 693 | #include <sys/stat.h> |
Andy Green | 37053b3 | 2017-06-07 07:46:51 +0800 | [diff] [blame] | 694 | #endif |
| 695 | |
| 696 | #if defined(LWS_HAVE_STDINT_H) |
| 697 | #include <stdint.h> |
| 698 | #else |
| 699 | #if defined(WIN32) || defined(_WIN32) |
| 700 | /* !!! >:-[ */ |
| 701 | typedef unsigned __int32 uint32_t; |
| 702 | typedef unsigned __int16 uint16_t; |
| 703 | typedef unsigned __int8 uint8_t; |
| 704 | #else |
| 705 | typedef unsigned int uint32_t; |
| 706 | typedef unsigned short uint16_t; |
| 707 | typedef unsigned char uint8_t; |
| 708 | #endif |
| 709 | #endif |
| 710 | |
WebsocketUser | 0be9e98 | 2017-06-09 20:20:42 +0800 | [diff] [blame] | 711 | typedef unsigned long long lws_filepos_t; |
| 712 | typedef long long lws_fileofs_t; |
Andy Green | 37053b3 | 2017-06-07 07:46:51 +0800 | [diff] [blame] | 713 | typedef uint32_t lws_fop_flags_t; |
| 714 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 715 | /** struct lws_pollargs - argument structure for all external poll related calls |
| 716 | * passed in via 'in' */ |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame] | 717 | struct lws_pollargs { |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 718 | lws_sockfd_type fd; /**< applicable socket descriptor */ |
| 719 | int events; /**< the new event mask */ |
| 720 | int prev_events; /**< the previous event mask */ |
| 721 | }; |
| 722 | |
| 723 | struct lws_tokens; |
| 724 | struct lws_token_limits; |
| 725 | |
| 726 | /*! \defgroup wsclose Websocket Close |
| 727 | * |
| 728 | * ##Websocket close frame control |
| 729 | * |
| 730 | * When we close a ws connection, we can send a reason code and a short |
| 731 | * UTF-8 description back with the close packet. |
| 732 | */ |
| 733 | ///@{ |
| 734 | |
| 735 | /* |
| 736 | * NOTE: These public enums are part of the abi. If you want to add one, |
| 737 | * add it at where specified so existing users are unaffected. |
| 738 | */ |
| 739 | /** enum lws_close_status - RFC6455 close status codes */ |
| 740 | enum lws_close_status { |
| 741 | LWS_CLOSE_STATUS_NOSTATUS = 0, |
| 742 | LWS_CLOSE_STATUS_NORMAL = 1000, |
| 743 | /**< 1000 indicates a normal closure, meaning that the purpose for |
| 744 | which the connection was established has been fulfilled. */ |
| 745 | LWS_CLOSE_STATUS_GOINGAWAY = 1001, |
| 746 | /**< 1001 indicates that an endpoint is "going away", such as a server |
| 747 | going down or a browser having navigated away from a page. */ |
| 748 | LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002, |
| 749 | /**< 1002 indicates that an endpoint is terminating the connection due |
| 750 | to a protocol error. */ |
| 751 | LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003, |
| 752 | /**< 1003 indicates that an endpoint is terminating the connection |
| 753 | because it has received a type of data it cannot accept (e.g., an |
| 754 | endpoint that understands only text data MAY send this if it |
| 755 | receives a binary message). */ |
| 756 | LWS_CLOSE_STATUS_RESERVED = 1004, |
| 757 | /**< Reserved. The specific meaning might be defined in the future. */ |
| 758 | LWS_CLOSE_STATUS_NO_STATUS = 1005, |
| 759 | /**< 1005 is a reserved value and MUST NOT be set as a status code in a |
| 760 | Close control frame by an endpoint. It is designated for use in |
| 761 | applications expecting a status code to indicate that no status |
| 762 | code was actually present. */ |
| 763 | LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006, |
| 764 | /**< 1006 is a reserved value and MUST NOT be set as a status code in a |
| 765 | Close control frame by an endpoint. It is designated for use in |
| 766 | applications expecting a status code to indicate that the |
| 767 | connection was closed abnormally, e.g., without sending or |
| 768 | receiving a Close control frame. */ |
| 769 | LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007, |
| 770 | /**< 1007 indicates that an endpoint is terminating the connection |
| 771 | because it has received data within a message that was not |
| 772 | consistent with the type of the message (e.g., non-UTF-8 [RFC3629] |
| 773 | data within a text message). */ |
| 774 | LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008, |
| 775 | /**< 1008 indicates that an endpoint is terminating the connection |
| 776 | because it has received a message that violates its policy. This |
| 777 | is a generic status code that can be returned when there is no |
| 778 | other more suitable status code (e.g., 1003 or 1009) or if there |
| 779 | is a need to hide specific details about the policy. */ |
| 780 | LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009, |
| 781 | /**< 1009 indicates that an endpoint is terminating the connection |
| 782 | because it has received a message that is too big for it to |
| 783 | process. */ |
| 784 | LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010, |
| 785 | /**< 1010 indicates that an endpoint (client) is terminating the |
| 786 | connection because it has expected the server to negotiate one or |
| 787 | more extension, but the server didn't return them in the response |
| 788 | message of the WebSocket handshake. The list of extensions that |
| 789 | are needed SHOULD appear in the /reason/ part of the Close frame. |
| 790 | Note that this status code is not used by the server, because it |
| 791 | can fail the WebSocket handshake instead */ |
| 792 | LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011, |
| 793 | /**< 1011 indicates that a server is terminating the connection because |
| 794 | it encountered an unexpected condition that prevented it from |
| 795 | fulfilling the request. */ |
| 796 | LWS_CLOSE_STATUS_TLS_FAILURE = 1015, |
| 797 | /**< 1015 is a reserved value and MUST NOT be set as a status code in a |
| 798 | Close control frame by an endpoint. It is designated for use in |
| 799 | applications expecting a status code to indicate that the |
| 800 | connection was closed due to a failure to perform a TLS handshake |
| 801 | (e.g., the server certificate can't be verified). */ |
| 802 | |
| 803 | /****** add new things just above ---^ ******/ |
| 804 | |
| 805 | LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY = 9999, |
Andy Green | 3b19386 | 2015-11-02 13:13:44 +0800 | [diff] [blame] | 806 | }; |
| 807 | |
SoapyMan | 11260da | 2015-12-10 07:52:31 +0800 | [diff] [blame] | 808 | /** |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 809 | * lws_close_reason - Set reason and aux data to send with Close packet |
| 810 | * If you are going to return nonzero from the callback |
| 811 | * requesting the connection to close, you can optionally |
| 812 | * call this to set the reason the peer will be told if |
| 813 | * possible. |
SoapyMan | 11260da | 2015-12-10 07:52:31 +0800 | [diff] [blame] | 814 | * |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 815 | * \param wsi: The websocket connection to set the close reason on |
| 816 | * \param status: A valid close status from websocket standard |
| 817 | * \param buf: NULL or buffer containing up to 124 bytes of auxiliary data |
| 818 | * \param len: Length of data in \param buf to send |
SoapyMan | 11260da | 2015-12-10 07:52:31 +0800 | [diff] [blame] | 819 | */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 820 | LWS_VISIBLE LWS_EXTERN void |
| 821 | lws_close_reason(struct lws *wsi, enum lws_close_status status, |
| 822 | unsigned char *buf, size_t len); |
SoapyMan | 11260da | 2015-12-10 07:52:31 +0800 | [diff] [blame] | 823 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 824 | ///@} |
| 825 | |
| 826 | struct lws; |
| 827 | struct lws_context; |
| 828 | /* needed even with extensions disabled for create context */ |
| 829 | struct lws_extension; |
| 830 | |
Andy Green | 6f11c13 | 2017-07-19 04:39:14 +0800 | [diff] [blame] | 831 | /*! \defgroup lwsmeta lws-meta |
| 832 | * |
| 833 | * ##lws-meta protocol |
| 834 | * |
| 835 | * The protocol wraps other muxed connections inside one tcp connection. |
| 836 | * |
| 837 | * Commands are assigned from 0x41 up (so they are valid unicode) |
| 838 | */ |
| 839 | ///@{ |
| 840 | |
| 841 | enum lws_meta_commands { |
| 842 | LWS_META_CMD_OPEN_SUBCHANNEL = 'A', |
| 843 | /**< Client requests to open new subchannel |
| 844 | */ |
| 845 | LWS_META_CMD_OPEN_RESULT, |
| 846 | /**< Result of client request to open new subchannel */ |
| 847 | LWS_META_CMD_CLOSE_NOTIFY, |
| 848 | /**< Notification of subchannel closure */ |
| 849 | LWS_META_CMD_CLOSE_RQ, |
| 850 | /**< client requests to close a subchannel */ |
| 851 | LWS_META_CMD_WRITE, |
| 852 | /**< connection writes something to specific channel index */ |
| 853 | |
| 854 | /****** add new things just above ---^ ******/ |
| 855 | }; |
| 856 | |
| 857 | /* channel numbers are transported offset by 0x20 so they are valid unicode */ |
| 858 | |
| 859 | #define LWS_META_TRANSPORT_OFFSET 0x20 |
| 860 | |
| 861 | ///@} |
| 862 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 863 | /*! \defgroup usercb User Callback |
| 864 | * |
| 865 | * ##User protocol callback |
| 866 | * |
| 867 | * The protocol callback is the primary way lws interacts with |
| 868 | * user code. For one of a list of a few dozen reasons the callback gets |
| 869 | * called at some event to be handled. |
| 870 | * |
| 871 | * All of the events can be ignored, returning 0 is taken as "OK" and returning |
| 872 | * nonzero in most cases indicates that the connection should be closed. |
| 873 | */ |
| 874 | ///@{ |
| 875 | |
Andy Green | 3ff720f | 2017-06-20 11:46:49 +0800 | [diff] [blame] | 876 | struct lws_ssl_info { |
| 877 | int where; |
| 878 | int ret; |
| 879 | }; |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 880 | |
| 881 | /* |
| 882 | * NOTE: These public enums are part of the abi. If you want to add one, |
| 883 | * add it at where specified so existing users are unaffected. |
| 884 | */ |
| 885 | /** enum lws_callback_reasons - reason you're getting a protocol callback */ |
| 886 | enum lws_callback_reasons { |
| 887 | LWS_CALLBACK_ESTABLISHED = 0, |
| 888 | /**< (VH) after the server completes a handshake with an incoming |
| 889 | * client. If you built the library with ssl support, in is a |
| 890 | * pointer to the ssl struct associated with the connection or NULL.*/ |
| 891 | LWS_CALLBACK_CLIENT_CONNECTION_ERROR = 1, |
| 892 | /**< the request client connection has been unable to complete a |
| 893 | * handshake with the remote server. If in is non-NULL, you can |
Andy Green | 81c221e | 2016-07-01 08:54:39 +0800 | [diff] [blame] | 894 | * find an error string of length len where it points to |
| 895 | * |
| 896 | * Diagnostic strings that may be returned include |
| 897 | * |
| 898 | * "getaddrinfo (ipv6) failed" |
| 899 | * "unknown address family" |
| 900 | * "getaddrinfo (ipv4) failed" |
| 901 | * "set socket opts failed" |
| 902 | * "insert wsi failed" |
| 903 | * "lws_ssl_client_connect1 failed" |
| 904 | * "lws_ssl_client_connect2 failed" |
| 905 | * "Peer hung up" |
| 906 | * "read failed" |
| 907 | * "HS: URI missing" |
| 908 | * "HS: Redirect code but no Location" |
| 909 | * "HS: URI did not parse" |
| 910 | * "HS: Redirect failed" |
| 911 | * "HS: Server did not return 200" |
| 912 | * "HS: OOM" |
| 913 | * "HS: disallowed by client filter" |
| 914 | * "HS: disallowed at ESTABLISHED" |
| 915 | * "HS: ACCEPT missing" |
| 916 | * "HS: ws upgrade response not 101" |
| 917 | * "HS: UPGRADE missing" |
| 918 | * "HS: Upgrade to something other than websocket" |
| 919 | * "HS: CONNECTION missing" |
| 920 | * "HS: UPGRADE malformed" |
| 921 | * "HS: PROTOCOL malformed" |
| 922 | * "HS: Cannot match protocol" |
| 923 | * "HS: EXT: list too big" |
| 924 | * "HS: EXT: failed setting defaults" |
| 925 | * "HS: EXT: failed parsing defaults" |
| 926 | * "HS: EXT: failed parsing options" |
| 927 | * "HS: EXT: Rejects server options" |
| 928 | * "HS: EXT: unknown ext" |
| 929 | * "HS: Accept hash wrong" |
| 930 | * "HS: Rejected by filter cb" |
| 931 | * "HS: OOM" |
| 932 | * "HS: SO_SNDBUF failed" |
| 933 | * "HS: Rejected at CLIENT_ESTABLISHED" |
| 934 | */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 935 | LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH = 2, |
| 936 | /**< this is the last chance for the client user code to examine the |
| 937 | * http headers and decide to reject the connection. If the |
| 938 | * content in the headers is interesting to the |
| 939 | * client (url, etc) it needs to copy it out at |
| 940 | * this point since it will be destroyed before |
| 941 | * the CLIENT_ESTABLISHED call */ |
| 942 | LWS_CALLBACK_CLIENT_ESTABLISHED = 3, |
| 943 | /**< after your client connection completed |
| 944 | * a handshake with the remote server */ |
| 945 | LWS_CALLBACK_CLOSED = 4, |
| 946 | /**< when the websocket session ends */ |
| 947 | LWS_CALLBACK_CLOSED_HTTP = 5, |
| 948 | /**< when a HTTP (non-websocket) session ends */ |
| 949 | LWS_CALLBACK_RECEIVE = 6, |
| 950 | /**< data has appeared for this server endpoint from a |
| 951 | * remote client, it can be found at *in and is |
| 952 | * len bytes long */ |
| 953 | LWS_CALLBACK_RECEIVE_PONG = 7, |
| 954 | /**< servers receive PONG packets with this callback reason */ |
| 955 | LWS_CALLBACK_CLIENT_RECEIVE = 8, |
| 956 | /**< data has appeared from the server for the client connection, it |
| 957 | * can be found at *in and is len bytes long */ |
| 958 | LWS_CALLBACK_CLIENT_RECEIVE_PONG = 9, |
| 959 | /**< clients receive PONG packets with this callback reason */ |
| 960 | LWS_CALLBACK_CLIENT_WRITEABLE = 10, |
| 961 | /**< If you call lws_callback_on_writable() on a connection, you will |
| 962 | * get one of these callbacks coming when the connection socket |
| 963 | * is able to accept another write packet without blocking. |
| 964 | * If it already was able to take another packet without blocking, |
| 965 | * you'll get this callback at the next call to the service loop |
| 966 | * function. Notice that CLIENTs get LWS_CALLBACK_CLIENT_WRITEABLE |
| 967 | * and servers get LWS_CALLBACK_SERVER_WRITEABLE. */ |
| 968 | LWS_CALLBACK_SERVER_WRITEABLE = 11, |
| 969 | /**< See LWS_CALLBACK_CLIENT_WRITEABLE */ |
| 970 | LWS_CALLBACK_HTTP = 12, |
| 971 | /**< an http request has come from a client that is not |
| 972 | * asking to upgrade the connection to a websocket |
| 973 | * one. This is a chance to serve http content, |
| 974 | * for example, to send a script to the client |
| 975 | * which will then open the websockets connection. |
| 976 | * in points to the URI path requested and |
| 977 | * lws_serve_http_file() makes it very |
| 978 | * simple to send back a file to the client. |
| 979 | * Normally after sending the file you are done |
| 980 | * with the http connection, since the rest of the |
| 981 | * activity will come by websockets from the script |
| 982 | * that was delivered by http, so you will want to |
| 983 | * return 1; to close and free up the connection. */ |
| 984 | LWS_CALLBACK_HTTP_BODY = 13, |
| 985 | /**< the next len bytes data from the http |
| 986 | * request body HTTP connection is now available in in. */ |
| 987 | LWS_CALLBACK_HTTP_BODY_COMPLETION = 14, |
| 988 | /**< the expected amount of http request body has been delivered */ |
| 989 | LWS_CALLBACK_HTTP_FILE_COMPLETION = 15, |
| 990 | /**< a file requested to be sent down http link has completed. */ |
| 991 | LWS_CALLBACK_HTTP_WRITEABLE = 16, |
| 992 | /**< you can write more down the http protocol link now. */ |
| 993 | LWS_CALLBACK_FILTER_NETWORK_CONNECTION = 17, |
| 994 | /**< called when a client connects to |
| 995 | * the server at network level; the connection is accepted but then |
| 996 | * passed to this callback to decide whether to hang up immediately |
| 997 | * or not, based on the client IP. in contains the connection |
| 998 | * socket's descriptor. Since the client connection information is |
| 999 | * not available yet, wsi still pointing to the main server socket. |
| 1000 | * Return non-zero to terminate the connection before sending or |
| 1001 | * receiving anything. Because this happens immediately after the |
| 1002 | * network connection from the client, there's no websocket protocol |
| 1003 | * selected yet so this callback is issued only to protocol 0. */ |
| 1004 | LWS_CALLBACK_FILTER_HTTP_CONNECTION = 18, |
| 1005 | /**< called when the request has |
| 1006 | * been received and parsed from the client, but the response is |
| 1007 | * not sent yet. Return non-zero to disallow the connection. |
| 1008 | * user is a pointer to the connection user space allocation, |
| 1009 | * in is the URI, eg, "/" |
| 1010 | * In your handler you can use the public APIs |
| 1011 | * lws_hdr_total_length() / lws_hdr_copy() to access all of the |
| 1012 | * headers using the header enums lws_token_indexes from |
| 1013 | * libwebsockets.h to check for and read the supported header |
| 1014 | * presence and content before deciding to allow the http |
| 1015 | * connection to proceed or to kill the connection. */ |
| 1016 | LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED = 19, |
| 1017 | /**< A new client just had |
| 1018 | * been connected, accepted, and instantiated into the pool. This |
| 1019 | * callback allows setting any relevant property to it. Because this |
| 1020 | * happens immediately after the instantiation of a new client, |
| 1021 | * there's no websocket protocol selected yet so this callback is |
| 1022 | * issued only to protocol 0. Only wsi is defined, pointing to the |
| 1023 | * new client, and the return value is ignored. */ |
| 1024 | LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION = 20, |
| 1025 | /**< called when the handshake has |
| 1026 | * been received and parsed from the client, but the response is |
| 1027 | * not sent yet. Return non-zero to disallow the connection. |
| 1028 | * user is a pointer to the connection user space allocation, |
| 1029 | * in is the requested protocol name |
| 1030 | * In your handler you can use the public APIs |
| 1031 | * lws_hdr_total_length() / lws_hdr_copy() to access all of the |
| 1032 | * headers using the header enums lws_token_indexes from |
| 1033 | * libwebsockets.h to check for and read the supported header |
| 1034 | * presence and content before deciding to allow the handshake |
| 1035 | * to proceed or to kill the connection. */ |
| 1036 | LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS = 21, |
| 1037 | /**< if configured for |
| 1038 | * including OpenSSL support, this callback allows your user code |
| 1039 | * to perform extra SSL_CTX_load_verify_locations() or similar |
| 1040 | * calls to direct OpenSSL where to find certificates the client |
| 1041 | * can use to confirm the remote server identity. user is the |
| 1042 | * OpenSSL SSL_CTX* */ |
| 1043 | LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS = 22, |
| 1044 | /**< if configured for |
| 1045 | * including OpenSSL support, this callback allows your user code |
| 1046 | * to load extra certifcates into the server which allow it to |
| 1047 | * verify the validity of certificates returned by clients. user |
| 1048 | * is the server's OpenSSL SSL_CTX* */ |
| 1049 | LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION = 23, |
| 1050 | /**< if the libwebsockets vhost was created with the option |
| 1051 | * LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this |
| 1052 | * callback is generated during OpenSSL verification of the cert |
| 1053 | * sent from the client. It is sent to protocol[0] callback as |
| 1054 | * no protocol has been negotiated on the connection yet. |
| 1055 | * Notice that the libwebsockets context and wsi are both NULL |
| 1056 | * during this callback. See |
| 1057 | * http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html |
| 1058 | * to understand more detail about the OpenSSL callback that |
| 1059 | * generates this libwebsockets callback and the meanings of the |
| 1060 | * arguments passed. In this callback, user is the x509_ctx, |
| 1061 | * in is the ssl pointer and len is preverify_ok |
| 1062 | * Notice that this callback maintains libwebsocket return |
| 1063 | * conventions, return 0 to mean the cert is OK or 1 to fail it. |
| 1064 | * This also means that if you don't handle this callback then |
| 1065 | * the default callback action of returning 0 allows the client |
| 1066 | * certificates. */ |
| 1067 | LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER = 24, |
| 1068 | /**< this callback happens |
| 1069 | * when a client handshake is being compiled. user is NULL, |
| 1070 | * in is a char **, it's pointing to a char * which holds the |
| 1071 | * next location in the header buffer where you can add |
| 1072 | * headers, and len is the remaining space in the header buffer, |
| 1073 | * which is typically some hundreds of bytes. So, to add a canned |
| 1074 | * cookie, your handler code might look similar to: |
| 1075 | * |
| 1076 | * char **p = (char **)in; |
| 1077 | * |
| 1078 | * if (len < 100) |
| 1079 | * return 1; |
| 1080 | * |
| 1081 | * *p += sprintf(*p, "Cookie: a=b\x0d\x0a"); |
| 1082 | * |
| 1083 | * return 0; |
| 1084 | * |
| 1085 | * Notice if you add anything, you just have to take care about |
| 1086 | * the CRLF on the line you added. Obviously this callback is |
| 1087 | * optional, if you don't handle it everything is fine. |
| 1088 | * |
| 1089 | * Notice the callback is coming to protocols[0] all the time, |
| 1090 | * because there is no specific protocol negotiated yet. */ |
| 1091 | LWS_CALLBACK_CONFIRM_EXTENSION_OKAY = 25, |
| 1092 | /**< When the server handshake code |
| 1093 | * sees that it does support a requested extension, before |
| 1094 | * accepting the extension by additing to the list sent back to |
| 1095 | * the client it gives this callback just to check that it's okay |
| 1096 | * to use that extension. It calls back to the requested protocol |
| 1097 | * and with in being the extension name, len is 0 and user is |
| 1098 | * valid. Note though at this time the ESTABLISHED callback hasn't |
| 1099 | * happened yet so if you initialize user content there, user |
emptyVoid | 348887e | 2017-05-27 22:51:58 +0700 | [diff] [blame] | 1100 | * content during this callback might not be useful for anything. */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1101 | LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED = 26, |
| 1102 | /**< When a client |
| 1103 | * connection is being prepared to start a handshake to a server, |
| 1104 | * each supported extension is checked with protocols[0] callback |
| 1105 | * with this reason, giving the user code a chance to suppress the |
| 1106 | * claim to support that extension by returning non-zero. If |
| 1107 | * unhandled, by default 0 will be returned and the extension |
| 1108 | * support included in the header to the server. Notice this |
| 1109 | * callback comes to protocols[0]. */ |
| 1110 | LWS_CALLBACK_PROTOCOL_INIT = 27, |
| 1111 | /**< One-time call per protocol, per-vhost using it, so it can |
| 1112 | * do initial setup / allocations etc */ |
| 1113 | LWS_CALLBACK_PROTOCOL_DESTROY = 28, |
| 1114 | /**< One-time call per protocol, per-vhost using it, indicating |
| 1115 | * this protocol won't get used at all after this callback, the |
| 1116 | * vhost is getting destroyed. Take the opportunity to |
| 1117 | * deallocate everything that was allocated by the protocol. */ |
| 1118 | LWS_CALLBACK_WSI_CREATE = 29, |
| 1119 | /**< outermost (earliest) wsi create notification to protocols[0] */ |
| 1120 | LWS_CALLBACK_WSI_DESTROY = 30, |
| 1121 | /**< outermost (latest) wsi destroy notification to protocols[0] */ |
| 1122 | LWS_CALLBACK_GET_THREAD_ID = 31, |
| 1123 | /**< lws can accept callback when writable requests from other |
| 1124 | * threads, if you implement this callback and return an opaque |
| 1125 | * current thread ID integer. */ |
| 1126 | |
| 1127 | /* external poll() management support */ |
| 1128 | LWS_CALLBACK_ADD_POLL_FD = 32, |
| 1129 | /**< lws normally deals with its poll() or other event loop |
| 1130 | * internally, but in the case you are integrating with another |
| 1131 | * server you will need to have lws sockets share a |
| 1132 | * polling array with the other server. This and the other |
| 1133 | * POLL_FD related callbacks let you put your specialized |
| 1134 | * poll array interface code in the callback for protocol 0, the |
| 1135 | * first protocol you support, usually the HTTP protocol in the |
| 1136 | * serving case. |
| 1137 | * This callback happens when a socket needs to be |
| 1138 | * added to the polling loop: in points to a struct |
| 1139 | * lws_pollargs; the fd member of the struct is the file |
| 1140 | * descriptor, and events contains the active events |
| 1141 | * |
| 1142 | * If you are using the internal lws polling / event loop |
| 1143 | * you can just ignore these callbacks. */ |
| 1144 | LWS_CALLBACK_DEL_POLL_FD = 33, |
| 1145 | /**< This callback happens when a socket descriptor |
| 1146 | * needs to be removed from an external polling array. in is |
| 1147 | * again the struct lws_pollargs containing the fd member |
| 1148 | * to be removed. If you are using the internal polling |
| 1149 | * loop, you can just ignore it. */ |
| 1150 | LWS_CALLBACK_CHANGE_MODE_POLL_FD = 34, |
| 1151 | /**< This callback happens when lws wants to modify the events for |
| 1152 | * a connection. |
| 1153 | * in is the struct lws_pollargs with the fd to change. |
| 1154 | * The new event mask is in events member and the old mask is in |
| 1155 | * the prev_events member. |
| 1156 | * If you are using the internal polling loop, you can just ignore |
| 1157 | * it. */ |
| 1158 | LWS_CALLBACK_LOCK_POLL = 35, |
| 1159 | /**< These allow the external poll changes driven |
| 1160 | * by lws to participate in an external thread locking |
| 1161 | * scheme around the changes, so the whole thing is threadsafe. |
| 1162 | * These are called around three activities in the library, |
| 1163 | * - inserting a new wsi in the wsi / fd table (len=1) |
| 1164 | * - deleting a wsi from the wsi / fd table (len=1) |
| 1165 | * - changing a wsi's POLLIN/OUT state (len=0) |
| 1166 | * Locking and unlocking external synchronization objects when |
| 1167 | * len == 1 allows external threads to be synchronized against |
| 1168 | * wsi lifecycle changes if it acquires the same lock for the |
| 1169 | * duration of wsi dereference from the other thread context. */ |
| 1170 | LWS_CALLBACK_UNLOCK_POLL = 36, |
| 1171 | /**< See LWS_CALLBACK_LOCK_POLL, ignore if using lws internal poll */ |
| 1172 | |
| 1173 | LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY = 37, |
| 1174 | /**< if configured for including OpenSSL support but no private key |
| 1175 | * file has been specified (ssl_private_key_filepath is NULL), this is |
| 1176 | * called to allow the user to set the private key directly via |
| 1177 | * libopenssl and perform further operations if required; this might be |
| 1178 | * useful in situations where the private key is not directly accessible |
| 1179 | * by the OS, for example if it is stored on a smartcard. |
| 1180 | * user is the server's OpenSSL SSL_CTX* */ |
| 1181 | LWS_CALLBACK_WS_PEER_INITIATED_CLOSE = 38, |
| 1182 | /**< The peer has sent an unsolicited Close WS packet. in and |
| 1183 | * len are the optional close code (first 2 bytes, network |
| 1184 | * order) and the optional additional information which is not |
| 1185 | * defined in the standard, and may be a string or non-human- readable data. |
| 1186 | * If you return 0 lws will echo the close and then close the |
| 1187 | * connection. If you return nonzero lws will just close the |
| 1188 | * connection. */ |
| 1189 | |
| 1190 | LWS_CALLBACK_WS_EXT_DEFAULTS = 39, |
| 1191 | /**< */ |
| 1192 | |
| 1193 | LWS_CALLBACK_CGI = 40, |
| 1194 | /**< */ |
| 1195 | LWS_CALLBACK_CGI_TERMINATED = 41, |
| 1196 | /**< */ |
| 1197 | LWS_CALLBACK_CGI_STDIN_DATA = 42, |
| 1198 | /**< */ |
| 1199 | LWS_CALLBACK_CGI_STDIN_COMPLETED = 43, |
| 1200 | /**< */ |
| 1201 | LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP = 44, |
| 1202 | /**< */ |
| 1203 | LWS_CALLBACK_CLOSED_CLIENT_HTTP = 45, |
| 1204 | /**< */ |
| 1205 | LWS_CALLBACK_RECEIVE_CLIENT_HTTP = 46, |
| 1206 | /**< */ |
| 1207 | LWS_CALLBACK_COMPLETED_CLIENT_HTTP = 47, |
| 1208 | /**< */ |
| 1209 | LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ = 48, |
| 1210 | /**< */ |
| 1211 | LWS_CALLBACK_HTTP_BIND_PROTOCOL = 49, |
| 1212 | /**< */ |
| 1213 | LWS_CALLBACK_HTTP_DROP_PROTOCOL = 50, |
| 1214 | /**< */ |
| 1215 | LWS_CALLBACK_CHECK_ACCESS_RIGHTS = 51, |
| 1216 | /**< */ |
| 1217 | LWS_CALLBACK_PROCESS_HTML = 52, |
| 1218 | /**< */ |
| 1219 | LWS_CALLBACK_ADD_HEADERS = 53, |
| 1220 | /**< */ |
| 1221 | LWS_CALLBACK_SESSION_INFO = 54, |
| 1222 | /**< */ |
| 1223 | |
| 1224 | LWS_CALLBACK_GS_EVENT = 55, |
| 1225 | /**< */ |
Andy Green | 722cc4a | 2016-06-26 06:29:20 +0800 | [diff] [blame] | 1226 | LWS_CALLBACK_HTTP_PMO = 56, |
| 1227 | /**< per-mount options for this connection, called before |
| 1228 | * the normal LWS_CALLBACK_HTTP when the mount has per-mount |
| 1229 | * options |
| 1230 | */ |
Andy Green | 95fff47 | 2016-08-08 21:54:30 +0800 | [diff] [blame] | 1231 | LWS_CALLBACK_CLIENT_HTTP_WRITEABLE = 57, |
| 1232 | /**< when doing an HTTP type client connection, you can call |
| 1233 | * lws_client_http_body_pending(wsi, 1) from |
| 1234 | * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER to get these callbacks |
| 1235 | * sending the HTTP headers. |
| 1236 | * |
| 1237 | * From this callback, when you have sent everything, you should let |
| 1238 | * lws know by calling lws_client_http_body_pending(wsi, 0) |
| 1239 | */ |
Namowen | b837f93 | 2017-01-10 09:31:23 +0800 | [diff] [blame] | 1240 | LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION = 58, |
| 1241 | /**< Similar to LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION |
| 1242 | * this callback is called during OpenSSL verification of the cert |
| 1243 | * sent from the server to the client. It is sent to protocol[0] |
| 1244 | * callback as no protocol has been negotiated on the connection yet. |
| 1245 | * Notice that the wsi is set because lws_client_connect_via_info was |
| 1246 | * successful. |
| 1247 | * |
| 1248 | * See http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html |
| 1249 | * to understand more detail about the OpenSSL callback that |
| 1250 | * generates this libwebsockets callback and the meanings of the |
| 1251 | * arguments passed. In this callback, user is the x509_ctx, |
| 1252 | * in is the ssl pointer and len is preverify_ok. |
| 1253 | * |
| 1254 | * THIS IS NOT RECOMMENDED BUT if a cert validation error shall be |
| 1255 | * overruled and cert shall be accepted as ok, |
| 1256 | * X509_STORE_CTX_set_error((X509_STORE_CTX*)user, X509_V_OK); must be |
| 1257 | * called and return value must be 0 to mean the cert is OK; |
| 1258 | * returning 1 will fail the cert in any case. |
| 1259 | * |
| 1260 | * This also means that if you don't handle this callback then |
| 1261 | * the default callback action of returning 0 will not accept the |
| 1262 | * certificate in case of a validation error decided by the SSL lib. |
| 1263 | * |
| 1264 | * This is expected and secure behaviour when validating certificates. |
| 1265 | * |
| 1266 | * Note: LCCSCF_ALLOW_SELFSIGNED and |
| 1267 | * LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK still work without this |
| 1268 | * callback being implemented. |
| 1269 | */ |
Andy Green | 297c031 | 2017-02-12 20:32:49 +0800 | [diff] [blame] | 1270 | LWS_CALLBACK_RAW_RX = 59, |
| 1271 | /**< RAW mode connection RX */ |
| 1272 | LWS_CALLBACK_RAW_CLOSE = 60, |
| 1273 | /**< RAW mode connection is closing */ |
| 1274 | LWS_CALLBACK_RAW_WRITEABLE = 61, |
| 1275 | /**< RAW mode connection may be written */ |
| 1276 | LWS_CALLBACK_RAW_ADOPT = 62, |
Andy Green | be8d791 | 2017-02-27 12:55:56 +0800 | [diff] [blame] | 1277 | /**< RAW mode connection was adopted (equivalent to 'wsi created') */ |
| 1278 | LWS_CALLBACK_RAW_ADOPT_FILE = 63, |
| 1279 | /**< RAW mode file was adopted (equivalent to 'wsi created') */ |
| 1280 | LWS_CALLBACK_RAW_RX_FILE = 64, |
| 1281 | /**< RAW mode file has something to read */ |
| 1282 | LWS_CALLBACK_RAW_WRITEABLE_FILE = 65, |
| 1283 | /**< RAW mode file is writeable */ |
| 1284 | LWS_CALLBACK_RAW_CLOSE_FILE = 66, |
| 1285 | /**< RAW mode wsi that adopted a file is closing */ |
Andy Green | 3ff720f | 2017-06-20 11:46:49 +0800 | [diff] [blame] | 1286 | LWS_CALLBACK_SSL_INFO = 67, |
| 1287 | /**< SSL connections only. An event you registered an |
| 1288 | * interest in at the vhost has occurred on a connection |
| 1289 | * using the vhost. @in is a pointer to a |
| 1290 | * struct lws_ssl_info containing information about the |
| 1291 | * event*/ |
Andy Green | 6f11c13 | 2017-07-19 04:39:14 +0800 | [diff] [blame] | 1292 | LWS_CALLBACK_CHILD_WRITE_VIA_PARENT = 68, |
| 1293 | /**< Child has been marked with parent_carries_io attribute, so |
| 1294 | * lws_write directs the to this callback at the parent, |
| 1295 | * @in is a struct lws_write_passthru containing the args |
| 1296 | * the lws_write() was called with. |
| 1297 | */ |
| 1298 | LWS_CALLBACK_CHILD_CLOSING = 69, |
| 1299 | /**< Sent to parent to notify them a child is closing / being |
| 1300 | * destroyed. @in is the child wsi. |
| 1301 | */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1302 | |
| 1303 | /****** add new things just above ---^ ******/ |
| 1304 | |
| 1305 | LWS_CALLBACK_USER = 1000, |
Andy Green | be8d791 | 2017-02-27 12:55:56 +0800 | [diff] [blame] | 1306 | /**< user code can use any including above without fear of clashes */ |
SoapyMan | 11260da | 2015-12-10 07:52:31 +0800 | [diff] [blame] | 1307 | }; |
| 1308 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1309 | |
| 1310 | |
| 1311 | /** |
| 1312 | * typedef lws_callback_function() - User server actions |
| 1313 | * \param wsi: Opaque websocket instance pointer |
| 1314 | * \param reason: The reason for the call |
| 1315 | * \param user: Pointer to per-session user data allocated by library |
| 1316 | * \param in: Pointer used for some callback reasons |
| 1317 | * \param len: Length set for some callback reasons |
| 1318 | * |
| 1319 | * This callback is the way the user controls what is served. All the |
| 1320 | * protocol detail is hidden and handled by the library. |
| 1321 | * |
| 1322 | * For each connection / session there is user data allocated that is |
| 1323 | * pointed to by "user". You set the size of this user data area when |
| 1324 | * the library is initialized with lws_create_server. |
| 1325 | */ |
| 1326 | typedef int |
| 1327 | lws_callback_function(struct lws *wsi, enum lws_callback_reasons reason, |
| 1328 | void *user, void *in, size_t len); |
Andy Green | 2e5110e | 2017-08-26 12:15:40 +0800 | [diff] [blame] | 1329 | |
| 1330 | #define LWS_CB_REASON_AUX_BF__CGI 1 |
| 1331 | #define LWS_CB_REASON_AUX_BF__PROXY 2 |
| 1332 | #define LWS_CB_REASON_AUX_BF__CGI_CHUNK_END 4 |
| 1333 | #define LWS_CB_REASON_AUX_BF__CGI_HEADERS 8 |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1334 | ///@} |
| 1335 | |
| 1336 | /*! \defgroup extensions |
| 1337 | * |
| 1338 | * ##Extension releated functions |
| 1339 | * |
| 1340 | * Ws defines optional extensions, lws provides the ability to implement these |
| 1341 | * in user code if so desired. |
| 1342 | * |
| 1343 | * We provide one extensions permessage-deflate. |
| 1344 | */ |
| 1345 | ///@{ |
| 1346 | |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 1347 | /* |
| 1348 | * NOTE: These public enums are part of the abi. If you want to add one, |
| 1349 | * add it at where specified so existing users are unaffected. |
| 1350 | */ |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame] | 1351 | enum lws_extension_callback_reasons { |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 1352 | LWS_EXT_CB_SERVER_CONTEXT_CONSTRUCT = 0, |
| 1353 | LWS_EXT_CB_CLIENT_CONTEXT_CONSTRUCT = 1, |
| 1354 | LWS_EXT_CB_SERVER_CONTEXT_DESTRUCT = 2, |
| 1355 | LWS_EXT_CB_CLIENT_CONTEXT_DESTRUCT = 3, |
| 1356 | LWS_EXT_CB_CONSTRUCT = 4, |
| 1357 | LWS_EXT_CB_CLIENT_CONSTRUCT = 5, |
| 1358 | LWS_EXT_CB_CHECK_OK_TO_REALLY_CLOSE = 6, |
Andy Green | 1b2c9a2 | 2016-01-29 21:18:54 +0800 | [diff] [blame] | 1359 | LWS_EXT_CB_CHECK_OK_TO_PROPOSE_EXTENSION = 7, |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 1360 | LWS_EXT_CB_DESTROY = 8, |
| 1361 | LWS_EXT_CB_DESTROY_ANY_WSI_CLOSING = 9, |
| 1362 | LWS_EXT_CB_ANY_WSI_ESTABLISHED = 10, |
| 1363 | LWS_EXT_CB_PACKET_RX_PREPARSE = 11, |
| 1364 | LWS_EXT_CB_PACKET_TX_PRESEND = 12, |
| 1365 | LWS_EXT_CB_PACKET_TX_DO_SEND = 13, |
| 1366 | LWS_EXT_CB_HANDSHAKE_REPLY_TX = 14, |
| 1367 | LWS_EXT_CB_FLUSH_PENDING_TX = 15, |
| 1368 | LWS_EXT_CB_EXTENDED_PAYLOAD_RX = 16, |
| 1369 | LWS_EXT_CB_CAN_PROXY_CLIENT_CONNECTION = 17, |
| 1370 | LWS_EXT_CB_1HZ = 18, |
| 1371 | LWS_EXT_CB_REQUEST_ON_WRITEABLE = 19, |
| 1372 | LWS_EXT_CB_IS_WRITEABLE = 20, |
| 1373 | LWS_EXT_CB_PAYLOAD_TX = 21, |
| 1374 | LWS_EXT_CB_PAYLOAD_RX = 22, |
| 1375 | LWS_EXT_CB_OPTION_DEFAULT = 23, |
| 1376 | LWS_EXT_CB_OPTION_SET = 24, |
| 1377 | LWS_EXT_CB_OPTION_CONFIRM = 25, |
Andy Green | c5376b1 | 2016-04-08 09:45:49 +0800 | [diff] [blame] | 1378 | LWS_EXT_CB_NAMED_OPTION_SET = 26, |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 1379 | |
| 1380 | /****** add new things just above ---^ ******/ |
Andy Green | c511482 | 2011-03-06 10:29:35 +0000 | [diff] [blame] | 1381 | }; |
| 1382 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1383 | /** enum lws_ext_options_types */ |
| 1384 | enum lws_ext_options_types { |
| 1385 | EXTARG_NONE, /**< does not take an argument */ |
| 1386 | EXTARG_DEC, /**< requires a decimal argument */ |
| 1387 | EXTARG_OPT_DEC /**< may have an optional decimal argument */ |
| 1388 | |
| 1389 | /* Add new things just above here ---^ |
| 1390 | * This is part of the ABI, don't needlessly break compatibility */ |
| 1391 | }; |
| 1392 | |
| 1393 | /** struct lws_ext_options - Option arguments to the extension. These are |
| 1394 | * used in the negotiation at ws upgrade time. |
| 1395 | * The helper function lws_ext_parse_options() |
| 1396 | * uses these to generate callbacks */ |
| 1397 | struct lws_ext_options { |
| 1398 | const char *name; /**< Option name, eg, "server_no_context_takeover" */ |
| 1399 | enum lws_ext_options_types type; /**< What kind of args the option can take */ |
| 1400 | |
| 1401 | /* Add new things just above here ---^ |
| 1402 | * This is part of the ABI, don't needlessly break compatibility */ |
| 1403 | }; |
| 1404 | |
| 1405 | /** struct lws_ext_option_arg */ |
| 1406 | struct lws_ext_option_arg { |
| 1407 | const char *option_name; /**< may be NULL, option_index used then */ |
| 1408 | int option_index; /**< argument ordinal to use if option_name missing */ |
| 1409 | const char *start; /**< value */ |
| 1410 | int len; /**< length of value */ |
| 1411 | }; |
| 1412 | |
| 1413 | /** |
| 1414 | * typedef lws_extension_callback_function() - Hooks to allow extensions to operate |
| 1415 | * \param context: Websockets context |
| 1416 | * \param ext: This extension |
| 1417 | * \param wsi: Opaque websocket instance pointer |
| 1418 | * \param reason: The reason for the call |
| 1419 | * \param user: Pointer to ptr to per-session user data allocated by library |
| 1420 | * \param in: Pointer used for some callback reasons |
| 1421 | * \param len: Length set for some callback reasons |
| 1422 | * |
| 1423 | * Each extension that is active on a particular connection receives |
| 1424 | * callbacks during the connection lifetime to allow the extension to |
| 1425 | * operate on websocket data and manage itself. |
| 1426 | * |
| 1427 | * Libwebsockets takes care of allocating and freeing "user" memory for |
| 1428 | * each active extension on each connection. That is what is pointed to |
| 1429 | * by the user parameter. |
| 1430 | * |
| 1431 | * LWS_EXT_CB_CONSTRUCT: called when the server has decided to |
| 1432 | * select this extension from the list provided by the client, |
| 1433 | * just before the server will send back the handshake accepting |
| 1434 | * the connection with this extension active. This gives the |
| 1435 | * extension a chance to initialize its connection context found |
| 1436 | * in user. |
| 1437 | * |
| 1438 | * LWS_EXT_CB_CLIENT_CONSTRUCT: same as LWS_EXT_CB_CONSTRUCT |
| 1439 | * but called when client is instantiating this extension. Some |
| 1440 | * extensions will work the same on client and server side and then |
| 1441 | * you can just merge handlers for both CONSTRUCTS. |
| 1442 | * |
| 1443 | * LWS_EXT_CB_DESTROY: called when the connection the extension was |
| 1444 | * being used on is about to be closed and deallocated. It's the |
| 1445 | * last chance for the extension to deallocate anything it has |
| 1446 | * allocated in the user data (pointed to by user) before the |
| 1447 | * user data is deleted. This same callback is used whether you |
| 1448 | * are in client or server instantiation context. |
| 1449 | * |
| 1450 | * LWS_EXT_CB_PACKET_RX_PREPARSE: when this extension was active on |
| 1451 | * a connection, and a packet of data arrived at the connection, |
| 1452 | * it is passed to this callback to give the extension a chance to |
| 1453 | * change the data, eg, decompress it. user is pointing to the |
| 1454 | * extension's private connection context data, in is pointing |
| 1455 | * to an lws_tokens struct, it consists of a char * pointer called |
| 1456 | * token, and an int called token_len. At entry, these are |
| 1457 | * set to point to the received buffer and set to the content |
| 1458 | * length. If the extension will grow the content, it should use |
| 1459 | * a new buffer allocated in its private user context data and |
| 1460 | * set the pointed-to lws_tokens members to point to its buffer. |
| 1461 | * |
| 1462 | * LWS_EXT_CB_PACKET_TX_PRESEND: this works the same way as |
| 1463 | * LWS_EXT_CB_PACKET_RX_PREPARSE above, except it gives the |
| 1464 | * extension a chance to change websocket data just before it will |
| 1465 | * be sent out. Using the same lws_token pointer scheme in in, |
| 1466 | * the extension can change the buffer and the length to be |
| 1467 | * transmitted how it likes. Again if it wants to grow the |
| 1468 | * buffer safely, it should copy the data into its own buffer and |
| 1469 | * set the lws_tokens token pointer to it. |
| 1470 | * |
| 1471 | * LWS_EXT_CB_ARGS_VALIDATE: |
| 1472 | */ |
| 1473 | typedef int |
| 1474 | lws_extension_callback_function(struct lws_context *context, |
| 1475 | const struct lws_extension *ext, struct lws *wsi, |
| 1476 | enum lws_extension_callback_reasons reason, |
| 1477 | void *user, void *in, size_t len); |
| 1478 | |
| 1479 | /** struct lws_extension - An extension we support */ |
| 1480 | struct lws_extension { |
| 1481 | const char *name; /**< Formal extension name, eg, "permessage-deflate" */ |
| 1482 | lws_extension_callback_function *callback; /**< Service callback */ |
| 1483 | const char *client_offer; /**< String containing exts and options client offers */ |
| 1484 | |
| 1485 | /* Add new things just above here ---^ |
| 1486 | * This is part of the ABI, don't needlessly break compatibility */ |
| 1487 | }; |
| 1488 | |
| 1489 | /** |
| 1490 | * lws_set_extension_option(): set extension option if possible |
| 1491 | * |
| 1492 | * \param wsi: websocket connection |
| 1493 | * \param ext_name: name of ext, like "permessage-deflate" |
| 1494 | * \param opt_name: name of option, like "rx_buf_size" |
| 1495 | * \param opt_val: value to set option to |
| 1496 | */ |
| 1497 | LWS_VISIBLE LWS_EXTERN int |
| 1498 | lws_set_extension_option(struct lws *wsi, const char *ext_name, |
| 1499 | const char *opt_name, const char *opt_val); |
| 1500 | |
| 1501 | #ifndef LWS_NO_EXTENSIONS |
| 1502 | /* lws_get_internal_extensions() - DEPRECATED |
| 1503 | * |
| 1504 | * \Deprecated There is no longer a set internal extensions table. The table is provided |
| 1505 | * by user code along with application-specific settings. See the test |
| 1506 | * client and server for how to do. |
| 1507 | */ |
| 1508 | static LWS_INLINE LWS_WARN_DEPRECATED const struct lws_extension * |
Joerg Pommnitz | 0733610 | 2016-10-10 20:10:39 +0800 | [diff] [blame] | 1509 | lws_get_internal_extensions(void) { return NULL; } |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1510 | |
| 1511 | /** |
| 1512 | * lws_ext_parse_options() - deal with parsing negotiated extension options |
| 1513 | * |
| 1514 | * \param ext: related extension struct |
| 1515 | * \param wsi: websocket connection |
| 1516 | * \param ext_user: per-connection extension private data |
| 1517 | * \param opts: list of supported options |
| 1518 | * \param o: option string to parse |
| 1519 | * \param len: length |
| 1520 | */ |
| 1521 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| 1522 | lws_ext_parse_options(const struct lws_extension *ext, struct lws *wsi, |
| 1523 | void *ext_user, const struct lws_ext_options *opts, |
| 1524 | const char *o, int len); |
| 1525 | #endif |
| 1526 | |
| 1527 | /** lws_extension_callback_pm_deflate() - extension for RFC7692 |
| 1528 | * |
| 1529 | * \param context: lws context |
| 1530 | * \param ext: related lws_extension struct |
| 1531 | * \param wsi: websocket connection |
| 1532 | * \param reason: incoming callback reason |
| 1533 | * \param user: per-connection extension private data |
| 1534 | * \param in: pointer parameter |
| 1535 | * \param len: length parameter |
| 1536 | * |
| 1537 | * Built-in callback implementing RFC7692 permessage-deflate |
| 1538 | */ |
| 1539 | LWS_EXTERN |
| 1540 | int lws_extension_callback_pm_deflate( |
| 1541 | struct lws_context *context, const struct lws_extension *ext, |
| 1542 | struct lws *wsi, enum lws_extension_callback_reasons reason, |
| 1543 | void *user, void *in, size_t len); |
| 1544 | |
| 1545 | /* |
| 1546 | * The internal exts are part of the public abi |
| 1547 | * If we add more extensions, publish the callback here ------v |
| 1548 | */ |
| 1549 | ///@} |
| 1550 | |
| 1551 | /*! \defgroup Protocols-and-Plugins Protocols and Plugins |
| 1552 | * \ingroup lwsapi |
| 1553 | * |
| 1554 | * ##Protocol and protocol plugin -related apis |
| 1555 | * |
| 1556 | * Protocols bind ws protocol names to a custom callback specific to that |
| 1557 | * protocol implementaion. |
| 1558 | * |
| 1559 | * A list of protocols can be passed in at context creation time, but it is |
| 1560 | * also legal to leave that NULL and add the protocols and their callback code |
| 1561 | * using plugins. |
| 1562 | * |
| 1563 | * Plugins are much preferable compared to cut and pasting code into an |
| 1564 | * application each time, since they can be used standalone. |
| 1565 | */ |
| 1566 | ///@{ |
| 1567 | /** struct lws_protocols - List of protocols and handlers client or server |
| 1568 | * supports. */ |
| 1569 | |
| 1570 | struct lws_protocols { |
| 1571 | const char *name; |
| 1572 | /**< Protocol name that must match the one given in the client |
| 1573 | * Javascript new WebSocket(url, 'protocol') name. */ |
| 1574 | lws_callback_function *callback; |
| 1575 | /**< The service callback used for this protocol. It allows the |
| 1576 | * service action for an entire protocol to be encapsulated in |
| 1577 | * the protocol-specific callback */ |
| 1578 | size_t per_session_data_size; |
| 1579 | /**< Each new connection using this protocol gets |
| 1580 | * this much memory allocated on connection establishment and |
| 1581 | * freed on connection takedown. A pointer to this per-connection |
| 1582 | * allocation is passed into the callback in the 'user' parameter */ |
| 1583 | size_t rx_buffer_size; |
| 1584 | /**< lws allocates this much space for rx data and informs callback |
| 1585 | * when something came. Due to rx flow control, the callback may not |
| 1586 | * be able to consume it all without having to return to the event |
| 1587 | * loop. That is supported in lws. |
| 1588 | * |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 1589 | * If .tx_packet_size is 0, this also controls how much may be sent at once |
| 1590 | * for backwards compatibility. |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1591 | */ |
| 1592 | unsigned int id; |
| 1593 | /**< ignored by lws, but useful to contain user information bound |
| 1594 | * to the selected protocol. For example if this protocol was |
| 1595 | * called "myprotocol-v2", you might set id to 2, and the user |
| 1596 | * code that acts differently according to the version can do so by |
| 1597 | * switch (wsi->protocol->id), user code might use some bits as |
| 1598 | * capability flags based on selected protocol version, etc. */ |
| 1599 | void *user; /**< ignored by lws, but user code can pass a pointer |
| 1600 | here it can later access from the protocol callback */ |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 1601 | size_t tx_packet_size; |
| 1602 | /**< 0 indicates restrict send() size to .rx_buffer_size for backwards- |
| 1603 | * compatibility. |
| 1604 | * If greater than zero, a single send() is restricted to this amount |
| 1605 | * and any remainder is buffered by lws and sent afterwards also in |
| 1606 | * these size chunks. Since that is expensive, it's preferable |
| 1607 | * to restrict one fragment you are trying to send to match this |
| 1608 | * size. |
| 1609 | */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1610 | |
| 1611 | /* Add new things just above here ---^ |
| 1612 | * This is part of the ABI, don't needlessly break compatibility */ |
| 1613 | }; |
| 1614 | |
| 1615 | struct lws_vhost; |
| 1616 | |
| 1617 | /** |
| 1618 | * lws_vhost_name_to_protocol() - get vhost's protocol object from its name |
| 1619 | * |
| 1620 | * \param vh: vhost to search |
| 1621 | * \param name: protocol name |
| 1622 | * |
| 1623 | * Returns NULL or a pointer to the vhost's protocol of the requested name |
| 1624 | */ |
| 1625 | LWS_VISIBLE LWS_EXTERN const struct lws_protocols * |
| 1626 | lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name); |
| 1627 | |
| 1628 | /** |
| 1629 | * lws_get_protocol() - Returns a protocol pointer from a websocket |
| 1630 | * connection. |
| 1631 | * \param wsi: pointer to struct websocket you want to know the protocol of |
| 1632 | * |
| 1633 | * |
| 1634 | * Some apis can act on all live connections of a given protocol, |
| 1635 | * this is how you can get a pointer to the active protocol if needed. |
| 1636 | */ |
| 1637 | LWS_VISIBLE LWS_EXTERN const struct lws_protocols * |
| 1638 | lws_get_protocol(struct lws *wsi); |
| 1639 | |
| 1640 | /** lws_protocol_get() - deprecated: use lws_get_protocol */ |
| 1641 | LWS_VISIBLE LWS_EXTERN const struct lws_protocols * |
| 1642 | lws_protocol_get(struct lws *wsi) LWS_WARN_DEPRECATED; |
| 1643 | |
| 1644 | /** |
| 1645 | * lws_protocol_vh_priv_zalloc() - Allocate and zero down a protocol's per-vhost |
| 1646 | * storage |
| 1647 | * \param vhost: vhost the instance is related to |
| 1648 | * \param prot: protocol the instance is related to |
| 1649 | * \param size: bytes to allocate |
| 1650 | * |
| 1651 | * Protocols often find it useful to allocate a per-vhost struct, this is a |
| 1652 | * helper to be called in the per-vhost init LWS_CALLBACK_PROTOCOL_INIT |
| 1653 | */ |
| 1654 | LWS_VISIBLE LWS_EXTERN void * |
| 1655 | lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_protocols *prot, |
| 1656 | int size); |
| 1657 | |
| 1658 | /** |
| 1659 | * lws_protocol_vh_priv_get() - retreive a protocol's per-vhost storage |
| 1660 | * |
| 1661 | * \param vhost: vhost the instance is related to |
| 1662 | * \param prot: protocol the instance is related to |
| 1663 | * |
| 1664 | * Recover a pointer to the allocated per-vhost storage for the protocol created |
| 1665 | * by lws_protocol_vh_priv_zalloc() earlier |
| 1666 | */ |
| 1667 | LWS_VISIBLE LWS_EXTERN void * |
| 1668 | lws_protocol_vh_priv_get(struct lws_vhost *vhost, const struct lws_protocols *prot); |
| 1669 | |
| 1670 | /** |
| 1671 | * lws_finalize_startup() - drop initial process privileges |
| 1672 | * |
| 1673 | * \param context: lws context |
| 1674 | * |
| 1675 | * This is called after the end of the vhost protocol initializations, but |
| 1676 | * you may choose to call it earlier |
| 1677 | */ |
| 1678 | LWS_VISIBLE LWS_EXTERN int |
| 1679 | lws_finalize_startup(struct lws_context *context); |
| 1680 | |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 1681 | LWS_VISIBLE LWS_EXTERN int |
| 1682 | lws_protocol_init(struct lws_context *context); |
| 1683 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1684 | #ifdef LWS_WITH_PLUGINS |
| 1685 | |
| 1686 | /* PLUGINS implies LIBUV */ |
| 1687 | |
| 1688 | #define LWS_PLUGIN_API_MAGIC 180 |
| 1689 | |
| 1690 | /** struct lws_plugin_capability - how a plugin introduces itself to lws */ |
| 1691 | struct lws_plugin_capability { |
| 1692 | unsigned int api_magic; /**< caller fills this in, plugin fills rest */ |
| 1693 | const struct lws_protocols *protocols; /**< array of supported protocols provided by plugin */ |
| 1694 | int count_protocols; /**< how many protocols */ |
| 1695 | const struct lws_extension *extensions; /**< array of extensions provided by plugin */ |
| 1696 | int count_extensions; /**< how many extensions */ |
| 1697 | }; |
| 1698 | |
| 1699 | typedef int (*lws_plugin_init_func)(struct lws_context *, |
| 1700 | struct lws_plugin_capability *); |
| 1701 | typedef int (*lws_plugin_destroy_func)(struct lws_context *); |
| 1702 | |
| 1703 | /** struct lws_plugin */ |
| 1704 | struct lws_plugin { |
| 1705 | struct lws_plugin *list; /**< linked list */ |
| 1706 | #if (UV_VERSION_MAJOR > 0) |
| 1707 | uv_lib_t lib; /**< shared library pointer */ |
| 1708 | #else |
| 1709 | void *l; /**< so we can compile on ancient libuv */ |
| 1710 | #endif |
| 1711 | char name[64]; /**< name of the plugin */ |
| 1712 | struct lws_plugin_capability caps; /**< plugin capabilities */ |
| 1713 | }; |
| 1714 | |
| 1715 | #endif |
| 1716 | |
| 1717 | ///@} |
| 1718 | |
| 1719 | |
| 1720 | /*! \defgroup generic-sessions plugin: generic-sessions |
| 1721 | * \ingroup Protocols-and-Plugins |
| 1722 | * |
| 1723 | * ##Plugin Generic-sessions related |
| 1724 | * |
| 1725 | * generic-sessions plugin provides a reusable, generic session and login / |
| 1726 | * register / forgot password framework including email verification. |
| 1727 | */ |
| 1728 | ///@{ |
| 1729 | |
| 1730 | #define LWSGS_EMAIL_CONTENT_SIZE 16384 |
| 1731 | /**< Maximum size of email we might send */ |
| 1732 | |
| 1733 | /* SHA-1 binary and hexified versions */ |
| 1734 | /** typedef struct lwsgw_hash_bin */ |
| 1735 | typedef struct { unsigned char bin[20]; /**< binary representation of hash */} lwsgw_hash_bin; |
| 1736 | /** typedef struct lwsgw_hash */ |
| 1737 | typedef struct { char id[41]; /**< ascii hex representation of hash */ } lwsgw_hash; |
| 1738 | |
| 1739 | /** enum lwsgs_auth_bits */ |
| 1740 | enum lwsgs_auth_bits { |
| 1741 | LWSGS_AUTH_LOGGED_IN = 1, /**< user is logged in as somebody */ |
| 1742 | LWSGS_AUTH_ADMIN = 2, /**< logged in as the admin user */ |
| 1743 | LWSGS_AUTH_VERIFIED = 4, /**< user has verified his email */ |
| 1744 | LWSGS_AUTH_FORGOT_FLOW = 8, /**< he just completed "forgot password" flow */ |
| 1745 | }; |
| 1746 | |
| 1747 | /** struct lws_session_info - information about user session status */ |
| 1748 | struct lws_session_info { |
| 1749 | char username[32]; /**< username logged in as, or empty string */ |
| 1750 | char email[100]; /**< email address associated with login, or empty string */ |
| 1751 | char ip[72]; /**< ip address session was started from */ |
| 1752 | unsigned int mask; /**< access rights mask associated with session |
| 1753 | * see enum lwsgs_auth_bits */ |
| 1754 | char session[42]; /**< session id string, usable as opaque uid when not logged in */ |
| 1755 | }; |
| 1756 | |
| 1757 | /** enum lws_gs_event */ |
| 1758 | enum lws_gs_event { |
| 1759 | LWSGSE_CREATED, /**< a new user was created */ |
| 1760 | LWSGSE_DELETED /**< an existing user was deleted */ |
| 1761 | }; |
| 1762 | |
| 1763 | /** struct lws_gs_event_args */ |
| 1764 | struct lws_gs_event_args { |
| 1765 | enum lws_gs_event event; /**< which event happened */ |
| 1766 | const char *username; /**< which username the event happened to */ |
| 1767 | const char *email; /**< the email address of that user */ |
| 1768 | }; |
| 1769 | |
| 1770 | ///@} |
| 1771 | |
| 1772 | |
| 1773 | /*! \defgroup context-and-vhost |
| 1774 | * \ingroup lwsapi |
| 1775 | * |
| 1776 | * ##Context and Vhost releated functions |
| 1777 | * |
| 1778 | * LWS requires that there is one context, in which you may define multiple |
| 1779 | * vhosts. Each vhost is a virtual host, with either its own listen port |
| 1780 | * or sharing an existing one. Each vhost has its own SSL context that can |
| 1781 | * be set up individually or left disabled. |
| 1782 | * |
| 1783 | * If you don't care about multiple "site" support, you can ignore it and |
| 1784 | * lws will create a single default vhost at context creation time. |
| 1785 | */ |
| 1786 | ///@{ |
| 1787 | |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 1788 | /* |
| 1789 | * NOTE: These public enums are part of the abi. If you want to add one, |
| 1790 | * add it at where specified so existing users are unaffected. |
| 1791 | */ |
Andy Green | 38e57bb | 2011-01-19 12:20:27 +0000 | [diff] [blame] | 1792 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1793 | /** enum lws_context_options - context and vhost options */ |
| 1794 | enum lws_context_options { |
| 1795 | LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = (1 << 1) | |
| 1796 | (1 << 12), |
| 1797 | /**< (VH) Don't allow the connection unless the client has a |
| 1798 | * client cert that we recognize; provides |
| 1799 | * LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT */ |
| 1800 | LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = (1 << 2), |
| 1801 | /**< (CTX) Don't try to get the server's hostname */ |
| 1802 | LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = (1 << 3) | |
| 1803 | (1 << 12), |
| 1804 | /**< (VH) Allow non-SSL (plaintext) connections on the same |
| 1805 | * port as SSL is listening... undermines the security of SSL; |
| 1806 | * provides LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT */ |
| 1807 | LWS_SERVER_OPTION_LIBEV = (1 << 4), |
| 1808 | /**< (CTX) Use libev event loop */ |
| 1809 | LWS_SERVER_OPTION_DISABLE_IPV6 = (1 << 5), |
| 1810 | /**< (VH) Disable IPV6 support */ |
| 1811 | LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = (1 << 6), |
| 1812 | /**< (VH) Don't load OS CA certs, you will need to load your |
| 1813 | * own CA cert(s) */ |
| 1814 | LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED = (1 << 7), |
| 1815 | /**< (VH) Accept connections with no valid Cert (eg, selfsigned) */ |
| 1816 | LWS_SERVER_OPTION_VALIDATE_UTF8 = (1 << 8), |
| 1817 | /**< (VH) Check UT-8 correctness */ |
| 1818 | LWS_SERVER_OPTION_SSL_ECDH = (1 << 9) | |
| 1819 | (1 << 12), |
| 1820 | /**< (VH) initialize ECDH ciphers */ |
| 1821 | LWS_SERVER_OPTION_LIBUV = (1 << 10), |
| 1822 | /**< (CTX) Use libuv event loop */ |
| 1823 | LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS = (1 << 11) | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1824 | (1 << 12), |
| 1825 | /**< (VH) Use http redirect to force http to https |
| 1826 | * (deprecated: use mount redirection) */ |
| 1827 | LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT = (1 << 12), |
| 1828 | /**< (CTX) Initialize the SSL library at all */ |
| 1829 | LWS_SERVER_OPTION_EXPLICIT_VHOSTS = (1 << 13), |
| 1830 | /**< (CTX) Only create the context when calling context |
| 1831 | * create api, implies user code will create its own vhosts */ |
| 1832 | LWS_SERVER_OPTION_UNIX_SOCK = (1 << 14), |
| 1833 | /**< (VH) Use Unix socket */ |
| 1834 | LWS_SERVER_OPTION_STS = (1 << 15), |
| 1835 | /**< (VH) Send Strict Transport Security header, making |
| 1836 | * clients subsequently go to https even if user asked for http */ |
| 1837 | LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY = (1 << 16), |
| 1838 | /**< (VH) Enable LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE to take effect */ |
| 1839 | LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE = (1 << 17), |
| 1840 | /**< (VH) if set, only ipv6 allowed on the vhost */ |
Andy Green | 90f513b | 2016-08-20 05:47:29 +0800 | [diff] [blame] | 1841 | LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN = (1 << 18), |
| 1842 | /**< (CTX) Libuv only: Do not spin on SIGSEGV / SIGFPE. A segfault |
| 1843 | * normally makes the lib spin so you can attach a debugger to it |
| 1844 | * even if it happened without a debugger in place. You can disable |
| 1845 | * that by giving this option. |
| 1846 | */ |
Andy Green | 716aaee | 2017-01-23 19:52:27 +0800 | [diff] [blame] | 1847 | LWS_SERVER_OPTION_JUST_USE_RAW_ORIGIN = (1 << 19), |
| 1848 | /**< For backwards-compatibility reasons, by default |
| 1849 | * lws prepends "http://" to the origin you give in the client |
| 1850 | * connection info struct. If you give this flag when you create |
| 1851 | * the context, only the string you give in the client connect |
| 1852 | * info for .origin (if any) will be used directly. |
| 1853 | */ |
Andy Green | 205cced | 2017-03-07 16:06:05 +0800 | [diff] [blame] | 1854 | LWS_SERVER_OPTION_FALLBACK_TO_RAW = (1 << 20), |
| 1855 | /**< (VH) if invalid http is coming in the first line, */ |
Aditya Tirumala | ec50eba | 2017-03-15 19:41:11 +0530 | [diff] [blame] | 1856 | LWS_SERVER_OPTION_LIBEVENT = (1 << 21), |
| 1857 | /**< (CTX) Use libevent event loop */ |
Andy Green | 6cae994 | 2017-04-06 07:57:45 +0800 | [diff] [blame] | 1858 | LWS_SERVER_OPTION_ONLY_RAW = (1 << 22), |
| 1859 | /**< (VH) All connections to this vhost / port are RAW as soon as |
| 1860 | * the connection is accepted, no HTTP is going to be coming. |
| 1861 | */ |
Andy Green | abc2a5c | 2017-06-23 13:08:46 +0800 | [diff] [blame] | 1862 | LWS_SERVER_OPTION_ALLOW_LISTEN_SHARE = (1 << 23), |
| 1863 | /**< (VH) Set to allow multiple listen sockets on one interface + |
| 1864 | * address + port. The default is to strictly allow only one |
| 1865 | * listen socket at a time. This is automatically selected if you |
| 1866 | * have multiple service threads. |
| 1867 | */ |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 1868 | |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 1869 | /****** add new things just above ---^ ******/ |
Andy Green | ff95d7a | 2010-10-28 22:36:01 +0100 | [diff] [blame] | 1870 | }; |
| 1871 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1872 | #define lws_check_opt(c, f) (((c) & (f)) == (f)) |
| 1873 | |
Andy Green | 1ada132 | 2017-03-01 14:28:56 +0800 | [diff] [blame] | 1874 | struct lws_plat_file_ops; |
| 1875 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1876 | /** struct lws_context_creation_info - parameters to create context and /or vhost with |
| 1877 | * |
| 1878 | * This is also used to create vhosts.... if LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
| 1879 | * is not given, then for backwards compatibility one vhost is created at |
| 1880 | * context-creation time using the info from this struct. |
| 1881 | * |
| 1882 | * If LWS_SERVER_OPTION_EXPLICIT_VHOSTS is given, then no vhosts are created |
| 1883 | * at the same time as the context, they are expected to be created afterwards. |
| 1884 | */ |
| 1885 | struct lws_context_creation_info { |
| 1886 | int port; |
Alan Conway | f3ad954 | 2016-12-21 09:32:44 +0800 | [diff] [blame] | 1887 | /**< VHOST: Port to listen on. Use CONTEXT_PORT_NO_LISTEN to suppress |
| 1888 | * listening for a client. Use CONTEXT_PORT_NO_LISTEN_SERVER if you are |
| 1889 | * writing a server but you are using \ref sock-adopt instead of the |
| 1890 | * built-in listener */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1891 | const char *iface; |
| 1892 | /**< VHOST: NULL to bind the listen socket to all interfaces, or the |
| 1893 | * interface name, eg, "eth2" |
| 1894 | * If options specifies LWS_SERVER_OPTION_UNIX_SOCK, this member is |
| 1895 | * the pathname of a UNIX domain socket. you can use the UNIX domain |
| 1896 | * sockets in abstract namespace, by prepending an at symbol to the |
| 1897 | * socket name. */ |
| 1898 | const struct lws_protocols *protocols; |
| 1899 | /**< VHOST: Array of structures listing supported protocols and a protocol- |
| 1900 | * specific callback for each one. The list is ended with an |
| 1901 | * entry that has a NULL callback pointer. */ |
| 1902 | const struct lws_extension *extensions; |
| 1903 | /**< VHOST: NULL or array of lws_extension structs listing the |
| 1904 | * extensions this context supports. */ |
| 1905 | const struct lws_token_limits *token_limits; |
| 1906 | /**< CONTEXT: NULL or struct lws_token_limits pointer which is initialized |
| 1907 | * with a token length limit for each possible WSI_TOKEN_ */ |
| 1908 | const char *ssl_private_key_password; |
| 1909 | /**< VHOST: NULL or the passphrase needed for the private key */ |
| 1910 | const char *ssl_cert_filepath; |
| 1911 | /**< VHOST: If libwebsockets was compiled to use ssl, and you want |
| 1912 | * to listen using SSL, set to the filepath to fetch the |
| 1913 | * server cert from, otherwise NULL for unencrypted */ |
| 1914 | const char *ssl_private_key_filepath; |
| 1915 | /**< VHOST: filepath to private key if wanting SSL mode; |
| 1916 | * if this is set to NULL but sll_cert_filepath is set, the |
| 1917 | * OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY callback is called |
| 1918 | * to allow setting of the private key directly via openSSL |
| 1919 | * library calls */ |
| 1920 | const char *ssl_ca_filepath; |
| 1921 | /**< VHOST: CA certificate filepath or NULL */ |
| 1922 | const char *ssl_cipher_list; |
| 1923 | /**< VHOST: List of valid ciphers to use (eg, |
| 1924 | * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" |
| 1925 | * or you can leave it as NULL to get "DEFAULT" */ |
| 1926 | const char *http_proxy_address; |
| 1927 | /**< VHOST: If non-NULL, attempts to proxy via the given address. |
| 1928 | * If proxy auth is required, use format "username:password\@server:port" */ |
| 1929 | unsigned int http_proxy_port; |
| 1930 | /**< VHOST: If http_proxy_address was non-NULL, uses this port */ |
| 1931 | int gid; |
| 1932 | /**< CONTEXT: group id to change to after setting listen socket, or -1. */ |
| 1933 | int uid; |
| 1934 | /**< CONTEXT: user id to change to after setting listen socket, or -1. */ |
| 1935 | unsigned int options; |
| 1936 | /**< VHOST + CONTEXT: 0, or LWS_SERVER_OPTION_... bitfields */ |
| 1937 | void *user; |
| 1938 | /**< CONTEXT: optional user pointer that can be recovered via the context |
Andy Ning | ed92b6d | 2017-05-05 11:38:34 -0400 | [diff] [blame] | 1939 | * pointer using lws_context_user */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 1940 | int ka_time; |
| 1941 | /**< CONTEXT: 0 for no TCP keepalive, otherwise apply this keepalive |
| 1942 | * timeout to all libwebsocket sockets, client or server */ |
| 1943 | int ka_probes; |
| 1944 | /**< CONTEXT: if ka_time was nonzero, after the timeout expires how many |
| 1945 | * times to try to get a response from the peer before giving up |
| 1946 | * and killing the connection */ |
| 1947 | int ka_interval; |
| 1948 | /**< CONTEXT: if ka_time was nonzero, how long to wait before each ka_probes |
| 1949 | * attempt */ |
| 1950 | #ifdef LWS_OPENSSL_SUPPORT |
| 1951 | SSL_CTX *provided_client_ssl_ctx; |
| 1952 | /**< CONTEXT: If non-null, swap out libwebsockets ssl |
| 1953 | * implementation for the one provided by provided_ssl_ctx. |
| 1954 | * Libwebsockets no longer is responsible for freeing the context |
| 1955 | * if this option is selected. */ |
| 1956 | #else /* maintain structure layout either way */ |
| 1957 | void *provided_client_ssl_ctx; /**< dummy if ssl disabled */ |
| 1958 | #endif |
| 1959 | |
| 1960 | short max_http_header_data; |
| 1961 | /**< CONTEXT: The max amount of header payload that can be handled |
| 1962 | * in an http request (unrecognized header payload is dropped) */ |
| 1963 | short max_http_header_pool; |
| 1964 | /**< CONTEXT: The max number of connections with http headers that |
| 1965 | * can be processed simultaneously (the corresponding memory is |
| 1966 | * allocated for the lifetime of the context). If the pool is |
| 1967 | * busy new incoming connections must wait for accept until one |
| 1968 | * becomes free. */ |
| 1969 | |
| 1970 | unsigned int count_threads; |
| 1971 | /**< CONTEXT: how many contexts to create in an array, 0 = 1 */ |
| 1972 | unsigned int fd_limit_per_thread; |
| 1973 | /**< CONTEXT: nonzero means restrict each service thread to this |
| 1974 | * many fds, 0 means the default which is divide the process fd |
| 1975 | * limit by the number of threads. */ |
| 1976 | unsigned int timeout_secs; |
| 1977 | /**< VHOST: various processes involving network roundtrips in the |
| 1978 | * library are protected from hanging forever by timeouts. If |
| 1979 | * nonzero, this member lets you set the timeout used in seconds. |
| 1980 | * Otherwise a default timeout is used. */ |
| 1981 | const char *ecdh_curve; |
| 1982 | /**< VHOST: if NULL, defaults to initializing server with "prime256v1" */ |
| 1983 | const char *vhost_name; |
| 1984 | /**< VHOST: name of vhost, must match external DNS name used to |
| 1985 | * access the site, like "warmcat.com" as it's used to match |
| 1986 | * Host: header and / or SNI name for SSL. */ |
| 1987 | const char * const *plugin_dirs; |
| 1988 | /**< CONTEXT: NULL, or NULL-terminated array of directories to |
| 1989 | * scan for lws protocol plugins at context creation time */ |
| 1990 | const struct lws_protocol_vhost_options *pvo; |
| 1991 | /**< VHOST: pointer to optional linked list of per-vhost |
| 1992 | * options made accessible to protocols */ |
| 1993 | int keepalive_timeout; |
| 1994 | /**< VHOST: (default = 0 = 60s) seconds to allow remote |
| 1995 | * client to hold on to an idle HTTP/1.1 connection */ |
| 1996 | const char *log_filepath; |
| 1997 | /**< VHOST: filepath to append logs to... this is opened before |
| 1998 | * any dropping of initial privileges */ |
| 1999 | const struct lws_http_mount *mounts; |
| 2000 | /**< VHOST: optional linked list of mounts for this vhost */ |
| 2001 | const char *server_string; |
| 2002 | /**< CONTEXT: string used in HTTP headers to identify server |
| 2003 | * software, if NULL, "libwebsockets". */ |
| 2004 | unsigned int pt_serv_buf_size; |
| 2005 | /**< CONTEXT: 0 = default of 4096. This buffer is used by |
| 2006 | * various service related features including file serving, it |
| 2007 | * defines the max chunk of file that can be sent at once. |
| 2008 | * At the risk of lws having to buffer failed large sends, it |
| 2009 | * can be increased to, eg, 128KiB to improve throughput. */ |
| 2010 | unsigned int max_http_header_data2; |
| 2011 | /**< CONTEXT: if max_http_header_data is 0 and this |
| 2012 | * is nonzero, this will be used in place of the default. It's |
| 2013 | * like this for compatibility with the original short version, |
| 2014 | * this is unsigned int length. */ |
| 2015 | long ssl_options_set; |
| 2016 | /**< VHOST: Any bits set here will be set as SSL options */ |
| 2017 | long ssl_options_clear; |
| 2018 | /**< VHOST: Any bits set here will be cleared as SSL options */ |
Andy Green | f32d250 | 2016-07-15 13:41:38 +0800 | [diff] [blame] | 2019 | unsigned short ws_ping_pong_interval; |
| 2020 | /**< CONTEXT: 0 for none, else interval in seconds between sending |
| 2021 | * PINGs on idle websocket connections. When the PING is sent, |
| 2022 | * the PONG must come within the normal timeout_secs timeout period |
| 2023 | * or the connection will be dropped. |
| 2024 | * Any RX or TX traffic on the connection restarts the interval timer, |
| 2025 | * so a connection which always sends or receives something at intervals |
| 2026 | * less than the interval given here will never send PINGs / expect |
| 2027 | * PONGs. Conversely as soon as the ws connection is established, an |
| 2028 | * idle connection will do the PING / PONG roundtrip as soon as |
| 2029 | * ws_ping_pong_interval seconds has passed without traffic |
| 2030 | */ |
Andy Green | e35d91a | 2016-08-27 17:07:06 +0800 | [diff] [blame] | 2031 | const struct lws_protocol_vhost_options *headers; |
| 2032 | /**< VHOST: pointer to optional linked list of per-vhost |
| 2033 | * canned headers that are added to server responses */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2034 | |
Andy Green | 3b93e34 | 2016-10-13 06:32:57 +0800 | [diff] [blame] | 2035 | const struct lws_protocol_vhost_options *reject_service_keywords; |
| 2036 | /**< CONTEXT: Optional list of keywords and rejection codes + text. |
| 2037 | * |
| 2038 | * The keywords are checked for existing in the user agent string. |
| 2039 | * |
| 2040 | * Eg, "badrobot" "404 Not Found" |
| 2041 | */ |
Andy Green | 69c88d9 | 2016-12-04 07:34:05 +0800 | [diff] [blame] | 2042 | void *external_baggage_free_on_destroy; |
| 2043 | /**< CONTEXT: NULL, or pointer to something externally malloc'd, that |
| 2044 | * should be freed when the context is destroyed. This allows you to |
| 2045 | * automatically sync the freeing action to the context destruction |
| 2046 | * action, so there is no need for an external free() if the context |
| 2047 | * succeeded to create. |
| 2048 | */ |
Andy Green | 3b93e34 | 2016-10-13 06:32:57 +0800 | [diff] [blame] | 2049 | |
Joel Winarske | 390ba34 | 2017-02-20 20:53:58 -0800 | [diff] [blame] | 2050 | #ifdef LWS_OPENSSL_SUPPORT |
| 2051 | /**< CONTEXT: NULL or struct lws_token_limits pointer which is initialized |
| 2052 | * with a token length limit for each possible WSI_TOKEN_ */ |
| 2053 | const char *client_ssl_private_key_password; |
| 2054 | /**< VHOST: NULL or the passphrase needed for the private key */ |
| 2055 | const char *client_ssl_cert_filepath; |
| 2056 | /**< VHOST: If libwebsockets was compiled to use ssl, and you want |
| 2057 | * to listen using SSL, set to the filepath to fetch the |
| 2058 | * server cert from, otherwise NULL for unencrypted */ |
| 2059 | const char *client_ssl_private_key_filepath; |
| 2060 | /**< VHOST: filepath to private key if wanting SSL mode; |
| 2061 | * if this is set to NULL but sll_cert_filepath is set, the |
| 2062 | * OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY callback is called |
| 2063 | * to allow setting of the private key directly via openSSL |
| 2064 | * library calls */ |
| 2065 | const char *client_ssl_ca_filepath; |
| 2066 | /**< VHOST: CA certificate filepath or NULL */ |
| 2067 | const char *client_ssl_cipher_list; |
| 2068 | /**< VHOST: List of valid ciphers to use (eg, |
| 2069 | * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" |
| 2070 | * or you can leave it as NULL to get "DEFAULT" */ |
| 2071 | #endif |
| 2072 | |
Andy Green | 1ada132 | 2017-03-01 14:28:56 +0800 | [diff] [blame] | 2073 | const struct lws_plat_file_ops *fops; |
| 2074 | /**< CONTEXT: NULL, or pointer to an array of fops structs, terminated |
| 2075 | * by a sentinel with NULL .open. |
| 2076 | * |
| 2077 | * If NULL, lws provides just the platform file operations struct for |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 2078 | * backwards compatibility. |
Andy Green | 1ada132 | 2017-03-01 14:28:56 +0800 | [diff] [blame] | 2079 | */ |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 2080 | int simultaneous_ssl_restriction; |
| 2081 | /**< CONTEXT: 0 (no limit) or limit of simultaneous SSL sessions possible.*/ |
Andy Ning | ed92b6d | 2017-05-05 11:38:34 -0400 | [diff] [blame] | 2082 | const char *socks_proxy_address; |
| 2083 | /**< VHOST: If non-NULL, attempts to proxy via the given address. |
| 2084 | * If proxy auth is required, use format "username:password\@server:port" */ |
| 2085 | unsigned int socks_proxy_port; |
| 2086 | /**< VHOST: If socks_proxy_address was non-NULL, uses this port */ |
Andy Green | 156363f | 2017-06-07 06:10:02 +0800 | [diff] [blame] | 2087 | #if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) |
| 2088 | cap_value_t caps[4]; |
| 2089 | /**< CONTEXT: array holding Linux capabilities you want to |
| 2090 | * continue to be available to the server after it transitions |
| 2091 | * to a noprivileged user. Usually none are needed but for, eg, |
| 2092 | * .bind_iface, CAP_NET_RAW is required. This gives you a way |
| 2093 | * to still have the capability but drop root. |
| 2094 | */ |
| 2095 | char count_caps; |
| 2096 | /**< CONTEXT: count of Linux capabilities in .caps[]. 0 means |
| 2097 | * no capabilities will be inherited from root (the default) */ |
| 2098 | #endif |
Leonardo Maccari Rufino | 393b38a | 2017-06-02 14:07:35 -0300 | [diff] [blame] | 2099 | int bind_iface; |
| 2100 | /**< VHOST: nonzero to strictly bind sockets to the interface name in |
| 2101 | * .iface (eg, "eth2"), using SO_BIND_TO_DEVICE. |
| 2102 | * |
| 2103 | * Requires SO_BINDTODEVICE support from your OS and CAP_NET_RAW |
| 2104 | * capability. |
| 2105 | * |
| 2106 | * Notice that common things like access network interface IP from |
| 2107 | * your local machine use your lo / loopback interface and will be |
| 2108 | * disallowed by this. |
| 2109 | */ |
Andy Green | 1ada132 | 2017-03-01 14:28:56 +0800 | [diff] [blame] | 2110 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2111 | /* Add new things just above here ---^ |
| 2112 | * This is part of the ABI, don't needlessly break compatibility |
| 2113 | * |
| 2114 | * The below is to ensure later library versions with new |
| 2115 | * members added above will see 0 (default) even if the app |
| 2116 | * was not built against the newer headers. |
| 2117 | */ |
Andy Green | 3ff720f | 2017-06-20 11:46:49 +0800 | [diff] [blame] | 2118 | int ssl_info_event_mask; |
| 2119 | /**< VHOST: mask of ssl events to be reported on LWS_CALLBACK_SSL_INFO |
| 2120 | * callback for connections on this vhost. The mask values are of |
| 2121 | * the form SSL_CB_ALERT, defined in openssl/ssl.h. The default of |
| 2122 | * 0 means no info events will be reported. |
| 2123 | */ |
Andy Green | ba45f7c | 2017-07-26 11:49:41 +0800 | [diff] [blame] | 2124 | unsigned int timeout_secs_ah_idle; |
| 2125 | /**< VHOST: seconds to allow a client to hold an ah without using it. |
| 2126 | * 0 defaults to 10s. */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2127 | |
| 2128 | void *_unused[8]; /**< dummy */ |
| 2129 | }; |
| 2130 | |
| 2131 | /** |
| 2132 | * lws_create_context() - Create the websocket handler |
| 2133 | * \param info: pointer to struct with parameters |
| 2134 | * |
| 2135 | * This function creates the listening socket (if serving) and takes care |
| 2136 | * of all initialization in one step. |
| 2137 | * |
| 2138 | * If option LWS_SERVER_OPTION_EXPLICIT_VHOSTS is given, no vhost is |
| 2139 | * created; you're expected to create your own vhosts afterwards using |
| 2140 | * lws_create_vhost(). Otherwise a vhost named "default" is also created |
| 2141 | * using the information in the vhost-related members, for compatibility. |
| 2142 | * |
| 2143 | * After initialization, it returns a struct lws_context * that |
| 2144 | * represents this server. After calling, user code needs to take care |
| 2145 | * of calling lws_service() with the context pointer to get the |
| 2146 | * server's sockets serviced. This must be done in the same process |
| 2147 | * context as the initialization call. |
| 2148 | * |
| 2149 | * The protocol callback functions are called for a handful of events |
| 2150 | * including http requests coming in, websocket connections becoming |
| 2151 | * established, and data arriving; it's also called periodically to allow |
| 2152 | * async transmission. |
| 2153 | * |
| 2154 | * HTTP requests are sent always to the FIRST protocol in protocol, since |
| 2155 | * at that time websocket protocol has not been negotiated. Other |
Yannick Kiekens | e7cc1ff | 2016-11-03 10:03:18 +0100 | [diff] [blame] | 2156 | * protocols after the first one never see any HTTP callback activity. |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2157 | * |
| 2158 | * The server created is a simple http server by default; part of the |
| 2159 | * websocket standard is upgrading this http connection to a websocket one. |
| 2160 | * |
| 2161 | * This allows the same server to provide files like scripts and favicon / |
| 2162 | * images or whatever over http and dynamic data over websockets all in |
| 2163 | * one place; they're all handled in the user callback. |
| 2164 | */ |
| 2165 | LWS_VISIBLE LWS_EXTERN struct lws_context * |
| 2166 | lws_create_context(struct lws_context_creation_info *info); |
| 2167 | |
| 2168 | /** |
| 2169 | * lws_context_destroy() - Destroy the websocket context |
| 2170 | * \param context: Websocket context |
| 2171 | * |
| 2172 | * This function closes any active connections and then frees the |
| 2173 | * context. After calling this, any further use of the context is |
| 2174 | * undefined. |
| 2175 | */ |
| 2176 | LWS_VISIBLE LWS_EXTERN void |
| 2177 | lws_context_destroy(struct lws_context *context); |
| 2178 | |
Andy Green | be9fb91 | 2016-12-16 07:37:43 +0800 | [diff] [blame] | 2179 | LWS_VISIBLE LWS_EXTERN void |
| 2180 | lws_context_destroy2(struct lws_context *context); |
| 2181 | |
| 2182 | typedef int (*lws_reload_func)(void); |
| 2183 | |
| 2184 | /** |
| 2185 | * lws_context_deprecate() - Deprecate the websocket context |
| 2186 | * \param context: Websocket context |
| 2187 | * |
| 2188 | * This function is used on an existing context before superceding it |
| 2189 | * with a new context. |
| 2190 | * |
| 2191 | * It closes any listen sockets in the context, so new connections are |
| 2192 | * not possible. |
| 2193 | * |
| 2194 | * And it marks the context to be deleted when the number of active |
| 2195 | * connections into it falls to zero. |
| 2196 | * |
| 2197 | * Otherwise if you attach the deprecated context to the replacement |
| 2198 | * context when it has been created using lws_context_attach_deprecated() |
| 2199 | * both any deprecated and the new context will service their connections. |
| 2200 | * |
| 2201 | * This is aimed at allowing seamless configuration reloads. |
| 2202 | * |
| 2203 | * The callback cb will be called after the listen sockets are actually |
| 2204 | * closed and may be reopened. In the callback the new context should be |
| 2205 | * configured and created. (With libuv, socket close happens async after |
| 2206 | * more loop events). |
| 2207 | */ |
| 2208 | LWS_VISIBLE LWS_EXTERN void |
| 2209 | lws_context_deprecate(struct lws_context *context, lws_reload_func cb); |
| 2210 | |
| 2211 | LWS_VISIBLE LWS_EXTERN int |
| 2212 | lws_context_is_deprecated(struct lws_context *context); |
| 2213 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2214 | /** |
| 2215 | * lws_set_proxy() - Setups proxy to lws_context. |
| 2216 | * \param vhost: pointer to struct lws_vhost you want set proxy for |
| 2217 | * \param proxy: pointer to c string containing proxy in format address:port |
| 2218 | * |
| 2219 | * Returns 0 if proxy string was parsed and proxy was setup. |
| 2220 | * Returns -1 if proxy is NULL or has incorrect format. |
| 2221 | * |
| 2222 | * This is only required if your OS does not provide the http_proxy |
| 2223 | * environment variable (eg, OSX) |
| 2224 | * |
| 2225 | * IMPORTANT! You should call this function right after creation of the |
| 2226 | * lws_context and before call to connect. If you call this |
| 2227 | * function after connect behavior is undefined. |
| 2228 | * This function will override proxy settings made on lws_context |
| 2229 | * creation with genenv() call. |
| 2230 | */ |
| 2231 | LWS_VISIBLE LWS_EXTERN int |
| 2232 | lws_set_proxy(struct lws_vhost *vhost, const char *proxy); |
| 2233 | |
Andy Ning | ed92b6d | 2017-05-05 11:38:34 -0400 | [diff] [blame] | 2234 | /** |
| 2235 | * lws_set_socks() - Setup socks to lws_context. |
| 2236 | * \param vhost: pointer to struct lws_vhost you want set socks for |
| 2237 | * \param socks: pointer to c string containing socks in format address:port |
| 2238 | * |
| 2239 | * Returns 0 if socks string was parsed and socks was setup. |
| 2240 | * Returns -1 if socks is NULL or has incorrect format. |
| 2241 | * |
| 2242 | * This is only required if your OS does not provide the socks_proxy |
| 2243 | * environment variable (eg, OSX) |
| 2244 | * |
| 2245 | * IMPORTANT! You should call this function right after creation of the |
| 2246 | * lws_context and before call to connect. If you call this |
| 2247 | * function after connect behavior is undefined. |
| 2248 | * This function will override proxy settings made on lws_context |
| 2249 | * creation with genenv() call. |
| 2250 | */ |
| 2251 | LWS_VISIBLE LWS_EXTERN int |
| 2252 | lws_set_socks(struct lws_vhost *vhost, const char *socks); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2253 | |
| 2254 | struct lws_vhost; |
| 2255 | |
| 2256 | /** |
| 2257 | * lws_create_vhost() - Create a vhost (virtual server context) |
| 2258 | * \param context: pointer to result of lws_create_context() |
| 2259 | * \param info: pointer to struct with parameters |
| 2260 | * |
| 2261 | * This function creates a virtual server (vhost) using the vhost-related |
| 2262 | * members of the info struct. You can create many vhosts inside one context |
| 2263 | * if you created the context with the option LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
| 2264 | */ |
Andy Green | faa1526 | 2017-07-15 14:37:04 +0800 | [diff] [blame] | 2265 | LWS_VISIBLE LWS_EXTERN struct lws_vhost * |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2266 | lws_create_vhost(struct lws_context *context, |
| 2267 | struct lws_context_creation_info *info); |
| 2268 | |
| 2269 | /** |
Andy Green | faa1526 | 2017-07-15 14:37:04 +0800 | [diff] [blame] | 2270 | * lws_destroy_vhost() - Destroy a vhost (virtual server context) |
| 2271 | * \param vhost: pointer to result of lws_create_vhost() |
| 2272 | * |
| 2273 | * This function destroys a vhost. Normally, if you just want to exit, |
| 2274 | * then lws_destroy_context() will take care of everything. If you want |
| 2275 | * to destroy an individual vhost and all connections and allocations, you |
| 2276 | * can do it with this. |
| 2277 | */ |
| 2278 | LWS_VISIBLE LWS_EXTERN void |
| 2279 | lws_vhost_destroy(struct lws_vhost *vh); |
| 2280 | |
| 2281 | /** |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2282 | * lwsws_get_config_globals() - Parse a JSON server config file |
| 2283 | * \param info: pointer to struct with parameters |
| 2284 | * \param d: filepath of the config file |
| 2285 | * \param config_strings: storage for the config strings extracted from JSON, |
| 2286 | * the pointer is incremented as strings are stored |
| 2287 | * \param len: pointer to the remaining length left in config_strings |
| 2288 | * the value is decremented as strings are stored |
| 2289 | * |
| 2290 | * This function prepares a n lws_context_creation_info struct with global |
| 2291 | * settings from a file d. |
| 2292 | * |
| 2293 | * Requires CMake option LWS_WITH_LEJP_CONF to have been enabled |
| 2294 | */ |
| 2295 | LWS_VISIBLE LWS_EXTERN int |
| 2296 | lwsws_get_config_globals(struct lws_context_creation_info *info, const char *d, |
| 2297 | char **config_strings, int *len); |
| 2298 | |
| 2299 | /** |
| 2300 | * lwsws_get_config_vhosts() - Create vhosts from a JSON server config file |
| 2301 | * \param context: pointer to result of lws_create_context() |
| 2302 | * \param info: pointer to struct with parameters |
| 2303 | * \param d: filepath of the config file |
| 2304 | * \param config_strings: storage for the config strings extracted from JSON, |
| 2305 | * the pointer is incremented as strings are stored |
| 2306 | * \param len: pointer to the remaining length left in config_strings |
| 2307 | * the value is decremented as strings are stored |
| 2308 | * |
| 2309 | * This function creates vhosts into a context according to the settings in |
| 2310 | *JSON files found in directory d. |
| 2311 | * |
| 2312 | * Requires CMake option LWS_WITH_LEJP_CONF to have been enabled |
| 2313 | */ |
| 2314 | LWS_VISIBLE LWS_EXTERN int |
| 2315 | lwsws_get_config_vhosts(struct lws_context *context, |
| 2316 | struct lws_context_creation_info *info, const char *d, |
| 2317 | char **config_strings, int *len); |
| 2318 | |
| 2319 | /** lws_vhost_get() - \deprecated deprecated: use lws_get_vhost() */ |
| 2320 | LWS_VISIBLE LWS_EXTERN struct lws_vhost * |
| 2321 | lws_vhost_get(struct lws *wsi) LWS_WARN_DEPRECATED; |
| 2322 | |
| 2323 | /** |
| 2324 | * lws_get_vhost() - return the vhost a wsi belongs to |
| 2325 | * |
| 2326 | * \param wsi: which connection |
| 2327 | */ |
| 2328 | LWS_VISIBLE LWS_EXTERN struct lws_vhost * |
| 2329 | lws_get_vhost(struct lws *wsi); |
| 2330 | |
| 2331 | /** |
| 2332 | * lws_json_dump_vhost() - describe vhost state and stats in JSON |
| 2333 | * |
| 2334 | * \param vh: the vhost |
| 2335 | * \param buf: buffer to fill with JSON |
| 2336 | * \param len: max length of buf |
| 2337 | */ |
| 2338 | LWS_VISIBLE LWS_EXTERN int |
| 2339 | lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len); |
| 2340 | |
| 2341 | /** |
| 2342 | * lws_json_dump_context() - describe context state and stats in JSON |
| 2343 | * |
| 2344 | * \param context: the context |
| 2345 | * \param buf: buffer to fill with JSON |
| 2346 | * \param len: max length of buf |
| 2347 | */ |
| 2348 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | be9fb91 | 2016-12-16 07:37:43 +0800 | [diff] [blame] | 2349 | lws_json_dump_context(const struct lws_context *context, char *buf, int len, |
| 2350 | int hide_vhosts); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2351 | |
| 2352 | /** |
| 2353 | * lws_context_user() - get the user data associated with the context |
| 2354 | * \param context: Websocket context |
| 2355 | * |
| 2356 | * This returns the optional user allocation that can be attached to |
| 2357 | * the context the sockets live in at context_create time. It's a way |
| 2358 | * to let all sockets serviced in the same context share data without |
| 2359 | * using globals statics in the user code. |
| 2360 | */ |
| 2361 | LWS_VISIBLE LWS_EXTERN void * |
| 2362 | lws_context_user(struct lws_context *context); |
| 2363 | |
| 2364 | /*! \defgroup vhost-mounts Vhost mounts and options |
| 2365 | * \ingroup context-and-vhost-creation |
| 2366 | * |
| 2367 | * ##Vhost mounts and options |
| 2368 | */ |
| 2369 | ///@{ |
| 2370 | /** struct lws_protocol_vhost_options - linked list of per-vhost protocol |
| 2371 | * name=value options |
| 2372 | * |
| 2373 | * This provides a general way to attach a linked-list of name=value pairs, |
| 2374 | * which can also have an optional child link-list using the options member. |
| 2375 | */ |
| 2376 | struct lws_protocol_vhost_options { |
| 2377 | const struct lws_protocol_vhost_options *next; /**< linked list */ |
| 2378 | const struct lws_protocol_vhost_options *options; /**< child linked-list of more options for this node */ |
| 2379 | const char *name; /**< name of name=value pair */ |
| 2380 | const char *value; /**< value of name=value pair */ |
| 2381 | }; |
| 2382 | |
| 2383 | /** enum lws_mount_protocols |
| 2384 | * This specifies the mount protocol for a mountpoint, whether it is to be |
| 2385 | * served from a filesystem, or it is a cgi etc. |
| 2386 | */ |
| 2387 | enum lws_mount_protocols { |
Andy Green | 581b86e | 2017-06-12 13:36:24 +0800 | [diff] [blame] | 2388 | LWSMPRO_HTTP = 0, /**< http reverse proxy */ |
| 2389 | LWSMPRO_HTTPS = 1, /**< https reverse proxy */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2390 | LWSMPRO_FILE = 2, /**< serve from filesystem directory */ |
| 2391 | LWSMPRO_CGI = 3, /**< pass to CGI to handle */ |
| 2392 | LWSMPRO_REDIR_HTTP = 4, /**< redirect to http:// url */ |
| 2393 | LWSMPRO_REDIR_HTTPS = 5, /**< redirect to https:// url */ |
| 2394 | LWSMPRO_CALLBACK = 6, /**< hand by named protocol's callback */ |
| 2395 | }; |
| 2396 | |
| 2397 | /** struct lws_http_mount |
| 2398 | * |
| 2399 | * arguments for mounting something in a vhost's url namespace |
| 2400 | */ |
| 2401 | struct lws_http_mount { |
Andy Green | 7acf76c | 2016-07-23 14:18:25 +0800 | [diff] [blame] | 2402 | const struct lws_http_mount *mount_next; |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2403 | /**< pointer to next struct lws_http_mount */ |
| 2404 | const char *mountpoint; |
| 2405 | /**< mountpoint in http pathspace, eg, "/" */ |
| 2406 | const char *origin; |
| 2407 | /**< path to be mounted, eg, "/var/www/warmcat.com" */ |
| 2408 | const char *def; |
| 2409 | /**< default target, eg, "index.html" */ |
| 2410 | const char *protocol; |
| 2411 | /**<"protocol-name" to handle mount */ |
| 2412 | |
| 2413 | const struct lws_protocol_vhost_options *cgienv; |
| 2414 | /**< optional linked-list of cgi options. These are created |
| 2415 | * as environment variables for the cgi process |
| 2416 | */ |
| 2417 | const struct lws_protocol_vhost_options *extra_mimetypes; |
| 2418 | /**< optional linked-list of mimetype mappings */ |
| 2419 | const struct lws_protocol_vhost_options *interpret; |
| 2420 | /**< optional linked-list of files to be interpreted */ |
| 2421 | |
| 2422 | int cgi_timeout; |
| 2423 | /**< seconds cgi is allowed to live, if cgi://mount type */ |
| 2424 | int cache_max_age; |
| 2425 | /**< max-age for reuse of client cache of files, seconds */ |
| 2426 | unsigned int auth_mask; |
| 2427 | /**< bits set here must be set for authorized client session */ |
| 2428 | |
| 2429 | unsigned int cache_reusable:1; /**< set if client cache may reuse this */ |
| 2430 | unsigned int cache_revalidate:1; /**< set if client cache should revalidate on use */ |
| 2431 | unsigned int cache_intermediaries:1; /**< set if intermediaries are allowed to cache */ |
| 2432 | |
| 2433 | unsigned char origin_protocol; /**< one of enum lws_mount_protocols */ |
| 2434 | unsigned char mountpoint_len; /**< length of mountpoint string */ |
Andy Green | ee94621 | 2016-12-03 15:13:15 +0800 | [diff] [blame] | 2435 | |
| 2436 | const char *basic_auth_login_file; |
| 2437 | /**<NULL, or filepath to use to check basic auth logins against */ |
| 2438 | |
| 2439 | /* Add new things just above here ---^ |
| 2440 | * This is part of the ABI, don't needlessly break compatibility |
| 2441 | * |
| 2442 | * The below is to ensure later library versions with new |
| 2443 | * members added above will see 0 (default) even if the app |
| 2444 | * was not built against the newer headers. |
| 2445 | */ |
| 2446 | |
| 2447 | void *_unused[2]; /**< dummy */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2448 | }; |
| 2449 | ///@} |
| 2450 | ///@} |
| 2451 | |
| 2452 | /*! \defgroup client |
| 2453 | * \ingroup lwsapi |
| 2454 | * |
| 2455 | * ##Client releated functions |
| 2456 | * */ |
| 2457 | ///@{ |
| 2458 | |
Andy Green | 675c349 | 2016-07-07 08:14:26 +0800 | [diff] [blame] | 2459 | /** enum lws_client_connect_ssl_connection_flags - flags that may be used |
| 2460 | * with struct lws_client_connect_info ssl_connection member to control if |
| 2461 | * and how SSL checks apply to the client connection being created |
| 2462 | */ |
| 2463 | |
| 2464 | enum lws_client_connect_ssl_connection_flags { |
| 2465 | LCCSCF_USE_SSL = (1 << 0), |
| 2466 | LCCSCF_ALLOW_SELFSIGNED = (1 << 1), |
Joachim Bauch | b3160f9 | 2016-11-11 12:19:53 +0100 | [diff] [blame] | 2467 | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK = (1 << 2), |
| 2468 | LCCSCF_ALLOW_EXPIRED = (1 << 3) |
Andy Green | 675c349 | 2016-07-07 08:14:26 +0800 | [diff] [blame] | 2469 | }; |
| 2470 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2471 | /** struct lws_client_connect_info - parameters to connect with when using |
| 2472 | * lws_client_connect_via_info() */ |
| 2473 | |
| 2474 | struct lws_client_connect_info { |
| 2475 | struct lws_context *context; |
| 2476 | /**< lws context to create connection in */ |
| 2477 | const char *address; |
| 2478 | /**< remote address to connect to */ |
| 2479 | int port; |
| 2480 | /**< remote port to connect to */ |
| 2481 | int ssl_connection; |
| 2482 | /**< nonzero for ssl */ |
| 2483 | const char *path; |
| 2484 | /**< uri path */ |
| 2485 | const char *host; |
| 2486 | /**< content of host header */ |
| 2487 | const char *origin; |
| 2488 | /**< content of origin header */ |
| 2489 | const char *protocol; |
| 2490 | /**< list of ws protocols we could accept */ |
| 2491 | int ietf_version_or_minus_one; |
| 2492 | /**< deprecated: currently leave at 0 or -1 */ |
| 2493 | void *userdata; |
| 2494 | /**< if non-NULL, use this as wsi user_data instead of malloc it */ |
Andy Green | ad94597 | 2017-02-03 10:39:37 +0800 | [diff] [blame] | 2495 | const void *client_exts; |
| 2496 | /**< UNUSED... provide in info.extensions at context creation time */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2497 | const char *method; |
| 2498 | /**< if non-NULL, do this http method instead of ws[s] upgrade. |
| 2499 | * use "GET" to be a simple http client connection */ |
| 2500 | struct lws *parent_wsi; |
| 2501 | /**< if another wsi is responsible for this connection, give it here. |
| 2502 | * this is used to make sure if the parent closes so do any |
| 2503 | * child connections first. */ |
| 2504 | const char *uri_replace_from; |
| 2505 | /**< if non-NULL, when this string is found in URIs in |
| 2506 | * text/html content-encoding, it's replaced with uri_replace_to */ |
| 2507 | const char *uri_replace_to; |
| 2508 | /**< see uri_replace_from */ |
| 2509 | struct lws_vhost *vhost; |
| 2510 | /**< vhost to bind to (used to determine related SSL_CTX) */ |
Andy Green | 81c221e | 2016-07-01 08:54:39 +0800 | [diff] [blame] | 2511 | struct lws **pwsi; |
| 2512 | /**< if not NULL, store the new wsi here early in the connection |
| 2513 | * process. Although we return the new wsi, the call to create the |
| 2514 | * client connection does progress the connection somewhat and may |
| 2515 | * meet an error that will result in the connection being scrubbed and |
| 2516 | * NULL returned. While the wsi exists though, he may process a |
| 2517 | * callback like CLIENT_CONNECTION_ERROR with his wsi: this gives the |
| 2518 | * user callback a way to identify which wsi it is that faced the error |
| 2519 | * even before the new wsi is returned and even if ultimately no wsi |
| 2520 | * is returned. |
| 2521 | */ |
Andy Green | 449eec9 | 2017-06-14 09:45:30 +0800 | [diff] [blame] | 2522 | const char *iface; |
| 2523 | /**< NULL to allow routing on any interface, or interface name or IP |
| 2524 | * to bind the socket to */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2525 | |
| 2526 | /* Add new things just above here ---^ |
| 2527 | * This is part of the ABI, don't needlessly break compatibility |
| 2528 | * |
| 2529 | * The below is to ensure later library versions with new |
| 2530 | * members added above will see 0 (default) even if the app |
| 2531 | * was not built against the newer headers. |
| 2532 | */ |
| 2533 | |
| 2534 | void *_unused[4]; /**< dummy */ |
| 2535 | }; |
| 2536 | |
| 2537 | /** |
| 2538 | * lws_client_connect_via_info() - Connect to another websocket server |
| 2539 | * \param ccinfo: pointer to lws_client_connect_info struct |
| 2540 | * |
Andy Green | 81c221e | 2016-07-01 08:54:39 +0800 | [diff] [blame] | 2541 | * This function creates a connection to a remote server using the |
| 2542 | * information provided in ccinfo. |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2543 | */ |
Andy Green | 81c221e | 2016-07-01 08:54:39 +0800 | [diff] [blame] | 2544 | LWS_VISIBLE LWS_EXTERN struct lws * |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2545 | lws_client_connect_via_info(struct lws_client_connect_info * ccinfo); |
| 2546 | |
| 2547 | /** |
| 2548 | * lws_client_connect() - Connect to another websocket server |
| 2549 | * \deprecated DEPRECATED use lws_client_connect_via_info |
| 2550 | * \param clients: Websocket context |
| 2551 | * \param address: Remote server address, eg, "myserver.com" |
| 2552 | * \param port: Port to connect to on the remote server, eg, 80 |
| 2553 | * \param ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self |
| 2554 | * signed certs |
| 2555 | * \param path: Websocket path on server |
| 2556 | * \param host: Hostname on server |
| 2557 | * \param origin: Socket origin name |
| 2558 | * \param protocol: Comma-separated list of protocols being asked for from |
| 2559 | * the server, or just one. The server will pick the one it |
| 2560 | * likes best. If you don't want to specify a protocol, which is |
| 2561 | * legal, use NULL here. |
| 2562 | * \param ietf_version_or_minus_one: -1 to ask to connect using the default, latest |
| 2563 | * protocol supported, or the specific protocol ordinal |
| 2564 | * |
| 2565 | * This function creates a connection to a remote server |
| 2566 | */ |
| 2567 | /* deprecated, use lws_client_connect_via_info() */ |
| 2568 | LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT |
| 2569 | lws_client_connect(struct lws_context *clients, const char *address, |
| 2570 | int port, int ssl_connection, const char *path, |
| 2571 | const char *host, const char *origin, const char *protocol, |
| 2572 | int ietf_version_or_minus_one) LWS_WARN_DEPRECATED; |
| 2573 | /* deprecated, use lws_client_connect_via_info() */ |
| 2574 | /** |
| 2575 | * lws_client_connect_extended() - Connect to another websocket server |
| 2576 | * \deprecated DEPRECATED use lws_client_connect_via_info |
| 2577 | * \param clients: Websocket context |
| 2578 | * \param address: Remote server address, eg, "myserver.com" |
| 2579 | * \param port: Port to connect to on the remote server, eg, 80 |
| 2580 | * \param ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self |
| 2581 | * signed certs |
| 2582 | * \param path: Websocket path on server |
| 2583 | * \param host: Hostname on server |
| 2584 | * \param origin: Socket origin name |
| 2585 | * \param protocol: Comma-separated list of protocols being asked for from |
| 2586 | * the server, or just one. The server will pick the one it |
| 2587 | * likes best. |
| 2588 | * \param ietf_version_or_minus_one: -1 to ask to connect using the default, latest |
| 2589 | * protocol supported, or the specific protocol ordinal |
| 2590 | * \param userdata: Pre-allocated user data |
| 2591 | * |
| 2592 | * This function creates a connection to a remote server |
| 2593 | */ |
| 2594 | LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT |
| 2595 | lws_client_connect_extended(struct lws_context *clients, const char *address, |
| 2596 | int port, int ssl_connection, const char *path, |
| 2597 | const char *host, const char *origin, |
| 2598 | const char *protocol, int ietf_version_or_minus_one, |
| 2599 | void *userdata) LWS_WARN_DEPRECATED; |
| 2600 | |
| 2601 | /** |
| 2602 | * lws_init_vhost_client_ssl() - also enable client SSL on an existing vhost |
| 2603 | * |
| 2604 | * \param info: client ssl related info |
| 2605 | * \param vhost: which vhost to initialize client ssl operations on |
| 2606 | * |
| 2607 | * You only need to call this if you plan on using SSL client connections on |
| 2608 | * the vhost. For non-SSL client connections, it's not necessary to call this. |
| 2609 | * |
| 2610 | * The following members of info are used during the call |
| 2611 | * |
| 2612 | * - options must have LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT set, |
| 2613 | * otherwise the call does nothing |
| 2614 | * - provided_client_ssl_ctx must be NULL to get a generated client |
| 2615 | * ssl context, otherwise you can pass a prepared one in by setting it |
| 2616 | * - ssl_cipher_list may be NULL or set to the client valid cipher list |
| 2617 | * - ssl_ca_filepath may be NULL or client cert filepath |
| 2618 | * - ssl_cert_filepath may be NULL or client cert filepath |
| 2619 | * - ssl_private_key_filepath may be NULL or client cert private key |
| 2620 | * |
| 2621 | * You must create your vhost explicitly if you want to use this, so you have |
| 2622 | * a pointer to the vhost. Create the context first with the option flag |
| 2623 | * LWS_SERVER_OPTION_EXPLICIT_VHOSTS and then call lws_create_vhost() with |
| 2624 | * the same info struct. |
| 2625 | */ |
| 2626 | LWS_VISIBLE LWS_EXTERN int |
| 2627 | lws_init_vhost_client_ssl(const struct lws_context_creation_info *info, |
| 2628 | struct lws_vhost *vhost); |
Andy Green | 5e25dc0 | 2017-02-09 09:10:57 +0800 | [diff] [blame] | 2629 | /** |
| 2630 | * lws_http_client_read() - consume waiting received http client data |
| 2631 | * |
| 2632 | * \param wsi: client connection |
| 2633 | * \param buf: pointer to buffer pointer - fill with pointer to your buffer |
| 2634 | * \param len: pointer to chunk length - fill with max length of buffer |
| 2635 | * |
| 2636 | * This is called when the user code is notified client http data has arrived. |
| 2637 | * The user code may choose to delay calling it to consume the data, for example |
| 2638 | * waiting until an onward connection is writeable. |
| 2639 | * |
| 2640 | * For non-chunked connections, up to len bytes of buf are filled with the |
| 2641 | * received content. len is set to the actual amount filled before return. |
| 2642 | * |
| 2643 | * For chunked connections, the linear buffer content contains the chunking |
| 2644 | * headers and it cannot be passed in one lump. Instead, this function will |
| 2645 | * call back LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ with in pointing to the |
| 2646 | * chunk start and len set to the chunk length. There will be as many calls |
| 2647 | * as there are chunks or partial chunks in the buffer. |
| 2648 | */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2649 | LWS_VISIBLE LWS_EXTERN int |
| 2650 | lws_http_client_read(struct lws *wsi, char **buf, int *len); |
Andy Green | 95fff47 | 2016-08-08 21:54:30 +0800 | [diff] [blame] | 2651 | |
Andy Green | 86ab060 | 2016-10-21 23:12:21 +0800 | [diff] [blame] | 2652 | /** |
| 2653 | * lws_http_client_http_response() - get last HTTP response code |
| 2654 | * |
| 2655 | * \param wsi: client connection |
| 2656 | * |
| 2657 | * Returns the last server response code, eg, 200 for client http connections. |
| 2658 | */ |
| 2659 | LWS_VISIBLE LWS_EXTERN unsigned int |
| 2660 | lws_http_client_http_response(struct lws *wsi); |
| 2661 | |
Andy Green | 95fff47 | 2016-08-08 21:54:30 +0800 | [diff] [blame] | 2662 | LWS_VISIBLE LWS_EXTERN void |
| 2663 | lws_client_http_body_pending(struct lws *wsi, int something_left_to_send); |
| 2664 | |
| 2665 | /** |
| 2666 | * lws_client_http_body_pending() - control if client connection neeeds to send body |
| 2667 | * |
| 2668 | * \param wsi: client connection |
| 2669 | * \param something_left_to_send: nonzero if need to send more body, 0 (default) |
| 2670 | * if nothing more to send |
| 2671 | * |
| 2672 | * If you will send payload data with your HTTP client connection, eg, for POST, |
| 2673 | * when you set the related http headers in |
| 2674 | * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER callback you should also call |
| 2675 | * this API with something_left_to_send nonzero, and call |
| 2676 | * lws_callback_on_writable(wsi); |
| 2677 | * |
| 2678 | * After sending the headers, lws will call your callback with |
| 2679 | * LWS_CALLBACK_CLIENT_HTTP_WRITEABLE reason when writable. You can send the |
| 2680 | * next part of the http body payload, calling lws_callback_on_writable(wsi); |
| 2681 | * if there is more to come, or lws_client_http_body_pending(wsi, 0); to |
| 2682 | * let lws know the last part is sent and the connection can move on. |
| 2683 | */ |
| 2684 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2685 | ///@} |
| 2686 | |
| 2687 | /** \defgroup service Built-in service loop entry |
| 2688 | * |
| 2689 | * ##Built-in service loop entry |
| 2690 | * |
| 2691 | * If you're not using libev / libuv, these apis are needed to enter the poll() |
| 2692 | * wait in lws and service any connections with pending events. |
| 2693 | */ |
| 2694 | ///@{ |
| 2695 | |
| 2696 | /** |
| 2697 | * lws_service() - Service any pending websocket activity |
| 2698 | * \param context: Websocket context |
| 2699 | * \param timeout_ms: Timeout for poll; 0 means return immediately if nothing needed |
| 2700 | * service otherwise block and service immediately, returning |
| 2701 | * after the timeout if nothing needed service. |
| 2702 | * |
| 2703 | * This function deals with any pending websocket traffic, for three |
| 2704 | * kinds of event. It handles these events on both server and client |
| 2705 | * types of connection the same. |
| 2706 | * |
| 2707 | * 1) Accept new connections to our context's server |
| 2708 | * |
| 2709 | * 2) Call the receive callback for incoming frame data received by |
| 2710 | * server or client connections. |
| 2711 | * |
| 2712 | * You need to call this service function periodically to all the above |
| 2713 | * functions to happen; if your application is single-threaded you can |
| 2714 | * just call it in your main event loop. |
| 2715 | * |
| 2716 | * Alternatively you can fork a new process that asynchronously handles |
| 2717 | * calling this service in a loop. In that case you are happy if this |
| 2718 | * call blocks your thread until it needs to take care of something and |
| 2719 | * would call it with a large nonzero timeout. Your loop then takes no |
| 2720 | * CPU while there is nothing happening. |
| 2721 | * |
| 2722 | * If you are calling it in a single-threaded app, you don't want it to |
| 2723 | * wait around blocking other things in your loop from happening, so you |
| 2724 | * would call it with a timeout_ms of 0, so it returns immediately if |
| 2725 | * nothing is pending, or as soon as it services whatever was pending. |
| 2726 | */ |
| 2727 | LWS_VISIBLE LWS_EXTERN int |
| 2728 | lws_service(struct lws_context *context, int timeout_ms); |
| 2729 | |
| 2730 | /** |
| 2731 | * lws_service() - Service any pending websocket activity |
| 2732 | * |
| 2733 | * \param context: Websocket context |
| 2734 | * \param timeout_ms: Timeout for poll; 0 means return immediately if nothing needed |
| 2735 | * service otherwise block and service immediately, returning |
| 2736 | * after the timeout if nothing needed service. |
| 2737 | * |
| 2738 | * Same as lws_service(), but for a specific thread service index. Only needed |
| 2739 | * if you are spawning multiple service threads. |
| 2740 | */ |
| 2741 | LWS_VISIBLE LWS_EXTERN int |
| 2742 | lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi); |
| 2743 | |
| 2744 | /** |
| 2745 | * lws_cancel_service_pt() - Cancel servicing of pending socket activity |
| 2746 | * on one thread |
| 2747 | * \param wsi: Cancel service on the thread this wsi is serviced by |
| 2748 | * |
| 2749 | * This function lets a call to lws_service() waiting for a timeout |
| 2750 | * immediately return. |
| 2751 | * |
| 2752 | * It works by creating a phony event and then swallowing it silently. |
| 2753 | * |
| 2754 | * The reason it may be needed is when waiting in poll(), changes to |
| 2755 | * the event masks are ignored by the OS until poll() is reentered. This |
| 2756 | * lets you halt the poll() wait and make the reentry happen immediately |
| 2757 | * instead of having the wait out the rest of the poll timeout. |
| 2758 | */ |
| 2759 | LWS_VISIBLE LWS_EXTERN void |
| 2760 | lws_cancel_service_pt(struct lws *wsi); |
| 2761 | |
| 2762 | /** |
| 2763 | * lws_cancel_service() - Cancel wait for new pending socket activity |
| 2764 | * \param context: Websocket context |
| 2765 | * |
| 2766 | * This function let a call to lws_service() waiting for a timeout |
| 2767 | * immediately return. |
| 2768 | * |
| 2769 | * What it basically does is provide a fake event that will be swallowed, |
| 2770 | * so the wait in poll() is ended. That's useful because poll() doesn't |
| 2771 | * attend to changes in POLLIN/OUT/ERR until it re-enters the wait. |
| 2772 | */ |
| 2773 | LWS_VISIBLE LWS_EXTERN void |
| 2774 | lws_cancel_service(struct lws_context *context); |
| 2775 | |
| 2776 | /** |
| 2777 | * lws_service_fd() - Service polled socket with something waiting |
| 2778 | * \param context: Websocket context |
| 2779 | * \param pollfd: The pollfd entry describing the socket fd and which events |
Denis Osvald | 4be9a52 | 2016-10-07 11:27:46 +0200 | [diff] [blame] | 2780 | * happened, or NULL to tell lws to do only timeout servicing. |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2781 | * |
| 2782 | * This function takes a pollfd that has POLLIN or POLLOUT activity and |
| 2783 | * services it according to the state of the associated |
| 2784 | * struct lws. |
| 2785 | * |
| 2786 | * The one call deals with all "service" that might happen on a socket |
| 2787 | * including listen accepts, http files as well as websocket protocol. |
| 2788 | * |
| 2789 | * If a pollfd says it has something, you can just pass it to |
| 2790 | * lws_service_fd() whether it is a socket handled by lws or not. |
| 2791 | * If it sees it is a lws socket, the traffic will be handled and |
| 2792 | * pollfd->revents will be zeroed now. |
| 2793 | * |
| 2794 | * If the socket is foreign to lws, it leaves revents alone. So you can |
| 2795 | * see if you should service yourself by checking the pollfd revents |
| 2796 | * after letting lws try to service it. |
Denis Osvald | 4be9a52 | 2016-10-07 11:27:46 +0200 | [diff] [blame] | 2797 | * |
| 2798 | * You should also call this with pollfd = NULL to just allow the |
| 2799 | * once-per-second global timeout checks; if less than a second since the last |
| 2800 | * check it returns immediately then. |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2801 | */ |
| 2802 | LWS_VISIBLE LWS_EXTERN int |
| 2803 | lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd); |
| 2804 | |
| 2805 | /** |
| 2806 | * lws_service_fd_tsi() - Service polled socket in specific service thread |
| 2807 | * \param context: Websocket context |
| 2808 | * \param pollfd: The pollfd entry describing the socket fd and which events |
| 2809 | * happened. |
| 2810 | * \param tsi: thread service index |
| 2811 | * |
| 2812 | * Same as lws_service_fd() but used with multiple service threads |
| 2813 | */ |
| 2814 | LWS_VISIBLE LWS_EXTERN int |
| 2815 | lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, |
| 2816 | int tsi); |
| 2817 | |
Andy Green | 443b31d | 2016-10-07 03:19:17 +0800 | [diff] [blame] | 2818 | /** |
| 2819 | * lws_service_adjust_timeout() - Check for any connection needing forced service |
| 2820 | * \param context: Websocket context |
| 2821 | * \param timeout_ms: The original poll timeout value. You can just set this |
| 2822 | * to 1 if you don't really have a poll timeout. |
| 2823 | * \param tsi: thread service index |
| 2824 | * |
| 2825 | * Under some conditions connections may need service even though there is no |
| 2826 | * pending network action on them, this is "forced service". For default |
| 2827 | * poll() and libuv / libev, the library takes care of calling this and |
| 2828 | * dealing with it for you. But for external poll() integration, you need |
| 2829 | * access to the apis. |
| 2830 | * |
| 2831 | * If anybody needs "forced service", returned timeout is zero. In that case, |
Andy Green | b46c401 | 2016-10-20 09:09:56 +0800 | [diff] [blame] | 2832 | * you can call lws_service_tsi() with a timeout of -1 to only service |
Andy Green | 443b31d | 2016-10-07 03:19:17 +0800 | [diff] [blame] | 2833 | * guys who need forced service. |
| 2834 | */ |
| 2835 | LWS_VISIBLE LWS_EXTERN int |
| 2836 | lws_service_adjust_timeout(struct lws_context *context, int timeout_ms, int tsi); |
| 2837 | |
Andy Green | b46c401 | 2016-10-20 09:09:56 +0800 | [diff] [blame] | 2838 | /* Backwards compatibility */ |
| 2839 | #define lws_plat_service_tsi lws_service_tsi |
Andy Green | 443b31d | 2016-10-07 03:19:17 +0800 | [diff] [blame] | 2840 | |
Andy Green | 6f11c13 | 2017-07-19 04:39:14 +0800 | [diff] [blame] | 2841 | LWS_VISIBLE LWS_EXTERN int |
| 2842 | lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd); |
| 2843 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2844 | ///@} |
| 2845 | |
| 2846 | /*! \defgroup http HTTP |
| 2847 | |
| 2848 | Modules related to handling HTTP |
| 2849 | */ |
| 2850 | //@{ |
| 2851 | |
| 2852 | /*! \defgroup httpft HTTP File transfer |
| 2853 | * \ingroup http |
| 2854 | |
| 2855 | APIs for sending local files in response to HTTP requests |
| 2856 | */ |
| 2857 | //@{ |
| 2858 | |
| 2859 | /** |
Andy Green | 906006e | 2016-07-03 09:20:11 +0800 | [diff] [blame] | 2860 | * lws_get_mimetype() - Determine mimetype to use from filename |
| 2861 | * |
| 2862 | * \param file: filename |
| 2863 | * \param m: NULL, or mount context |
| 2864 | * |
| 2865 | * This uses a canned list of known filetypes first, if no match and m is |
| 2866 | * non-NULL, then tries a list of per-mount file suffix to mimtype mappings. |
| 2867 | * |
| 2868 | * Returns either NULL or a pointer to the mimetype matching the file. |
| 2869 | */ |
| 2870 | LWS_VISIBLE LWS_EXTERN const char * |
| 2871 | lws_get_mimetype(const char *file, const struct lws_http_mount *m); |
| 2872 | |
| 2873 | /** |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2874 | * lws_serve_http_file() - Send a file back to the client using http |
| 2875 | * \param wsi: Websocket instance (available from user callback) |
| 2876 | * \param file: The file to issue over http |
| 2877 | * \param content_type: The http content type, eg, text/html |
| 2878 | * \param other_headers: NULL or pointer to header string |
| 2879 | * \param other_headers_len: length of the other headers if non-NULL |
| 2880 | * |
| 2881 | * This function is intended to be called from the callback in response |
| 2882 | * to http requests from the client. It allows the callback to issue |
| 2883 | * local files down the http link in a single step. |
| 2884 | * |
| 2885 | * Returning <0 indicates error and the wsi should be closed. Returning |
| 2886 | * >0 indicates the file was completely sent and |
| 2887 | * lws_http_transaction_completed() called on the wsi (and close if != 0) |
| 2888 | * ==0 indicates the file transfer is started and needs more service later, |
| 2889 | * the wsi should be left alone. |
| 2890 | */ |
| 2891 | LWS_VISIBLE LWS_EXTERN int |
| 2892 | lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, |
| 2893 | const char *other_headers, int other_headers_len); |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 2894 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2895 | LWS_VISIBLE LWS_EXTERN int |
| 2896 | lws_serve_http_file_fragment(struct lws *wsi); |
| 2897 | //@} |
| 2898 | |
| 2899 | /*! \defgroup html-chunked-substitution HTML Chunked Substitution |
| 2900 | * \ingroup http |
| 2901 | * |
| 2902 | * ##HTML chunked Substitution |
| 2903 | * |
| 2904 | * APIs for receiving chunks of text, replacing a set of variable names via |
| 2905 | * a callback, and then prepending and appending HTML chunked encoding |
| 2906 | * headers. |
| 2907 | */ |
| 2908 | //@{ |
| 2909 | |
| 2910 | enum http_status { |
| 2911 | HTTP_STATUS_OK = 200, |
| 2912 | HTTP_STATUS_NO_CONTENT = 204, |
Andy Green | ed4acef | 2016-12-12 13:36:25 +0800 | [diff] [blame] | 2913 | HTTP_STATUS_PARTIAL_CONTENT = 206, |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2914 | |
| 2915 | HTTP_STATUS_MOVED_PERMANENTLY = 301, |
| 2916 | HTTP_STATUS_FOUND = 302, |
| 2917 | HTTP_STATUS_SEE_OTHER = 303, |
Andy Green | 4219a32 | 2017-03-08 07:51:47 +0800 | [diff] [blame] | 2918 | HTTP_STATUS_NOT_MODIFIED = 304, |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 2919 | |
| 2920 | HTTP_STATUS_BAD_REQUEST = 400, |
| 2921 | HTTP_STATUS_UNAUTHORIZED, |
| 2922 | HTTP_STATUS_PAYMENT_REQUIRED, |
| 2923 | HTTP_STATUS_FORBIDDEN, |
| 2924 | HTTP_STATUS_NOT_FOUND, |
| 2925 | HTTP_STATUS_METHOD_NOT_ALLOWED, |
| 2926 | HTTP_STATUS_NOT_ACCEPTABLE, |
| 2927 | HTTP_STATUS_PROXY_AUTH_REQUIRED, |
| 2928 | HTTP_STATUS_REQUEST_TIMEOUT, |
| 2929 | HTTP_STATUS_CONFLICT, |
| 2930 | HTTP_STATUS_GONE, |
| 2931 | HTTP_STATUS_LENGTH_REQUIRED, |
| 2932 | HTTP_STATUS_PRECONDITION_FAILED, |
| 2933 | HTTP_STATUS_REQ_ENTITY_TOO_LARGE, |
| 2934 | HTTP_STATUS_REQ_URI_TOO_LONG, |
| 2935 | HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, |
| 2936 | HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE, |
| 2937 | HTTP_STATUS_EXPECTATION_FAILED, |
| 2938 | |
| 2939 | HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, |
| 2940 | HTTP_STATUS_NOT_IMPLEMENTED, |
| 2941 | HTTP_STATUS_BAD_GATEWAY, |
| 2942 | HTTP_STATUS_SERVICE_UNAVAILABLE, |
| 2943 | HTTP_STATUS_GATEWAY_TIMEOUT, |
| 2944 | HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED, |
| 2945 | }; |
| 2946 | |
| 2947 | struct lws_process_html_args { |
| 2948 | char *p; /**< pointer to the buffer containing the data */ |
| 2949 | int len; /**< length of the original data at p */ |
| 2950 | int max_len; /**< maximum length we can grow the data to */ |
| 2951 | int final; /**< set if this is the last chunk of the file */ |
| 2952 | }; |
| 2953 | |
| 2954 | typedef const char *(*lws_process_html_state_cb)(void *data, int index); |
| 2955 | |
| 2956 | struct lws_process_html_state { |
| 2957 | char *start; /**< pointer to start of match */ |
| 2958 | char swallow[16]; /**< matched character buffer */ |
| 2959 | int pos; /**< position in match */ |
| 2960 | void *data; /**< opaque pointer */ |
| 2961 | const char * const *vars; /**< list of variable names */ |
| 2962 | int count_vars; /**< count of variable names */ |
| 2963 | |
| 2964 | lws_process_html_state_cb replace; /**< called on match to perform substitution */ |
| 2965 | }; |
| 2966 | |
| 2967 | /*! lws_chunked_html_process() - generic chunked substitution |
| 2968 | * \param args: buffer to process using chunked encoding |
| 2969 | * \param s: current processing state |
| 2970 | */ |
| 2971 | LWS_VISIBLE LWS_EXTERN int |
| 2972 | lws_chunked_html_process(struct lws_process_html_args *args, |
| 2973 | struct lws_process_html_state *s); |
| 2974 | //@} |
| 2975 | |
| 2976 | /** \defgroup HTTP-headers-read HTTP headers: read |
| 2977 | * \ingroup http |
| 2978 | * |
| 2979 | * ##HTTP header releated functions |
| 2980 | * |
| 2981 | * In lws the client http headers are temporarily stored in a pool, only for the |
| 2982 | * duration of the http part of the handshake. It's because in most cases, |
| 2983 | * the header content is ignored for the whole rest of the connection lifetime |
| 2984 | * and would then just be taking up space needlessly. |
| 2985 | * |
| 2986 | * During LWS_CALLBACK_HTTP when the URI path is delivered is the last time |
| 2987 | * the http headers are still allocated, you can use these apis then to |
| 2988 | * look at and copy out interesting header content (cookies, etc) |
| 2989 | * |
| 2990 | * Notice that the header total length reported does not include a terminating |
| 2991 | * '\0', however you must allocate for it when using the _copy apis. So the |
| 2992 | * length reported for a header containing "123" is 3, but you must provide |
| 2993 | * a buffer of length 4 so that "123\0" may be copied into it, or the copy |
| 2994 | * will fail with a nonzero return code. |
| 2995 | * |
| 2996 | * In the special case of URL arguments, like ?x=1&y=2, the arguments are |
| 2997 | * stored in a token named for the method, eg, WSI_TOKEN_GET_URI if it |
| 2998 | * was a GET or WSI_TOKEN_POST_URI if POST. You can check the total |
| 2999 | * length to confirm the method. |
| 3000 | * |
| 3001 | * For URL arguments, each argument is stored urldecoded in a "fragment", so |
| 3002 | * you can use the fragment-aware api lws_hdr_copy_fragment() to access each |
| 3003 | * argument in turn: the fragments contain urldecoded strings like x=1 or y=2. |
| 3004 | * |
| 3005 | * As a convenience, lws has an api that will find the fragment with a |
| 3006 | * given name= part, lws_get_urlarg_by_name(). |
| 3007 | */ |
| 3008 | ///@{ |
| 3009 | |
| 3010 | /** struct lws_tokens |
Andy Green | c85619d | 2011-02-13 08:25:26 +0000 | [diff] [blame] | 3011 | * you need these to look at headers that have been parsed if using the |
| 3012 | * LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum |
| 3013 | * list below is absent, .token = NULL and token_len = 0. Otherwise .token |
| 3014 | * points to .token_len chars containing that header content. |
| 3015 | */ |
Andy Green | c85619d | 2011-02-13 08:25:26 +0000 | [diff] [blame] | 3016 | struct lws_tokens { |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3017 | char *token; /**< pointer to start of the token */ |
| 3018 | int token_len; /**< length of the token's value */ |
Andy Green | c85619d | 2011-02-13 08:25:26 +0000 | [diff] [blame] | 3019 | }; |
| 3020 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3021 | /* enum lws_token_indexes |
Andy Green | 1ee42a5 | 2014-02-23 14:38:59 +0800 | [diff] [blame] | 3022 | * these have to be kept in sync with lextable.h / minilex.c |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 3023 | * |
| 3024 | * NOTE: These public enums are part of the abi. If you want to add one, |
| 3025 | * add it at where specified so existing users are unaffected. |
Andy Green | 1ee42a5 | 2014-02-23 14:38:59 +0800 | [diff] [blame] | 3026 | */ |
Andy Green | c85619d | 2011-02-13 08:25:26 +0000 | [diff] [blame] | 3027 | enum lws_token_indexes { |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 3028 | WSI_TOKEN_GET_URI = 0, |
| 3029 | WSI_TOKEN_POST_URI = 1, |
| 3030 | WSI_TOKEN_OPTIONS_URI = 2, |
| 3031 | WSI_TOKEN_HOST = 3, |
| 3032 | WSI_TOKEN_CONNECTION = 4, |
| 3033 | WSI_TOKEN_UPGRADE = 5, |
| 3034 | WSI_TOKEN_ORIGIN = 6, |
| 3035 | WSI_TOKEN_DRAFT = 7, |
| 3036 | WSI_TOKEN_CHALLENGE = 8, |
| 3037 | WSI_TOKEN_EXTENSIONS = 9, |
| 3038 | WSI_TOKEN_KEY1 = 10, |
| 3039 | WSI_TOKEN_KEY2 = 11, |
| 3040 | WSI_TOKEN_PROTOCOL = 12, |
| 3041 | WSI_TOKEN_ACCEPT = 13, |
| 3042 | WSI_TOKEN_NONCE = 14, |
| 3043 | WSI_TOKEN_HTTP = 15, |
| 3044 | WSI_TOKEN_HTTP2_SETTINGS = 16, |
| 3045 | WSI_TOKEN_HTTP_ACCEPT = 17, |
| 3046 | WSI_TOKEN_HTTP_AC_REQUEST_HEADERS = 18, |
| 3047 | WSI_TOKEN_HTTP_IF_MODIFIED_SINCE = 19, |
| 3048 | WSI_TOKEN_HTTP_IF_NONE_MATCH = 20, |
| 3049 | WSI_TOKEN_HTTP_ACCEPT_ENCODING = 21, |
| 3050 | WSI_TOKEN_HTTP_ACCEPT_LANGUAGE = 22, |
| 3051 | WSI_TOKEN_HTTP_PRAGMA = 23, |
| 3052 | WSI_TOKEN_HTTP_CACHE_CONTROL = 24, |
| 3053 | WSI_TOKEN_HTTP_AUTHORIZATION = 25, |
| 3054 | WSI_TOKEN_HTTP_COOKIE = 26, |
| 3055 | WSI_TOKEN_HTTP_CONTENT_LENGTH = 27, |
| 3056 | WSI_TOKEN_HTTP_CONTENT_TYPE = 28, |
| 3057 | WSI_TOKEN_HTTP_DATE = 29, |
| 3058 | WSI_TOKEN_HTTP_RANGE = 30, |
| 3059 | WSI_TOKEN_HTTP_REFERER = 31, |
| 3060 | WSI_TOKEN_KEY = 32, |
| 3061 | WSI_TOKEN_VERSION = 33, |
| 3062 | WSI_TOKEN_SWORIGIN = 34, |
Andy Green | cc13c6f | 2013-11-09 10:09:09 +0800 | [diff] [blame] | 3063 | |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 3064 | WSI_TOKEN_HTTP_COLON_AUTHORITY = 35, |
| 3065 | WSI_TOKEN_HTTP_COLON_METHOD = 36, |
| 3066 | WSI_TOKEN_HTTP_COLON_PATH = 37, |
| 3067 | WSI_TOKEN_HTTP_COLON_SCHEME = 38, |
| 3068 | WSI_TOKEN_HTTP_COLON_STATUS = 39, |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 3069 | |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 3070 | WSI_TOKEN_HTTP_ACCEPT_CHARSET = 40, |
| 3071 | WSI_TOKEN_HTTP_ACCEPT_RANGES = 41, |
| 3072 | WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN = 42, |
| 3073 | WSI_TOKEN_HTTP_AGE = 43, |
| 3074 | WSI_TOKEN_HTTP_ALLOW = 44, |
| 3075 | WSI_TOKEN_HTTP_CONTENT_DISPOSITION = 45, |
| 3076 | WSI_TOKEN_HTTP_CONTENT_ENCODING = 46, |
| 3077 | WSI_TOKEN_HTTP_CONTENT_LANGUAGE = 47, |
| 3078 | WSI_TOKEN_HTTP_CONTENT_LOCATION = 48, |
| 3079 | WSI_TOKEN_HTTP_CONTENT_RANGE = 49, |
| 3080 | WSI_TOKEN_HTTP_ETAG = 50, |
| 3081 | WSI_TOKEN_HTTP_EXPECT = 51, |
| 3082 | WSI_TOKEN_HTTP_EXPIRES = 52, |
| 3083 | WSI_TOKEN_HTTP_FROM = 53, |
| 3084 | WSI_TOKEN_HTTP_IF_MATCH = 54, |
| 3085 | WSI_TOKEN_HTTP_IF_RANGE = 55, |
| 3086 | WSI_TOKEN_HTTP_IF_UNMODIFIED_SINCE = 56, |
| 3087 | WSI_TOKEN_HTTP_LAST_MODIFIED = 57, |
| 3088 | WSI_TOKEN_HTTP_LINK = 58, |
| 3089 | WSI_TOKEN_HTTP_LOCATION = 59, |
| 3090 | WSI_TOKEN_HTTP_MAX_FORWARDS = 60, |
| 3091 | WSI_TOKEN_HTTP_PROXY_AUTHENTICATE = 61, |
| 3092 | WSI_TOKEN_HTTP_PROXY_AUTHORIZATION = 62, |
| 3093 | WSI_TOKEN_HTTP_REFRESH = 63, |
| 3094 | WSI_TOKEN_HTTP_RETRY_AFTER = 64, |
| 3095 | WSI_TOKEN_HTTP_SERVER = 65, |
| 3096 | WSI_TOKEN_HTTP_SET_COOKIE = 66, |
| 3097 | WSI_TOKEN_HTTP_STRICT_TRANSPORT_SECURITY = 67, |
| 3098 | WSI_TOKEN_HTTP_TRANSFER_ENCODING = 68, |
| 3099 | WSI_TOKEN_HTTP_USER_AGENT = 69, |
| 3100 | WSI_TOKEN_HTTP_VARY = 70, |
| 3101 | WSI_TOKEN_HTTP_VIA = 71, |
| 3102 | WSI_TOKEN_HTTP_WWW_AUTHENTICATE = 72, |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 3103 | |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 3104 | WSI_TOKEN_PATCH_URI = 73, |
| 3105 | WSI_TOKEN_PUT_URI = 74, |
| 3106 | WSI_TOKEN_DELETE_URI = 75, |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 3107 | |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 3108 | WSI_TOKEN_HTTP_URI_ARGS = 76, |
Danomi Czaski | 4e9c7f3 | 2016-01-28 09:40:53 +0800 | [diff] [blame] | 3109 | WSI_TOKEN_PROXY = 77, |
| 3110 | WSI_TOKEN_HTTP_X_REAL_IP = 78, |
Andy Green | a661ee5 | 2016-02-29 13:18:30 +0800 | [diff] [blame] | 3111 | WSI_TOKEN_HTTP1_0 = 79, |
Andy Green | ba8fb14 | 2016-12-08 08:14:15 +0800 | [diff] [blame] | 3112 | WSI_TOKEN_X_FORWARDED_FOR = 80, |
Andy Green | 297c031 | 2017-02-12 20:32:49 +0800 | [diff] [blame] | 3113 | WSI_TOKEN_CONNECT = 81, |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 3114 | /****** add new things just above ---^ ******/ |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 3115 | |
Danomi Czaski | 4e9c7f3 | 2016-01-28 09:40:53 +0800 | [diff] [blame] | 3116 | /* use token storage to stash these internally, not for |
| 3117 | * user use */ |
| 3118 | |
| 3119 | _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, |
| 3120 | _WSI_TOKEN_CLIENT_PEER_ADDRESS, |
| 3121 | _WSI_TOKEN_CLIENT_URI, |
| 3122 | _WSI_TOKEN_CLIENT_HOST, |
| 3123 | _WSI_TOKEN_CLIENT_ORIGIN, |
Andy Green | a661ee5 | 2016-02-29 13:18:30 +0800 | [diff] [blame] | 3124 | _WSI_TOKEN_CLIENT_METHOD, |
Andy Green | 449eec9 | 2017-06-14 09:45:30 +0800 | [diff] [blame] | 3125 | _WSI_TOKEN_CLIENT_IFACE, |
Danomi Czaski | 4e9c7f3 | 2016-01-28 09:40:53 +0800 | [diff] [blame] | 3126 | |
Andy Green | c85619d | 2011-02-13 08:25:26 +0000 | [diff] [blame] | 3127 | /* always last real token index*/ |
| 3128 | WSI_TOKEN_COUNT, |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 3129 | |
Andy Green | 1b2c9a2 | 2016-01-29 21:18:54 +0800 | [diff] [blame] | 3130 | /* parser state additions, no storage associated */ |
Andy Green | c85619d | 2011-02-13 08:25:26 +0000 | [diff] [blame] | 3131 | WSI_TOKEN_NAME_PART, |
| 3132 | WSI_TOKEN_SKIPPING, |
| 3133 | WSI_TOKEN_SKIPPING_SAW_CR, |
Andy Green | a41314f | 2011-05-23 10:00:03 +0100 | [diff] [blame] | 3134 | WSI_PARSING_COMPLETE, |
| 3135 | WSI_INIT_TOKEN_MUXURL, |
Andy Green | c85619d | 2011-02-13 08:25:26 +0000 | [diff] [blame] | 3136 | }; |
| 3137 | |
Andy Green | 510c3c8 | 2015-12-10 07:50:51 +0800 | [diff] [blame] | 3138 | struct lws_token_limits { |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3139 | unsigned short token_limit[WSI_TOKEN_COUNT]; /**< max chars for this token */ |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 3140 | }; |
| 3141 | |
| 3142 | /** |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3143 | * lws_token_to_string() - returns a textual representation of a hdr token index |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 3144 | * |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3145 | * \param: token index |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 3146 | */ |
Andy Green | 917f43a | 2014-10-12 14:31:47 +0800 | [diff] [blame] | 3147 | LWS_VISIBLE LWS_EXTERN const unsigned char * |
| 3148 | lws_token_to_string(enum lws_token_indexes token); |
| 3149 | |
Andy Green | 16146cd | 2016-04-23 07:53:46 +0800 | [diff] [blame] | 3150 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3151 | /** |
| 3152 | * lws_hdr_total_length: report length of all fragments of a header totalled up |
| 3153 | * The returned length does not include the space for a |
| 3154 | * terminating '\0' |
| 3155 | * |
| 3156 | * \param wsi: websocket connection |
| 3157 | * \param h: which header index we are interested in |
| 3158 | */ |
Andy Green | 16146cd | 2016-04-23 07:53:46 +0800 | [diff] [blame] | 3159 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3160 | lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h); |
| 3161 | |
| 3162 | /** |
| 3163 | * lws_hdr_fragment_length: report length of a single fragment of a header |
| 3164 | * The returned length does not include the space for a |
| 3165 | * terminating '\0' |
| 3166 | * |
| 3167 | * \param wsi: websocket connection |
| 3168 | * \param h: which header index we are interested in |
| 3169 | * \param frag_idx: which fragment of h we want to get the length of |
| 3170 | */ |
Andy Green | 16146cd | 2016-04-23 07:53:46 +0800 | [diff] [blame] | 3171 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3172 | lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx); |
| 3173 | |
| 3174 | /** |
| 3175 | * lws_hdr_copy() - copy a single fragment of the given header to a buffer |
| 3176 | * The buffer length len must include space for an additional |
| 3177 | * terminating '\0', or it will fail returning -1. |
| 3178 | * |
| 3179 | * \param wsi: websocket connection |
| 3180 | * \param dest: destination buffer |
| 3181 | * \param len: length of destination buffer |
| 3182 | * \param h: which header index we are interested in |
| 3183 | * |
| 3184 | * copies the whole, aggregated header, even if it was delivered in |
| 3185 | * several actual headers piece by piece |
| 3186 | */ |
| 3187 | LWS_VISIBLE LWS_EXTERN int |
| 3188 | lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h); |
| 3189 | |
| 3190 | /** |
| 3191 | * lws_hdr_copy_fragment() - copy a single fragment of the given header to a buffer |
| 3192 | * The buffer length len must include space for an additional |
| 3193 | * terminating '\0', or it will fail returning -1. |
| 3194 | * If the requested fragment index is not present, it fails |
| 3195 | * returning -1. |
| 3196 | * |
| 3197 | * \param wsi: websocket connection |
| 3198 | * \param dest: destination buffer |
| 3199 | * \param len: length of destination buffer |
| 3200 | * \param h: which header index we are interested in |
| 3201 | * \param frag_idx: which fragment of h we want to copy |
| 3202 | * |
| 3203 | * Normally this is only useful |
| 3204 | * to parse URI arguments like ?x=1&y=2, token index WSI_TOKEN_HTTP_URI_ARGS |
| 3205 | * fragment 0 will contain "x=1" and fragment 1 "y=2" |
| 3206 | */ |
| 3207 | LWS_VISIBLE LWS_EXTERN int |
| 3208 | lws_hdr_copy_fragment(struct lws *wsi, char *dest, int len, |
| 3209 | enum lws_token_indexes h, int frag_idx); |
| 3210 | |
| 3211 | /** |
| 3212 | * lws_get_urlarg_by_name() - return pointer to arg value if present |
| 3213 | * \param wsi: the connection to check |
| 3214 | * \param name: the arg name, like "token=" |
| 3215 | * \param buf: the buffer to receive the urlarg (including the name= part) |
| 3216 | * \param len: the length of the buffer to receive the urlarg |
| 3217 | * |
| 3218 | * Returns NULL if not found or a pointer inside buf to just after the |
| 3219 | * name= part. |
| 3220 | */ |
| 3221 | LWS_VISIBLE LWS_EXTERN const char * |
| 3222 | lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len); |
| 3223 | ///@} |
| 3224 | |
| 3225 | /*! \defgroup HTTP-headers-create HTTP headers: create |
| 3226 | * |
| 3227 | * ## HTTP headers: Create |
| 3228 | * |
| 3229 | * These apis allow you to create HTTP response headers in a way compatible with |
| 3230 | * both HTTP/1.x and HTTP/2. |
| 3231 | * |
| 3232 | * They each append to a buffer taking care about the buffer end, which is |
| 3233 | * passed in as a pointer. When data is written to the buffer, the current |
| 3234 | * position p is updated accordingly. |
| 3235 | * |
| 3236 | * All of these apis are LWS_WARN_UNUSED_RESULT as they can run out of space |
| 3237 | * and fail with nonzero return. |
| 3238 | */ |
| 3239 | ///@{ |
Andy Green | 4219a32 | 2017-03-08 07:51:47 +0800 | [diff] [blame] | 3240 | |
| 3241 | #define LWSAHH_CODE_MASK ((1 << 16) - 1) |
| 3242 | #define LWSAHH_FLAG_NO_SERVER_NAME (1 << 30) |
| 3243 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3244 | /** |
| 3245 | * lws_add_http_header_status() - add the HTTP response status code |
| 3246 | * |
| 3247 | * \param wsi: the connection to check |
| 3248 | * \param code: an HTTP code like 200, 404 etc (see enum http_status) |
| 3249 | * \param p: pointer to current position in buffer pointer |
| 3250 | * \param end: pointer to end of buffer |
| 3251 | * |
Andy Green | 4219a32 | 2017-03-08 07:51:47 +0800 | [diff] [blame] | 3252 | * Adds the initial response code, so should be called first. |
| 3253 | * |
| 3254 | * Code may additionally take OR'd flags: |
| 3255 | * |
| 3256 | * LWSAHH_FLAG_NO_SERVER_NAME: don't apply server name header this time |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3257 | */ |
Andy Green | 16146cd | 2016-04-23 07:53:46 +0800 | [diff] [blame] | 3258 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
Andy Green | 11c05bf | 2015-12-16 18:19:08 +0800 | [diff] [blame] | 3259 | lws_add_http_header_status(struct lws *wsi, |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 3260 | unsigned int code, unsigned char **p, |
| 3261 | unsigned char *end); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3262 | /** |
| 3263 | * lws_add_http_header_by_name() - append named header and value |
| 3264 | * |
| 3265 | * \param wsi: the connection to check |
| 3266 | * \param name: the hdr name, like "my-header" |
| 3267 | * \param value: the value after the = for this header |
| 3268 | * \param length: the length of the value |
| 3269 | * \param p: pointer to current position in buffer pointer |
| 3270 | * \param end: pointer to end of buffer |
| 3271 | * |
| 3272 | * Appends name: value to the headers |
| 3273 | */ |
| 3274 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| 3275 | lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name, |
| 3276 | const unsigned char *value, int length, |
| 3277 | unsigned char **p, unsigned char *end); |
| 3278 | /** |
| 3279 | * lws_add_http_header_by_token() - append given header and value |
| 3280 | * |
| 3281 | * \param wsi: the connection to check |
| 3282 | * \param token: the token index for the hdr |
| 3283 | * \param value: the value after the = for this header |
| 3284 | * \param length: the length of the value |
| 3285 | * \param p: pointer to current position in buffer pointer |
| 3286 | * \param end: pointer to end of buffer |
| 3287 | * |
| 3288 | * Appends name=value to the headers, but is able to take advantage of better |
| 3289 | * HTTP/2 coding mechanisms where possible. |
| 3290 | */ |
| 3291 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| 3292 | lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token, |
| 3293 | const unsigned char *value, int length, |
| 3294 | unsigned char **p, unsigned char *end); |
| 3295 | /** |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 3296 | * lws_add_http_header_content_length() - append content-length helper |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3297 | * |
| 3298 | * \param wsi: the connection to check |
| 3299 | * \param content_length: the content length to use |
| 3300 | * \param p: pointer to current position in buffer pointer |
| 3301 | * \param end: pointer to end of buffer |
| 3302 | * |
| 3303 | * Appends content-length: content_length to the headers |
| 3304 | */ |
| 3305 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| 3306 | lws_add_http_header_content_length(struct lws *wsi, |
Andy Green | 37053b3 | 2017-06-07 07:46:51 +0800 | [diff] [blame] | 3307 | lws_filepos_t content_length, |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3308 | unsigned char **p, unsigned char *end); |
| 3309 | /** |
| 3310 | * lws_finalize_http_header() - terminate header block |
| 3311 | * |
| 3312 | * \param wsi: the connection to check |
| 3313 | * \param p: pointer to current position in buffer pointer |
| 3314 | * \param end: pointer to end of buffer |
| 3315 | * |
| 3316 | * Indicates no more headers will be added |
| 3317 | */ |
| 3318 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| 3319 | lws_finalize_http_header(struct lws *wsi, unsigned char **p, |
| 3320 | unsigned char *end); |
| 3321 | ///@} |
Andy Green | 917f43a | 2014-10-12 14:31:47 +0800 | [diff] [blame] | 3322 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3323 | /** \defgroup form-parsing Form Parsing |
| 3324 | * \ingroup http |
| 3325 | * ##POSTed form parsing functions |
| 3326 | * |
| 3327 | * These lws_spa (stateful post arguments) apis let you parse and urldecode |
| 3328 | * POSTed form arguments, both using simple urlencoded and multipart transfer |
| 3329 | * encoding. |
| 3330 | * |
| 3331 | * It's capable of handling file uploads as well a named input parsing, |
| 3332 | * and the apis are the same for both form upload styles. |
| 3333 | * |
| 3334 | * You feed it a list of parameter names and it creates pointers to the |
| 3335 | * urldecoded arguments: file upload parameters pass the file data in chunks to |
| 3336 | * a user-supplied callback as they come. |
| 3337 | * |
| 3338 | * Since it's stateful, it handles the incoming data needing more than one |
| 3339 | * POST_BODY callback and has no limit on uploaded file size. |
| 3340 | */ |
| 3341 | ///@{ |
| 3342 | |
| 3343 | /** enum lws_spa_fileupload_states */ |
| 3344 | enum lws_spa_fileupload_states { |
| 3345 | LWS_UFS_CONTENT, |
| 3346 | /**< a chunk of file content has arrived */ |
| 3347 | LWS_UFS_FINAL_CONTENT, |
| 3348 | /**< the last chunk (possibly zero length) of file content has arrived */ |
| 3349 | LWS_UFS_OPEN |
| 3350 | /**< a new file is starting to arrive */ |
| 3351 | }; |
| 3352 | |
| 3353 | /** |
| 3354 | * lws_spa_fileupload_cb() - callback to receive file upload data |
| 3355 | * |
| 3356 | * \param data: opt_data pointer set in lws_spa_create |
| 3357 | * \param name: name of the form field being uploaded |
| 3358 | * \param filename: original filename from client |
| 3359 | * \param buf: start of data to receive |
| 3360 | * \param len: length of data to receive |
| 3361 | * \param state: information about how this call relates to file |
| 3362 | * |
| 3363 | * Notice name and filename shouldn't be trusted, as they are passed from |
| 3364 | * HTTP provided by the client. |
| 3365 | */ |
| 3366 | typedef int (*lws_spa_fileupload_cb)(void *data, const char *name, |
| 3367 | const char *filename, char *buf, int len, |
| 3368 | enum lws_spa_fileupload_states state); |
| 3369 | |
| 3370 | /** struct lws_spa - opaque urldecode parser capable of handling multipart |
| 3371 | * and file uploads */ |
| 3372 | struct lws_spa; |
| 3373 | |
| 3374 | /** |
| 3375 | * lws_spa_create() - create urldecode parser |
| 3376 | * |
| 3377 | * \param wsi: lws connection (used to find Content Type) |
| 3378 | * \param param_names: array of form parameter names, like "username" |
| 3379 | * \param count_params: count of param_names |
| 3380 | * \param max_storage: total amount of form parameter values we can store |
| 3381 | * \param opt_cb: NULL, or callback to receive file upload data. |
| 3382 | * \param opt_data: NULL, or user pointer provided to opt_cb. |
| 3383 | * |
| 3384 | * Creates a urldecode parser and initializes it. |
| 3385 | * |
| 3386 | * opt_cb can be NULL if you just want normal name=value parsing, however |
| 3387 | * if one or more entries in your form are bulk data (file transfer), you |
| 3388 | * can provide this callback and filter on the name callback parameter to |
| 3389 | * treat that urldecoded data separately. The callback should return -1 |
| 3390 | * in case of fatal error, and 0 if OK. |
| 3391 | */ |
| 3392 | LWS_VISIBLE LWS_EXTERN struct lws_spa * |
| 3393 | lws_spa_create(struct lws *wsi, const char * const *param_names, |
| 3394 | int count_params, int max_storage, lws_spa_fileupload_cb opt_cb, |
| 3395 | void *opt_data); |
| 3396 | |
| 3397 | /** |
| 3398 | * lws_spa_process() - parses a chunk of input data |
| 3399 | * |
| 3400 | * \param spa: the parser object previously created |
| 3401 | * \param in: incoming, urlencoded data |
| 3402 | * \param len: count of bytes valid at \param in |
| 3403 | */ |
| 3404 | LWS_VISIBLE LWS_EXTERN int |
| 3405 | lws_spa_process(struct lws_spa *spa, const char *in, int len); |
| 3406 | |
| 3407 | /** |
| 3408 | * lws_spa_finalize() - indicate incoming data completed |
| 3409 | * |
| 3410 | * \param spa: the parser object previously created |
| 3411 | */ |
| 3412 | LWS_VISIBLE LWS_EXTERN int |
| 3413 | lws_spa_finalize(struct lws_spa *spa); |
| 3414 | |
| 3415 | /** |
| 3416 | * lws_spa_get_length() - return length of parameter value |
| 3417 | * |
| 3418 | * \param spa: the parser object previously created |
| 3419 | * \param n: parameter ordinal to return length of value for |
| 3420 | */ |
| 3421 | LWS_VISIBLE LWS_EXTERN int |
| 3422 | lws_spa_get_length(struct lws_spa *spa, int n); |
| 3423 | |
| 3424 | /** |
| 3425 | * lws_spa_get_string() - return pointer to parameter value |
| 3426 | * \param spa: the parser object previously created |
| 3427 | * \param n: parameter ordinal to return pointer to value for |
| 3428 | */ |
| 3429 | LWS_VISIBLE LWS_EXTERN const char * |
| 3430 | lws_spa_get_string(struct lws_spa *spa, int n); |
| 3431 | |
| 3432 | /** |
| 3433 | * lws_spa_destroy() - destroy parser object |
| 3434 | * |
| 3435 | * \param spa: the parser object previously created |
| 3436 | */ |
| 3437 | LWS_VISIBLE LWS_EXTERN int |
| 3438 | lws_spa_destroy(struct lws_spa *spa); |
| 3439 | ///@} |
| 3440 | |
| 3441 | /*! \defgroup urlendec Urlencode and Urldecode |
| 3442 | * \ingroup http |
| 3443 | * |
| 3444 | * ##HTML chunked Substitution |
| 3445 | * |
| 3446 | * APIs for receiving chunks of text, replacing a set of variable names via |
| 3447 | * a callback, and then prepending and appending HTML chunked encoding |
| 3448 | * headers. |
| 3449 | */ |
| 3450 | //@{ |
| 3451 | |
| 3452 | /** |
| 3453 | * lws_urlencode() - like strncpy but with urlencoding |
| 3454 | * |
| 3455 | * \param escaped: output buffer |
| 3456 | * \param string: input buffer ('/0' terminated) |
| 3457 | * \param len: output buffer max length |
| 3458 | * |
| 3459 | * Because urlencoding expands the output string, it's not |
| 3460 | * possible to do it in-place, ie, with escaped == string |
| 3461 | */ |
Andy Green | c55fd27 | 2016-06-08 10:07:02 +0800 | [diff] [blame] | 3462 | LWS_VISIBLE LWS_EXTERN const char * |
| 3463 | lws_urlencode(char *escaped, const char *string, int len); |
| 3464 | |
Andy Green | c55fd27 | 2016-06-08 10:07:02 +0800 | [diff] [blame] | 3465 | /* |
| 3466 | * URLDECODE 1 / 2 |
| 3467 | * |
| 3468 | * This simple urldecode only operates until the first '\0' and requires the |
| 3469 | * data to exist all at once |
| 3470 | */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3471 | /** |
| 3472 | * lws_urldecode() - like strncpy but with urldecoding |
| 3473 | * |
| 3474 | * \param string: output buffer |
| 3475 | * \param escaped: input buffer ('\0' terminated) |
| 3476 | * \param len: output buffer max length |
| 3477 | * |
| 3478 | * This is only useful for '\0' terminated strings |
| 3479 | * |
| 3480 | * Since urldecoding only shrinks the output string, it is possible to |
| 3481 | * do it in-place, ie, string == escaped |
| 3482 | */ |
Andy Green | c55fd27 | 2016-06-08 10:07:02 +0800 | [diff] [blame] | 3483 | LWS_VISIBLE LWS_EXTERN int |
| 3484 | lws_urldecode(char *string, const char *escaped, int len); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3485 | ///@} |
| 3486 | /** |
| 3487 | * lws_return_http_status() - Return simple http status |
| 3488 | * \param wsi: Websocket instance (available from user callback) |
| 3489 | * \param code: Status index, eg, 404 |
| 3490 | * \param html_body: User-readable HTML description < 1KB, or NULL |
Andy Green | c55fd27 | 2016-06-08 10:07:02 +0800 | [diff] [blame] | 3491 | * |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3492 | * Helper to report HTTP errors back to the client cleanly and |
| 3493 | * consistently |
Andy Green | c55fd27 | 2016-06-08 10:07:02 +0800 | [diff] [blame] | 3494 | */ |
Andy Green | c55fd27 | 2016-06-08 10:07:02 +0800 | [diff] [blame] | 3495 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3496 | lws_return_http_status(struct lws *wsi, unsigned int code, |
| 3497 | const char *html_body); |
Andy Green | c55fd27 | 2016-06-08 10:07:02 +0800 | [diff] [blame] | 3498 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3499 | /** |
| 3500 | * lws_http_redirect() - write http redirect into buffer |
| 3501 | * |
| 3502 | * \param wsi: websocket connection |
| 3503 | * \param code: HTTP response code (eg, 301) |
| 3504 | * \param loc: where to redirect to |
| 3505 | * \param len: length of loc |
| 3506 | * \param p: pointer current position in buffer (updated as we write) |
| 3507 | * \param end: pointer to end of buffer |
| 3508 | */ |
Andy Green | 16146cd | 2016-04-23 07:53:46 +0800 | [diff] [blame] | 3509 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
Andy Green | f79534e | 2016-04-25 10:04:49 +0800 | [diff] [blame] | 3510 | lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int len, |
Andy Green | 7e2c385 | 2016-04-15 20:09:36 +0800 | [diff] [blame] | 3511 | unsigned char **p, unsigned char *end); |
| 3512 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3513 | /** |
| 3514 | * lws_http_transaction_completed() - wait for new http transaction or close |
| 3515 | * \param wsi: websocket connection |
| 3516 | * |
| 3517 | * Returns 1 if the HTTP connection must close now |
| 3518 | * Returns 0 and resets connection to wait for new HTTP header / |
| 3519 | * transaction if possible |
| 3520 | */ |
Andy Green | 5a0e786 | 2016-01-21 10:57:39 +0800 | [diff] [blame] | 3521 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
Andy Green | dc8a3a8 | 2015-12-06 09:15:27 +0800 | [diff] [blame] | 3522 | lws_http_transaction_completed(struct lws *wsi); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3523 | ///@} |
| 3524 | |
| 3525 | /*! \defgroup pur Sanitize / purify SQL and JSON helpers |
| 3526 | * |
| 3527 | * ##Sanitize / purify SQL and JSON helpers |
| 3528 | * |
| 3529 | * APIs for escaping untrusted JSON and SQL safely before use |
| 3530 | */ |
| 3531 | //@{ |
| 3532 | |
| 3533 | /** |
| 3534 | * lws_sql_purify() - like strncpy but with escaping for sql quotes |
| 3535 | * |
| 3536 | * \param escaped: output buffer |
| 3537 | * \param string: input buffer ('/0' terminated) |
| 3538 | * \param len: output buffer max length |
| 3539 | * |
| 3540 | * Because escaping expands the output string, it's not |
| 3541 | * possible to do it in-place, ie, with escaped == string |
| 3542 | */ |
| 3543 | LWS_VISIBLE LWS_EXTERN const char * |
| 3544 | lws_sql_purify(char *escaped, const char *string, int len); |
| 3545 | |
| 3546 | /** |
| 3547 | * lws_json_purify() - like strncpy but with escaping for json chars |
| 3548 | * |
| 3549 | * \param escaped: output buffer |
| 3550 | * \param string: input buffer ('/0' terminated) |
| 3551 | * \param len: output buffer max length |
| 3552 | * |
| 3553 | * Because escaping expands the output string, it's not |
| 3554 | * possible to do it in-place, ie, with escaped == string |
| 3555 | */ |
| 3556 | LWS_VISIBLE LWS_EXTERN const char * |
| 3557 | lws_json_purify(char *escaped, const char *string, int len); |
| 3558 | ///@} |
| 3559 | |
| 3560 | /*! \defgroup ev libev helpers |
| 3561 | * |
| 3562 | * ##libev helpers |
| 3563 | * |
| 3564 | * APIs specific to libev event loop itegration |
| 3565 | */ |
| 3566 | ///@{ |
Andy Green | 91b0589 | 2014-10-17 08:38:44 +0800 | [diff] [blame] | 3567 | |
Andrew Canaday | 9769f4f | 2014-03-23 13:25:07 +0800 | [diff] [blame] | 3568 | #ifdef LWS_USE_LIBEV |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 3569 | typedef void (lws_ev_signal_cb_t)(EV_P_ struct ev_signal *w, int revents); |
Andrew Canaday | a8f47c9 | 2015-04-26 22:50:59 -0400 | [diff] [blame] | 3570 | |
| 3571 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 3572 | lws_ev_sigint_cfg(struct lws_context *context, int use_ev_sigint, |
| 3573 | lws_ev_signal_cb_t *cb); |
Andrew Canaday | a8f47c9 | 2015-04-26 22:50:59 -0400 | [diff] [blame] | 3574 | |
Andrew Canaday | 9769f4f | 2014-03-23 13:25:07 +0800 | [diff] [blame] | 3575 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 3576 | lws_ev_initloop(struct lws_context *context, struct ev_loop *loop, int tsi); |
Andrew Canaday | 9769f4f | 2014-03-23 13:25:07 +0800 | [diff] [blame] | 3577 | |
Andy Green | bf31c1b | 2016-05-13 08:20:12 +0800 | [diff] [blame] | 3578 | LWS_VISIBLE LWS_EXTERN void |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 3579 | lws_ev_sigint_cb(struct ev_loop *loop, struct ev_signal *watcher, int revents); |
Andrew Canaday | 9769f4f | 2014-03-23 13:25:07 +0800 | [diff] [blame] | 3580 | #endif /* LWS_USE_LIBEV */ |
| 3581 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3582 | ///@} |
| 3583 | |
| 3584 | /*! \defgroup uv libuv helpers |
| 3585 | * |
| 3586 | * ##libuv helpers |
| 3587 | * |
| 3588 | * APIs specific to libuv event loop itegration |
| 3589 | */ |
| 3590 | ///@{ |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 3591 | #ifdef LWS_USE_LIBUV |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 3592 | LWS_VISIBLE LWS_EXTERN int |
| 3593 | lws_uv_sigint_cfg(struct lws_context *context, int use_uv_sigint, |
Denis Osvald | f107e4b | 2016-03-22 14:04:15 +0100 | [diff] [blame] | 3594 | uv_signal_cb cb); |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 3595 | |
| 3596 | LWS_VISIBLE LWS_EXTERN void |
| 3597 | lws_libuv_run(const struct lws_context *context, int tsi); |
| 3598 | |
Andy Green | bf31c1b | 2016-05-13 08:20:12 +0800 | [diff] [blame] | 3599 | LWS_VISIBLE LWS_EXTERN void |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 3600 | lws_libuv_stop(struct lws_context *context); |
| 3601 | |
Andy Green | be9fb91 | 2016-12-16 07:37:43 +0800 | [diff] [blame] | 3602 | LWS_VISIBLE LWS_EXTERN void |
| 3603 | lws_libuv_stop_without_kill(const struct lws_context *context, int tsi); |
| 3604 | |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 3605 | LWS_VISIBLE LWS_EXTERN int |
Denis Osvald | f107e4b | 2016-03-22 14:04:15 +0100 | [diff] [blame] | 3606 | lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, int tsi); |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 3607 | |
| 3608 | LWS_VISIBLE LWS_EXTERN uv_loop_t * |
| 3609 | lws_uv_getloop(struct lws_context *context, int tsi); |
| 3610 | |
Andy Green | bf31c1b | 2016-05-13 08:20:12 +0800 | [diff] [blame] | 3611 | LWS_VISIBLE LWS_EXTERN void |
Denis Osvald | f107e4b | 2016-03-22 14:04:15 +0100 | [diff] [blame] | 3612 | lws_uv_sigint_cb(uv_signal_t *watcher, int signum); |
Andy Green | a150072 | 2017-07-15 17:48:37 +0800 | [diff] [blame] | 3613 | |
| 3614 | LWS_VISIBLE LWS_EXTERN void |
| 3615 | lws_close_all_handles_in_loop(uv_loop_t *loop); |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 3616 | #endif /* LWS_USE_LIBUV */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3617 | ///@} |
Andy Green | 86ed65f | 2016-02-14 09:27:41 +0800 | [diff] [blame] | 3618 | |
Aditya Tirumala | ec50eba | 2017-03-15 19:41:11 +0530 | [diff] [blame] | 3619 | /*! \defgroup event libevent helpers |
| 3620 | * |
| 3621 | * ##libevent helpers |
| 3622 | * |
| 3623 | * APIs specific to libevent event loop itegration |
| 3624 | */ |
| 3625 | ///@{ |
| 3626 | |
| 3627 | #ifdef LWS_USE_LIBEVENT |
| 3628 | typedef void (lws_event_signal_cb_t) (evutil_socket_t sock_fd, short revents, |
| 3629 | void *ctx); |
| 3630 | |
| 3631 | LWS_VISIBLE LWS_EXTERN int |
| 3632 | lws_event_sigint_cfg(struct lws_context *context, int use_event_sigint, |
| 3633 | lws_event_signal_cb_t cb); |
| 3634 | |
| 3635 | LWS_VISIBLE LWS_EXTERN int |
| 3636 | lws_event_initloop(struct lws_context *context, struct event_base *loop, |
| 3637 | int tsi); |
| 3638 | |
| 3639 | LWS_VISIBLE LWS_EXTERN void |
| 3640 | lws_event_sigint_cb(evutil_socket_t sock_fd, short revents, |
| 3641 | void *ctx); |
| 3642 | #endif /* LWS_USE_LIBEVENT */ |
| 3643 | |
| 3644 | ///@} |
| 3645 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3646 | /*! \defgroup timeout Connection timeouts |
Andy Green | 9f99034 | 2011-02-12 11:57:45 +0000 | [diff] [blame] | 3647 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3648 | APIs related to setting connection timeouts |
| 3649 | */ |
| 3650 | //@{ |
Andy Green | 3f62870 | 2015-12-14 07:16:32 +0800 | [diff] [blame] | 3651 | |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 3652 | /* |
| 3653 | * NOTE: These public enums are part of the abi. If you want to add one, |
| 3654 | * add it at where specified so existing users are unaffected. |
| 3655 | */ |
Andy Green | 9beedc1 | 2013-09-18 08:47:15 +0800 | [diff] [blame] | 3656 | enum pending_timeout { |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 3657 | NO_PENDING_TIMEOUT = 0, |
| 3658 | PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE = 1, |
| 3659 | PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE = 2, |
| 3660 | PENDING_TIMEOUT_ESTABLISH_WITH_SERVER = 3, |
| 3661 | PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE = 4, |
| 3662 | PENDING_TIMEOUT_AWAITING_PING = 5, |
| 3663 | PENDING_TIMEOUT_CLOSE_ACK = 6, |
| 3664 | PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE = 7, |
| 3665 | PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE = 8, |
| 3666 | PENDING_TIMEOUT_SSL_ACCEPT = 9, |
| 3667 | PENDING_TIMEOUT_HTTP_CONTENT = 10, |
| 3668 | PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND = 11, |
| 3669 | PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE = 12, |
Andy Green | 8c1f602 | 2016-01-26 20:56:56 +0800 | [diff] [blame] | 3670 | PENDING_TIMEOUT_SHUTDOWN_FLUSH = 13, |
Andy Green | 6a8099b | 2016-02-21 21:25:48 +0800 | [diff] [blame] | 3671 | PENDING_TIMEOUT_CGI = 14, |
Andy Green | b46e4a8 | 2016-04-12 16:26:03 +0800 | [diff] [blame] | 3672 | PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE = 15, |
Andy Green | f32d250 | 2016-07-15 13:41:38 +0800 | [diff] [blame] | 3673 | PENDING_TIMEOUT_WS_PONG_CHECK_SEND_PING = 16, |
| 3674 | PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG = 17, |
Andy Green | 95fff47 | 2016-08-08 21:54:30 +0800 | [diff] [blame] | 3675 | PENDING_TIMEOUT_CLIENT_ISSUE_PAYLOAD = 18, |
Andy Ning | ed92b6d | 2017-05-05 11:38:34 -0400 | [diff] [blame] | 3676 | PENDING_TIMEOUT_AWAITING_SOCKS_GREETING_REPLY = 19, |
| 3677 | PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY = 20, |
| 3678 | PENDING_TIMEOUT_AWAITING_SOCKS_AUTH_REPLY = 21, |
Andy Green | 3ff720f | 2017-06-20 11:46:49 +0800 | [diff] [blame] | 3679 | PENDING_TIMEOUT_KILLED_BY_SSL_INFO = 22, |
Andy Green | 3b0066c | 2017-07-17 10:11:17 +0800 | [diff] [blame] | 3680 | PENDING_TIMEOUT_KILLED_BY_PARENT = 23, |
| 3681 | PENDING_TIMEOUT_CLOSE_SEND = 24, |
Andy Green | ba45f7c | 2017-07-26 11:49:41 +0800 | [diff] [blame] | 3682 | PENDING_TIMEOUT_HOLDING_AH = 25, |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 3683 | |
Andy Green | dc0731b | 2015-12-08 11:04:19 +0800 | [diff] [blame] | 3684 | /****** add new things just above ---^ ******/ |
Andy Green | 9beedc1 | 2013-09-18 08:47:15 +0800 | [diff] [blame] | 3685 | }; |
| 3686 | |
Andy Green | 6f11c13 | 2017-07-19 04:39:14 +0800 | [diff] [blame] | 3687 | #define LWS_TO_KILL_ASYNC -1 |
| 3688 | /**< If LWS_TO_KILL_ASYNC is given as the timeout sec in a lws_set_timeout() |
| 3689 | * call, then the connection is marked to be killed at the next timeout |
| 3690 | * check. This is how you should force-close the wsi being serviced if |
| 3691 | * you are doing it outside the callback (where you should close by nonzero |
| 3692 | * return). |
| 3693 | */ |
| 3694 | #define LWS_TO_KILL_SYNC -2 |
| 3695 | /**< If LWS_TO_KILL_SYNC is given as the timeout sec in a lws_set_timeout() |
| 3696 | * call, then the connection is closed before returning (which may delete |
| 3697 | * the wsi). This should only be used where the wsi being closed is not the |
| 3698 | * wsi currently being serviced. |
| 3699 | */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3700 | /** |
| 3701 | * lws_set_timeout() - marks the wsi as subject to a timeout |
| 3702 | * |
| 3703 | * You will not need this unless you are doing something special |
| 3704 | * |
| 3705 | * \param wsi: Websocket connection instance |
| 3706 | * \param reason: timeout reason |
Andy Green | 6f11c13 | 2017-07-19 04:39:14 +0800 | [diff] [blame] | 3707 | * \param secs: how many seconds. You may set to LWS_TO_KILL_ASYNC to |
| 3708 | * force the connection to timeout at the next opportunity, or |
| 3709 | * LWS_TO_KILL_SYNC to close it synchronously if you know the |
| 3710 | * wsi is not the one currently being serviced. |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3711 | */ |
Patrick Gansterer | 2ff6955 | 2014-02-26 18:51:05 +0100 | [diff] [blame] | 3712 | LWS_VISIBLE LWS_EXTERN void |
Andy Green | dc8a3a8 | 2015-12-06 09:15:27 +0800 | [diff] [blame] | 3713 | lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3714 | ///@} |
| 3715 | |
| 3716 | /*! \defgroup sending-data Sending data |
| 3717 | |
| 3718 | APIs related to writing data on a connection |
| 3719 | */ |
| 3720 | //@{ |
| 3721 | #if !defined(LWS_SIZEOFPTR) |
| 3722 | #define LWS_SIZEOFPTR (sizeof (void *)) |
| 3723 | #endif |
| 3724 | #if !defined(u_int64_t) |
| 3725 | #define u_int64_t unsigned long long |
| 3726 | #endif |
| 3727 | |
Robin Rowe | 8fdff10 | 2016-06-30 02:02:08 +0800 | [diff] [blame] | 3728 | #if defined(__x86_64__) |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3729 | #define _LWS_PAD_SIZE 16 /* Intel recommended for best performance */ |
| 3730 | #else |
| 3731 | #define _LWS_PAD_SIZE LWS_SIZEOFPTR /* Size of a pointer on the target arch */ |
| 3732 | #endif |
| 3733 | #define _LWS_PAD(n) (((n) % _LWS_PAD_SIZE) ? \ |
| 3734 | ((n) + (_LWS_PAD_SIZE - ((n) % _LWS_PAD_SIZE))) : (n)) |
Andy Green | 6f11c13 | 2017-07-19 04:39:14 +0800 | [diff] [blame] | 3735 | /* last 2 is for lws-meta */ |
| 3736 | #define LWS_PRE _LWS_PAD(4 + 10 + 2) |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3737 | /* used prior to 1.7 and retained for backward compatibility */ |
| 3738 | #define LWS_SEND_BUFFER_PRE_PADDING LWS_PRE |
| 3739 | #define LWS_SEND_BUFFER_POST_PADDING 0 |
Andy Green | 9beedc1 | 2013-09-18 08:47:15 +0800 | [diff] [blame] | 3740 | |
Andy Green | 4ea6006 | 2010-10-30 12:15:07 +0100 | [diff] [blame] | 3741 | /* |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3742 | * NOTE: These public enums are part of the abi. If you want to add one, |
| 3743 | * add it at where specified so existing users are unaffected. |
| 3744 | */ |
| 3745 | enum lws_write_protocol { |
| 3746 | LWS_WRITE_TEXT = 0, |
| 3747 | /**< Send a ws TEXT message,the pointer must have LWS_PRE valid |
| 3748 | * memory behind it. The receiver expects only valid utf-8 in the |
| 3749 | * payload */ |
| 3750 | LWS_WRITE_BINARY = 1, |
| 3751 | /**< Send a ws BINARY message, the pointer must have LWS_PRE valid |
| 3752 | * memory behind it. Any sequence of bytes is valid */ |
| 3753 | LWS_WRITE_CONTINUATION = 2, |
| 3754 | /**< Continue a previous ws message, the pointer must have LWS_PRE valid |
| 3755 | * memory behind it */ |
| 3756 | LWS_WRITE_HTTP = 3, |
| 3757 | /**< Send HTTP content */ |
| 3758 | |
| 3759 | /* LWS_WRITE_CLOSE is handled by lws_close_reason() */ |
| 3760 | LWS_WRITE_PING = 5, |
| 3761 | LWS_WRITE_PONG = 6, |
| 3762 | |
| 3763 | /* Same as write_http but we know this write ends the transaction */ |
| 3764 | LWS_WRITE_HTTP_FINAL = 7, |
| 3765 | |
| 3766 | /* HTTP2 */ |
| 3767 | |
| 3768 | LWS_WRITE_HTTP_HEADERS = 8, |
| 3769 | /**< Send http headers (http2 encodes this payload and LWS_WRITE_HTTP |
| 3770 | * payload differently, http 1.x links also handle this correctly. so |
| 3771 | * to be compatible with both in the future,header response part should |
| 3772 | * be sent using this regardless of http version expected) |
| 3773 | */ |
| 3774 | |
| 3775 | /****** add new things just above ---^ ******/ |
| 3776 | |
| 3777 | /* flags */ |
| 3778 | |
| 3779 | LWS_WRITE_NO_FIN = 0x40, |
| 3780 | /**< This part of the message is not the end of the message */ |
| 3781 | |
| 3782 | LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80 |
| 3783 | /**< client packet payload goes out on wire unmunged |
| 3784 | * only useful for security tests since normal servers cannot |
| 3785 | * decode the content if used */ |
| 3786 | }; |
| 3787 | |
Andy Green | 6f11c13 | 2017-07-19 04:39:14 +0800 | [diff] [blame] | 3788 | /* used with LWS_CALLBACK_CHILD_WRITE_VIA_PARENT */ |
| 3789 | |
| 3790 | struct lws_write_passthru { |
| 3791 | struct lws *wsi; |
| 3792 | unsigned char *buf; |
| 3793 | size_t len; |
| 3794 | enum lws_write_protocol wp; |
| 3795 | }; |
| 3796 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3797 | |
| 3798 | /** |
| 3799 | * lws_write() - Apply protocol then write data to client |
| 3800 | * \param wsi: Websocket instance (available from user callback) |
| 3801 | * \param buf: The data to send. For data being sent on a websocket |
| 3802 | * connection (ie, not default http), this buffer MUST have |
| 3803 | * LWS_PRE bytes valid BEFORE the pointer. |
| 3804 | * This is so the protocol header data can be added in-situ. |
| 3805 | * \param len: Count of the data bytes in the payload starting from buf |
| 3806 | * \param protocol: Use LWS_WRITE_HTTP to reply to an http connection, and one |
| 3807 | * of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate |
| 3808 | * data on a websockets connection. Remember to allow the extra |
| 3809 | * bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT |
| 3810 | * are used. |
| 3811 | * |
| 3812 | * This function provides the way to issue data back to the client |
| 3813 | * for both http and websocket protocols. |
| 3814 | * |
Andy Green | 4ea6006 | 2010-10-30 12:15:07 +0100 | [diff] [blame] | 3815 | * IMPORTANT NOTICE! |
Andy Green | e77ddd8 | 2010-11-13 10:03:47 +0000 | [diff] [blame] | 3816 | * |
Andy Green | 3246ebb | 2015-12-26 12:03:06 +0800 | [diff] [blame] | 3817 | * When sending with websocket protocol |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 3818 | * |
Andy Green | 3246ebb | 2015-12-26 12:03:06 +0800 | [diff] [blame] | 3819 | * LWS_WRITE_TEXT, |
| 3820 | * LWS_WRITE_BINARY, |
| 3821 | * LWS_WRITE_CONTINUATION, |
Andy Green | 3246ebb | 2015-12-26 12:03:06 +0800 | [diff] [blame] | 3822 | * LWS_WRITE_PING, |
| 3823 | * LWS_WRITE_PONG |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 3824 | * |
| 3825 | * the send buffer has to have LWS_PRE bytes valid BEFORE |
Andy Green | 3246ebb | 2015-12-26 12:03:06 +0800 | [diff] [blame] | 3826 | * the buffer pointer you pass to lws_write(). |
Andy Green | e77ddd8 | 2010-11-13 10:03:47 +0000 | [diff] [blame] | 3827 | * |
Andy Green | 4ea6006 | 2010-10-30 12:15:07 +0100 | [diff] [blame] | 3828 | * This allows us to add protocol info before and after the data, and send as |
| 3829 | * one packet on the network without payload copying, for maximum efficiency. |
Andy Green | e77ddd8 | 2010-11-13 10:03:47 +0000 | [diff] [blame] | 3830 | * |
Andy Green | 6230476 | 2015-12-04 08:43:54 +0800 | [diff] [blame] | 3831 | * So for example you need this kind of code to use lws_write with a |
Andy Green | e77ddd8 | 2010-11-13 10:03:47 +0000 | [diff] [blame] | 3832 | * 128-byte payload |
| 3833 | * |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 3834 | * char buf[LWS_PRE + 128]; |
Andy Green | e77ddd8 | 2010-11-13 10:03:47 +0000 | [diff] [blame] | 3835 | * |
Andy Green | ab990e4 | 2010-10-31 12:42:52 +0000 | [diff] [blame] | 3836 | * // fill your part of the buffer... for example here it's all zeros |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 3837 | * memset(&buf[LWS_PRE], 0, 128); |
Andy Green | e77ddd8 | 2010-11-13 10:03:47 +0000 | [diff] [blame] | 3838 | * |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 3839 | * lws_write(wsi, &buf[LWS_PRE], 128, LWS_WRITE_TEXT); |
| 3840 | * |
Andy Green | 3246ebb | 2015-12-26 12:03:06 +0800 | [diff] [blame] | 3841 | * When sending HTTP, with |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 3842 | * |
Andy Green | 3246ebb | 2015-12-26 12:03:06 +0800 | [diff] [blame] | 3843 | * LWS_WRITE_HTTP, |
| 3844 | * LWS_WRITE_HTTP_HEADERS |
| 3845 | * LWS_WRITE_HTTP_FINAL |
Andy Green | 3246ebb | 2015-12-26 12:03:06 +0800 | [diff] [blame] | 3846 | * |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 3847 | * there is no protocol data prepended, and don't need to take care about the |
| 3848 | * LWS_PRE bytes valid before the buffer pointer. |
| 3849 | * |
| 3850 | * LWS_PRE is at least the frame nonce + 2 header + 8 length |
Andy Green | 3246ebb | 2015-12-26 12:03:06 +0800 | [diff] [blame] | 3851 | * LWS_SEND_BUFFER_POST_PADDING is deprecated, it's now 0 and can be left off. |
| 3852 | * The example apps no longer use it. |
| 3853 | * |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 3854 | * Pad LWS_PRE to the CPU word size, so that word references |
Andy Green | dc8a3a8 | 2015-12-06 09:15:27 +0800 | [diff] [blame] | 3855 | * to the address immediately after the padding won't cause an unaligned access |
| 3856 | * error. Sometimes for performance reasons the recommended padding is even |
| 3857 | * larger than sizeof(void *). |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3858 | * |
| 3859 | * In the case of sending using websocket protocol, be sure to allocate |
| 3860 | * valid storage before and after buf as explained above. This scheme |
| 3861 | * allows maximum efficiency of sending data and protocol in a single |
| 3862 | * packet while not burdening the user code with any protocol knowledge. |
| 3863 | * |
Andy Green | abe0c5e | 2016-10-08 18:08:03 +0800 | [diff] [blame] | 3864 | * Return may be -1 for a fatal error needing connection close, or the |
| 3865 | * number of bytes sent. |
| 3866 | * |
| 3867 | * Truncated Writes |
| 3868 | * ================ |
| 3869 | * |
| 3870 | * The OS may not accept everything you asked to write on the connection. |
| 3871 | * |
| 3872 | * Posix defines POLLOUT indication from poll() to show that the connection |
| 3873 | * will accept more write data, but it doesn't specifiy how much. It may just |
| 3874 | * accept one byte of whatever you wanted to send. |
| 3875 | * |
| 3876 | * LWS will buffer the remainder automatically, and send it out autonomously. |
| 3877 | * |
| 3878 | * During that time, WRITABLE callbacks will be suppressed. |
| 3879 | * |
| 3880 | * This is to handle corner cases where unexpectedly the OS refuses what we |
| 3881 | * usually expect it to accept. You should try to send in chunks that are |
| 3882 | * almost always accepted in order to avoid the inefficiency of the buffering. |
Andy Green | dc8a3a8 | 2015-12-06 09:15:27 +0800 | [diff] [blame] | 3883 | */ |
Peter Pentchev | 9a4fef7 | 2013-03-30 09:52:21 +0800 | [diff] [blame] | 3884 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame] | 3885 | lws_write(struct lws *wsi, unsigned char *buf, size_t len, |
Andy Green | dc8a3a8 | 2015-12-06 09:15:27 +0800 | [diff] [blame] | 3886 | enum lws_write_protocol protocol); |
Andy Green | a2b0ab0 | 2010-11-11 12:28:29 +0000 | [diff] [blame] | 3887 | |
Gabriel Gritsch | 890f8e9 | 2014-02-15 16:20:25 +0800 | [diff] [blame] | 3888 | /* helper for case where buffer may be const */ |
Andy Green | 29a44cf | 2015-12-04 07:55:17 +0800 | [diff] [blame] | 3889 | #define lws_write_http(wsi, buf, len) \ |
| 3890 | lws_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP) |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3891 | ///@} |
Andy Green | b45993c | 2010-12-18 15:13:50 +0000 | [diff] [blame] | 3892 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3893 | /** \defgroup callback-when-writeable Callback when writeable |
| 3894 | * |
| 3895 | * ##Callback When Writeable |
| 3896 | * |
| 3897 | * lws can only write data on a connection when it is able to accept more |
| 3898 | * data without blocking. |
| 3899 | * |
| 3900 | * So a basic requirement is we should only use the lws_write() apis when the |
| 3901 | * connection we want to write on says that he can accept more data. |
| 3902 | * |
| 3903 | * When lws cannot complete your send at the time, it will buffer the data |
| 3904 | * and send it in the background, suppressing any further WRITEABLE callbacks |
| 3905 | * on that connection until it completes. So it is important to write new |
| 3906 | * things in a new writeable callback. |
| 3907 | * |
| 3908 | * These apis reflect the various ways we can indicate we would like to be |
| 3909 | * called back when one or more connections is writeable. |
| 3910 | */ |
| 3911 | ///@{ |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame] | 3912 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3913 | /** |
| 3914 | * lws_callback_on_writable() - Request a callback when this socket |
| 3915 | * becomes able to be written to without |
| 3916 | * blocking |
| 3917 | * |
| 3918 | * \param wsi: Websocket connection instance to get callback for |
| 3919 | * |
| 3920 | * - Which: only this wsi |
| 3921 | * - When: when the individual connection becomes writeable |
| 3922 | * - What: LWS_CALLBACK_*_WRITEABLE |
| 3923 | */ |
Peter Pentchev | 9a4fef7 | 2013-03-30 09:52:21 +0800 | [diff] [blame] | 3924 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | 11c05bf | 2015-12-16 18:19:08 +0800 | [diff] [blame] | 3925 | lws_callback_on_writable(struct lws *wsi); |
Andy Green | 90c7cbc | 2011-01-27 06:26:52 +0000 | [diff] [blame] | 3926 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3927 | /** |
| 3928 | * lws_callback_on_writable_all_protocol() - Request a callback for all |
Andy Green | 872e8d7 | 2017-08-16 15:21:22 +0800 | [diff] [blame] | 3929 | * connections using the given protocol when it |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3930 | * becomes possible to write to each socket without |
| 3931 | * blocking in turn. |
| 3932 | * |
| 3933 | * \param context: lws_context |
| 3934 | * \param protocol: Protocol whose connections will get callbacks |
| 3935 | * |
| 3936 | * - Which: connections using this protocol on ANY VHOST |
| 3937 | * - When: when the individual connection becomes writeable |
| 3938 | * - What: LWS_CALLBACK_*_WRITEABLE |
| 3939 | */ |
Peter Pentchev | 9a4fef7 | 2013-03-30 09:52:21 +0800 | [diff] [blame] | 3940 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | d2ac22c | 2015-12-11 10:45:35 +0800 | [diff] [blame] | 3941 | lws_callback_on_writable_all_protocol(const struct lws_context *context, |
| 3942 | const struct lws_protocols *protocol); |
Andy Green | e39e6ef | 2014-02-15 16:36:38 +0800 | [diff] [blame] | 3943 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3944 | /** |
| 3945 | * lws_callback_on_writable_all_protocol_vhost() - Request a callback for |
Andy Green | 872e8d7 | 2017-08-16 15:21:22 +0800 | [diff] [blame] | 3946 | * all connections on same vhost using the given protocol |
| 3947 | * when it becomes possible to write to each socket without |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3948 | * blocking in turn. |
| 3949 | * |
| 3950 | * \param vhost: Only consider connections on this lws_vhost |
| 3951 | * \param protocol: Protocol whose connections will get callbacks |
| 3952 | * |
| 3953 | * - Which: connections using this protocol on GIVEN VHOST ONLY |
| 3954 | * - When: when the individual connection becomes writeable |
| 3955 | * - What: LWS_CALLBACK_*_WRITEABLE |
| 3956 | */ |
Andy Green | bf31c1b | 2016-05-13 08:20:12 +0800 | [diff] [blame] | 3957 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | 0207705 | 2016-04-06 16:15:40 +0800 | [diff] [blame] | 3958 | lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost, |
| 3959 | const struct lws_protocols *protocol); |
| 3960 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3961 | /** |
| 3962 | * lws_callback_all_protocol() - Callback all connections using |
| 3963 | * the given protocol with the given reason |
| 3964 | * |
| 3965 | * \param context: lws_context |
| 3966 | * \param protocol: Protocol whose connections will get callbacks |
| 3967 | * \param reason: Callback reason index |
| 3968 | * |
| 3969 | * - Which: connections using this protocol on ALL VHOSTS |
Andy Green | ed27be4 | 2017-03-15 07:28:51 +0800 | [diff] [blame] | 3970 | * - When: before returning |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3971 | * - What: reason |
Andy Green | ed27be4 | 2017-03-15 07:28:51 +0800 | [diff] [blame] | 3972 | * |
| 3973 | * This isn't normally what you want... normally any update of connection- |
| 3974 | * specific information can wait until a network-related callback like rx, |
| 3975 | * writable, or close. |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3976 | */ |
Andy Green | e39e6ef | 2014-02-15 16:36:38 +0800 | [diff] [blame] | 3977 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | d2ac22c | 2015-12-11 10:45:35 +0800 | [diff] [blame] | 3978 | lws_callback_all_protocol(struct lws_context *context, |
| 3979 | const struct lws_protocols *protocol, int reason); |
Andy Green | 90c7cbc | 2011-01-27 06:26:52 +0000 | [diff] [blame] | 3980 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3981 | /** |
| 3982 | * lws_callback_all_protocol_vhost() - Callback all connections using |
Andy Green | 93a5b58 | 2017-08-05 10:38:59 +0800 | [diff] [blame] | 3983 | * the given protocol with the given reason. This is |
| 3984 | * deprecated since v2.4: use lws_callback_all_protocol_vhost_args |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3985 | * |
| 3986 | * \param vh: Vhost whose connections will get callbacks |
Andy Green | 93a5b58 | 2017-08-05 10:38:59 +0800 | [diff] [blame] | 3987 | * \param protocol: Which protocol to match. NULL means all. |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 3988 | * \param reason: Callback reason index |
| 3989 | * |
| 3990 | * - Which: connections using this protocol on GIVEN VHOST ONLY |
| 3991 | * - When: now |
| 3992 | * - What: reason |
| 3993 | */ |
Andy Green | bf31c1b | 2016-05-13 08:20:12 +0800 | [diff] [blame] | 3994 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | 0207705 | 2016-04-06 16:15:40 +0800 | [diff] [blame] | 3995 | lws_callback_all_protocol_vhost(struct lws_vhost *vh, |
Andy Green | 93a5b58 | 2017-08-05 10:38:59 +0800 | [diff] [blame] | 3996 | const struct lws_protocols *protocol, int reason) |
| 3997 | LWS_WARN_DEPRECATED; |
| 3998 | |
| 3999 | /** |
| 4000 | * lws_callback_all_protocol_vhost_args() - Callback all connections using |
| 4001 | * the given protocol with the given reason and args |
| 4002 | * |
| 4003 | * \param vh: Vhost whose connections will get callbacks |
| 4004 | * \param protocol: Which protocol to match. NULL means all. |
| 4005 | * \param reason: Callback reason index |
| 4006 | * \param argp: Callback "in" parameter |
| 4007 | * \param len: Callback "len" parameter |
| 4008 | * |
| 4009 | * - Which: connections using this protocol on GIVEN VHOST ONLY |
| 4010 | * - When: now |
| 4011 | * - What: reason |
| 4012 | */ |
| 4013 | LWS_VISIBLE int |
| 4014 | lws_callback_all_protocol_vhost_args(struct lws_vhost *vh, |
| 4015 | const struct lws_protocols *protocol, int reason, |
| 4016 | void *argp, size_t len); |
Andy Green | 0207705 | 2016-04-06 16:15:40 +0800 | [diff] [blame] | 4017 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4018 | /** |
| 4019 | * lws_callback_vhost_protocols() - Callback all protocols enabled on a vhost |
| 4020 | * with the given reason |
| 4021 | * |
| 4022 | * \param wsi: wsi whose vhost will get callbacks |
| 4023 | * \param reason: Callback reason index |
| 4024 | * \param in: in argument to callback |
| 4025 | * \param len: len argument to callback |
| 4026 | * |
| 4027 | * - Which: connections using this protocol on same VHOST as wsi ONLY |
| 4028 | * - When: now |
| 4029 | * - What: reason |
| 4030 | */ |
Peter Pentchev | 9a4fef7 | 2013-03-30 09:52:21 +0800 | [diff] [blame] | 4031 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | 3f17a8e | 2016-06-15 10:46:58 +0800 | [diff] [blame] | 4032 | lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, int len); |
| 4033 | |
Andy Green | 7acf76c | 2016-07-23 14:18:25 +0800 | [diff] [blame] | 4034 | LWS_VISIBLE LWS_EXTERN int |
| 4035 | lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, |
| 4036 | void *user, void *in, size_t len); |
| 4037 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4038 | /** |
| 4039 | * lws_get_socket_fd() - returns the socket file descriptor |
| 4040 | * |
| 4041 | * You will not need this unless you are doing something special |
| 4042 | * |
| 4043 | * \param wsi: Websocket connection instance |
| 4044 | */ |
Andy Green | 3f17a8e | 2016-06-15 10:46:58 +0800 | [diff] [blame] | 4045 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame] | 4046 | lws_get_socket_fd(struct lws *wsi); |
| 4047 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4048 | /** |
| 4049 | * lws_get_peer_write_allowance() - get the amount of data writeable to peer |
| 4050 | * if known |
| 4051 | * |
| 4052 | * \param wsi: Websocket connection instance |
| 4053 | * |
Peter Pentchev | bb085da | 2015-12-03 15:55:11 +0200 | [diff] [blame] | 4054 | * if the protocol does not have any guidance, returns -1. Currently only |
Andy Green | 97ee57f | 2014-10-29 09:39:08 +0800 | [diff] [blame] | 4055 | * http2 connections get send window information from this API. But your code |
| 4056 | * should use it so it can work properly with any protocol. |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 4057 | * |
Andy Green | 97ee57f | 2014-10-29 09:39:08 +0800 | [diff] [blame] | 4058 | * If nonzero return is the amount of payload data the peer or intermediary has |
| 4059 | * reported it has buffer space for. That has NO relationship with the amount |
| 4060 | * of buffer space your OS can accept on this connection for a write action. |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 4061 | * |
Andy Green | 97ee57f | 2014-10-29 09:39:08 +0800 | [diff] [blame] | 4062 | * This number represents the maximum you could send to the peer or intermediary |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4063 | * on this connection right now without the protocol complaining. |
Andy Green | 40110e8 | 2015-12-14 08:52:03 +0800 | [diff] [blame] | 4064 | * |
Andy Green | 97ee57f | 2014-10-29 09:39:08 +0800 | [diff] [blame] | 4065 | * lws manages accounting for send window updates and payload writes |
| 4066 | * automatically, so this number reflects the situation at the peer or |
| 4067 | * intermediary dynamically. |
| 4068 | */ |
| 4069 | LWS_VISIBLE LWS_EXTERN size_t |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame] | 4070 | lws_get_peer_write_allowance(struct lws *wsi); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4071 | ///@} |
Andy Green | 97ee57f | 2014-10-29 09:39:08 +0800 | [diff] [blame] | 4072 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4073 | /** |
| 4074 | * lws_rx_flow_control() - Enable and disable socket servicing for |
| 4075 | * received packets. |
| 4076 | * |
| 4077 | * If the output side of a server process becomes choked, this allows flow |
| 4078 | * control for the input side. |
| 4079 | * |
| 4080 | * \param wsi: Websocket connection instance to get callback for |
| 4081 | * \param enable: 0 = disable read servicing for this connection, 1 = enable |
| 4082 | */ |
| 4083 | LWS_VISIBLE LWS_EXTERN int |
| 4084 | lws_rx_flow_control(struct lws *wsi, int enable); |
David Brooks | 2c60d95 | 2012-04-20 12:19:01 +0800 | [diff] [blame] | 4085 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4086 | /** |
| 4087 | * lws_rx_flow_allow_all_protocol() - Allow all connections with this protocol to receive |
| 4088 | * |
| 4089 | * When the user server code realizes it can accept more input, it can |
| 4090 | * call this to have the RX flow restriction removed from all connections using |
| 4091 | * the given protocol. |
| 4092 | * \param context: lws_context |
| 4093 | * \param protocol: all connections using this protocol will be allowed to receive |
| 4094 | */ |
| 4095 | LWS_VISIBLE LWS_EXTERN void |
| 4096 | lws_rx_flow_allow_all_protocol(const struct lws_context *context, |
| 4097 | const struct lws_protocols *protocol); |
Andy Green | 6711266 | 2016-01-11 11:34:01 +0800 | [diff] [blame] | 4098 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4099 | /** |
| 4100 | * lws_remaining_packet_payload() - Bytes to come before "overall" |
| 4101 | * rx packet is complete |
| 4102 | * \param wsi: Websocket instance (available from user callback) |
| 4103 | * |
| 4104 | * This function is intended to be called from the callback if the |
| 4105 | * user code is interested in "complete packets" from the client. |
| 4106 | * libwebsockets just passes through payload as it comes and issues a buffer |
| 4107 | * additionally when it hits a built-in limit. The LWS_CALLBACK_RECEIVE |
| 4108 | * callback handler can use this API to find out if the buffer it has just |
| 4109 | * been given is the last piece of a "complete packet" from the client -- |
| 4110 | * when that is the case lws_remaining_packet_payload() will return |
| 4111 | * 0. |
| 4112 | * |
| 4113 | * Many protocols won't care becuse their packets are always small. |
| 4114 | */ |
| 4115 | LWS_VISIBLE LWS_EXTERN size_t |
| 4116 | lws_remaining_packet_payload(struct lws *wsi); |
| 4117 | |
| 4118 | |
| 4119 | /** \defgroup sock-adopt Socket adoption helpers |
| 4120 | * ##Socket adoption helpers |
| 4121 | * |
| 4122 | * When integrating with an external app with its own event loop, these can |
| 4123 | * be used to accept connections from someone else's listening socket. |
| 4124 | * |
| 4125 | * When using lws own event loop, these are not needed. |
| 4126 | */ |
| 4127 | ///@{ |
| 4128 | |
| 4129 | /** |
| 4130 | * lws_adopt_socket() - adopt foreign socket as if listen socket accepted it |
Alan Conway | acdf0c7 | 2016-12-21 09:32:16 +0800 | [diff] [blame] | 4131 | * for the default vhost of context. |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4132 | * \param context: lws context |
| 4133 | * \param accept_fd: fd of already-accepted socket to adopt |
| 4134 | * |
| 4135 | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
| 4136 | * returns NULL, having cleaned up any new wsi pieces. |
| 4137 | * |
| 4138 | * LWS adopts the socket in http serving mode, it's ready to accept an upgrade |
| 4139 | * to ws or just serve http. |
| 4140 | */ |
Andy Green | ba119e9 | 2016-01-26 21:40:32 +0800 | [diff] [blame] | 4141 | LWS_VISIBLE LWS_EXTERN struct lws * |
| 4142 | lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4143 | /** |
Alan Conway | acdf0c7 | 2016-12-21 09:32:16 +0800 | [diff] [blame] | 4144 | * lws_adopt_socket_vhost() - adopt foreign socket as if listen socket accepted it |
| 4145 | * for vhost |
| 4146 | * \param vhost: lws vhost |
| 4147 | * \param accept_fd: fd of already-accepted socket to adopt |
| 4148 | * |
| 4149 | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
| 4150 | * returns NULL, having cleaned up any new wsi pieces. |
| 4151 | * |
| 4152 | * LWS adopts the socket in http serving mode, it's ready to accept an upgrade |
| 4153 | * to ws or just serve http. |
| 4154 | */ |
| 4155 | LWS_VISIBLE LWS_EXTERN struct lws * |
| 4156 | lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd); |
Andy Green | be8d791 | 2017-02-27 12:55:56 +0800 | [diff] [blame] | 4157 | |
| 4158 | typedef enum { |
Per Bothner | 60f4569 | 2017-03-03 07:36:08 +0800 | [diff] [blame] | 4159 | LWS_ADOPT_RAW_FILE_DESC = 0, /* convenience constant */ |
| 4160 | LWS_ADOPT_HTTP = 1, /* flag: absent implies RAW */ |
| 4161 | LWS_ADOPT_SOCKET = 2, /* flag: absent implies file descr */ |
Andy Green | 6f11c13 | 2017-07-19 04:39:14 +0800 | [diff] [blame] | 4162 | LWS_ADOPT_ALLOW_SSL = 4, /* flag: if set requires LWS_ADOPT_SOCKET */ |
| 4163 | LWS_ADOPT_WS_PARENTIO = 8, /* flag: ws mode parent handles IO |
| 4164 | * if given must be only flag |
| 4165 | * wsi put directly into ws mode |
| 4166 | */ |
Andy Green | be8d791 | 2017-02-27 12:55:56 +0800 | [diff] [blame] | 4167 | } lws_adoption_type; |
| 4168 | |
| 4169 | typedef union { |
| 4170 | lws_sockfd_type sockfd; |
| 4171 | lws_filefd_type filefd; |
| 4172 | } lws_sock_file_fd_type; |
| 4173 | |
Andy Green | 297c031 | 2017-02-12 20:32:49 +0800 | [diff] [blame] | 4174 | /* |
Andy Green | be8d791 | 2017-02-27 12:55:56 +0800 | [diff] [blame] | 4175 | * lws_adopt_descriptor_vhost() - adopt foreign socket or file descriptor |
| 4176 | * if socket descriptor, should already have been accepted from listen socket |
| 4177 | * |
Andy Green | 297c031 | 2017-02-12 20:32:49 +0800 | [diff] [blame] | 4178 | * \param vhost: lws vhost |
Andy Green | be8d791 | 2017-02-27 12:55:56 +0800 | [diff] [blame] | 4179 | * \param type: OR-ed combinations of lws_adoption_type flags |
| 4180 | * \param fd: union with either .sockfd or .filefd set |
| 4181 | * \param vh_prot_name: NULL or vh protocol name to bind raw connection to |
Per Bothner | 60f4569 | 2017-03-03 07:36:08 +0800 | [diff] [blame] | 4182 | * \param parent: NULL or struct lws to attach new_wsi to as a child |
Andy Green | 297c031 | 2017-02-12 20:32:49 +0800 | [diff] [blame] | 4183 | * |
| 4184 | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
| 4185 | * returns NULL, having cleaned up any new wsi pieces. |
| 4186 | * |
Andy Green | be8d791 | 2017-02-27 12:55:56 +0800 | [diff] [blame] | 4187 | * If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, it's |
| 4188 | * ready to accept an upgrade to ws or just serve http. |
Per Bothner | 60f4569 | 2017-03-03 07:36:08 +0800 | [diff] [blame] | 4189 | * |
| 4190 | * parent may be NULL, if given it should be an existing wsi that will become the |
| 4191 | * parent of the new wsi created by this call. |
Andy Green | 297c031 | 2017-02-12 20:32:49 +0800 | [diff] [blame] | 4192 | */ |
Andy Green | 632a0ac | 2017-07-15 19:02:04 +0800 | [diff] [blame] | 4193 | LWS_VISIBLE LWS_EXTERN struct lws * |
Andy Green | be8d791 | 2017-02-27 12:55:56 +0800 | [diff] [blame] | 4194 | lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type, |
Per Bothner | 60f4569 | 2017-03-03 07:36:08 +0800 | [diff] [blame] | 4195 | lws_sock_file_fd_type fd, const char *vh_prot_name, |
| 4196 | struct lws *parent); |
Andy Green | 297c031 | 2017-02-12 20:32:49 +0800 | [diff] [blame] | 4197 | |
Alan Conway | acdf0c7 | 2016-12-21 09:32:16 +0800 | [diff] [blame] | 4198 | /** |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4199 | * lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if listen socket accepted it |
Alan Conway | acdf0c7 | 2016-12-21 09:32:16 +0800 | [diff] [blame] | 4200 | * for the default vhost of context. |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4201 | * \param context: lws context |
| 4202 | * \param accept_fd: fd of already-accepted socket to adopt |
| 4203 | * \param readbuf: NULL or pointer to data that must be drained before reading from |
| 4204 | * accept_fd |
| 4205 | * \param len: The length of the data held at \param readbuf |
| 4206 | * |
| 4207 | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
| 4208 | * returns NULL, having cleaned up any new wsi pieces. |
| 4209 | * |
| 4210 | * LWS adopts the socket in http serving mode, it's ready to accept an upgrade |
| 4211 | * to ws or just serve http. |
| 4212 | * |
| 4213 | * If your external code did not already read from the socket, you can use |
| 4214 | * lws_adopt_socket() instead. |
| 4215 | * |
| 4216 | * This api is guaranteed to use the data at \param readbuf first, before reading from |
| 4217 | * the socket. |
| 4218 | * |
| 4219 | * readbuf is limited to the size of the ah rx buf, currently 2048 bytes. |
| 4220 | */ |
Andy Green | 51d9afa | 2016-02-24 11:05:56 +0800 | [diff] [blame] | 4221 | LWS_VISIBLE LWS_EXTERN struct lws * |
| 4222 | lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd, |
Alan Conway | acdf0c7 | 2016-12-21 09:32:16 +0800 | [diff] [blame] | 4223 | const char *readbuf, size_t len); |
| 4224 | /** |
| 4225 | * lws_adopt_socket_vhost_readbuf() - adopt foreign socket and first rx as if listen socket |
| 4226 | * accepted it for vhost. |
| 4227 | * \param vhost: lws vhost |
| 4228 | * \param accept_fd: fd of already-accepted socket to adopt |
| 4229 | * \param readbuf: NULL or pointer to data that must be drained before reading from |
| 4230 | * accept_fd |
| 4231 | * \param len: The length of the data held at \param readbuf |
| 4232 | * |
| 4233 | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
| 4234 | * returns NULL, having cleaned up any new wsi pieces. |
| 4235 | * |
| 4236 | * LWS adopts the socket in http serving mode, it's ready to accept an upgrade |
| 4237 | * to ws or just serve http. |
| 4238 | * |
| 4239 | * If your external code did not already read from the socket, you can use |
| 4240 | * lws_adopt_socket() instead. |
| 4241 | * |
| 4242 | * This api is guaranteed to use the data at \param readbuf first, before reading from |
| 4243 | * the socket. |
| 4244 | * |
| 4245 | * readbuf is limited to the size of the ah rx buf, currently 2048 bytes. |
| 4246 | */ |
| 4247 | LWS_VISIBLE LWS_EXTERN struct lws * |
| 4248 | lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost, lws_sockfd_type accept_fd, |
| 4249 | const char *readbuf, size_t len); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4250 | ///@} |
Andy Green | ba119e9 | 2016-01-26 21:40:32 +0800 | [diff] [blame] | 4251 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4252 | /** \defgroup net Network related helper APIs |
| 4253 | * ##Network related helper APIs |
| 4254 | * |
| 4255 | * These wrap miscellaneous useful network-related functions |
| 4256 | */ |
| 4257 | ///@{ |
| 4258 | |
| 4259 | /** |
| 4260 | * lws_canonical_hostname() - returns this host's hostname |
| 4261 | * |
| 4262 | * This is typically used by client code to fill in the host parameter |
| 4263 | * when making a client connection. You can only call it after the context |
| 4264 | * has been created. |
| 4265 | * |
| 4266 | * \param context: Websocket context |
| 4267 | */ |
Andy Green | e99a83c | 2016-01-20 16:56:06 +0800 | [diff] [blame] | 4268 | LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame] | 4269 | lws_canonical_hostname(struct lws_context *context); |
Andy Green | 2ac5a6f | 2011-01-28 10:00:18 +0000 | [diff] [blame] | 4270 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4271 | /** |
| 4272 | * lws_get_peer_addresses() - Get client address information |
| 4273 | * \param wsi: Local struct lws associated with |
| 4274 | * \param fd: Connection socket descriptor |
| 4275 | * \param name: Buffer to take client address name |
| 4276 | * \param name_len: Length of client address name buffer |
| 4277 | * \param rip: Buffer to take client address IP dotted quad |
| 4278 | * \param rip_len: Length of client address IP buffer |
| 4279 | * |
| 4280 | * This function fills in name and rip with the name and IP of |
| 4281 | * the client connected with socket descriptor fd. Names may be |
| 4282 | * truncated if there is not enough room. If either cannot be |
| 4283 | * determined, they will be returned as valid zero-length strings. |
| 4284 | */ |
Peter Pentchev | 9a4fef7 | 2013-03-30 09:52:21 +0800 | [diff] [blame] | 4285 | LWS_VISIBLE LWS_EXTERN void |
Andy Green | ab5ed3c | 2015-12-19 07:18:55 +0800 | [diff] [blame] | 4286 | lws_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name, |
| 4287 | int name_len, char *rip, int rip_len); |
Andy Green | 0703409 | 2011-02-13 08:37:12 +0000 | [diff] [blame] | 4288 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4289 | /** |
| 4290 | * lws_get_peer_simple() - Get client address information without RDNS |
| 4291 | * |
| 4292 | * \param wsi: Local struct lws associated with |
| 4293 | * \param name: Buffer to take client address name |
| 4294 | * \param namelen: Length of client address name buffer |
| 4295 | * |
| 4296 | * This provides a 123.123.123.123 type IP address in name from the |
| 4297 | * peer that has connected to wsi |
| 4298 | */ |
Andy Green | 264786d | 2016-05-25 08:04:52 +0800 | [diff] [blame] | 4299 | LWS_VISIBLE LWS_EXTERN const char * |
| 4300 | lws_get_peer_simple(struct lws *wsi, char *name, int namelen); |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 4301 | #if !defined(LWS_WITH_ESP8266) && !defined(LWS_WITH_ESP32) |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4302 | /** |
| 4303 | * lws_interface_to_sa() - Convert interface name or IP to sockaddr struct |
| 4304 | * |
| 4305 | * \param ipv6: Allow IPV6 addresses |
| 4306 | * \param ifname: Interface name or IP |
| 4307 | * \param addr: struct sockaddr_in * to be written |
| 4308 | * \param addrlen: Length of addr |
| 4309 | * |
| 4310 | * This converts a textual network interface name to a sockaddr usable by |
| 4311 | * other network functions |
| 4312 | */ |
| 4313 | LWS_VISIBLE LWS_EXTERN int |
| 4314 | lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr, |
| 4315 | size_t addrlen); |
| 4316 | ///@} |
Andy Green | 7acf76c | 2016-07-23 14:18:25 +0800 | [diff] [blame] | 4317 | #endif |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4318 | |
| 4319 | /** \defgroup misc Miscellaneous APIs |
| 4320 | * ##Miscellaneous APIs |
| 4321 | * |
| 4322 | * Various APIs outside of other categories |
| 4323 | */ |
| 4324 | ///@{ |
| 4325 | |
| 4326 | /** |
Andy Green | e2a926d | 2017-07-09 10:11:59 +0800 | [diff] [blame] | 4327 | * lws_start_foreach_ll(): linkedlist iterator helper start |
| 4328 | * |
| 4329 | * \param type: type of iteration, eg, struct xyz * |
| 4330 | * \param it: iterator var name to create |
| 4331 | * \param start: start of list |
| 4332 | * |
| 4333 | * This helper creates an iterator and starts a while (it) { |
| 4334 | * loop. The iterator runs through the linked list starting at start and |
| 4335 | * ends when it gets a NULL. |
| 4336 | * The while loop should be terminated using lws_start_foreach_ll(). |
| 4337 | */ |
| 4338 | #define lws_start_foreach_ll(type, it, start)\ |
| 4339 | { \ |
| 4340 | type it = start; \ |
| 4341 | while (it) { |
| 4342 | |
| 4343 | /** |
| 4344 | * lws_end_foreach_ll(): linkedlist iterator helper end |
| 4345 | * |
| 4346 | * \param it: same iterator var name given when starting |
| 4347 | * \param nxt: member name in the iterator pointing to next list element |
| 4348 | * |
| 4349 | * This helper is the partner for lws_start_foreach_ll() that ends the |
| 4350 | * while loop. |
| 4351 | */ |
| 4352 | |
| 4353 | #define lws_end_foreach_ll(it, nxt) \ |
| 4354 | it = it->nxt; \ |
| 4355 | } \ |
| 4356 | } |
| 4357 | |
| 4358 | /** |
| 4359 | * lws_start_foreach_llp(): linkedlist pointer iterator helper start |
| 4360 | * |
| 4361 | * \param type: type of iteration, eg, struct xyz ** |
| 4362 | * \param it: iterator var name to create |
| 4363 | * \param start: start of list |
| 4364 | * |
| 4365 | * This helper creates an iterator and starts a while (it) { |
| 4366 | * loop. The iterator runs through the linked list starting at the |
| 4367 | * address of start and ends when it gets a NULL. |
| 4368 | * The while loop should be terminated using lws_start_foreach_llp(). |
| 4369 | * |
| 4370 | * This helper variant iterates using a pointer to the previous linked-list |
| 4371 | * element. That allows you to easily delete list members by rewriting the |
| 4372 | * previous pointer to the element's next pointer. |
| 4373 | */ |
| 4374 | #define lws_start_foreach_llp(type, it, start)\ |
| 4375 | { \ |
| 4376 | type it = &(start); \ |
| 4377 | while (*(it)) { |
| 4378 | |
| 4379 | /** |
| 4380 | * lws_end_foreach_llp(): linkedlist pointer iterator helper end |
| 4381 | * |
| 4382 | * \param it: same iterator var name given when starting |
| 4383 | * \param nxt: member name in the iterator pointing to next list element |
| 4384 | * |
| 4385 | * This helper is the partner for lws_start_foreach_llp() that ends the |
| 4386 | * while loop. |
| 4387 | */ |
| 4388 | |
| 4389 | #define lws_end_foreach_llp(it, nxt) \ |
| 4390 | it = &(*(it))->nxt; \ |
| 4391 | } \ |
| 4392 | } |
| 4393 | |
| 4394 | /** |
Andy Green | a496700 | 2016-09-15 02:22:57 +0800 | [diff] [blame] | 4395 | * lws_snprintf(): snprintf that truncates the returned length too |
| 4396 | * |
| 4397 | * \param str: destination buffer |
| 4398 | * \param size: bytes left in destination buffer |
| 4399 | * \param format: format string |
| 4400 | * \param ...: args for format |
| 4401 | * |
| 4402 | * This lets you correctly truncate buffers by concatenating lengths, if you |
| 4403 | * reach the limit the reported length doesn't exceed the limit. |
| 4404 | */ |
| 4405 | LWS_VISIBLE LWS_EXTERN int |
Martin Milata | be1f0a3 | 2017-02-04 13:09:00 +0100 | [diff] [blame] | 4406 | lws_snprintf(char *str, size_t size, const char *format, ...) LWS_FORMAT(3); |
Andy Green | a496700 | 2016-09-15 02:22:57 +0800 | [diff] [blame] | 4407 | |
| 4408 | /** |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4409 | * lws_get_random(): fill a buffer with platform random data |
| 4410 | * |
| 4411 | * \param context: the lws context |
| 4412 | * \param buf: buffer to fill |
| 4413 | * \param len: how much to fill |
| 4414 | * |
| 4415 | * This is intended to be called from the LWS_CALLBACK_RECEIVE callback if |
| 4416 | * it's interested to see if the frame it's dealing with was sent in binary |
| 4417 | * mode. |
| 4418 | */ |
Peter Pentchev | 9a4fef7 | 2013-03-30 09:52:21 +0800 | [diff] [blame] | 4419 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame] | 4420 | lws_get_random(struct lws_context *context, void *buf, int len); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4421 | /** |
Martin Milata | e96b698 | 2017-02-04 13:03:26 +0100 | [diff] [blame] | 4422 | * lws_daemonize(): make current process run in the background |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4423 | * |
| 4424 | * \param _lock_path: the filepath to write the lock file |
| 4425 | * |
| 4426 | * Spawn lws as a background process, taking care of various things |
| 4427 | */ |
Andy Green | e99a83c | 2016-01-20 16:56:06 +0800 | [diff] [blame] | 4428 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
Andy Green | 279a303 | 2013-01-17 10:05:39 +0800 | [diff] [blame] | 4429 | lws_daemonize(const char *_lock_path); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4430 | /** |
| 4431 | * lws_get_library_version(): return string describing the version of lws |
| 4432 | * |
| 4433 | * On unix, also includes the git describe |
| 4434 | */ |
Andy Green | e99a83c | 2016-01-20 16:56:06 +0800 | [diff] [blame] | 4435 | LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT |
Andy Green | 7b40545 | 2013-02-01 10:50:15 +0800 | [diff] [blame] | 4436 | lws_get_library_version(void); |
| 4437 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4438 | /** |
| 4439 | * lws_wsi_user() - get the user data associated with the connection |
| 4440 | * \param wsi: lws connection |
| 4441 | * |
| 4442 | * Not normally needed since it's passed into the callback |
| 4443 | */ |
| 4444 | LWS_VISIBLE LWS_EXTERN void * |
| 4445 | lws_wsi_user(struct lws *wsi); |
| 4446 | |
| 4447 | /** |
Lukas Geyer | 16ee4b6 | 2017-02-28 21:17:25 +0800 | [diff] [blame] | 4448 | * lws_wsi_set_user() - set the user data associated with the client connection |
| 4449 | * \param wsi: lws connection |
| 4450 | * \param user: user data |
| 4451 | * |
| 4452 | * By default lws allocates this and it's not legal to externally set it |
| 4453 | * yourself. However client connections may have it set externally when the |
| 4454 | * connection is created... if so, this api can be used to modify it at |
| 4455 | * runtime additionally. |
| 4456 | */ |
| 4457 | LWS_VISIBLE LWS_EXTERN void |
| 4458 | lws_set_wsi_user(struct lws *wsi, void *user); |
| 4459 | |
| 4460 | /** |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4461 | * lws_parse_uri: cut up prot:/ads:port/path into pieces |
| 4462 | * Notice it does so by dropping '\0' into input string |
| 4463 | * and the leading / on the path is consequently lost |
| 4464 | * |
| 4465 | * \param p: incoming uri string.. will get written to |
| 4466 | * \param prot: result pointer for protocol part (https://) |
| 4467 | * \param ads: result pointer for address part |
| 4468 | * \param port: result pointer for port part |
| 4469 | * \param path: result pointer for path part |
| 4470 | */ |
Andy Green | e99a83c | 2016-01-20 16:56:06 +0800 | [diff] [blame] | 4471 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
Andy Green | a547554 | 2016-01-18 09:49:24 +0800 | [diff] [blame] | 4472 | lws_parse_uri(char *p, const char **prot, const char **ads, int *port, |
| 4473 | const char **path); |
Andy Green | 7a0fcf2 | 2016-01-14 13:39:02 +0800 | [diff] [blame] | 4474 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4475 | /** |
| 4476 | * lws_now_secs(): return seconds since 1970-1-1 |
Andy Green | e974f0c | 2015-12-19 07:35:23 +0800 | [diff] [blame] | 4477 | */ |
Andy Green | 36f87b0 | 2016-06-17 09:41:22 +0800 | [diff] [blame] | 4478 | LWS_VISIBLE LWS_EXTERN unsigned long |
| 4479 | lws_now_secs(void); |
| 4480 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4481 | /** |
| 4482 | * lws_get_context - Allow geting lws_context from a Websocket connection |
| 4483 | * instance |
| 4484 | * |
| 4485 | * With this function, users can access context in the callback function. |
| 4486 | * Otherwise users may have to declare context as a global variable. |
| 4487 | * |
| 4488 | * \param wsi: Websocket connection instance |
| 4489 | */ |
Andy Green | e99a83c | 2016-01-20 16:56:06 +0800 | [diff] [blame] | 4490 | LWS_VISIBLE LWS_EXTERN struct lws_context * LWS_WARN_UNUSED_RESULT |
Andy Green | 6d64539 | 2015-12-17 18:25:25 +0800 | [diff] [blame] | 4491 | lws_get_context(const struct lws *wsi); |
Andy Green | 8203be6 | 2015-12-11 09:36:14 +0800 | [diff] [blame] | 4492 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4493 | /** |
| 4494 | * lws_get_count_threads(): how many service threads the context uses |
| 4495 | * |
| 4496 | * \param context: the lws context |
| 4497 | * |
| 4498 | * By default this is always 1, if you asked for more than lws can handle it |
| 4499 | * will clip the number of threads. So you can use this to find out how many |
| 4500 | * threads are actually in use. |
| 4501 | */ |
Andy Green | e99a83c | 2016-01-20 16:56:06 +0800 | [diff] [blame] | 4502 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
Andy Green | d3a5505 | 2016-01-19 03:34:24 +0800 | [diff] [blame] | 4503 | lws_get_count_threads(struct lws_context *context); |
| 4504 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4505 | /** |
| 4506 | * lws_get_parent() - get parent wsi or NULL |
| 4507 | * \param wsi: lws connection |
| 4508 | * |
| 4509 | * Specialized wsi like cgi stdin/out/err are associated to a parent wsi, |
| 4510 | * this allows you to get their parent. |
| 4511 | */ |
Andy Green | 494418a | 2016-03-02 09:17:22 +0800 | [diff] [blame] | 4512 | LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT |
| 4513 | lws_get_parent(const struct lws *wsi); |
| 4514 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4515 | /** |
| 4516 | * lws_get_child() - get child wsi or NULL |
| 4517 | * \param wsi: lws connection |
| 4518 | * |
| 4519 | * Allows you to find a related wsi from the parent wsi. |
| 4520 | */ |
Andy Green | 494418a | 2016-03-02 09:17:22 +0800 | [diff] [blame] | 4521 | LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT |
| 4522 | lws_get_child(const struct lws *wsi); |
| 4523 | |
Andy Green | 6f11c13 | 2017-07-19 04:39:14 +0800 | [diff] [blame] | 4524 | /** |
| 4525 | * lws_parent_carries_io() - mark wsi as needing to send messages via parent |
| 4526 | * |
| 4527 | * \param wsi: child lws connection |
| 4528 | */ |
| 4529 | |
| 4530 | LWS_VISIBLE LWS_EXTERN void |
| 4531 | lws_set_parent_carries_io(struct lws *wsi); |
| 4532 | |
| 4533 | LWS_VISIBLE LWS_EXTERN void * |
| 4534 | lws_get_opaque_parent_data(const struct lws *wsi); |
| 4535 | |
| 4536 | LWS_VISIBLE LWS_EXTERN void |
| 4537 | lws_set_opaque_parent_data(struct lws *wsi, void *data); |
| 4538 | |
| 4539 | LWS_VISIBLE LWS_EXTERN int |
| 4540 | lws_get_child_pending_on_writable(const struct lws *wsi); |
| 4541 | |
| 4542 | LWS_VISIBLE LWS_EXTERN void |
| 4543 | lws_clear_child_pending_on_writable(struct lws *wsi); |
| 4544 | |
| 4545 | LWS_VISIBLE LWS_EXTERN int |
| 4546 | lws_get_close_length(struct lws *wsi); |
| 4547 | |
| 4548 | LWS_VISIBLE LWS_EXTERN unsigned char * |
| 4549 | lws_get_close_payload(struct lws *wsi); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4550 | |
| 4551 | /* |
| 4552 | * \deprecated DEPRECATED Note: this is not normally needed as a user api. |
| 4553 | * It's provided in case it is |
| 4554 | * useful when integrating with other app poll loop service code. |
| 4555 | */ |
| 4556 | LWS_VISIBLE LWS_EXTERN int |
WebsocketUser | 0be9e98 | 2017-06-09 20:20:42 +0800 | [diff] [blame] | 4557 | lws_read(struct lws *wsi, unsigned char *buf, lws_filepos_t len); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4558 | |
| 4559 | /** |
| 4560 | * lws_set_allocator() - custom allocator support |
| 4561 | * |
| 4562 | * \param realloc |
| 4563 | * |
| 4564 | * Allows you to replace the allocator (and deallocator) used by lws |
| 4565 | */ |
| 4566 | LWS_VISIBLE LWS_EXTERN void |
| 4567 | lws_set_allocator(void *(*realloc)(void *ptr, size_t size)); |
| 4568 | ///@} |
| 4569 | |
| 4570 | /** \defgroup wsstatus Websocket status APIs |
| 4571 | * ##Websocket connection status APIs |
| 4572 | * |
| 4573 | * These provide information about ws connection or message status |
| 4574 | */ |
| 4575 | ///@{ |
| 4576 | /** |
| 4577 | * lws_send_pipe_choked() - tests if socket is writable or not |
| 4578 | * \param wsi: lws connection |
| 4579 | * |
| 4580 | * Allows you to check if you can write more on the socket |
| 4581 | */ |
| 4582 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| 4583 | lws_send_pipe_choked(struct lws *wsi); |
| 4584 | |
| 4585 | /** |
| 4586 | * lws_is_final_fragment() - tests if last part of ws message |
Andy Green | 6f11c13 | 2017-07-19 04:39:14 +0800 | [diff] [blame] | 4587 | * |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4588 | * \param wsi: lws connection |
| 4589 | */ |
| 4590 | LWS_VISIBLE LWS_EXTERN int |
| 4591 | lws_is_final_fragment(struct lws *wsi); |
| 4592 | |
| 4593 | /** |
Andy Green | 6f11c13 | 2017-07-19 04:39:14 +0800 | [diff] [blame] | 4594 | * lws_is_first_fragment() - tests if first part of ws message |
| 4595 | * |
| 4596 | * \param wsi: lws connection |
| 4597 | */ |
| 4598 | LWS_VISIBLE LWS_EXTERN int |
| 4599 | lws_is_first_fragment(struct lws *wsi); |
| 4600 | |
| 4601 | /** |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4602 | * lws_get_reserved_bits() - access reserved bits of ws frame |
| 4603 | * \param wsi: lws connection |
| 4604 | */ |
| 4605 | LWS_VISIBLE LWS_EXTERN unsigned char |
| 4606 | lws_get_reserved_bits(struct lws *wsi); |
| 4607 | |
| 4608 | /** |
| 4609 | * lws_partial_buffered() - find out if lws buffered the last write |
| 4610 | * \param wsi: websocket connection to check |
| 4611 | * |
| 4612 | * Returns 1 if you cannot use lws_write because the last |
| 4613 | * write on this connection is still buffered, and can't be cleared without |
| 4614 | * returning to the service loop and waiting for the connection to be |
| 4615 | * writeable again. |
| 4616 | * |
| 4617 | * If you will try to do >1 lws_write call inside a single |
| 4618 | * WRITEABLE callback, you must check this after every write and bail if |
| 4619 | * set, ask for a new writeable callback and continue writing from there. |
| 4620 | * |
| 4621 | * This is never set at the start of a writeable callback, but any write |
| 4622 | * may set it. |
| 4623 | */ |
| 4624 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| 4625 | lws_partial_buffered(struct lws *wsi); |
| 4626 | |
| 4627 | /** |
| 4628 | * lws_frame_is_binary(): true if the current frame was sent in binary mode |
| 4629 | * |
| 4630 | * \param wsi: the connection we are inquiring about |
| 4631 | * |
| 4632 | * This is intended to be called from the LWS_CALLBACK_RECEIVE callback if |
| 4633 | * it's interested to see if the frame it's dealing with was sent in binary |
| 4634 | * mode. |
| 4635 | */ |
| 4636 | LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT |
| 4637 | lws_frame_is_binary(struct lws *wsi); |
| 4638 | |
| 4639 | /** |
| 4640 | * lws_is_ssl() - Find out if connection is using SSL |
| 4641 | * \param wsi: websocket connection to check |
| 4642 | * |
| 4643 | * Returns 0 if the connection is not using SSL, 1 if using SSL and |
| 4644 | * using verified cert, and 2 if using SSL but the cert was not |
| 4645 | * checked (appears for client wsi told to skip check on connection) |
| 4646 | */ |
| 4647 | LWS_VISIBLE LWS_EXTERN int |
| 4648 | lws_is_ssl(struct lws *wsi); |
| 4649 | /** |
| 4650 | * lws_is_cgi() - find out if this wsi is running a cgi process |
| 4651 | * \param wsi: lws connection |
| 4652 | */ |
| 4653 | LWS_VISIBLE LWS_EXTERN int |
| 4654 | lws_is_cgi(struct lws *wsi); |
Denis Osvald | bcce732 | 2017-01-23 19:34:46 +0800 | [diff] [blame] | 4655 | |
| 4656 | #ifdef LWS_OPENSSL_SUPPORT |
| 4657 | /** |
| 4658 | * lws_get_ssl() - Return wsi's SSL context structure |
| 4659 | * \param wsi: websocket connection |
| 4660 | * |
| 4661 | * Returns pointer to the SSL library's context structure |
| 4662 | */ |
| 4663 | LWS_VISIBLE LWS_EXTERN SSL* |
| 4664 | lws_get_ssl(struct lws *wsi); |
| 4665 | #endif |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4666 | ///@} |
| 4667 | |
| 4668 | |
| 4669 | /** \defgroup sha SHA and B64 helpers |
| 4670 | * ##SHA and B64 helpers |
| 4671 | * |
| 4672 | * These provide SHA-1 and B64 helper apis |
| 4673 | */ |
| 4674 | ///@{ |
| 4675 | #ifdef LWS_SHA1_USE_OPENSSL_NAME |
| 4676 | #define lws_SHA1 SHA1 |
| 4677 | #else |
| 4678 | /** |
| 4679 | * lws_SHA1(): make a SHA-1 digest of a buffer |
| 4680 | * |
| 4681 | * \param d: incoming buffer |
| 4682 | * \param n: length of incoming buffer |
| 4683 | * \param md: buffer for message digest (must be >= 20 bytes) |
| 4684 | * |
| 4685 | * Reduces any size buffer into a 20-byte SHA-1 hash. |
| 4686 | */ |
| 4687 | LWS_VISIBLE LWS_EXTERN unsigned char * |
| 4688 | lws_SHA1(const unsigned char *d, size_t n, unsigned char *md); |
| 4689 | #endif |
| 4690 | /** |
| 4691 | * lws_b64_encode_string(): encode a string into base 64 |
| 4692 | * |
| 4693 | * \param in: incoming buffer |
| 4694 | * \param in_len: length of incoming buffer |
| 4695 | * \param out: result buffer |
| 4696 | * \param out_size: length of result buffer |
| 4697 | * |
| 4698 | * Encodes a string using b64 |
| 4699 | */ |
| 4700 | LWS_VISIBLE LWS_EXTERN int |
| 4701 | lws_b64_encode_string(const char *in, int in_len, char *out, int out_size); |
| 4702 | /** |
| 4703 | * lws_b64_decode_string(): decode a string from base 64 |
| 4704 | * |
| 4705 | * \param in: incoming buffer |
| 4706 | * \param out: result buffer |
| 4707 | * \param out_size: length of result buffer |
| 4708 | * |
| 4709 | * Decodes a string using b64 |
| 4710 | */ |
| 4711 | LWS_VISIBLE LWS_EXTERN int |
| 4712 | lws_b64_decode_string(const char *in, char *out, int out_size); |
| 4713 | ///@} |
| 4714 | |
| 4715 | |
| 4716 | /*! \defgroup cgi cgi handling |
| 4717 | * |
| 4718 | * ##CGI handling |
| 4719 | * |
| 4720 | * These functions allow low-level control over stdin/out/err of the cgi. |
| 4721 | * |
| 4722 | * However for most cases, binding the cgi to http in and out, the default |
| 4723 | * lws implementation already does the right thing. |
| 4724 | */ |
Andy Green | 6a8099b | 2016-02-21 21:25:48 +0800 | [diff] [blame] | 4725 | #ifdef LWS_WITH_CGI |
| 4726 | enum lws_enum_stdinouterr { |
| 4727 | LWS_STDIN = 0, |
| 4728 | LWS_STDOUT = 1, |
| 4729 | LWS_STDERR = 2, |
| 4730 | }; |
| 4731 | |
Andy Green | c3c2d6d | 2016-03-09 07:41:59 +0800 | [diff] [blame] | 4732 | enum lws_cgi_hdr_state { |
| 4733 | LCHS_HEADER, |
| 4734 | LCHS_CR1, |
| 4735 | LCHS_LF1, |
| 4736 | LCHS_CR2, |
| 4737 | LCHS_LF2, |
Andy Green | de12c86 | 2017-05-18 21:19:57 +0800 | [diff] [blame] | 4738 | LHCS_RESPONSE, |
| 4739 | LHCS_DUMP_HEADERS, |
Andy Green | c3c2d6d | 2016-03-09 07:41:59 +0800 | [diff] [blame] | 4740 | LHCS_PAYLOAD, |
Andy Green | f5efa74 | 2016-04-13 11:42:53 +0800 | [diff] [blame] | 4741 | LCHS_SINGLE_0A, |
Andy Green | c3c2d6d | 2016-03-09 07:41:59 +0800 | [diff] [blame] | 4742 | }; |
| 4743 | |
Andy Green | 6a8099b | 2016-02-21 21:25:48 +0800 | [diff] [blame] | 4744 | struct lws_cgi_args { |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4745 | struct lws **stdwsi; /**< get fd with lws_get_socket_fd() */ |
| 4746 | enum lws_enum_stdinouterr ch; /**< channel index */ |
| 4747 | unsigned char *data; /**< for messages with payload */ |
| 4748 | enum lws_cgi_hdr_state hdr_state; /**< track where we are in cgi headers */ |
| 4749 | int len; /**< length */ |
Andy Green | 6a8099b | 2016-02-21 21:25:48 +0800 | [diff] [blame] | 4750 | }; |
| 4751 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4752 | |
| 4753 | /** |
| 4754 | * lws_cgi: spawn network-connected cgi process |
| 4755 | * |
| 4756 | * \param wsi: connection to own the process |
| 4757 | * \param exec_array: array of "exec-name" "arg1" ... "argn" NULL |
| 4758 | * \param script_uri_path_len: how many chars on the left of the uri are the path to the cgi |
| 4759 | * \param timeout_secs: seconds script should be allowed to run |
| 4760 | * \param mp_cgienv: pvo list with per-vhost cgi options to put in env |
| 4761 | */ |
Andy Green | 6a8099b | 2016-02-21 21:25:48 +0800 | [diff] [blame] | 4762 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | a5e73a1 | 2016-04-13 11:49:07 +0800 | [diff] [blame] | 4763 | lws_cgi(struct lws *wsi, const char * const *exec_array, |
| 4764 | int script_uri_path_len, int timeout_secs, |
Andy Green | 952fcde | 2016-05-02 06:01:59 +0800 | [diff] [blame] | 4765 | const struct lws_protocol_vhost_options *mp_cgienv); |
Andy Green | 6a8099b | 2016-02-21 21:25:48 +0800 | [diff] [blame] | 4766 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4767 | /** |
| 4768 | * lws_cgi_write_split_stdout_headers: write cgi output accounting for header part |
| 4769 | * |
| 4770 | * \param wsi: connection to own the process |
| 4771 | */ |
Andy Green | 6a8099b | 2016-02-21 21:25:48 +0800 | [diff] [blame] | 4772 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | c3c2d6d | 2016-03-09 07:41:59 +0800 | [diff] [blame] | 4773 | lws_cgi_write_split_stdout_headers(struct lws *wsi); |
| 4774 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4775 | /** |
| 4776 | * lws_cgi_kill: terminate cgi process associated with wsi |
| 4777 | * |
| 4778 | * \param wsi: connection to own the process |
| 4779 | */ |
Andy Green | c3c2d6d | 2016-03-09 07:41:59 +0800 | [diff] [blame] | 4780 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | 6a8099b | 2016-02-21 21:25:48 +0800 | [diff] [blame] | 4781 | lws_cgi_kill(struct lws *wsi); |
| 4782 | #endif |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4783 | ///@} |
Andy Green | 6a8099b | 2016-02-21 21:25:48 +0800 | [diff] [blame] | 4784 | |
Andy Green | 1e5a9ad | 2016-03-20 11:59:53 +0800 | [diff] [blame] | 4785 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4786 | /*! \defgroup fops file operation wrapping |
| 4787 | * |
| 4788 | * ##File operation wrapping |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 4789 | * |
Andy Green | 891628b | 2015-12-11 13:12:58 +0800 | [diff] [blame] | 4790 | * Use these helper functions if you want to access a file from the perspective |
| 4791 | * of a specific wsi, which is usually the case. If you just want contextless |
| 4792 | * file access, use the fops callbacks directly with NULL wsi instead of these |
| 4793 | * helpers. |
| 4794 | * |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 4795 | * If so, then it calls the platform handler or user overrides where present |
| 4796 | * (as defined in info->fops) |
| 4797 | * |
| 4798 | * The advantage from all this is user code can be portable for file operations |
| 4799 | * without having to deal with differences between platforms. |
| 4800 | */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4801 | //@{ |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 4802 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4803 | /** struct lws_plat_file_ops - Platform-specific file operations |
| 4804 | * |
| 4805 | * These provide platform-agnostic ways to deal with filesystem access in the |
| 4806 | * library and in the user code. |
| 4807 | */ |
Andy Green | 21faff3 | 2017-02-12 18:11:11 +0800 | [diff] [blame] | 4808 | |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 4809 | #if defined(LWS_WITH_ESP32) |
| 4810 | /* sdk preprocessor defs? compiler issue? gets confused with member names */ |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4811 | #define LWS_FOP_OPEN _open |
| 4812 | #define LWS_FOP_CLOSE _close |
| 4813 | #define LWS_FOP_SEEK_CUR _seek_cur |
| 4814 | #define LWS_FOP_READ _read |
| 4815 | #define LWS_FOP_WRITE _write |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 4816 | #else |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4817 | #define LWS_FOP_OPEN open |
| 4818 | #define LWS_FOP_CLOSE close |
| 4819 | #define LWS_FOP_SEEK_CUR seek_cur |
| 4820 | #define LWS_FOP_READ read |
| 4821 | #define LWS_FOP_WRITE write |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 4822 | #endif |
Andy Green | 21faff3 | 2017-02-12 18:11:11 +0800 | [diff] [blame] | 4823 | |
Andy Green | 2e11efa | 2017-02-12 18:15:15 +0800 | [diff] [blame] | 4824 | #define LWS_FOP_FLAGS_MASK ((1 << 23) - 1) |
| 4825 | #define LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP (1 << 24) |
| 4826 | #define LWS_FOP_FLAG_COMPR_IS_GZIP (1 << 25) |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4827 | #define LWS_FOP_FLAG_MOD_TIME_VALID (1 << 26) |
| 4828 | #define LWS_FOP_FLAG_VIRTUAL (1 << 27) |
Andy Green | 2e11efa | 2017-02-12 18:15:15 +0800 | [diff] [blame] | 4829 | |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4830 | struct lws_plat_file_ops; |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4831 | |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4832 | struct lws_fop_fd { |
| 4833 | lws_filefd_type fd; |
| 4834 | /**< real file descriptor related to the file... */ |
| 4835 | const struct lws_plat_file_ops *fops; |
| 4836 | /**< fops that apply to this fop_fd */ |
| 4837 | void *filesystem_priv; |
| 4838 | /**< ignored by lws; owned by the fops handlers */ |
| 4839 | lws_filepos_t pos; |
| 4840 | /**< generic "position in file" */ |
| 4841 | lws_filepos_t len; |
| 4842 | /**< generic "length of file" */ |
| 4843 | lws_fop_flags_t flags; |
| 4844 | /**< copy of the returned flags */ |
| 4845 | uint32_t mod_time; |
| 4846 | /**< optional "modification time of file", only valid if .open() |
| 4847 | * set the LWS_FOP_FLAG_MOD_TIME_VALID flag */ |
| 4848 | }; |
| 4849 | typedef struct lws_fop_fd *lws_fop_fd_t; |
| 4850 | |
| 4851 | struct lws_fops_index { |
| 4852 | const char *sig; /* NULL or vfs signature, eg, ".zip/" */ |
| 4853 | uint8_t len; /* length of above string */ |
| 4854 | }; |
| 4855 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4856 | struct lws_plat_file_ops { |
Andy Green | 1ada132 | 2017-03-01 14:28:56 +0800 | [diff] [blame] | 4857 | lws_fop_fd_t (*LWS_FOP_OPEN)(const struct lws_plat_file_ops *fops, |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4858 | const char *filename, const char *vpath, |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4859 | lws_fop_flags_t *flags); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4860 | /**< Open file (always binary access if plat supports it) |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4861 | * vpath may be NULL, or if the fops understands it, the point at which |
| 4862 | * the filename's virtual part starts. |
Andy Green | 2e11efa | 2017-02-12 18:15:15 +0800 | [diff] [blame] | 4863 | * *flags & LWS_FOP_FLAGS_MASK should be set to O_RDONLY or O_RDWR. |
| 4864 | * If the file may be gzip-compressed, |
| 4865 | * LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP is set. If it actually is |
| 4866 | * gzip-compressed, then the open handler should OR |
| 4867 | * LWS_FOP_FLAG_COMPR_IS_GZIP on to *flags before returning. |
| 4868 | */ |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4869 | int (*LWS_FOP_CLOSE)(lws_fop_fd_t *fop_fd); |
| 4870 | /**< close file AND set the pointer to NULL */ |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4871 | lws_fileofs_t (*LWS_FOP_SEEK_CUR)(lws_fop_fd_t fop_fd, |
| 4872 | lws_fileofs_t offset_from_cur_pos); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4873 | /**< seek from current position */ |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4874 | int (*LWS_FOP_READ)(lws_fop_fd_t fop_fd, lws_filepos_t *amount, |
| 4875 | uint8_t *buf, lws_filepos_t len); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4876 | /**< Read from file, on exit *amount is set to amount actually read */ |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4877 | int (*LWS_FOP_WRITE)(lws_fop_fd_t fop_fd, lws_filepos_t *amount, |
| 4878 | uint8_t *buf, lws_filepos_t len); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4879 | /**< Write to file, on exit *amount is set to amount actually written */ |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4880 | |
| 4881 | struct lws_fops_index fi[3]; |
| 4882 | /**< vfs path signatures implying use of this fops */ |
| 4883 | |
| 4884 | const struct lws_plat_file_ops *next; |
| 4885 | /**< NULL or next fops in list */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4886 | |
| 4887 | /* Add new things just above here ---^ |
| 4888 | * This is part of the ABI, don't needlessly break compatibility */ |
| 4889 | }; |
| 4890 | |
| 4891 | /** |
| 4892 | * lws_get_fops() - get current file ops |
| 4893 | * |
| 4894 | * \param context: context |
| 4895 | */ |
| 4896 | LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops * LWS_WARN_UNUSED_RESULT |
| 4897 | lws_get_fops(struct lws_context *context); |
Andy Green | c7c4ae0 | 2017-02-18 17:26:40 +0800 | [diff] [blame] | 4898 | LWS_VISIBLE LWS_EXTERN void |
Andy Green | 3a09c3b | 2017-03-08 11:11:41 +0800 | [diff] [blame] | 4899 | lws_set_fops(struct lws_context *context, const struct lws_plat_file_ops *fops); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4900 | /** |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4901 | * lws_vfs_tell() - get current file position |
| 4902 | * |
| 4903 | * \param fop_fd: fop_fd we are asking about |
| 4904 | */ |
| 4905 | LWS_VISIBLE LWS_EXTERN lws_filepos_t LWS_WARN_UNUSED_RESULT |
| 4906 | lws_vfs_tell(lws_fop_fd_t fop_fd); |
| 4907 | /** |
| 4908 | * lws_vfs_get_length() - get current file total length in bytes |
| 4909 | * |
| 4910 | * \param fop_fd: fop_fd we are asking about |
| 4911 | */ |
| 4912 | LWS_VISIBLE LWS_EXTERN lws_filepos_t LWS_WARN_UNUSED_RESULT |
| 4913 | lws_vfs_get_length(lws_fop_fd_t fop_fd); |
| 4914 | /** |
| 4915 | * lws_vfs_get_mod_time() - get time file last modified |
| 4916 | * |
| 4917 | * \param fop_fd: fop_fd we are asking about |
| 4918 | */ |
| 4919 | LWS_VISIBLE LWS_EXTERN uint32_t LWS_WARN_UNUSED_RESULT |
| 4920 | lws_vfs_get_mod_time(lws_fop_fd_t fop_fd); |
| 4921 | /** |
| 4922 | * lws_vfs_file_seek_set() - seek relative to start of file |
| 4923 | * |
| 4924 | * \param fop_fd: fop_fd we are seeking in |
| 4925 | * \param offset: offset from start of file |
| 4926 | */ |
| 4927 | LWS_VISIBLE LWS_EXTERN lws_fileofs_t |
| 4928 | lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset); |
| 4929 | /** |
| 4930 | * lws_vfs_file_seek_end() - seek relative to end of file |
| 4931 | * |
| 4932 | * \param fop_fd: fop_fd we are seeking in |
| 4933 | * \param offset: offset from start of file |
| 4934 | */ |
| 4935 | LWS_VISIBLE LWS_EXTERN lws_fileofs_t |
| 4936 | lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset); |
| 4937 | |
Andy Green | e769af4 | 2017-03-15 07:25:36 +0800 | [diff] [blame] | 4938 | extern struct lws_plat_file_ops fops_zip; |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4939 | |
| 4940 | /** |
| 4941 | * lws_plat_file_open() - open vfs filepath |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4942 | * |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4943 | * \param fops: file ops struct that applies to this descriptor |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4944 | * \param vfs_path: filename to open |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4945 | * \param flags: pointer to open flags |
| 4946 | * |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4947 | * The vfs_path is scanned for known fops signatures, and the open directed |
| 4948 | * to any matching fops open. |
| 4949 | * |
| 4950 | * User code should use this api to perform vfs opens. |
| 4951 | * |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4952 | * returns semi-opaque handle |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4953 | */ |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4954 | LWS_VISIBLE LWS_EXTERN lws_fop_fd_t LWS_WARN_UNUSED_RESULT |
| 4955 | lws_vfs_file_open(const struct lws_plat_file_ops *fops, const char *vfs_path, |
| 4956 | lws_fop_flags_t *flags); |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 4957 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4958 | /** |
| 4959 | * lws_plat_file_close() - close file |
| 4960 | * |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4961 | * \param fop_fd: file handle to close |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4962 | */ |
Andy Green | 8a97c06 | 2015-12-16 15:02:47 +0800 | [diff] [blame] | 4963 | static LWS_INLINE int |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4964 | lws_vfs_file_close(lws_fop_fd_t *fop_fd) |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 4965 | { |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 4966 | return (*fop_fd)->fops->LWS_FOP_CLOSE(fop_fd); |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 4967 | } |
| 4968 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4969 | /** |
| 4970 | * lws_plat_file_seek_cur() - close file |
| 4971 | * |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4972 | * |
| 4973 | * \param fop_fd: file handle |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4974 | * \param offset: position to seek to |
| 4975 | */ |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4976 | static LWS_INLINE lws_fileofs_t |
Andy Green | 1ada132 | 2017-03-01 14:28:56 +0800 | [diff] [blame] | 4977 | lws_vfs_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset) |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 4978 | { |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4979 | return fop_fd->fops->LWS_FOP_SEEK_CUR(fop_fd, offset); |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 4980 | } |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4981 | /** |
| 4982 | * lws_plat_file_read() - read from file |
| 4983 | * |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4984 | * \param fop_fd: file handle |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4985 | * \param amount: how much to read (rewritten by call) |
| 4986 | * \param buf: buffer to write to |
| 4987 | * \param len: max length |
| 4988 | */ |
Andy Green | e99a83c | 2016-01-20 16:56:06 +0800 | [diff] [blame] | 4989 | static LWS_INLINE int LWS_WARN_UNUSED_RESULT |
Andy Green | 1ada132 | 2017-03-01 14:28:56 +0800 | [diff] [blame] | 4990 | lws_vfs_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4991 | uint8_t *buf, lws_filepos_t len) |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 4992 | { |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4993 | return fop_fd->fops->LWS_FOP_READ(fop_fd, amount, buf, len); |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 4994 | } |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4995 | /** |
| 4996 | * lws_plat_file_write() - write from file |
| 4997 | * |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 4998 | * \param fop_fd: file handle |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 4999 | * \param amount: how much to write (rewritten by call) |
| 5000 | * \param buf: buffer to read from |
| 5001 | * \param len: max length |
| 5002 | */ |
Andy Green | e99a83c | 2016-01-20 16:56:06 +0800 | [diff] [blame] | 5003 | static LWS_INLINE int LWS_WARN_UNUSED_RESULT |
Andy Green | 1ada132 | 2017-03-01 14:28:56 +0800 | [diff] [blame] | 5004 | lws_vfs_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount, |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 5005 | uint8_t *buf, lws_filepos_t len) |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 5006 | { |
Andy Green | 1789d0a | 2017-02-25 12:42:45 +0800 | [diff] [blame] | 5007 | return fop_fd->fops->LWS_FOP_WRITE(fop_fd, amount, buf, len); |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 5008 | } |
Andy Green | 1ada132 | 2017-03-01 14:28:56 +0800 | [diff] [blame] | 5009 | |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 5010 | /* these are the platform file operations implementations... they can |
Andy Green | 1ada132 | 2017-03-01 14:28:56 +0800 | [diff] [blame] | 5011 | * be called directly and used in fops arrays |
| 5012 | */ |
| 5013 | |
| 5014 | LWS_VISIBLE LWS_EXTERN lws_fop_fd_t |
| 5015 | _lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 5016 | const char *vpath, lws_fop_flags_t *flags); |
Andy Green | 1ada132 | 2017-03-01 14:28:56 +0800 | [diff] [blame] | 5017 | LWS_VISIBLE LWS_EXTERN int |
Andy Green | 19cc7ac | 2017-03-03 12:38:10 +0800 | [diff] [blame] | 5018 | _lws_plat_file_close(lws_fop_fd_t *fop_fd); |
Andy Green | 1ada132 | 2017-03-01 14:28:56 +0800 | [diff] [blame] | 5019 | LWS_VISIBLE LWS_EXTERN lws_fileofs_t |
| 5020 | _lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset); |
| 5021 | LWS_VISIBLE LWS_EXTERN int |
| 5022 | _lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, |
| 5023 | uint8_t *buf, lws_filepos_t len); |
| 5024 | LWS_VISIBLE LWS_EXTERN int |
| 5025 | _lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount, |
| 5026 | uint8_t *buf, lws_filepos_t len); |
| 5027 | |
Andy Green | 00ae909 | 2017-03-16 10:46:31 +0800 | [diff] [blame] | 5028 | LWS_VISIBLE LWS_EXTERN int |
| 5029 | lws_alloc_vfs_file(struct lws_context *context, const char *filename, uint8_t **buf, |
| 5030 | lws_filepos_t *amount); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5031 | //@} |
Andy Green | 4e442b7 | 2015-12-10 07:58:58 +0800 | [diff] [blame] | 5032 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5033 | /** \defgroup smtp |
| 5034 | * \ingroup lwsapi |
| 5035 | * ##SMTP related functions |
Andy Green | 4939a70 | 2016-02-02 09:02:24 +0800 | [diff] [blame] | 5036 | * |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5037 | * These apis let you communicate with a local SMTP server to send email from |
| 5038 | * lws. It handles all the SMTP sequencing and protocol actions. |
| 5039 | * |
| 5040 | * Your system should have postfix, sendmail or another MTA listening on port |
| 5041 | * 25 and able to send email using the "mail" commandline app. Usually distro |
| 5042 | * MTAs are configured for this by default. |
| 5043 | * |
| 5044 | * It runs via its own libuv events if initialized (which requires giving it |
| 5045 | * a libuv loop to attach to). |
| 5046 | * |
| 5047 | * It operates using three callbacks, on_next() queries if there is a new email |
| 5048 | * to send, on_get_body() asks for the body of the email, and on_sent() is |
| 5049 | * called after the email is successfully sent. |
| 5050 | * |
| 5051 | * To use it |
| 5052 | * |
| 5053 | * - create an lws_email struct |
| 5054 | * |
| 5055 | * - initialize data, loop, the email_* strings, max_content_size and |
| 5056 | * the callbacks |
| 5057 | * |
| 5058 | * - call lws_email_init() |
| 5059 | * |
| 5060 | * When you have at least one email to send, call lws_email_check() to |
| 5061 | * schedule starting to send it. |
Andy Green | 4939a70 | 2016-02-02 09:02:24 +0800 | [diff] [blame] | 5062 | */ |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5063 | //@{ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5064 | #ifdef LWS_WITH_SMTP |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5065 | |
| 5066 | /** enum lwsgs_smtp_states - where we are in SMTP protocol sequence */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5067 | enum lwsgs_smtp_states { |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5068 | LGSSMTP_IDLE, /**< awaiting new email */ |
| 5069 | LGSSMTP_CONNECTING, /**< opening tcp connection to MTA */ |
| 5070 | LGSSMTP_CONNECTED, /**< tcp connection to MTA is connected */ |
| 5071 | LGSSMTP_SENT_HELO, /**< sent the HELO */ |
| 5072 | LGSSMTP_SENT_FROM, /**< sent FROM */ |
| 5073 | LGSSMTP_SENT_TO, /**< sent TO */ |
| 5074 | LGSSMTP_SENT_DATA, /**< sent DATA request */ |
| 5075 | LGSSMTP_SENT_BODY, /**< sent the email body */ |
| 5076 | LGSSMTP_SENT_QUIT, /**< sent the session quit */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5077 | }; |
| 5078 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5079 | /** struct lws_email - abstract context for performing SMTP operations */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5080 | struct lws_email { |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5081 | void *data; |
| 5082 | /**< opaque pointer set by user code and available to the callbacks */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5083 | uv_loop_t *loop; |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5084 | /**< the libuv loop we will work on */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5085 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5086 | char email_smtp_ip[32]; /**< Fill before init, eg, "127.0.0.1" */ |
| 5087 | char email_helo[32]; /**< Fill before init, eg, "myserver.com" */ |
| 5088 | char email_from[100]; /**< Fill before init or on_next */ |
| 5089 | char email_to[100]; /**< Fill before init or on_next */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5090 | |
| 5091 | unsigned int max_content_size; |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5092 | /**< largest possible email body size */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5093 | |
| 5094 | /* Fill all the callbacks before init */ |
| 5095 | |
| 5096 | int (*on_next)(struct lws_email *email); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5097 | /**< (Fill in before calling lws_email_init) |
| 5098 | * called when idle, 0 = another email to send, nonzero is idle. |
| 5099 | * If you return 0, all of the email_* char arrays must be set |
| 5100 | * to something useful. */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5101 | int (*on_sent)(struct lws_email *email); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5102 | /**< (Fill in before calling lws_email_init) |
| 5103 | * called when transfer of the email to the SMTP server was |
| 5104 | * successful, your callback would remove the current email |
| 5105 | * from its queue */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5106 | int (*on_get_body)(struct lws_email *email, char *buf, int len); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5107 | /**< (Fill in before calling lws_email_init) |
| 5108 | * called when the body part of the queued email is about to be |
| 5109 | * sent to the SMTP server. */ |
| 5110 | |
| 5111 | |
| 5112 | /* private things */ |
| 5113 | uv_timer_t timeout_email; /**< private */ |
| 5114 | enum lwsgs_smtp_states estate; /**< private */ |
| 5115 | uv_connect_t email_connect_req; /**< private */ |
| 5116 | uv_tcp_t email_client; /**< private */ |
| 5117 | time_t email_connect_started; /**< private */ |
| 5118 | char email_buf[256]; /**< private */ |
| 5119 | char *content; /**< private */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5120 | }; |
| 5121 | |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5122 | /** |
| 5123 | * lws_email_init() - Initialize a struct lws_email |
| 5124 | * |
| 5125 | * \param email: struct lws_email to init |
| 5126 | * \param loop: libuv loop to use |
| 5127 | * \param max_content: max email content size |
| 5128 | * |
| 5129 | * Prepares a struct lws_email for use ending SMTP |
| 5130 | */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5131 | LWS_VISIBLE LWS_EXTERN int |
| 5132 | lws_email_init(struct lws_email *email, uv_loop_t *loop, int max_content); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5133 | |
| 5134 | /** |
| 5135 | * lws_email_check() - Request check for new email |
| 5136 | * |
| 5137 | * \param email: struct lws_email context to check |
| 5138 | * |
| 5139 | * Schedules a check for new emails in 1s... call this when you have queued an |
| 5140 | * email for send. |
| 5141 | */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5142 | LWS_VISIBLE LWS_EXTERN void |
| 5143 | lws_email_check(struct lws_email *email); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5144 | /** |
| 5145 | * lws_email_destroy() - stop using the struct lws_email |
| 5146 | * |
| 5147 | * \param email: the struct lws_email context |
| 5148 | * |
| 5149 | * Stop sending email using email and free allocations |
| 5150 | */ |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5151 | LWS_VISIBLE LWS_EXTERN void |
| 5152 | lws_email_destroy(struct lws_email *email); |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5153 | |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5154 | #endif |
Andy Green | 014481e | 2016-06-20 17:05:31 +0800 | [diff] [blame] | 5155 | //@} |
Andy Green | 602d884 | 2016-06-07 09:49:59 +0800 | [diff] [blame] | 5156 | |
Andy Green | a7def3c | 2017-05-07 10:02:03 +0800 | [diff] [blame] | 5157 | /* |
| 5158 | * Stats are all uint64_t numbers that start at 0. |
| 5159 | * Index names here have the convention |
| 5160 | * |
| 5161 | * _C_ counter |
| 5162 | * _B_ byte count |
| 5163 | * _MS_ millisecond count |
| 5164 | */ |
| 5165 | |
| 5166 | enum { |
| 5167 | LWSSTATS_C_CONNECTIONS, /**< count incoming connections */ |
| 5168 | LWSSTATS_C_API_CLOSE, /**< count calls to close api */ |
| 5169 | LWSSTATS_C_API_READ, /**< count calls to read from socket api */ |
| 5170 | LWSSTATS_C_API_LWS_WRITE, /**< count calls to lws_write API */ |
| 5171 | LWSSTATS_C_API_WRITE, /**< count calls to write API */ |
| 5172 | LWSSTATS_C_WRITE_PARTIALS, /**< count of partial writes */ |
| 5173 | LWSSTATS_C_WRITEABLE_CB_REQ, /**< count of writable callback requests */ |
| 5174 | LWSSTATS_C_WRITEABLE_CB_EFF_REQ, /**< count of effective writable callback requests */ |
| 5175 | LWSSTATS_C_WRITEABLE_CB, /**< count of writable callbacks */ |
| 5176 | LWSSTATS_C_SSL_CONNECTIONS_FAILED, /**< count of failed SSL connections */ |
| 5177 | LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED, /**< count of accepted SSL connections */ |
Andy Green | b2f8bc5 | 2017-05-13 10:26:59 +0800 | [diff] [blame] | 5178 | LWSSTATS_C_SSL_CONNS_HAD_RX, /**< count of accepted SSL conns that have had some RX */ |
Andy Green | a7def3c | 2017-05-07 10:02:03 +0800 | [diff] [blame] | 5179 | LWSSTATS_C_TIMEOUTS, /**< count of timed-out connections */ |
| 5180 | LWSSTATS_C_SERVICE_ENTRY, /**< count of entries to lws service loop */ |
| 5181 | LWSSTATS_B_READ, /**< aggregate bytes read */ |
| 5182 | LWSSTATS_B_WRITE, /**< aggregate bytes written */ |
| 5183 | LWSSTATS_B_PARTIALS_ACCEPTED_PARTS, /**< aggreate of size of accepted write data from new partials */ |
| 5184 | LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY, /**< aggregate delay in accepting connection */ |
| 5185 | LWSSTATS_MS_WRITABLE_DELAY, /**< aggregate delay between asking for writable and getting cb */ |
| 5186 | LWSSTATS_MS_WORST_WRITABLE_DELAY, /**< single worst delay between asking for writable and getting cb */ |
Andy Green | b2f8bc5 | 2017-05-13 10:26:59 +0800 | [diff] [blame] | 5187 | LWSSTATS_MS_SSL_RX_DELAY, /**< aggregate delay between ssl accept complete and first RX */ |
Andy Green | a7def3c | 2017-05-07 10:02:03 +0800 | [diff] [blame] | 5188 | |
| 5189 | /* Add new things just above here ---^ |
| 5190 | * This is part of the ABI, don't needlessly break compatibility */ |
| 5191 | LWSSTATS_SIZE |
| 5192 | }; |
| 5193 | |
| 5194 | #if defined(LWS_WITH_STATS) |
| 5195 | |
| 5196 | LWS_VISIBLE LWS_EXTERN uint64_t |
| 5197 | lws_stats_get(struct lws_context *context, int index); |
| 5198 | LWS_VISIBLE LWS_EXTERN void |
| 5199 | lws_stats_log_dump(struct lws_context *context); |
| 5200 | #else |
Andy Ning | ce2e74e | 2017-05-26 09:33:55 -0400 | [diff] [blame] | 5201 | static LWS_INLINE uint64_t |
Andy Green | a7def3c | 2017-05-07 10:02:03 +0800 | [diff] [blame] | 5202 | lws_stats_get(struct lws_context *context, int index) { return 0; } |
Andy Ning | ce2e74e | 2017-05-26 09:33:55 -0400 | [diff] [blame] | 5203 | static LWS_INLINE void |
Andy Green | a7def3c | 2017-05-07 10:02:03 +0800 | [diff] [blame] | 5204 | lws_stats_log_dump(struct lws_context *context) { } |
| 5205 | #endif |
| 5206 | |
Peter Hinz | 56885f3 | 2011-03-02 22:03:47 +0000 | [diff] [blame] | 5207 | #ifdef __cplusplus |
| 5208 | } |
| 5209 | #endif |
Andy Green | a11fe94 | 2011-09-25 10:30:26 +0100 | [diff] [blame] | 5210 | |
Andy Green | ab990e4 | 2010-10-31 12:42:52 +0000 | [diff] [blame] | 5211 | #endif |