mongoose.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. // Copyright (c) 2004-2013 Sergey Lyubka
  2. // Copyright (c) 2013-2020 Cesanta Software Limited
  3. // All rights reserved
  4. //
  5. // This software is dual-licensed: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License version 2 as
  7. // published by the Free Software Foundation. For the terms of this
  8. // license, see <http://www.gnu.org/licenses/>.
  9. //
  10. // You are free to use this software under the terms of the GNU General
  11. // Public License, but WITHOUT ANY WARRANTY; without even the implied
  12. // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. // See the GNU General Public License for more details.
  14. //
  15. // Alternatively, you can license this software under a commercial
  16. // license, as set out in <https://www.cesanta.com/license>.
  17. #pragma once
  18. #define MG_VERSION "7.2"
  19. #define MG_ARCH_CUSTOM 0
  20. #define MG_ARCH_UNIX 1
  21. #define MG_ARCH_WIN32 2
  22. #define MG_ARCH_ESP32 3
  23. #define MG_ARCH_ESP8266 4
  24. #define MG_ARCH_CC3100 5
  25. #define MG_ARCH_CC3200 6
  26. #define MG_ARCH_CC3220 7
  27. #define MG_ARCH_MSP432 8
  28. #define MG_ARCH_TM4C129 9
  29. #define MG_ARCH_MBED 10
  30. #define MG_ARCH_WINCE 11
  31. #define MG_ARCH_NXP_LPC 12
  32. #define MG_ARCH_NXP_KINETIS 13
  33. #define MG_ARCH_NRF51 14
  34. #define MG_ARCH_NRF52 15
  35. #define MG_ARCH_PIC32 16
  36. #define MG_ARCH_RS14100 17
  37. #define MG_ARCH_STM32 18
  38. #define MG_ARCH_FREERTOS 19
  39. #if !defined(MG_ARCH)
  40. #if defined(TARGET_IS_MSP432P4XX) || defined(__MSP432P401R__)
  41. #define MG_ARCH MG_ARCH_MSP432
  42. #elif defined(cc3200) || defined(TARGET_IS_CC3200)
  43. #define MG_ARCH MG_ARCH_CC3200
  44. #elif defined(cc3220) || defined(TARGET_IS_CC3220)
  45. #define MG_ARCH MG_ARCH_CC3220
  46. #elif defined(__unix__) || defined(__APPLE__)
  47. #define MG_ARCH MG_ARCH_UNIX
  48. #elif defined(WINCE)
  49. #define MG_ARCH MG_ARCH_WINCE
  50. #elif defined(_WIN32)
  51. #define MG_ARCH MG_ARCH_WIN32
  52. #elif defined(__MBED__)
  53. #define MG_ARCH MG_ARCH_MBED
  54. #elif defined(__USE_LPCOPEN)
  55. #define MG_ARCH MG_ARCH_NXP_LPC
  56. #elif defined(FRDM_K64F) || defined(FREEDOM)
  57. #define MG_ARCH MG_ARCH_NXP_KINETIS
  58. #elif defined(PIC32)
  59. #define MG_ARCH MG_ARCH_PIC32
  60. #elif defined(ICACHE_FLASH) || defined(ICACHE_RAM_ATTR)
  61. #define MG_ARCH MG_ARCH_ESP8266
  62. #elif defined(ESP_PLATFORM)
  63. #define MG_ARCH MG_ARCH_ESP32
  64. #elif defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || \
  65. defined(TARGET_IS_TM4C129_RA2)
  66. #define MG_ARCH MG_ARCH_TM4C129
  67. #elif defined(RS14100)
  68. #define MG_ARCH MG_ARCH_RS14100
  69. #elif defined(STM32)
  70. #define MG_ARCH MG_ARCH_STM32
  71. #endif
  72. #if !defined(MG_ARCH)
  73. #error "MG_ARCH is not specified and we couldn't guess it."
  74. #endif
  75. #endif // !defined(MG_ARCH)
  76. #define WIN32_LEAN_AND_MEAN
  77. #define _CRT_SECURE_NO_WARNINGS
  78. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  79. // Standard C headers
  80. #include <ctype.h>
  81. #include <errno.h>
  82. #include <fcntl.h>
  83. #include <limits.h>
  84. #include <stdarg.h>
  85. #include <stddef.h>
  86. #include <stdio.h>
  87. #include <stdlib.h>
  88. #include <string.h>
  89. #include <sys/stat.h>
  90. #include <sys/types.h>
  91. #include <time.h>
  92. #if MG_ARCH == MG_ARCH_CUSTOM
  93. #include <mongoose_custom.h>
  94. #endif
  95. #if !defined(PRINTF_LIKE)
  96. #if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__)
  97. #define PRINTF_LIKE(f, a) __attribute__((format(printf, f, a)))
  98. #else
  99. #define PRINTF_LIKE(f, a)
  100. #endif
  101. #endif
  102. #if MG_ARCH == MG_ARCH_ESP32
  103. #include <dirent.h>
  104. #include <netdb.h>
  105. #define MG_DIRSEP '/'
  106. #define MG_INT64_FMT "%lld"
  107. #endif
  108. #if MG_ARCH == MG_ARCH_ESP8266
  109. #include <dirent.h>
  110. #include <esp_system.h>
  111. #include <netdb.h>
  112. #include <stdbool.h>
  113. #include <sys/time.h>
  114. #define MG_DIRSEP '/'
  115. #define MG_INT64_FMT "%lld"
  116. #endif
  117. #if MG_ARCH == MG_ARCH_FREERTOS
  118. #include <FreeRTOS.h>
  119. #include <task.h>
  120. #include <FreeRTOS_IP.h>
  121. #include <FreeRTOS_Sockets.h>
  122. #include <stdbool.h>
  123. #define MG_INT64_FMT "%lld"
  124. #define MG_DIRSEP '/'
  125. #define IPPROTO_TCP FREERTOS_IPPROTO_TCP
  126. #define IPPROTO_UDP FREERTOS_IPPROTO_UDP
  127. #define AF_INET FREERTOS_AF_INET
  128. #define SOCK_STREAM FREERTOS_SOCK_STREAM
  129. #define SOCK_DGRAM FREERTOS_SOCK_DGRAM
  130. #define SO_BROADCAST 0
  131. #define SO_ERROR 0
  132. #define SOL_SOCKET 0
  133. #define SO_REUSEADDR 0
  134. #define sockaddr_in freertos_sockaddr
  135. struct sockaddr {
  136. uint8_t sa_len, sa_family;
  137. };
  138. #define accept(a, b, c) FreeRTOS_accept((a), (b), (c))
  139. #define connect(a, b, c) FreeRTOS_connect((a), (b), (c))
  140. #define bind(a, b, c) FreeRTOS_bind((a), (b), (c))
  141. #define listen(a, b) FreeRTOS_listen((a), (b))
  142. #define socket(a, b, c) FreeRTOS_socket((a), (b), (c))
  143. #define send(a, b, c, d) FreeRTOS_send((a), (b), (c), (d))
  144. #define recv(a, b, c, d) FreeRTOS_recv((a), (b), (c), (d))
  145. #define setsockopt(a, b, c, d, e) FreeRTOS_setsockopt((a), (b), (c), (d), (e))
  146. #define sendto(a, b, c, d, e, f) FreeRTOS_sendto((a), (b), (c), (d), (e), (f))
  147. #define recvfrom(a, b, c, d, e, f) \
  148. FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f))
  149. #define closesocket(x) FreeRTOS_closesocket(x)
  150. #define gethostbyname(x) FreeRTOS_gethostbyname(x)
  151. #include <ff_stdio.h>
  152. #undef FILE
  153. #define FILE FF_FILE
  154. //#define SEEK_SET FF_SEEK_SET
  155. //#define SEEK_END FF_SEEK_END
  156. #define stat(a, b) ff_stat((a), (b))
  157. #define fopen(a, b) ff_fopen((a), (b))
  158. #define fclose(a) ff_fclose(a)
  159. #define fread(a, b, c, d) ff_fread((a), (b), (c), (d))
  160. #define fwrite(a, b, c, d) ff_fwrite((a), (b), (c), (d))
  161. #define vfprintf ff_vfprintf
  162. #define fprintf ff_fprintf
  163. #define remove(a) ff_remove(a)
  164. #define rename(a, b) ff_rename((a), (b), 1)
  165. static inline int ff_vfprintf(FF_FILE *fp, const char *fmt, va_list ap) {
  166. char *buf = NULL;
  167. int n = mg_vasprintf(&buf, 0, fmt, ap);
  168. if (buf != NULL) ff_fwrite(buf, 1, n, fp), free(buf);
  169. return n;
  170. }
  171. #endif
  172. #if MG_ARCH == MG_ARCH_UNIX
  173. #define _DARWIN_UNLIMITED_SELECT 1
  174. #include <arpa/inet.h>
  175. #include <dirent.h>
  176. #include <inttypes.h>
  177. #include <netdb.h>
  178. #include <netinet/tcp.h>
  179. #include <signal.h>
  180. #include <stdbool.h>
  181. #include <stdint.h>
  182. #include <sys/select.h>
  183. #include <sys/socket.h>
  184. #include <sys/time.h>
  185. #include <unistd.h>
  186. #define MG_DIRSEP '/'
  187. #define MG_ENABLE_POSIX 1
  188. #define MG_INT64_FMT "%" PRId64
  189. #endif
  190. #if MG_ARCH == MG_ARCH_WIN32
  191. #if defined(_MSC_VER) && _MSC_VER < 1700
  192. #define __func__ ""
  193. typedef __int64 int64_t;
  194. typedef unsigned __int64 uint64_t;
  195. typedef unsigned char uint8_t;
  196. typedef char int8_t;
  197. typedef unsigned short uint16_t;
  198. typedef short int16_t;
  199. typedef unsigned int uint32_t;
  200. typedef int int32_t;
  201. typedef enum { false = 0, true = 1 } bool;
  202. #else
  203. #include <stdbool.h>
  204. #include <stdint.h>
  205. #include <ws2tcpip.h>
  206. #endif
  207. #include <winsock2.h>
  208. // Protect from calls like std::snprintf in app code
  209. // See https://github.com/cesanta/mongoose/issues/1047
  210. #ifndef __cplusplus
  211. #define snprintf _snprintf
  212. #define vsnprintf _vsnprintf
  213. #define strdup(x) _strdup(x)
  214. #endif
  215. typedef int socklen_t;
  216. #define MG_DIRSEP '\\'
  217. #ifndef PATH_MAX
  218. #define PATH_MAX MAX_PATH
  219. #endif
  220. #ifndef EINPROGRESS
  221. #define EINPROGRESS WSAEINPROGRESS
  222. #endif
  223. #ifndef EWOULDBLOCK
  224. #define EWOULDBLOCK WSAEWOULDBLOCK
  225. #endif
  226. #define realpath(a, b) _fullpath((b), (a), 512)
  227. #ifndef va_copy
  228. #ifdef __va_copy
  229. #define va_copy __va_copy
  230. #else
  231. #define va_copy(x, y) (x) = (y)
  232. #endif
  233. #endif
  234. #ifndef S_ISDIR
  235. #define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
  236. #endif
  237. #define MG_INT64_FMT "%I64d"
  238. #endif
  239. #ifndef MG_ENABLE_LWIP
  240. #define MG_ENABLE_LWIP 0
  241. #endif
  242. #if MG_ENABLE_LWIP
  243. #define MG_ENABLE_SOCKET 0
  244. #elif !defined(MG_ENABLE_SOCKET)
  245. #define MG_ENABLE_SOCKET 1
  246. #endif
  247. #ifndef MG_ENABLE_MBEDTLS
  248. #define MG_ENABLE_MBEDTLS 0
  249. #endif
  250. #ifndef MG_ENABLE_OPENSSL
  251. #define MG_ENABLE_OPENSSL 0
  252. #endif
  253. #ifndef MG_ENABLE_FS
  254. #define MG_ENABLE_FS 1
  255. #endif
  256. #ifndef MG_ENABLE_SSI
  257. #define MG_ENABLE_SSI 0
  258. #endif
  259. #ifndef MG_ENABLE_IPV6
  260. #define MG_ENABLE_IPV6 0
  261. #endif
  262. #ifndef MG_ENABLE_LOG
  263. #define MG_ENABLE_LOG 1
  264. #endif
  265. #ifndef MG_ENABLE_MGOS
  266. #define MG_ENABLE_MGOS 0
  267. #endif
  268. #ifndef MG_ENABLE_MD5
  269. #define MG_ENABLE_MD5 0
  270. #endif
  271. #ifndef MG_ENABLE_DIRECTORY_LISTING
  272. #define MG_ENABLE_DIRECTORY_LISTING 0
  273. #endif
  274. #ifndef MG_ENABLE_HTTP_DEBUG_ENDPOINT
  275. #define MG_ENABLE_HTTP_DEBUG_ENDPOINT 0
  276. #endif
  277. #ifndef MG_ENABLE_SOCKETPAIR
  278. #define MG_ENABLE_SOCKETPAIR 0
  279. #endif
  280. // Granularity of the send/recv IO buffer growth
  281. #ifndef MG_IO_SIZE
  282. #define MG_IO_SIZE 512
  283. #endif
  284. // Maximum size of the recv IO buffer
  285. #ifndef MG_MAX_RECV_BUF_SIZE
  286. #define MG_MAX_RECV_BUF_SIZE (3 * 1024 * 1024)
  287. #endif
  288. #ifndef MG_MAX_HTTP_HEADERS
  289. #define MG_MAX_HTTP_HEADERS 40
  290. #endif
  291. #include <ctype.h>
  292. #include <string.h>
  293. struct mg_str {
  294. const char *ptr;
  295. size_t len;
  296. };
  297. #define MG_NULL_STR \
  298. { NULL, 0 }
  299. struct mg_str mg_str(const char *s);
  300. struct mg_str mg_str_n(const char *s, size_t n);
  301. int mg_lower(const char *s);
  302. int mg_ncasecmp(const char *s1, const char *s2, size_t len);
  303. int mg_casecmp(const char *s1, const char *s2);
  304. int mg_vcmp(const struct mg_str *s1, const char *s2);
  305. int mg_vcasecmp(const struct mg_str *str1, const char *str2);
  306. int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
  307. struct mg_str mg_strstrip(struct mg_str s);
  308. struct mg_str mg_strdup(const struct mg_str s);
  309. const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle);
  310. #if MG_ENABLE_MGOS
  311. #include <common/cs_dbg.h>
  312. #else
  313. #if MG_ENABLE_LOG
  314. #define LOG(level, args) \
  315. do { \
  316. if (mg_log_prefix((level), __FILE__, __LINE__, __func__)) mg_log args; \
  317. } while (0)
  318. enum { LL_NONE, LL_ERROR, LL_INFO, LL_DEBUG, LL_VERBOSE_DEBUG };
  319. bool mg_log_prefix(int ll, const char *file, int line, const char *fname);
  320. void mg_log(const char *fmt, ...) PRINTF_LIKE(1, 2);
  321. void mg_log_set(const char *spec);
  322. void mg_log_set_callback(void (*fn)(const void *, int, void *), void *param);
  323. #else
  324. #define LOG(level, args)
  325. #endif
  326. #endif
  327. struct mg_timer {
  328. int period_ms; // Timer period in milliseconds
  329. int flags; // Possible flags values below
  330. #define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
  331. #define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
  332. void (*fn)(void *); // Function to call
  333. void *arg; // Function agrument
  334. unsigned long expire; // Expiration timestamp in milliseconds
  335. struct mg_timer *next; // Linkage in g_timers list
  336. };
  337. extern struct mg_timer *g_timers; // Global list of timers
  338. void mg_timer_init(struct mg_timer *, int ms, int, void (*fn)(void *), void *);
  339. void mg_timer_free(struct mg_timer *);
  340. void mg_timer_poll(unsigned long uptime_ms);
  341. char *mg_file_read(const char *path);
  342. size_t mg_file_size(const char *path);
  343. bool mg_file_write(const char *path, const void *buf, size_t len);
  344. bool mg_file_printf(const char *path, const char *fmt, ...);
  345. void mg_random(void *buf, size_t len);
  346. bool mg_globmatch(const char *pattern, int plen, const char *s, int n);
  347. bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v);
  348. uint16_t mg_ntohs(uint16_t net);
  349. uint32_t mg_ntohl(uint32_t net);
  350. char *mg_hexdump(const void *buf, size_t len);
  351. char *mg_hex(const void *buf, int len, char *dst);
  352. void mg_unhex(const char *buf, int len, unsigned char *to);
  353. unsigned long mg_unhexn(const char *s, int len);
  354. int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
  355. int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap);
  356. int64_t mg_to64(struct mg_str str);
  357. double mg_time(void);
  358. unsigned long mg_millis(void);
  359. void mg_usleep(unsigned long usecs);
  360. #if MG_ENABLE_FS
  361. #ifdef _WIN32
  362. typedef struct _stati64 mg_stat_t;
  363. #define mg_stat(a, b) _stati64((a), (b))
  364. #else
  365. typedef struct stat mg_stat_t;
  366. #define mg_stat(a, b) stat((a), (b))
  367. #endif
  368. #endif
  369. #define mg_htons(x) mg_ntohs(x)
  370. #define mg_htonl(x) mg_ntohl(x)
  371. #define MG_SWAP16(x) ((((x) >> 8) & 255) | ((x & 255) << 8))
  372. #define MG_SWAP32(x) \
  373. (((x) >> 24) | (((x) &0xff0000) >> 8) | (((x) &0xff00) << 8) | ((x) << 24))
  374. #if !defined(WEAK)
  375. #if (defined(__GNUC__) || defined(__clang__) || \
  376. defined(__TI_COMPILER_VERSION__)) && \
  377. !defined(_WIN32)
  378. #define WEAK __attribute__((weak))
  379. #else
  380. #define WEAK
  381. #endif
  382. #endif
  383. // Expands to a string representation of its argument: e.g.
  384. // MG_STRINGIFY_LITERAL(5) expands to "5"
  385. #if !defined(_MSC_VER) || _MSC_VER >= 1900
  386. #define MG_STRINGIFY_LITERAL(...) #__VA_ARGS__
  387. #else
  388. #define MG_STRINGIFY_LITERAL(x) #x
  389. #endif
  390. #define LIST_ADD_HEAD(type_, head_, elem_) \
  391. do { \
  392. (elem_)->next = (*head_); \
  393. *(head_) = (elem_); \
  394. } while (0)
  395. #define LIST_ADD_TAIL(type_, head_, elem_) \
  396. do { \
  397. type_ **h = head_; \
  398. while (*h != NULL) h = &(*h)->next; \
  399. *h = (elem_); \
  400. } while (0)
  401. #define LIST_DELETE(type_, head_, elem_) \
  402. do { \
  403. type_ **h = head_; \
  404. while (*h != (elem_)) h = &(*h)->next; \
  405. *h = (elem_)->next; \
  406. } while (0)
  407. // Expands to a string representation of its argument, which can be a macro:
  408. // #define FOO 123
  409. // MG_STRINGIFY_MACRO(FOO) // Expands to 123
  410. #define MG_STRINGIFY_MACRO(x) MG_STRINGIFY_LITERAL(x)
  411. unsigned short mg_url_port(const char *url);
  412. int mg_url_is_ssl(const char *url);
  413. struct mg_str mg_url_host(const char *url);
  414. struct mg_str mg_url_user(const char *url);
  415. struct mg_str mg_url_pass(const char *url);
  416. const char *mg_url_uri(const char *url);
  417. #include <stddef.h>
  418. struct mg_iobuf {
  419. unsigned char *buf;
  420. size_t size, len;
  421. };
  422. int mg_iobuf_init(struct mg_iobuf *, size_t);
  423. int mg_iobuf_resize(struct mg_iobuf *, size_t);
  424. void mg_iobuf_free(struct mg_iobuf *);
  425. size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t);
  426. size_t mg_iobuf_delete(struct mg_iobuf *, size_t);
  427. int mg_base64_update(unsigned char p, char *to, int len);
  428. int mg_base64_final(char *to, int len);
  429. int mg_base64_encode(const unsigned char *p, int n, char *to);
  430. int mg_base64_decode(const char *src, int n, char *dst);
  431. typedef struct {
  432. uint32_t buf[4];
  433. uint32_t bits[2];
  434. unsigned char in[64];
  435. } mg_md5_ctx;
  436. void mg_md5_init(mg_md5_ctx *c);
  437. void mg_md5_update(mg_md5_ctx *c, const unsigned char *data, size_t len);
  438. void mg_md5_final(mg_md5_ctx *c, unsigned char[16]);
  439. typedef struct {
  440. uint32_t state[5];
  441. uint32_t count[2];
  442. unsigned char buffer[64];
  443. } mg_sha1_ctx;
  444. void mg_sha1_init(mg_sha1_ctx *);
  445. void mg_sha1_update(mg_sha1_ctx *, const unsigned char *data, size_t len);
  446. void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *);
  447. void mg_hmac_sha1(const unsigned char *key, size_t key_len,
  448. const unsigned char *text, size_t text_len,
  449. unsigned char out[20]);
  450. struct mg_connection;
  451. typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
  452. void *ev_data, void *fn_data);
  453. #if 0
  454. struct mg_fn {
  455. struct mg_fn *next;
  456. mg_event_handler_t fn;
  457. void *fn_data;
  458. };
  459. void mg_fn_add(struct mg_connection *c, mg_event_handler_t fn, void *fn_data);
  460. void mg_fn_del(struct mg_connection *c, mg_event_handler_t fn);
  461. #endif
  462. void mg_call(struct mg_connection *c, int ev, void *ev_data);
  463. void mg_error(struct mg_connection *c, const char *fmt, ...);
  464. enum {
  465. MG_EV_ERROR, // Error char *error_message
  466. MG_EV_POLL, // mg_mgr_poll iteration unsigned long *millis
  467. MG_EV_RESOLVE, // Host name is resolved NULL
  468. MG_EV_CONNECT, // Connection established NULL
  469. MG_EV_ACCEPT, // Connection accepted NULL
  470. MG_EV_READ, // Data received from socket struct mg_str *
  471. MG_EV_WRITE, // Data written to socket int *num_bytes_written
  472. MG_EV_CLOSE, // Connection closed NULL
  473. MG_EV_HTTP_MSG, // HTTP request/response struct mg_http_message *
  474. MG_EV_WS_OPEN, // Websocket handshake done struct mg_http_message *
  475. MG_EV_WS_MSG, // Websocket msg, text or bin struct mg_ws_message *
  476. MG_EV_WS_CTL, // Websocket control msg struct mg_ws_message *
  477. MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message *
  478. MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message *
  479. MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code
  480. MG_EV_SNTP_TIME, // SNTP time received struct timeval *
  481. MG_EV_USER, // Starting ID for user events
  482. };
  483. struct mg_dns {
  484. const char *url; // DNS server URL
  485. struct mg_connection *c; // DNS server connection
  486. };
  487. struct mg_addr {
  488. uint16_t port; // TCP or UDP port in network byte order
  489. uint32_t ip; // IP address in network byte order
  490. uint8_t ip6[16]; // IPv6 address
  491. bool is_ip6; // True when address is IPv6 address
  492. };
  493. struct mg_mgr {
  494. struct mg_connection *conns; // List of active connections
  495. struct mg_dns dns4; // DNS for IPv4
  496. struct mg_dns dns6; // DNS for IPv6
  497. int dnstimeout; // DNS resolve timeout in milliseconds
  498. unsigned long nextid; // Next connection ID
  499. #if MG_ARCH == MG_ARCH_FREERTOS
  500. SocketSet_t ss; // NOTE(lsm): referenced from socket struct
  501. #endif
  502. };
  503. struct mg_connection {
  504. struct mg_connection *next; // Linkage in struct mg_mgr :: connections
  505. struct mg_mgr *mgr; // Our container
  506. struct mg_addr peer; // Remote peer address
  507. void *fd; // Connected socket, or LWIP data
  508. unsigned long id; // Auto-incrementing unique connection ID
  509. struct mg_iobuf recv; // Incoming data
  510. struct mg_iobuf send; // Outgoing data
  511. mg_event_handler_t fn; // User-specified event handler function
  512. void *fn_data; // User-speficied function parameter
  513. mg_event_handler_t pfn; // Protocol-specific handler function
  514. void *pfn_data; // Protocol-specific function parameter
  515. char label[32]; // Arbitrary label
  516. void *tls; // TLS specific data
  517. unsigned is_listening : 1; // Listening connection
  518. unsigned is_client : 1; // Outbound (client) connection
  519. unsigned is_accepted : 1; // Accepted (server) connection
  520. unsigned is_resolving : 1; // Non-blocking DNS resolv is in progress
  521. unsigned is_connecting : 1; // Non-blocking connect is in progress
  522. unsigned is_tls : 1; // TLS-enabled connection
  523. unsigned is_tls_hs : 1; // TLS handshake is in progress
  524. unsigned is_udp : 1; // UDP connection
  525. unsigned is_websocket : 1; // WebSocket connection
  526. unsigned is_hexdumping : 1; // Hexdump in/out traffic
  527. unsigned is_draining : 1; // Send remaining data, then close and free
  528. unsigned is_closing : 1; // Close and free the connection immediately
  529. unsigned is_readable : 1; // Connection is ready to read
  530. unsigned is_writable : 1; // Connection is ready to write
  531. };
  532. void mg_mgr_poll(struct mg_mgr *, int ms);
  533. void mg_mgr_init(struct mg_mgr *);
  534. void mg_mgr_free(struct mg_mgr *);
  535. struct mg_connection *mg_listen(struct mg_mgr *, const char *url,
  536. mg_event_handler_t fn, void *fn_data);
  537. struct mg_connection *mg_connect(struct mg_mgr *, const char *url,
  538. mg_event_handler_t fn, void *fn_data);
  539. int mg_send(struct mg_connection *, const void *, size_t);
  540. int mg_printf(struct mg_connection *, const char *fmt, ...);
  541. int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
  542. char *mg_straddr(struct mg_connection *, char *, size_t);
  543. bool mg_socketpair(int *s1, int *s2);
  544. bool mg_aton(struct mg_str str, struct mg_addr *addr);
  545. char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len);
  546. struct mg_http_header {
  547. struct mg_str name;
  548. struct mg_str value;
  549. };
  550. struct mg_http_message {
  551. // GET /foo/bar/baz?aa=b&cc=ddd HTTP/1.1
  552. // method |-| |----uri---| |--query--| |proto-|
  553. struct mg_str method, uri, query, proto; // Request/response line
  554. struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers
  555. struct mg_str body; // Body
  556. struct mg_str message; // Request line + headers + body
  557. };
  558. // Parameter for mg_http_serve_dir()
  559. struct mg_http_serve_opts {
  560. const char *root_dir; // Web root directory, must be non-NULL
  561. const char *ssi_pattern; // SSI filename pattern, e.g. #.shtml
  562. };
  563. int mg_http_parse(const char *s, size_t len, struct mg_http_message *);
  564. int mg_http_get_request_len(const unsigned char *buf, size_t buf_len);
  565. void mg_http_printf_chunk(struct mg_connection *cnn, const char *fmt, ...);
  566. void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len);
  567. struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
  568. mg_event_handler_t fn, void *fn_data);
  569. struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
  570. mg_event_handler_t fn, void *fn_data);
  571. void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
  572. struct mg_http_serve_opts *);
  573. void mg_http_serve_file(struct mg_connection *, struct mg_http_message *,
  574. const char *, const char *mime, const char *headers);
  575. void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
  576. const char *body_fmt, ...);
  577. struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
  578. void mg_http_event_handler(struct mg_connection *c, int ev);
  579. int mg_http_get_var(const struct mg_str *, const char *name, char *, int);
  580. int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
  581. void mg_http_creds(struct mg_http_message *, char *user, int, char *pass, int);
  582. bool mg_http_match_uri(const struct mg_http_message *, const char *glob);
  583. int mg_http_upload(struct mg_connection *, struct mg_http_message *hm,
  584. const char *dir);
  585. void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
  586. void mg_http_serve_ssi(struct mg_connection *c, const char *root,
  587. const char *fullpath);
  588. struct mg_tls_opts {
  589. const char *ca; // CA certificate file. For both listeners and clients
  590. const char *cert; // Certificate
  591. const char *certkey; // Certificate key
  592. const char *ciphers; // Cipher list
  593. const char *srvname; // If not NULL, enables server name verification
  594. };
  595. int mg_tls_init(struct mg_connection *, struct mg_tls_opts *);
  596. int mg_tls_free(struct mg_connection *);
  597. int mg_tls_send(struct mg_connection *, const void *buf, size_t len, int *fail);
  598. int mg_tls_recv(struct mg_connection *, void *buf, size_t len, int *fail);
  599. int mg_tls_handshake(struct mg_connection *);
  600. #define WEBSOCKET_OP_CONTINUE 0
  601. #define WEBSOCKET_OP_TEXT 1
  602. #define WEBSOCKET_OP_BINARY 2
  603. #define WEBSOCKET_OP_CLOSE 8
  604. #define WEBSOCKET_OP_PING 9
  605. #define WEBSOCKET_OP_PONG 10
  606. #define WEBSOCKET_FLAGS_MASK_FIN 128
  607. #define WEBSOCKET_FLAGS_MASK_OP 15
  608. struct mg_ws_message {
  609. struct mg_str data;
  610. uint8_t flags; // Websocket message flags
  611. };
  612. struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
  613. mg_event_handler_t fn, void *fn_data,
  614. const char *fmt, ...);
  615. void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
  616. const char *fmt, ...);
  617. size_t mg_ws_send(struct mg_connection *, const char *buf, size_t len, int op);
  618. struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
  619. mg_event_handler_t fn, void *fn_data);
  620. void mg_sntp_send(struct mg_connection *c, unsigned long utc);
  621. int mg_sntp_parse(const unsigned char *buf, size_t len, struct timeval *tv);
  622. #define MQTT_CMD_CONNECT 1
  623. #define MQTT_CMD_CONNACK 2
  624. #define MQTT_CMD_PUBLISH 3
  625. #define MQTT_CMD_PUBACK 4
  626. #define MQTT_CMD_PUBREC 5
  627. #define MQTT_CMD_PUBREL 6
  628. #define MQTT_CMD_PUBCOMP 7
  629. #define MQTT_CMD_SUBSCRIBE 8
  630. #define MQTT_CMD_SUBACK 9
  631. #define MQTT_CMD_UNSUBSCRIBE 10
  632. #define MQTT_CMD_UNSUBACK 11
  633. #define MQTT_CMD_PINGREQ 12
  634. #define MQTT_CMD_PINGRESP 13
  635. #define MQTT_CMD_DISCONNECT 14
  636. #define MQTT_QOS(qos) ((qos) << 1)
  637. #define MQTT_GET_QOS(flags) (((flags) &0x6) >> 1)
  638. #define MQTT_SET_QOS(flags, qos) (flags) = ((flags) & ~0x6) | ((qos) << 1)
  639. struct mg_mqtt_opts {
  640. struct mg_str client_id;
  641. struct mg_str will_topic;
  642. struct mg_str will_message;
  643. uint8_t qos; // Quality of service
  644. bool will_retain; // Retain last will
  645. bool clean; // Use clean session, 0 or 1
  646. uint16_t keepalive; // Keep-alive timer in seconds
  647. };
  648. struct mg_mqtt_message {
  649. struct mg_str topic; // Parsed topic
  650. struct mg_str data; // Parsed message
  651. struct mg_str dgram; // Whole MQTT datagram, including headers
  652. uint16_t id; // Set for PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, PUBLISH
  653. uint8_t cmd; // MQTT command, one of MQTT_CMD_*
  654. uint8_t qos; // Quality of service
  655. uint8_t ack; // Connack return code. 0 - success
  656. };
  657. struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url,
  658. struct mg_mqtt_opts *opts,
  659. mg_event_handler_t fn, void *fn_data);
  660. struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
  661. mg_event_handler_t fn, void *fn_data);
  662. void mg_mqtt_pub(struct mg_connection *, struct mg_str *topic,
  663. struct mg_str *data);
  664. void mg_mqtt_sub(struct mg_connection *, struct mg_str *topic);
  665. int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m);
  666. void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags,
  667. uint32_t len);
  668. int mg_mqtt_next_sub(struct mg_mqtt_message *msg, struct mg_str *topic,
  669. uint8_t *qos, int pos);
  670. // Mongoose sends DNS queries that contain only one question:
  671. // either A (IPv4) or AAAA (IPv6) address lookup.
  672. // Therefore, we expect zero or one answer.
  673. // If `resolved` is true, then `addr` contains resolved IPv4 or IPV6 address.
  674. struct mg_dns_message {
  675. uint16_t txnid; // Transaction ID
  676. bool resolved; // Resolve successful, addr is set
  677. struct mg_addr addr; // Resolved address
  678. char name[256]; // Host name
  679. };
  680. struct mg_dns_header {
  681. uint16_t txnid; // Transaction ID
  682. uint16_t flags;
  683. uint16_t num_questions;
  684. uint16_t num_answers;
  685. uint16_t num_authority_prs;
  686. uint16_t num_other_prs;
  687. };
  688. // DNS resource record
  689. struct mg_dns_rr {
  690. uint16_t nlen; // Name or pointer length
  691. uint16_t atype; // Address type
  692. uint16_t aclass; // Address class
  693. uint16_t alen; // Address length
  694. };
  695. void mg_resolve(struct mg_connection *, struct mg_str *, int);
  696. void mg_resolve_cancel(struct mg_connection *);
  697. bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *);
  698. size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
  699. bool is_question, struct mg_dns_rr *);
  700. size_t mg_dns_decode_name(const uint8_t *, size_t, size_t, char *, size_t);