mongoose.h 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456
  1. // Copyright (c) 2004-2013 Sergey Lyubka
  2. // Copyright (c) 2013-2022 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.mongoose.ws/licensing/
  17. //
  18. // SPDX-License-Identifier: GPL-2.0 or commercial
  19. #ifndef MONGOOSE_H
  20. #define MONGOOSE_H
  21. #define MG_VERSION "7.8"
  22. #ifdef __cplusplus
  23. extern "C" {
  24. #endif
  25. #define MG_ARCH_CUSTOM 0
  26. #define MG_ARCH_UNIX 1
  27. #define MG_ARCH_WIN32 2
  28. #define MG_ARCH_ESP32 3
  29. #define MG_ARCH_ESP8266 4
  30. #define MG_ARCH_FREERTOS_TCP 5
  31. #define MG_ARCH_FREERTOS_LWIP 6
  32. #define MG_ARCH_AZURERTOS 7
  33. #define MG_ARCH_RTX_LWIP 8
  34. #define MG_ARCH_ZEPHYR 9
  35. #define MG_ARCH_NEWLIB 10
  36. #define MG_ARCH_RTX 11
  37. #define MG_ARCH_TIRTOS 12
  38. #define MG_ARCH_RP2040 13
  39. #if !defined(MG_ARCH)
  40. #if defined(__unix__) || defined(__APPLE__)
  41. #define MG_ARCH MG_ARCH_UNIX
  42. #elif defined(_WIN32)
  43. #define MG_ARCH MG_ARCH_WIN32
  44. #elif defined(ICACHE_FLASH) || defined(ICACHE_RAM_ATTR)
  45. #define MG_ARCH MG_ARCH_ESP8266
  46. #elif defined(ESP_PLATFORM)
  47. #define MG_ARCH MG_ARCH_ESP32
  48. #elif defined(FREERTOS_IP_H)
  49. #define MG_ARCH MG_ARCH_FREERTOS_TCP
  50. #elif defined(AZURE_RTOS_THREADX)
  51. #define MG_ARCH MG_ARCH_AZURERTOS
  52. #elif defined(__ZEPHYR__)
  53. #define MG_ARCH MG_ARCH_ZEPHYR
  54. #elif defined(PICO_TARGET_NAME)
  55. #define MG_ARCH MG_ARCH_RP2040
  56. #endif
  57. #if !defined(MG_ARCH)
  58. #include "mongoose_custom.h" // keep this include
  59. #endif
  60. #if !defined(MG_ARCH)
  61. #error "MG_ARCH is not specified and we couldn't guess it. Set -D MG_ARCH=..."
  62. #endif
  63. #endif // !defined(MG_ARCH)
  64. #if MG_ARCH == MG_ARCH_AZURERTOS
  65. #include <stdarg.h>
  66. #include <stdbool.h>
  67. #include <stdint.h>
  68. #include <stdio.h>
  69. #include <time.h>
  70. #include <fx_api.h>
  71. #include <tx_api.h>
  72. #include <nx_api.h>
  73. #include <nx_bsd.h>
  74. #include <nx_port.h>
  75. #include <tx_port.h>
  76. #ifdef __REDLIB__
  77. #define va_copy(d, s) __builtin_va_copy(d, s)
  78. #endif
  79. #define PATH_MAX FX_MAXIMUM_PATH
  80. #define MG_DIRSEP '\\'
  81. #define socklen_t int
  82. #define closesocket(x) soc_close(x)
  83. #undef FOPEN_MAX
  84. #endif
  85. #if MG_ARCH == MG_ARCH_ESP32
  86. #include <ctype.h>
  87. #include <dirent.h>
  88. #include <errno.h>
  89. #include <fcntl.h>
  90. #include <limits.h>
  91. #include <netdb.h>
  92. #include <stdarg.h>
  93. #include <stddef.h>
  94. #include <stdio.h>
  95. #include <stdlib.h>
  96. #include <string.h>
  97. #include <sys/stat.h>
  98. #include <sys/types.h>
  99. #include <time.h>
  100. #include <esp_timer.h>
  101. #define MG_PATH_MAX 128
  102. #endif
  103. #if MG_ARCH == MG_ARCH_ESP8266
  104. #include <ctype.h>
  105. #include <dirent.h>
  106. #include <errno.h>
  107. #include <fcntl.h>
  108. #include <limits.h>
  109. #include <netdb.h>
  110. #include <stdarg.h>
  111. #include <stdbool.h>
  112. #include <stddef.h>
  113. #include <stdio.h>
  114. #include <stdlib.h>
  115. #include <string.h>
  116. #include <sys/stat.h>
  117. #include <sys/time.h>
  118. #include <sys/types.h>
  119. #include <time.h>
  120. #include <esp_system.h>
  121. #define MG_PATH_MAX 128
  122. #endif
  123. #if MG_ARCH == MG_ARCH_FREERTOS_LWIP
  124. #include <ctype.h>
  125. #include <stdarg.h>
  126. #include <stdbool.h>
  127. #include <stddef.h>
  128. #include <stdint.h>
  129. #include <stdio.h>
  130. #include <string.h>
  131. #if defined(__GNUC__)
  132. #include <sys/stat.h>
  133. #include <sys/time.h>
  134. #else
  135. struct timeval {
  136. time_t tv_sec;
  137. long tv_usec;
  138. };
  139. #endif
  140. #include <FreeRTOS.h>
  141. #include <task.h>
  142. #include <lwip/sockets.h>
  143. #if LWIP_SOCKET != 1
  144. // Sockets support disabled in LWIP by default
  145. #error Set LWIP_SOCKET variable to 1 (in lwipopts.h)
  146. #endif
  147. // Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
  148. static inline void *mg_calloc(int cnt, size_t size) {
  149. void *p = pvPortMalloc(cnt * size);
  150. if (p != NULL) memset(p, 0, size * cnt);
  151. return p;
  152. }
  153. #define calloc(a, b) mg_calloc((a), (b))
  154. #define free(a) vPortFree(a)
  155. #define malloc(a) pvPortMalloc(a)
  156. #define strdup(s) ((char *) mg_strdup(mg_str(s)).ptr)
  157. #define mkdir(a, b) (-1)
  158. #ifndef MG_IO_SIZE
  159. #define MG_IO_SIZE 512
  160. #endif
  161. #endif // MG_ARCH == MG_ARCH_FREERTOS_LWIP
  162. #if MG_ARCH == MG_ARCH_FREERTOS_TCP
  163. #include <ctype.h>
  164. #include <errno.h>
  165. #include <limits.h>
  166. #include <stdarg.h>
  167. #include <stdbool.h>
  168. #include <stddef.h>
  169. #include <stdio.h>
  170. #include <stdlib.h>
  171. #include <string.h>
  172. #include <sys/stat.h>
  173. #include <time.h>
  174. #include <FreeRTOS.h>
  175. #include <list.h>
  176. #include <task.h>
  177. #include <FreeRTOS_IP.h>
  178. #include <FreeRTOS_Sockets.h>
  179. // Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing
  180. // with FreeRTOS_ prefix, is beyond me
  181. #define IPPROTO_TCP FREERTOS_IPPROTO_TCP
  182. #define IPPROTO_UDP FREERTOS_IPPROTO_UDP
  183. #define AF_INET FREERTOS_AF_INET
  184. #define SOCK_STREAM FREERTOS_SOCK_STREAM
  185. #define SOCK_DGRAM FREERTOS_SOCK_DGRAM
  186. #define SO_BROADCAST 0
  187. #define SO_ERROR 0
  188. #define SOL_SOCKET 0
  189. #define SO_REUSEADDR 0
  190. #define sockaddr_in freertos_sockaddr
  191. #define sockaddr freertos_sockaddr
  192. #define accept(a, b, c) FreeRTOS_accept((a), (b), (c))
  193. #define connect(a, b, c) FreeRTOS_connect((a), (b), (c))
  194. #define bind(a, b, c) FreeRTOS_bind((a), (b), (c))
  195. #define listen(a, b) FreeRTOS_listen((a), (b))
  196. #define socket(a, b, c) FreeRTOS_socket((a), (b), (c))
  197. #define send(a, b, c, d) FreeRTOS_send((a), (b), (c), (d))
  198. #define recv(a, b, c, d) FreeRTOS_recv((a), (b), (c), (d))
  199. #define setsockopt(a, b, c, d, e) FreeRTOS_setsockopt((a), (b), (c), (d), (e))
  200. #define sendto(a, b, c, d, e, f) FreeRTOS_sendto((a), (b), (c), (d), (e), (f))
  201. #define recvfrom(a, b, c, d, e, f) \
  202. FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f))
  203. #define closesocket(x) FreeRTOS_closesocket(x)
  204. #define gethostbyname(x) FreeRTOS_gethostbyname(x)
  205. #define getsockname(a, b, c) (-1)
  206. #define getpeername(a, b, c) 0
  207. // Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
  208. static inline void *mg_calloc(int cnt, size_t size) {
  209. void *p = pvPortMalloc(cnt * size);
  210. if (p != NULL) memset(p, 0, size * cnt);
  211. return p;
  212. }
  213. #define calloc(a, b) mg_calloc((a), (b))
  214. #define free(a) vPortFree(a)
  215. #define malloc(a) pvPortMalloc(a)
  216. #define mkdir(a, b) (-1)
  217. #if !defined(__GNUC__)
  218. // copied from GCC on ARM; for some reason useconds are signed
  219. struct timeval {
  220. time_t tv_sec;
  221. long tv_usec;
  222. };
  223. #endif
  224. #ifndef EINPROGRESS
  225. #define EINPROGRESS pdFREERTOS_ERRNO_EINPROGRESS
  226. #endif
  227. #ifndef EWOULDBLOCK
  228. #define EWOULDBLOCK pdFREERTOS_ERRNO_EWOULDBLOCK
  229. #endif
  230. #ifndef EAGAIN
  231. #define EAGAIN pdFREERTOS_ERRNO_EAGAIN
  232. #endif
  233. #ifndef EINTR
  234. #define EINTR pdFREERTOS_ERRNO_EINTR
  235. #endif
  236. #endif // MG_ARCH == MG_ARCH_FREERTOS_TCP
  237. #if MG_ARCH == MG_ARCH_NEWLIB
  238. #define _POSIX_TIMERS
  239. #include <ctype.h>
  240. #include <errno.h>
  241. #include <stdarg.h>
  242. #include <stdbool.h>
  243. #include <stdio.h>
  244. #include <stdlib.h>
  245. #include <string.h>
  246. #include <sys/stat.h>
  247. #include <sys/time.h>
  248. #include <sys/types.h>
  249. #include <time.h>
  250. #include <unistd.h>
  251. #define MG_PATH_MAX 100
  252. #define MG_ENABLE_SOCKET 0
  253. #define MG_ENABLE_DIRLIST 0
  254. #endif
  255. #if MG_ARCH == MG_ARCH_RP2040
  256. #include <errno.h>
  257. #include <stdarg.h>
  258. #include <stdbool.h>
  259. #include <stdint.h>
  260. #include <stdio.h>
  261. #include <stdlib.h>
  262. #include <string.h>
  263. #include <time.h>
  264. #include <pico/stdlib.h>
  265. int mkdir(const char *, mode_t);
  266. #endif
  267. #if MG_ARCH == MG_ARCH_RTX
  268. #include <ctype.h>
  269. #include <errno.h>
  270. #include <stdarg.h>
  271. #include <stdbool.h>
  272. #include <stddef.h>
  273. #include <stdint.h>
  274. #include <stdio.h>
  275. #include <stdlib.h>
  276. #include <string.h>
  277. #include <time.h>
  278. #include <rl_net.h>
  279. #define MG_ENABLE_CUSTOM_MILLIS 1
  280. typedef int socklen_t;
  281. #define closesocket(x) closesocket(x)
  282. #define mkdir(a, b) (-1)
  283. #define EWOULDBLOCK BSD_EWOULDBLOCK
  284. #define EAGAIN BSD_EWOULDBLOCK
  285. #define EINPROGRESS BSD_EWOULDBLOCK
  286. #define EINTR BSD_EWOULDBLOCK
  287. #define ECONNRESET BSD_ECONNRESET
  288. #define EPIPE BSD_ECONNRESET
  289. #define TCP_NODELAY SO_KEEPALIVE
  290. #endif
  291. #if MG_ARCH == MG_ARCH_RTX_LWIP
  292. #include <ctype.h>
  293. #include <stdarg.h>
  294. #include <stdbool.h>
  295. #include <stdint.h>
  296. #include <stdio.h>
  297. #include <string.h>
  298. #if defined(__GNUC__)
  299. #include <sys/stat.h>
  300. #include <sys/time.h>
  301. #else
  302. struct timeval {
  303. time_t tv_sec;
  304. long tv_usec;
  305. };
  306. #endif
  307. #include <lwip/sockets.h>
  308. #if LWIP_SOCKET != 1
  309. // Sockets support disabled in LWIP by default
  310. #error Set LWIP_SOCKET variable to 1 (in lwipopts.h)
  311. #endif
  312. #define mkdir(a, b) (-1)
  313. #ifndef MG_IO_SIZE
  314. #define MG_IO_SIZE 512
  315. #endif
  316. #ifndef MG_PATH_MAX
  317. #define MG_PATH_MAX 128
  318. #endif
  319. #endif
  320. #if MG_ARCH == MG_ARCH_TIRTOS
  321. #include <stdlib.h>
  322. #include <ctype.h>
  323. #include <stdarg.h>
  324. #include <stdbool.h>
  325. #include <stdint.h>
  326. #include <stdio.h>
  327. #include <string.h>
  328. #include <time.h>
  329. #include <time.h>
  330. #include <errno.h>
  331. #include <sys/socket.h>
  332. extern int SockStatus(SOCKET hSock, int request, int *results );
  333. extern int SockSet(SOCKET hSock, int Type, int Prop, void *pbuf, int size);
  334. #endif
  335. #if MG_ARCH == MG_ARCH_UNIX
  336. #define _DARWIN_UNLIMITED_SELECT 1 // No limit on file descriptors
  337. #if defined(__APPLE__)
  338. #include <mach/mach_time.h>
  339. #endif
  340. #if !defined(MG_ENABLE_EPOLL) && defined(__linux__)
  341. #define MG_ENABLE_EPOLL 1
  342. #elif !defined(MG_ENABLE_POLL)
  343. #define MG_ENABLE_POLL 1
  344. #endif
  345. #include <arpa/inet.h>
  346. #include <ctype.h>
  347. #include <dirent.h>
  348. #include <errno.h>
  349. #include <fcntl.h>
  350. #include <inttypes.h>
  351. #include <limits.h>
  352. #include <netdb.h>
  353. #include <netinet/in.h>
  354. #include <netinet/tcp.h>
  355. #include <signal.h>
  356. #include <stdarg.h>
  357. #include <stdbool.h>
  358. #include <stddef.h>
  359. #include <stdint.h>
  360. #include <stdio.h>
  361. #include <stdlib.h>
  362. #include <string.h>
  363. #if defined(MG_ENABLE_EPOLL) && MG_ENABLE_EPOLL
  364. #include <sys/epoll.h>
  365. #elif defined(MG_ENABLE_POLL) && MG_ENABLE_POLL
  366. #include <poll.h>
  367. #else
  368. #include <sys/select.h>
  369. #endif
  370. #include <sys/socket.h>
  371. #include <sys/stat.h>
  372. #include <sys/time.h>
  373. #include <sys/types.h>
  374. #include <time.h>
  375. #include <unistd.h>
  376. #ifndef MG_ENABLE_DIRLIST
  377. #define MG_ENABLE_DIRLIST 1
  378. #endif
  379. #ifndef MG_PATH_MAX
  380. #define MG_PATH_MAX FILENAME_MAX
  381. #endif
  382. #endif
  383. #if MG_ARCH == MG_ARCH_WIN32
  384. #ifndef WIN32_LEAN_AND_MEAN
  385. #define WIN32_LEAN_AND_MEAN
  386. #endif
  387. #ifndef _CRT_SECURE_NO_WARNINGS
  388. #define _CRT_SECURE_NO_WARNINGS
  389. #endif
  390. #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
  391. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  392. #endif
  393. #include <ctype.h>
  394. #include <direct.h>
  395. #include <errno.h>
  396. #include <fcntl.h>
  397. #include <limits.h>
  398. #include <signal.h>
  399. #include <stdarg.h>
  400. #include <stddef.h>
  401. #include <stdio.h>
  402. #include <stdlib.h>
  403. #include <string.h>
  404. #include <sys/stat.h>
  405. #include <sys/types.h>
  406. #include <time.h>
  407. #if defined(_MSC_VER) && _MSC_VER < 1700
  408. #define __func__ ""
  409. typedef __int64 int64_t;
  410. typedef unsigned __int64 uint64_t;
  411. typedef unsigned char uint8_t;
  412. typedef char int8_t;
  413. typedef unsigned short uint16_t;
  414. typedef short int16_t;
  415. typedef unsigned int uint32_t;
  416. typedef int int32_t;
  417. typedef enum { false = 0, true = 1 } bool;
  418. #else
  419. #include <stdbool.h>
  420. #include <stdint.h>
  421. #include <ws2tcpip.h>
  422. #endif
  423. #include <process.h>
  424. #include <winerror.h>
  425. #include <winsock2.h>
  426. // Protect from calls like std::snprintf in app code
  427. // See https://github.com/cesanta/mongoose/issues/1047
  428. #ifndef __cplusplus
  429. #define snprintf _snprintf
  430. #define vsnprintf _vsnprintf
  431. #ifndef strdup // For MSVC with _DEBUG, see #1359
  432. #define strdup(x) _strdup(x)
  433. #endif
  434. #endif
  435. typedef int socklen_t;
  436. #define MG_DIRSEP '\\'
  437. #ifndef MG_PATH_MAX
  438. #define MG_PATH_MAX FILENAME_MAX
  439. #endif
  440. #ifndef EINPROGRESS
  441. #define EINPROGRESS WSAEINPROGRESS
  442. #endif
  443. #ifndef EWOULDBLOCK
  444. #define EWOULDBLOCK WSAEWOULDBLOCK
  445. #endif
  446. #define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
  447. #define sleep(x) Sleep(x)
  448. #define mkdir(a, b) _mkdir(a)
  449. #ifndef va_copy
  450. #ifdef __va_copy
  451. #define va_copy __va_copy
  452. #else
  453. #define va_copy(x, y) (x) = (y)
  454. #endif
  455. #endif
  456. #ifndef S_ISDIR
  457. #define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
  458. #endif
  459. #ifndef MG_ENABLE_DIRLIST
  460. #define MG_ENABLE_DIRLIST 1
  461. #endif
  462. #endif
  463. #if MG_ARCH == MG_ARCH_ZEPHYR
  464. #include <zephyr.h>
  465. #include <ctype.h>
  466. #include <errno.h>
  467. #include <fcntl.h>
  468. #include <net/socket.h>
  469. #include <stdarg.h>
  470. #include <stdbool.h>
  471. #include <stdint.h>
  472. #include <stdio.h>
  473. #include <stdlib.h>
  474. #include <string.h>
  475. #include <sys/types.h>
  476. #include <time.h>
  477. #define MG_PUTCHAR(x) printk("%c", x)
  478. #define strerror(x) zsock_gai_strerror(x)
  479. #define FD_CLOEXEC 0
  480. #define F_SETFD 0
  481. #define MG_ENABLE_SSI 0
  482. int rand(void);
  483. int sscanf(const char *, const char *, ...);
  484. #endif
  485. #ifndef MG_ENABLE_LOG
  486. #define MG_ENABLE_LOG 1
  487. #endif
  488. #ifndef MG_ENABLE_MIP
  489. #define MG_ENABLE_MIP 0
  490. #endif
  491. #ifndef MG_ENABLE_POLL
  492. #define MG_ENABLE_POLL 0
  493. #endif
  494. #ifndef MG_ENABLE_EPOLL
  495. #define MG_ENABLE_EPOLL 0
  496. #endif
  497. #ifndef MG_ENABLE_FATFS
  498. #define MG_ENABLE_FATFS 0
  499. #endif
  500. #ifndef MG_ENABLE_SOCKET
  501. #define MG_ENABLE_SOCKET 1
  502. #endif
  503. #ifndef MG_ENABLE_MBEDTLS
  504. #define MG_ENABLE_MBEDTLS 0
  505. #endif
  506. #ifndef MG_ENABLE_OPENSSL
  507. #define MG_ENABLE_OPENSSL 0
  508. #endif
  509. #ifndef MG_ENABLE_CUSTOM_TLS
  510. #define MG_ENABLE_CUSTOM_TLS 0
  511. #endif
  512. #ifndef MG_ENABLE_SSI
  513. #define MG_ENABLE_SSI 0
  514. #endif
  515. #ifndef MG_ENABLE_IPV6
  516. #define MG_ENABLE_IPV6 0
  517. #endif
  518. #ifndef MG_ENABLE_MD5
  519. #define MG_ENABLE_MD5 0
  520. #endif
  521. // Set MG_ENABLE_WINSOCK=0 for Win32 builds with external IP stack (like LWIP)
  522. #ifndef MG_ENABLE_WINSOCK
  523. #define MG_ENABLE_WINSOCK 1
  524. #endif
  525. #ifndef MG_ENABLE_DIRLIST
  526. #define MG_ENABLE_DIRLIST 0
  527. #endif
  528. #ifndef MG_ENABLE_CUSTOM_RANDOM
  529. #define MG_ENABLE_CUSTOM_RANDOM 0
  530. #endif
  531. #ifndef MG_ENABLE_CUSTOM_MILLIS
  532. #define MG_ENABLE_CUSTOM_MILLIS 0
  533. #endif
  534. #ifndef MG_ENABLE_PACKED_FS
  535. #define MG_ENABLE_PACKED_FS 0
  536. #endif
  537. // Granularity of the send/recv IO buffer growth
  538. #ifndef MG_IO_SIZE
  539. #define MG_IO_SIZE 2048
  540. #endif
  541. // Maximum size of the recv IO buffer
  542. #ifndef MG_MAX_RECV_SIZE
  543. #define MG_MAX_RECV_SIZE (3 * 1024 * 1024)
  544. #endif
  545. #ifndef MG_MAX_HTTP_HEADERS
  546. #define MG_MAX_HTTP_HEADERS 30
  547. #endif
  548. #ifndef MG_HTTP_INDEX
  549. #define MG_HTTP_INDEX "index.html"
  550. #endif
  551. #ifndef MG_PATH_MAX
  552. #ifdef PATH_MAX
  553. #define MG_PATH_MAX PATH_MAX
  554. #else
  555. #define MG_PATH_MAX 128
  556. #endif
  557. #endif
  558. #ifndef MG_SOCK_LISTEN_BACKLOG_SIZE
  559. #define MG_SOCK_LISTEN_BACKLOG_SIZE 3
  560. #endif
  561. #ifndef MG_DIRSEP
  562. #define MG_DIRSEP '/'
  563. #endif
  564. #ifndef MG_ENABLE_FILE
  565. #if defined(FOPEN_MAX)
  566. #define MG_ENABLE_FILE 1
  567. #else
  568. #define MG_ENABLE_FILE 0
  569. #endif
  570. #endif
  571. #if MG_ENABLE_EPOLL
  572. #define MG_EPOLL_ADD(c) \
  573. do { \
  574. struct epoll_event ev = {EPOLLIN | EPOLLERR | EPOLLHUP, {c}}; \
  575. epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_ADD, (int) (size_t) c->fd, &ev); \
  576. } while (0)
  577. #define MG_EPOLL_MOD(c, wr) \
  578. do { \
  579. struct epoll_event ev = {EPOLLIN | EPOLLERR | EPOLLHUP, {c}}; \
  580. if (wr) ev.events |= EPOLLOUT; \
  581. epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_MOD, (int) (size_t) c->fd, &ev); \
  582. } while (0)
  583. #else
  584. #define MG_EPOLL_ADD(c)
  585. #define MG_EPOLL_MOD(c, wr)
  586. #endif
  587. struct mg_str {
  588. const char *ptr; // Pointer to string data
  589. size_t len; // String len
  590. };
  591. #define MG_NULL_STR \
  592. { NULL, 0 }
  593. #define MG_C_STR(a) \
  594. { (a), sizeof(a) - 1 }
  595. // Using macro to avoid shadowing C++ struct constructor, see #1298
  596. #define mg_str(s) mg_str_s(s)
  597. struct mg_str mg_str(const char *s);
  598. struct mg_str mg_str_n(const char *s, size_t n);
  599. int mg_lower(const char *s);
  600. int mg_ncasecmp(const char *s1, const char *s2, size_t len);
  601. int mg_casecmp(const char *s1, const char *s2);
  602. int mg_vcmp(const struct mg_str *s1, const char *s2);
  603. int mg_vcasecmp(const struct mg_str *str1, const char *str2);
  604. int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
  605. struct mg_str mg_strstrip(struct mg_str s);
  606. struct mg_str mg_strdup(const struct mg_str s);
  607. const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle);
  608. bool mg_match(struct mg_str str, struct mg_str pattern, struct mg_str *caps);
  609. bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
  610. bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v);
  611. bool mg_split(struct mg_str *s, struct mg_str *k, struct mg_str *v, char delim);
  612. char *mg_hex(const void *buf, size_t len, char *dst);
  613. void mg_unhex(const char *buf, size_t len, unsigned char *to);
  614. unsigned long mg_unhexn(const char *s, size_t len);
  615. int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip);
  616. int64_t mg_to64(struct mg_str str);
  617. uint64_t mg_tou64(struct mg_str str);
  618. char *mg_remove_double_dots(char *s);
  619. typedef void (*mg_pfn_t)(char, void *); // Custom putchar
  620. typedef size_t (*mg_pm_t)(mg_pfn_t, void *, va_list *); // %M printer
  621. void mg_pfn_iobuf(char ch, void *param); // iobuf printer
  622. size_t mg_vxprintf(void (*)(char, void *), void *, const char *fmt, va_list *);
  623. size_t mg_xprintf(void (*fn)(char, void *), void *, const char *fmt, ...);
  624. size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap);
  625. size_t mg_snprintf(char *, size_t, const char *fmt, ...);
  626. char *mg_vmprintf(const char *fmt, va_list *ap);
  627. char *mg_mprintf(const char *fmt, ...);
  628. enum { MG_LL_NONE, MG_LL_ERROR, MG_LL_INFO, MG_LL_DEBUG, MG_LL_VERBOSE };
  629. void mg_log(const char *fmt, ...);
  630. bool mg_log_prefix(int ll, const char *file, int line, const char *fname);
  631. void mg_log_set(int log_level);
  632. void mg_hexdump(const void *buf, size_t len);
  633. void mg_log_set_fn(mg_pfn_t fn, void *param);
  634. #if MG_ENABLE_LOG
  635. #define MG_LOG(level, args) \
  636. do { \
  637. if (mg_log_prefix((level), __FILE__, __LINE__, __func__)) mg_log args; \
  638. } while (0)
  639. #else
  640. #define MG_LOG(level, args) \
  641. do { \
  642. if (0) mg_log args; \
  643. } while (0)
  644. #endif
  645. #define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  646. #define MG_INFO(args) MG_LOG(MG_LL_INFO, args)
  647. #define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  648. #define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
  649. struct mg_timer {
  650. unsigned long id; // Timer ID
  651. uint64_t period_ms; // Timer period in milliseconds
  652. uint64_t prev_ms; // Timestamp of a previous poll
  653. uint64_t expire; // Expiration timestamp in milliseconds
  654. unsigned flags; // Possible flags values below
  655. #define MG_TIMER_ONCE 0 // Call function once
  656. #define MG_TIMER_REPEAT 1 // Call function periodically
  657. #define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
  658. void (*fn)(void *); // Function to call
  659. void *arg; // Function argument
  660. struct mg_timer *next; // Linkage
  661. };
  662. void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
  663. uint64_t milliseconds, unsigned flags, void (*fn)(void *),
  664. void *arg);
  665. void mg_timer_free(struct mg_timer **head, struct mg_timer *);
  666. void mg_timer_poll(struct mg_timer **head, uint64_t new_ms);
  667. enum { MG_FS_READ = 1, MG_FS_WRITE = 2, MG_FS_DIR = 4 };
  668. // Filesystem API functions
  669. // st() returns MG_FS_* flags and populates file size and modification time
  670. // ls() calls fn() for every directory entry, allowing to list a directory
  671. //
  672. // NOTE: UNIX-style shorthand names for the API functions are deliberately
  673. // chosen to avoid conflicts with some libraries that make macros for e.g.
  674. // stat(), write(), read() calls.
  675. struct mg_fs {
  676. int (*st)(const char *path, size_t *size, time_t *mtime); // stat file
  677. void (*ls)(const char *path, void (*fn)(const char *, void *), void *);
  678. void *(*op)(const char *path, int flags); // Open file
  679. void (*cl)(void *fd); // Close file
  680. size_t (*rd)(void *fd, void *buf, size_t len); // Read file
  681. size_t (*wr)(void *fd, const void *buf, size_t len); // Write file
  682. size_t (*sk)(void *fd, size_t offset); // Set file position
  683. bool (*mv)(const char *from, const char *to); // Rename file
  684. bool (*rm)(const char *path); // Delete file
  685. bool (*mkd)(const char *path); // Create directory
  686. };
  687. extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
  688. extern struct mg_fs mg_fs_packed; // Packed FS, see examples/device-dashboard
  689. extern struct mg_fs mg_fs_fat; // FAT FS
  690. // File descriptor
  691. struct mg_fd {
  692. void *fd;
  693. struct mg_fs *fs;
  694. };
  695. struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags);
  696. void mg_fs_close(struct mg_fd *fd);
  697. char *mg_file_read(struct mg_fs *fs, const char *path, size_t *size);
  698. bool mg_file_write(struct mg_fs *fs, const char *path, const void *, size_t);
  699. bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...);
  700. void mg_random(void *buf, size_t len);
  701. char *mg_random_str(char *buf, size_t len);
  702. uint16_t mg_ntohs(uint16_t net);
  703. uint32_t mg_ntohl(uint32_t net);
  704. uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
  705. uint64_t mg_millis(void);
  706. #define mg_htons(x) mg_ntohs(x)
  707. #define mg_htonl(x) mg_ntohl(x)
  708. // Linked list management macros
  709. #define LIST_ADD_HEAD(type_, head_, elem_) \
  710. do { \
  711. (elem_)->next = (*head_); \
  712. *(head_) = (elem_); \
  713. } while (0)
  714. #define LIST_ADD_TAIL(type_, head_, elem_) \
  715. do { \
  716. type_ **h = head_; \
  717. while (*h != NULL) h = &(*h)->next; \
  718. *h = (elem_); \
  719. } while (0)
  720. #define LIST_DELETE(type_, head_, elem_) \
  721. do { \
  722. type_ **h = head_; \
  723. while (*h != (elem_)) h = &(*h)->next; \
  724. *h = (elem_)->next; \
  725. } while (0)
  726. unsigned short mg_url_port(const char *url);
  727. int mg_url_is_ssl(const char *url);
  728. struct mg_str mg_url_host(const char *url);
  729. struct mg_str mg_url_user(const char *url);
  730. struct mg_str mg_url_pass(const char *url);
  731. const char *mg_url_uri(const char *url);
  732. struct mg_iobuf {
  733. unsigned char *buf; // Pointer to stored data
  734. size_t size; // Total size available
  735. size_t len; // Current number of bytes
  736. size_t align; // Alignment during allocation
  737. };
  738. int mg_iobuf_init(struct mg_iobuf *, size_t, size_t);
  739. int mg_iobuf_resize(struct mg_iobuf *, size_t);
  740. void mg_iobuf_free(struct mg_iobuf *);
  741. size_t mg_iobuf_add(struct mg_iobuf *, size_t, const void *, size_t);
  742. size_t mg_iobuf_del(struct mg_iobuf *, size_t ofs, size_t len);
  743. int mg_base64_update(unsigned char p, char *to, int len);
  744. int mg_base64_final(char *to, int len);
  745. int mg_base64_encode(const unsigned char *p, int n, char *to);
  746. int mg_base64_decode(const char *src, int n, char *dst);
  747. typedef struct {
  748. uint32_t buf[4];
  749. uint32_t bits[2];
  750. unsigned char in[64];
  751. } mg_md5_ctx;
  752. void mg_md5_init(mg_md5_ctx *c);
  753. void mg_md5_update(mg_md5_ctx *c, const unsigned char *data, size_t len);
  754. void mg_md5_final(mg_md5_ctx *c, unsigned char[16]);
  755. typedef struct {
  756. uint32_t state[5];
  757. uint32_t count[2];
  758. unsigned char buffer[64];
  759. } mg_sha1_ctx;
  760. void mg_sha1_init(mg_sha1_ctx *);
  761. void mg_sha1_update(mg_sha1_ctx *, const unsigned char *data, size_t len);
  762. void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *);
  763. struct mg_connection;
  764. typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
  765. void *ev_data, void *fn_data);
  766. void mg_call(struct mg_connection *c, int ev, void *ev_data);
  767. void mg_error(struct mg_connection *c, const char *fmt, ...);
  768. enum {
  769. MG_EV_ERROR, // Error char *error_message
  770. MG_EV_OPEN, // Connection created NULL
  771. MG_EV_POLL, // mg_mgr_poll iteration uint64_t *milliseconds
  772. MG_EV_RESOLVE, // Host name is resolved NULL
  773. MG_EV_CONNECT, // Connection established NULL
  774. MG_EV_ACCEPT, // Connection accepted NULL
  775. MG_EV_READ, // Data received from socket struct mg_str *
  776. MG_EV_WRITE, // Data written to socket long *bytes_written
  777. MG_EV_CLOSE, // Connection closed NULL
  778. MG_EV_HTTP_MSG, // HTTP request/response struct mg_http_message *
  779. MG_EV_HTTP_CHUNK, // HTTP chunk (partial msg) struct mg_http_message *
  780. MG_EV_WS_OPEN, // Websocket handshake done struct mg_http_message *
  781. MG_EV_WS_MSG, // Websocket msg, text or bin struct mg_ws_message *
  782. MG_EV_WS_CTL, // Websocket control msg struct mg_ws_message *
  783. MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message *
  784. MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message *
  785. MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code
  786. MG_EV_SNTP_TIME, // SNTP time received uint64_t *milliseconds
  787. MG_EV_USER, // Starting ID for user events
  788. };
  789. struct mg_dns {
  790. const char *url; // DNS server URL
  791. struct mg_connection *c; // DNS server connection
  792. };
  793. struct mg_addr {
  794. uint16_t port; // TCP or UDP port in network byte order
  795. uint32_t ip; // IP address in network byte order
  796. uint8_t ip6[16]; // IPv6 address
  797. bool is_ip6; // True when address is IPv6 address
  798. };
  799. struct mg_mgr {
  800. struct mg_connection *conns; // List of active connections
  801. struct mg_dns dns4; // DNS for IPv4
  802. struct mg_dns dns6; // DNS for IPv6
  803. int dnstimeout; // DNS resolve timeout in milliseconds
  804. bool use_dns6; // Use DNS6 server by default, see #1532
  805. unsigned long nextid; // Next connection ID
  806. unsigned long timerid; // Next timer ID
  807. void *userdata; // Arbitrary user data pointer
  808. uint16_t mqtt_id; // MQTT IDs for pub/sub
  809. void *active_dns_requests; // DNS requests in progress
  810. struct mg_timer *timers; // Active timers
  811. int epoll_fd; // Used when MG_EPOLL_ENABLE=1
  812. void *priv; // Used by the MIP stack
  813. size_t extraconnsize; // Used by the MIP stack
  814. #if MG_ARCH == MG_ARCH_FREERTOS_TCP
  815. SocketSet_t ss; // NOTE(lsm): referenced from socket struct
  816. #endif
  817. };
  818. struct mg_connection {
  819. struct mg_connection *next; // Linkage in struct mg_mgr :: connections
  820. struct mg_mgr *mgr; // Our container
  821. struct mg_addr loc; // Local address
  822. struct mg_addr rem; // Remote address
  823. void *fd; // Connected socket, or LWIP data
  824. unsigned long id; // Auto-incrementing unique connection ID
  825. struct mg_iobuf recv; // Incoming data
  826. struct mg_iobuf send; // Outgoing data
  827. mg_event_handler_t fn; // User-specified event handler function
  828. void *fn_data; // User-specified function parameter
  829. mg_event_handler_t pfn; // Protocol-specific handler function
  830. void *pfn_data; // Protocol-specific function parameter
  831. char label[50]; // Arbitrary label
  832. void *tls; // TLS specific data
  833. unsigned is_listening : 1; // Listening connection
  834. unsigned is_client : 1; // Outbound (client) connection
  835. unsigned is_accepted : 1; // Accepted (server) connection
  836. unsigned is_resolving : 1; // Non-blocking DNS resolution is in progress
  837. unsigned is_connecting : 1; // Non-blocking connect is in progress
  838. unsigned is_tls : 1; // TLS-enabled connection
  839. unsigned is_tls_hs : 1; // TLS handshake is in progress
  840. unsigned is_udp : 1; // UDP connection
  841. unsigned is_websocket : 1; // WebSocket connection
  842. unsigned is_mqtt5 : 1; // For MQTT connection, v5 indicator
  843. unsigned is_hexdumping : 1; // Hexdump in/out traffic
  844. unsigned is_draining : 1; // Send remaining data, then close and free
  845. unsigned is_closing : 1; // Close and free the connection immediately
  846. unsigned is_full : 1; // Stop reads, until cleared
  847. unsigned is_resp : 1; // Response is still being generated
  848. unsigned is_readable : 1; // Connection is ready to read
  849. unsigned is_writable : 1; // Connection is ready to write
  850. };
  851. void mg_mgr_poll(struct mg_mgr *, int ms);
  852. void mg_mgr_init(struct mg_mgr *);
  853. void mg_mgr_free(struct mg_mgr *);
  854. struct mg_connection *mg_listen(struct mg_mgr *, const char *url,
  855. mg_event_handler_t fn, void *fn_data);
  856. struct mg_connection *mg_connect(struct mg_mgr *, const char *url,
  857. mg_event_handler_t fn, void *fn_data);
  858. struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd,
  859. mg_event_handler_t fn, void *fn_data);
  860. void mg_connect_resolved(struct mg_connection *);
  861. bool mg_send(struct mg_connection *, const void *, size_t);
  862. size_t mg_printf(struct mg_connection *, const char *fmt, ...);
  863. size_t mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
  864. char *mg_straddr(struct mg_addr *, char *, size_t);
  865. bool mg_aton(struct mg_str str, struct mg_addr *addr);
  866. char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len);
  867. int mg_mkpipe(struct mg_mgr *, mg_event_handler_t, void *, bool udp);
  868. // These functions are used to integrate with custom network stacks
  869. struct mg_connection *mg_alloc_conn(struct mg_mgr *);
  870. void mg_close_conn(struct mg_connection *c);
  871. bool mg_open_listener(struct mg_connection *c, const char *url);
  872. struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
  873. unsigned flags, void (*fn)(void *), void *arg);
  874. struct mg_http_header {
  875. struct mg_str name; // Header name
  876. struct mg_str value; // Header value
  877. };
  878. struct mg_http_message {
  879. struct mg_str method, uri, query, proto; // Request/response line
  880. struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers
  881. struct mg_str body; // Body
  882. struct mg_str head; // Request + headers
  883. struct mg_str chunk; // Chunk for chunked encoding, or partial body
  884. struct mg_str message; // Request + headers + body
  885. };
  886. // Parameter for mg_http_serve_dir()
  887. struct mg_http_serve_opts {
  888. const char *root_dir; // Web root directory, must be non-NULL
  889. const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml
  890. const char *extra_headers; // Extra HTTP headers to add in responses
  891. const char *mime_types; // Extra mime types, ext1=type1,ext2=type2,..
  892. const char *page404; // Path to the 404 page, or NULL by default
  893. struct mg_fs *fs; // Filesystem implementation. Use NULL for POSIX
  894. };
  895. // Parameter for mg_http_next_multipart
  896. struct mg_http_part {
  897. struct mg_str name; // Form field name
  898. struct mg_str filename; // Filename for file uploads
  899. struct mg_str body; // Part contents
  900. };
  901. int mg_http_parse(const char *s, size_t len, struct mg_http_message *);
  902. int mg_http_get_request_len(const unsigned char *buf, size_t buf_len);
  903. void mg_http_printf_chunk(struct mg_connection *cnn, const char *fmt, ...);
  904. void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len);
  905. void mg_http_delete_chunk(struct mg_connection *c, struct mg_http_message *hm);
  906. struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
  907. mg_event_handler_t fn, void *fn_data);
  908. struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
  909. mg_event_handler_t fn, void *fn_data);
  910. void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
  911. const struct mg_http_serve_opts *);
  912. void mg_http_serve_file(struct mg_connection *, struct mg_http_message *hm,
  913. const char *path, const struct mg_http_serve_opts *);
  914. void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
  915. const char *body_fmt, ...);
  916. struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
  917. struct mg_str mg_http_var(struct mg_str buf, struct mg_str name);
  918. int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
  919. int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
  920. size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);
  921. void mg_http_creds(struct mg_http_message *, char *, size_t, char *, size_t);
  922. bool mg_http_match_uri(const struct mg_http_message *, const char *glob);
  923. long mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
  924. struct mg_fs *fs, const char *path, size_t max_size);
  925. void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
  926. struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v);
  927. size_t mg_http_next_multipart(struct mg_str, size_t, struct mg_http_part *);
  928. int mg_http_status(const struct mg_http_message *hm);
  929. void mg_http_serve_ssi(struct mg_connection *c, const char *root,
  930. const char *fullpath);
  931. struct mg_tls_opts {
  932. const char *ca; // CA certificate file. For both listeners and clients
  933. const char *crl; // Certificate Revocation List. For clients
  934. const char *cert; // Certificate
  935. const char *certkey; // Certificate key
  936. const char *ciphers; // Cipher list
  937. struct mg_str srvname; // If not empty, enables server name verification
  938. struct mg_fs *fs; // FS API for reading certificate files
  939. };
  940. void mg_tls_init(struct mg_connection *, const struct mg_tls_opts *);
  941. void mg_tls_free(struct mg_connection *);
  942. long mg_tls_send(struct mg_connection *, const void *buf, size_t len);
  943. long mg_tls_recv(struct mg_connection *, void *buf, size_t len);
  944. size_t mg_tls_pending(struct mg_connection *);
  945. void mg_tls_handshake(struct mg_connection *);
  946. #if MG_ENABLE_MBEDTLS
  947. #include <mbedtls/debug.h>
  948. #include <mbedtls/net_sockets.h>
  949. #include <mbedtls/ssl.h>
  950. struct mg_tls {
  951. char *cafile; // CA certificate path
  952. mbedtls_x509_crt ca; // Parsed CA certificate
  953. mbedtls_x509_crt cert; // Parsed certificate
  954. mbedtls_ssl_context ssl; // SSL/TLS context
  955. mbedtls_ssl_config conf; // SSL-TLS config
  956. mbedtls_pk_context pk; // Private key context
  957. };
  958. #endif
  959. #if MG_ENABLE_OPENSSL
  960. #include <openssl/err.h>
  961. #include <openssl/ssl.h>
  962. struct mg_tls {
  963. SSL_CTX *ctx;
  964. SSL *ssl;
  965. };
  966. #endif
  967. #define WEBSOCKET_OP_CONTINUE 0
  968. #define WEBSOCKET_OP_TEXT 1
  969. #define WEBSOCKET_OP_BINARY 2
  970. #define WEBSOCKET_OP_CLOSE 8
  971. #define WEBSOCKET_OP_PING 9
  972. #define WEBSOCKET_OP_PONG 10
  973. struct mg_ws_message {
  974. struct mg_str data; // Websocket message data
  975. uint8_t flags; // Websocket message flags
  976. };
  977. struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
  978. mg_event_handler_t fn, void *fn_data,
  979. const char *fmt, ...);
  980. void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
  981. const char *fmt, ...);
  982. size_t mg_ws_send(struct mg_connection *, const void *buf, size_t len, int op);
  983. size_t mg_ws_wrap(struct mg_connection *, size_t len, int op);
  984. size_t mg_ws_printf(struct mg_connection *c, int op, const char *fmt, ...);
  985. size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt,
  986. va_list *);
  987. struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
  988. mg_event_handler_t fn, void *fn_data);
  989. void mg_sntp_request(struct mg_connection *c);
  990. int64_t mg_sntp_parse(const unsigned char *buf, size_t len);
  991. #define MQTT_CMD_CONNECT 1
  992. #define MQTT_CMD_CONNACK 2
  993. #define MQTT_CMD_PUBLISH 3
  994. #define MQTT_CMD_PUBACK 4
  995. #define MQTT_CMD_PUBREC 5
  996. #define MQTT_CMD_PUBREL 6
  997. #define MQTT_CMD_PUBCOMP 7
  998. #define MQTT_CMD_SUBSCRIBE 8
  999. #define MQTT_CMD_SUBACK 9
  1000. #define MQTT_CMD_UNSUBSCRIBE 10
  1001. #define MQTT_CMD_UNSUBACK 11
  1002. #define MQTT_CMD_PINGREQ 12
  1003. #define MQTT_CMD_PINGRESP 13
  1004. #define MQTT_CMD_DISCONNECT 14
  1005. #define MQTT_CMD_AUTH 15
  1006. enum { MQTT_OK, MQTT_INCOMPLETE, MQTT_MALFORMED };
  1007. struct mg_mqtt_opts {
  1008. struct mg_str user; // Username, can be empty
  1009. struct mg_str pass; // Password, can be empty
  1010. struct mg_str client_id; // Client ID
  1011. struct mg_str will_topic; // Will topic
  1012. struct mg_str will_message; // Will message
  1013. uint8_t will_qos; // Will message quality of service
  1014. uint8_t version; // Can be 4 (3.1.1), or 5. If 0, assume 4.
  1015. uint16_t keepalive; // Keep-alive timer in seconds
  1016. bool will_retain; // Retain last will
  1017. bool clean; // Use clean session, 0 or 1
  1018. };
  1019. struct mg_mqtt_message {
  1020. struct mg_str topic; // Parsed topic
  1021. struct mg_str data; // Parsed message
  1022. struct mg_str dgram; // Whole MQTT datagram, including headers
  1023. uint16_t id; // Set for PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, PUBLISH
  1024. uint8_t cmd; // MQTT command, one of MQTT_CMD_*
  1025. uint8_t qos; // Quality of service
  1026. uint8_t ack; // Connack return code. 0 - success
  1027. };
  1028. struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url,
  1029. const struct mg_mqtt_opts *opts,
  1030. mg_event_handler_t fn, void *fn_data);
  1031. struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
  1032. mg_event_handler_t fn, void *fn_data);
  1033. void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts);
  1034. void mg_mqtt_pub(struct mg_connection *c, struct mg_str topic,
  1035. struct mg_str data, int qos, bool retain);
  1036. void mg_mqtt_sub(struct mg_connection *, struct mg_str topic, int qos);
  1037. int mg_mqtt_parse(const uint8_t *, size_t, uint8_t, struct mg_mqtt_message *);
  1038. void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags,
  1039. uint32_t len);
  1040. void mg_mqtt_ping(struct mg_connection *);
  1041. void mg_mqtt_pong(struct mg_connection *);
  1042. void mg_mqtt_disconnect(struct mg_connection *);
  1043. // Mongoose sends DNS queries that contain only one question:
  1044. // either A (IPv4) or AAAA (IPv6) address lookup.
  1045. // Therefore, we expect zero or one answer.
  1046. // If `resolved` is true, then `addr` contains resolved IPv4 or IPV6 address.
  1047. struct mg_dns_message {
  1048. uint16_t txnid; // Transaction ID
  1049. bool resolved; // Resolve successful, addr is set
  1050. struct mg_addr addr; // Resolved address
  1051. char name[256]; // Host name
  1052. };
  1053. struct mg_dns_header {
  1054. uint16_t txnid; // Transaction ID
  1055. uint16_t flags;
  1056. uint16_t num_questions;
  1057. uint16_t num_answers;
  1058. uint16_t num_authority_prs;
  1059. uint16_t num_other_prs;
  1060. };
  1061. // DNS resource record
  1062. struct mg_dns_rr {
  1063. uint16_t nlen; // Name or pointer length
  1064. uint16_t atype; // Address type
  1065. uint16_t aclass; // Address class
  1066. uint16_t alen; // Address length
  1067. };
  1068. void mg_resolve(struct mg_connection *, const char *url);
  1069. void mg_resolve_cancel(struct mg_connection *);
  1070. bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *);
  1071. size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
  1072. bool is_question, struct mg_dns_rr *);
  1073. #ifndef MG_JSON_MAX_DEPTH
  1074. #define MG_JSON_MAX_DEPTH 30
  1075. #endif
  1076. // Error return values - negative. Successful returns are >= 0
  1077. enum { MG_JSON_TOO_DEEP = -1, MG_JSON_INVALID = -2, MG_JSON_NOT_FOUND = -3 };
  1078. int mg_json_get(struct mg_str json, const char *path, int *toklen);
  1079. bool mg_json_get_num(struct mg_str json, const char *path, double *v);
  1080. bool mg_json_get_bool(struct mg_str json, const char *path, bool *v);
  1081. long mg_json_get_long(struct mg_str json, const char *path, long dflt);
  1082. char *mg_json_get_str(struct mg_str json, const char *path);
  1083. char *mg_json_get_hex(struct mg_str json, const char *path, int *len);
  1084. char *mg_json_get_b64(struct mg_str json, const char *path, int *len);
  1085. // JSON-RPC request descriptor
  1086. struct mg_rpc_req {
  1087. struct mg_rpc **head; // RPC handlers list head
  1088. struct mg_rpc *rpc; // RPC handler being called
  1089. mg_pfn_t pfn; // Response printing function
  1090. void *pfn_data; // Response printing function data
  1091. void *req_data; // Arbitrary request data
  1092. struct mg_str frame; // Request, e.g. {"id":1,"method":"add","params":[1,2]}
  1093. };
  1094. // JSON-RPC method handler
  1095. struct mg_rpc {
  1096. struct mg_rpc *next; // Next in list
  1097. struct mg_str method; // Method pattern
  1098. void (*fn)(struct mg_rpc_req *); // Handler function
  1099. void *fn_data; // Handler function argument
  1100. };
  1101. void mg_rpc_add(struct mg_rpc **head, struct mg_str method_pattern,
  1102. void (*handler)(struct mg_rpc_req *), void *handler_data);
  1103. void mg_rpc_del(struct mg_rpc **head, void (*handler)(struct mg_rpc_req *));
  1104. void mg_rpc_process(struct mg_rpc_req *);
  1105. // Helper functions to print result or error frame
  1106. void mg_rpc_ok(struct mg_rpc_req *, const char *fmt, ...);
  1107. void mg_rpc_vok(struct mg_rpc_req *, const char *fmt, va_list *ap);
  1108. void mg_rpc_err(struct mg_rpc_req *, int code, const char *fmt, ...);
  1109. void mg_rpc_verr(struct mg_rpc_req *, int code, const char *fmt, va_list *);
  1110. void mg_rpc_list(struct mg_rpc_req *r);
  1111. struct mip_driver {
  1112. bool (*init)(uint8_t *mac, void *data); // Initialise driver
  1113. size_t (*tx)(const void *, size_t, void *data); // Transmit frame
  1114. size_t (*rx)(void *buf, size_t len, void *data); // Receive frame (polling)
  1115. bool (*up)(void *data); // Up/down status
  1116. // Set receive callback for interrupt-driven drivers
  1117. void (*setrx)(void (*fn)(void *buf, size_t len, void *rxdata), void *rxdata);
  1118. };
  1119. struct mip_cfg {
  1120. uint8_t mac[6]; // MAC address. Must not be 0
  1121. uint32_t ip, mask, gw; // IP, netmask, GW. If IP is 0, DHCP is used
  1122. };
  1123. void mip_init(struct mg_mgr *, struct mip_cfg *, struct mip_driver *, void *);
  1124. extern struct mip_driver mip_driver_stm32;
  1125. extern struct mip_driver mip_driver_enc28j60;
  1126. extern struct mip_driver mip_driver_w5500;
  1127. // Drivers that require SPI, can use this SPI abstraction
  1128. struct mip_spi {
  1129. void *spi; // Opaque SPI bus descriptor
  1130. void (*begin)(void *); // SPI begin: slave select low
  1131. void (*end)(void *); // SPI end: slave select high
  1132. uint8_t (*txn)(void *, uint8_t); // SPI transaction: write 1 byte, read reply
  1133. };
  1134. #ifdef __cplusplus
  1135. }
  1136. #endif
  1137. #endif // MONGOOSE_H