Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mongoose.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file mongoose.h
1 /*
2  * Copyright (c) 2004-2013 Sergey Lyubka
3  * Copyright (c) 2013-2015 Cesanta Software Limited
4  * All rights reserved
5  *
6  * This software is dual-licensed: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation. For the terms of this
9  * license, see <http://www.gnu.org/licenses/>.
10  *
11  * You are free to use this software under the terms of the GNU General
12  * Public License, but WITHOUT ANY WARRANTY; without even the implied
13  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * Alternatively, you can license this software under a commercial
17  * license, as set out in <https://www.cesanta.com/license>.
18  */
19 
20 #ifndef CS_MONGOOSE_SRC_COMMON_H_
21 #define CS_MONGOOSE_SRC_COMMON_H_
22 
23 #define MG_VERSION "6.4"
24 
25 /* Local tweaks, applied before any of Mongoose's own headers. */
26 #ifdef MG_LOCALS
27 #include <mg_locals.h>
28 #endif
29 
30 #if defined(MG_ENABLE_DEBUG) && !defined(CS_ENABLE_DEBUG)
31 #define CS_ENABLE_DEBUG
32 #endif
33 #if defined(MG_DISABLE_STDIO) && !defined(CS_DISABLE_STDIO)
34 #define CS_DISABLE_STDIO
35 #elif defined(CS_DISABLE_STDIO) && !defined(MG_DISABLE_STDIO)
36 #define MG_DISABLE_STDIO
37 #endif
38 
39 /* All of the below features depend on filesystem access, disable them. */
40 #ifdef MG_DISABLE_FILESYSTEM
41 #ifndef MG_DISABLE_DAV
42 #define MG_DISABLE_DAV
43 #endif
44 #ifndef MG_DISABLE_CGI
45 #define MG_DISABLE_CGI
46 #endif
47 #ifndef MG_DISABLE_DIRECTORY_LISTING
48 #define MG_DISABLE_DIRECTORY_LISTING
49 #endif
50 #ifndef MG_DISABLE_DAV
51 #define MG_DISABLE_DAV
52 #endif
53 #endif /* MG_DISABLE_FILESYSTEM */
54 
55 #ifdef MG_NO_BSD_SOCKETS
56 #ifndef MG_DISABLE_SYNC_RESOLVER
57 #define MG_DISABLE_SYNC_RESOLVER
58 #endif
59 #ifndef MG_DISABLE_SOCKETPAIR
60 #define MG_DISABLE_SOCKETPAIR
61 #endif
62 #endif /* MG_NO_BSD_SOCKETS */
63 
64 
65 #endif /* CS_MONGOOSE_SRC_COMMON_H_ */
66 #ifndef CS_COMMON_PLATFORM_H_
67 #define CS_COMMON_PLATFORM_H_
68 
69 /*
70  * For the "custom" platform, includes and dependencies can be
71  * provided through mg_locals.h.
72  */
73 #define CS_P_CUSTOM 0
74 #define CS_P_UNIX 1
75 #define CS_P_WINDOWS 2
76 #define CS_P_ESP_LWIP 3
77 #define CS_P_CC3200 4
78 #define CS_P_MSP432 5
79 
80 /* If not specified explicitly, we guess platform by defines. */
81 #ifndef CS_PLATFORM
82 
83 #if defined(TARGET_IS_MSP432P4XX) || defined(__MSP432P401R__)
84 
85 #define CS_PLATFORM CS_P_MSP432
86 #elif defined(cc3200)
87 #define CS_PLATFORM CS_P_CC3200
88 #elif defined(__unix__) || defined(__APPLE__)
89 #define CS_PLATFORM CS_P_UNIX
90 #elif defined(_WIN32)
91 #define CS_PLATFORM CS_P_WINDOWS
92 #endif
93 
94 #ifndef CS_PLATFORM
95 #error "CS_PLATFORM is not specified and we couldn't guess it."
96 #endif
97 
98 #endif /* !defined(CS_PLATFORM) */
99 
100 
101 /* Common stuff */
102 
103 #ifdef __GNUC__
104 #define NORETURN __attribute__((noreturn))
105 #define NOINLINE __attribute__((noinline))
106 #define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
107 #else
108 #define NORETURN
109 #define NOINLINE
110 #define WARN_UNUSED_RESULT
111 #endif /* __GNUC__ */
112 
113 #ifndef ARRAY_SIZE
114 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
115 #endif
116 
117 #endif /* CS_COMMON_PLATFORM_H_ */
118 #ifndef CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_
119 #define CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_
120 #if CS_PLATFORM == CS_P_WINDOWS
121 
122 /*
123  * MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
124  * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
125  * MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
126  * MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
127  * MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
128  * MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
129  * MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio 2003)
130  * MSVC++ 7.0 _MSC_VER == 1300
131  * MSVC++ 6.0 _MSC_VER == 1200
132  * MSVC++ 5.0 _MSC_VER == 1100
133  */
134 #ifdef _MSC_VER
135 #pragma warning(disable : 4127) /* FD_SET() emits warning, disable it */
136 #pragma warning(disable : 4204) /* missing c99 support */
137 #endif
138 
139 #include <assert.h>
140 #include <direct.h>
141 #include <errno.h>
142 #include <fcntl.h>
143 #include <io.h>
144 #include <limits.h>
145 #include <signal.h>
146 #include <stddef.h>
147 #include <stdio.h>
148 #include <stdlib.h>
149 #include <sys/stat.h>
150 #include <time.h>
151 
152 #define random() rand()
153 #ifdef _MSC_VER
154 #pragma comment(lib, "ws2_32.lib") /* Linking with winsock library */
155 #endif
156 
157 #include <winsock2.h>
158 #include <ws2tcpip.h>
159 #include <windows.h>
160 #include <process.h>
161 
162 #ifndef EINPROGRESS
163 #define EINPROGRESS WSAEINPROGRESS
164 #endif
165 #ifndef EWOULDBLOCK
166 #define EWOULDBLOCK WSAEWOULDBLOCK
167 #endif
168 #ifndef __func__
169 #define STRX(x) #x
170 #define STR(x) STRX(x)
171 #define __func__ __FILE__ ":" STR(__LINE__)
172 #endif
173 #define snprintf _snprintf
174 #define fileno _fileno
175 #define vsnprintf _vsnprintf
176 #define sleep(x) Sleep((x) *1000)
177 #define to64(x) _atoi64(x)
178 #if !defined(__MINGW32__) && !defined(__MINGW64__)
179 #define popen(x, y) _popen((x), (y))
180 #define pclose(x) _pclose(x)
181 #endif
182 #define rmdir _rmdir
183 #if defined(_MSC_VER) && _MSC_VER >= 1400
184 #define fseeko(x, y, z) _fseeki64((x), (y), (z))
185 #else
186 #define fseeko(x, y, z) fseek((x), (y), (z))
187 #endif
188 #define random() rand()
189 typedef int socklen_t;
190 #if _MSC_VER >= 1700
191 #include <stdint.h>
192 #else
193 typedef signed char int8_t;
194 typedef unsigned char uint8_t;
195 typedef int int32_t;
196 typedef unsigned int uint32_t;
197 typedef short int16_t;
198 typedef unsigned short uint16_t;
199 typedef __int64 int64_t;
200 typedef unsigned __int64 uint64_t;
201 #endif
202 typedef SOCKET sock_t;
203 typedef uint32_t in_addr_t;
204 #ifndef UINT16_MAX
205 #define UINT16_MAX 65535
206 #endif
207 #ifndef UINT32_MAX
208 #define UINT32_MAX 4294967295
209 #endif
210 #ifndef pid_t
211 #define pid_t HANDLE
212 #endif
213 #define INT64_FMT "I64d"
214 #define INT64_X_FMT "I64x"
215 #define SIZE_T_FMT "Iu"
216 #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
217 typedef struct stat cs_stat_t;
218 #else
219 typedef struct _stati64 cs_stat_t;
220 #endif
221 #ifndef S_ISDIR
222 #define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
223 #endif
224 #ifndef S_ISREG
225 #define S_ISREG(x) (((x) &_S_IFMT) == _S_IFREG)
226 #endif
227 #define DIRSEP '\\'
228 
229 #ifndef va_copy
230 #ifdef __va_copy
231 #define va_copy __va_copy
232 #else
233 #define va_copy(x, y) (x) = (y)
234 #endif
235 #endif
236 
237 #ifndef MG_MAX_HTTP_REQUEST_SIZE
238 #define MG_MAX_HTTP_REQUEST_SIZE 8192
239 #endif
240 
241 #ifndef MG_MAX_HTTP_SEND_MBUF
242 #define MG_MAX_HTTP_SEND_MBUF 4096
243 #endif
244 
245 #ifndef MG_MAX_HTTP_HEADERS
246 #define MG_MAX_HTTP_HEADERS 40
247 #endif
248 
249 #endif /* CS_PLATFORM == CS_P_WINDOWS */
250 #endif /* CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_ */
251 #ifndef CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_
252 #define CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_
253 #if CS_PLATFORM == CS_P_UNIX
254 
255 #ifndef _XOPEN_SOURCE
256 #define _XOPEN_SOURCE 600
257 #endif
258 
259 /* <inttypes.h> wants this for C++ */
260 #ifndef __STDC_FORMAT_MACROS
261 #define __STDC_FORMAT_MACROS
262 #endif
263 
264 /* C++ wants that for INT64_MAX */
265 #ifndef __STDC_LIMIT_MACROS
266 #define __STDC_LIMIT_MACROS
267 #endif
268 
269 /* Enable fseeko() and ftello() functions */
270 #ifndef _LARGEFILE_SOURCE
271 #define _LARGEFILE_SOURCE
272 #endif
273 
274 /* Enable 64-bit file offsets */
275 #ifndef _FILE_OFFSET_BITS
276 #define _FILE_OFFSET_BITS 64
277 #endif
278 
279 #include <arpa/inet.h>
280 #include <assert.h>
281 #include <ctype.h>
282 #include <dirent.h>
283 #include <errno.h>
284 #include <fcntl.h>
285 #include <inttypes.h>
286 #include <limits.h>
287 #include <math.h>
288 #include <netdb.h>
289 #include <netinet/in.h>
290 #include <pthread.h>
291 #include <signal.h>
292 #include <stdarg.h>
293 #include <stdio.h>
294 #include <stdlib.h>
295 #include <string.h>
296 #include <sys/socket.h>
297 #include <sys/select.h>
298 #include <sys/stat.h>
299 #include <sys/time.h>
300 #include <sys/types.h>
301 #include <unistd.h>
302 
303 /*
304  * osx correctly avoids defining strtoll when compiling in strict ansi mode.
305  * We require strtoll, and if your embedded pre-c99 compiler lacks one, please
306  * implement a shim.
307  */
308 #if !(defined(__DARWIN_C_LEVEL) && __DARWIN_C_LEVEL >= 200809L)
309 long long strtoll(const char *, char **, int);
310 #endif
311 
312 typedef int sock_t;
313 #define INVALID_SOCKET (-1)
314 #define SIZE_T_FMT "zu"
315 typedef struct stat cs_stat_t;
316 #define DIRSEP '/'
317 #define to64(x) strtoll(x, NULL, 10)
318 #define INT64_FMT PRId64
319 #define INT64_X_FMT PRIx64
320 
321 #ifndef __cdecl
322 #define __cdecl
323 #endif
324 
325 #ifndef va_copy
326 #ifdef __va_copy
327 #define va_copy __va_copy
328 #else
329 #define va_copy(x, y) (x) = (y)
330 #endif
331 #endif
332 
333 #define closesocket(x) close(x)
334 
335 #ifndef MG_MAX_HTTP_REQUEST_SIZE
336 #define MG_MAX_HTTP_REQUEST_SIZE 8192
337 #endif
338 
339 #ifndef MG_MAX_HTTP_SEND_MBUF
340 #define MG_MAX_HTTP_SEND_MBUF 4096
341 #endif
342 
343 #ifndef MG_MAX_HTTP_HEADERS
344 #define MG_MAX_HTTP_HEADERS 40
345 #endif
346 
347 #endif /* CS_PLATFORM == CS_P_UNIX */
348 #endif /* CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_ */
349 #ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP_LWIP_H_
350 #define CS_COMMON_PLATFORMS_PLATFORM_ESP_LWIP_H_
351 #if CS_PLATFORM == CS_P_ESP_LWIP
352 
353 #include <assert.h>
354 #include <ctype.h>
355 #include <fcntl.h>
356 #include <inttypes.h>
357 #include <string.h>
358 #include <sys/stat.h>
359 #include <sys/time.h>
360 
361 #include <lwip/err.h>
362 #include <lwip/ip_addr.h>
363 #include <lwip/inet.h>
364 #include <lwip/netdb.h>
365 #include <lwip/dns.h>
366 
367 #ifndef LWIP_PROVIDE_ERRNO
368 #include <errno.h>
369 #endif
370 
371 #define LWIP_TIMEVAL_PRIVATE 0
372 
373 #if LWIP_SOCKET
374 #include <lwip/sockets.h>
375 #define SOMAXCONN 10
376 #else
377 /* We really need the definitions from sockets.h. */
378 #undef LWIP_SOCKET
379 #define LWIP_SOCKET 1
380 #include <lwip/sockets.h>
381 #undef LWIP_SOCKET
382 #define LWIP_SOCKET 0
383 #endif
384 
385 typedef int sock_t;
386 #define INVALID_SOCKET (-1)
387 #define SIZE_T_FMT "u"
388 typedef struct stat cs_stat_t;
389 #define DIRSEP '/'
390 #define to64(x) strtoll(x, NULL, 10)
391 #define INT64_FMT PRId64
392 #define INT64_X_FMT PRIx64
393 #define __cdecl
394 
395 unsigned long os_random(void);
396 #define random os_random
397 
398 #endif /* CS_PLATFORM == CS_P_ESP_LWIP */
399 #endif /* CS_COMMON_PLATFORMS_PLATFORM_ESP_LWIP_H_ */
400 /*
401  * Copyright (c) 2014-2016 Cesanta Software Limited
402  * All rights reserved
403  */
404 
405 #ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
406 #define CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
407 #if CS_PLATFORM == CS_P_CC3200
408 
409 #include <assert.h>
410 #include <ctype.h>
411 #include <errno.h>
412 #include <inttypes.h>
413 #include <stdint.h>
414 #include <string.h>
415 #include <time.h>
416 
417 #ifndef __TI_COMPILER_VERSION__
418 #include <fcntl.h>
419 #include <sys/time.h>
420 #endif
421 
422 #define MG_SOCKET_SIMPLELINK 1
423 #define MG_DISABLE_SOCKETPAIR 1
424 #define MG_DISABLE_SYNC_RESOLVER 1
425 #define MG_DISABLE_POPEN 1
426 #define MG_DISABLE_CGI 1
427 /* Only SPIFFS supports directories, SLFS does not. */
428 #ifndef CC3200_FS_SPIFFS
429 #define MG_DISABLE_DAV 1
430 #define MG_DISABLE_DIRECTORY_LISTING 1
431 #endif
432 
433 
434 typedef int sock_t;
435 #define INVALID_SOCKET (-1)
436 #define SIZE_T_FMT "u"
437 typedef struct stat cs_stat_t;
438 #define DIRSEP '/'
439 #define to64(x) strtoll(x, NULL, 10)
440 #define INT64_FMT PRId64
441 #define INT64_X_FMT PRIx64
442 #define __cdecl
443 
444 #define fileno(x) -1
445 
446 /* Some functions we implement for Mongoose. */
447 
448 #ifdef __cplusplus
449 extern "C" {
450 #endif
451 
452 #ifdef __TI_COMPILER_VERSION__
453  struct SlTimeval_t;
454 #define timeval SlTimeval_t
455  int gettimeofday(struct timeval *t, void *tz);
456 
457  int asprintf(char **strp, const char *fmt, ...);
458 
459 #endif
460 
461  long int random(void);
462 
463  /* TI's libc does not have stat & friends, add them. */
464 #ifdef __TI_COMPILER_VERSION__
465 
466 #include <file.h>
467 
468  typedef unsigned int mode_t;
469  typedef size_t _off_t;
470  typedef long ssize_t;
471 
472  struct stat {
473  int st_ino;
474  mode_t st_mode;
475  int st_nlink;
476  time_t st_mtime;
477  off_t st_size;
478  };
479 
480  int _stat(const char *pathname, struct stat *st);
481 #define stat(a, b) _stat(a, b)
482 
483 #define __S_IFMT 0170000
484 
485 #define __S_IFDIR 0040000
486 #define __S_IFCHR 0020000
487 #define __S_IFREG 0100000
488 
489 #define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
490 
491 #define S_IFDIR __S_IFDIR
492 #define S_IFCHR __S_IFCHR
493 #define S_IFREG __S_IFREG
494 #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
495 #define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
496 
497  /* As of 5.2.7, TI compiler does not support va_copy() yet. */
498 #define va_copy(apc, ap) ((apc) = (ap))
499 
500 #endif /* __TI_COMPILER_VERSION__ */
501 
502 #ifdef CC3200_FS_SPIFFS
503 #include <common/spiffs/spiffs.h>
504 
505  typedef struct {
506  spiffs_DIR dh;
507  struct spiffs_dirent de;
508  } DIR;
509 
510 #define d_name name
511 #define dirent spiffs_dirent
512 
513  DIR *opendir(const char *dir_name);
514  int closedir(DIR *dir);
515  struct dirent *readdir(DIR *dir);
516 #endif /* CC3200_FS_SPIFFS */
517 
518 #ifdef CC3200_FS_SLFS
519 #define MG_FS_SLFS
520 #endif
521 
522 #ifdef __cplusplus
523 }
524 #endif
525 
526 #endif /* CS_PLATFORM == CS_P_CC3200 */
527 #endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ */
528 /*
529  * Copyright (c) 2014-2016 Cesanta Software Limited
530  * All rights reserved
531  */
532 
533 #ifndef CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
534 #define CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
535 #if CS_PLATFORM == CS_P_MSP432
536 
537 #include <assert.h>
538 #include <ctype.h>
539 #include <errno.h>
540 #include <inttypes.h>
541 #include <stdint.h>
542 #include <string.h>
543 #include <time.h>
544 
545 #ifndef __TI_COMPILER_VERSION__
546 #include <fcntl.h>
547 #include <sys/time.h>
548 #endif
549 
550 #define MG_SOCKET_SIMPLELINK 1
551 #define MG_DISABLE_SOCKETPAIR 1
552 #define MG_DISABLE_SYNC_RESOLVER 1
553 #define MG_DISABLE_POPEN 1
554 #define MG_DISABLE_CGI 1
555 #define MG_DISABLE_DAV 1
556 #define MG_DISABLE_DIRECTORY_LISTING 1
557 
558 
559 typedef int sock_t;
560 #define INVALID_SOCKET (-1)
561 #define SIZE_T_FMT "u"
562 typedef struct stat cs_stat_t;
563 #define DIRSEP '/'
564 #define to64(x) strtoll(x, NULL, 10)
565 #define INT64_FMT PRId64
566 #define INT64_X_FMT PRIx64
567 #define __cdecl
568 
569 #define fileno(x) -1
570 
571 /* Some functions we implement for Mongoose. */
572 
573 #ifdef __cplusplus
574 extern "C" {
575 #endif
576 
577 #ifdef __TI_COMPILER_VERSION__
578  struct SlTimeval_t;
579 #define timeval SlTimeval_t
580  int gettimeofday(struct timeval *t, void *tz);
581 #endif
582 
583  long int random(void);
584 
585  /* TI's libc does not have stat & friends, add them. */
586 #ifdef __TI_COMPILER_VERSION__
587 
588 #include <file.h>
589 
590  typedef unsigned int mode_t;
591  typedef size_t _off_t;
592  typedef long ssize_t;
593 
594  struct stat {
595  int st_ino;
596  mode_t st_mode;
597  int st_nlink;
598  time_t st_mtime;
599  off_t st_size;
600  };
601 
602  int _stat(const char *pathname, struct stat *st);
603 #define stat(a, b) _stat(a, b)
604 
605 #define __S_IFMT 0170000
606 
607 #define __S_IFDIR 0040000
608 #define __S_IFCHR 0020000
609 #define __S_IFREG 0100000
610 
611 #define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
612 
613 #define S_IFDIR __S_IFDIR
614 #define S_IFCHR __S_IFCHR
615 #define S_IFREG __S_IFREG
616 #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
617 #define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
618 
619  /* As of 5.2.7, TI compiler does not support va_copy() yet. */
620 #define va_copy(apc, ap) ((apc) = (ap))
621 
622 #endif /* __TI_COMPILER_VERSION__ */
623 
624 #ifdef __cplusplus
625 }
626 #endif
627 
628 #endif /* CS_PLATFORM == CS_P_MSP432 */
629 #endif /* CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_ */
630 /*
631  * Copyright (c) 2014-2016 Cesanta Software Limited
632  * All rights reserved
633  */
634 
635 #ifndef CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
636 #define CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
637 
638 /* If simplelink.h is already included, all bets are off. */
639 #if defined(MG_SOCKET_SIMPLELINK) && !defined(__SIMPLELINK_H__)
640 
641 #include <stdbool.h>
642 
643 #ifndef __TI_COMPILER_VERSION__
644 #undef __CONCAT
645 #undef FD_CLR
646 #undef FD_ISSET
647 #undef FD_SET
648 #undef FD_SETSIZE
649 #undef FD_ZERO
650 #undef fd_set
651 #endif
652 
653 /* We want to disable SL_INC_STD_BSD_API_NAMING, so we include user.h ourselves
654  * and undef it. */
655 #define PROVISIONING_API_H_
656 #include <simplelink/user.h>
657 #undef PROVISIONING_API_H_
658 #undef SL_INC_STD_BSD_API_NAMING
659 
660 #include <simplelink/include/simplelink.h>
661 
662 /* Now define only the subset of the BSD API that we use.
663  * Notably, close(), read() and write() are not defined. */
664 #define AF_INET SL_AF_INET
665 
666 #define socklen_t SlSocklen_t
667 #define sockaddr SlSockAddr_t
668 #define sockaddr_in SlSockAddrIn_t
669 #define in_addr SlInAddr_t
670 
671 #define SOCK_STREAM SL_SOCK_STREAM
672 #define SOCK_DGRAM SL_SOCK_DGRAM
673 
674 #define FD_SET SL_FD_SET
675 #define FD_CLR SL_FD_CLR
676 #define FD_ISSET SL_FD_ISSET
677 #define FD_ZERO SL_FD_ZERO
678 #define fd_set SlFdSet_t
679 
680 #define htonl sl_Htonl
681 #define ntohl sl_Ntohl
682 #define htons sl_Htons
683 #define ntohs sl_Ntohs
684 
685 #define accept sl_Accept
686 #define closesocket sl_Close
687 #define bind sl_Bind
688 #define connect sl_Connect
689 #define listen sl_Listen
690 #define recv sl_Recv
691 #define recvfrom sl_RecvFrom
692 #define send sl_Send
693 #define sendto sl_SendTo
694 #define socket sl_Socket
695 
696 #define select(nfds, rfds, wfds, efds, tout) \
697 sl_Select((nfds), (rfds), (wfds), (efds), (struct SlTimeval_t *)(tout))
698 
699 #ifndef EACCES
700 #define EACCES SL_EACCES
701 #endif
702 #ifndef EAFNOSUPPORT
703 #define EAFNOSUPPORT SL_EAFNOSUPPORT
704 #endif
705 #ifndef EAGAIN
706 #define EAGAIN SL_EAGAIN
707 #endif
708 #ifndef EBADF
709 #define EBADF SL_EBADF
710 #endif
711 #ifndef EINVAL
712 #define EINVAL SL_EINVAL
713 #endif
714 #ifndef ENOMEM
715 #define ENOMEM SL_ENOMEM
716 #endif
717 #ifndef EWOULDBLOCK
718 #define EWOULDBLOCK SL_EWOULDBLOCK
719 #endif
720 
721 #define SOMAXCONN 8
722 
723 #ifdef __cplusplus
724 extern "C" {
725 #endif
726 
727  const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
728  char *inet_ntoa(struct in_addr in);
729  int inet_pton(int af, const char *src, void *dst);
730 
731  struct mg_mgr;
732 
733  typedef void (*mg_init_cb)(struct mg_mgr *mgr);
734  bool mg_start_task(int priority, int stack_size, mg_init_cb mg_init);
735 
736  void mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg);
737 
738  int sl_fs_init();
739 
740 #ifdef __cplusplus
741 }
742 #endif
743 
744 #endif /* defined(MG_SOCKET_SIMPLELINK) && !defined(__SIMPLELINK_H__) */
745 
746 #endif /* CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_ */
747 /*
748  * Copyright (c) 2014-2016 Cesanta Software Limited
749  * All rights reserved
750  */
751 
752 #ifndef CS_COMMON_CS_DBG_H_
753 #define CS_COMMON_CS_DBG_H_
754 
755 #ifndef CS_DISABLE_STDIO
756 #include <stdio.h>
757 #endif
758 
759 #ifdef __cplusplus
760 extern "C" {
761 #endif /* __cplusplus */
762 
764  LL_NONE = -1,
765  LL_ERROR = 0,
766  LL_WARN = 1,
767  LL_INFO = 2,
768  LL_DEBUG = 3,
770 
771  _LL_MIN = -2,
772  _LL_MAX = 5,
773  };
774 
776 
777 #ifndef CS_DISABLE_STDIO
778 
779  void cs_log_set_file(FILE *file);
780 
781  extern enum cs_log_level cs_log_level;
782  void cs_log_print_prefix(const char *func);
783  void cs_log_printf(const char *fmt, ...);
784 
785 #define LOG(l, x) \
786 if (cs_log_level >= l) { \
787 cs_log_print_prefix(__func__); \
788 cs_log_printf x; \
789 }
790 
791 #ifndef CS_NDEBUG
792 
793 #define DBG(x) \
794 if (cs_log_level >= LL_VERBOSE_DEBUG) { \
795 cs_log_print_prefix(__func__); \
796 cs_log_printf x; \
797 }
798 
799 #else /* NDEBUG */
800 
801 #define DBG(x)
802 
803 #endif
804 
805 #else /* CS_DISABLE_STDIO */
806 
807 #define LOG(l, x)
808 #define DBG(x)
809 
810 #endif
811 
812 #ifdef __cplusplus
813 }
814 #endif /* __cplusplus */
815 
816 #endif /* CS_COMMON_CS_DBG_H_ */
817 /*
818  * Copyright (c) 2014-2016 Cesanta Software Limited
819  * All rights reserved
820  */
821 
822 #ifndef CS_COMMON_CS_TIME_H_
823 #define CS_COMMON_CS_TIME_H_
824 
825 #ifdef __cplusplus
826 extern "C" {
827 #endif /* __cplusplus */
828 
829  /* Sub-second granularity time(). */
830  double cs_time();
831 
832 #ifdef __cplusplus
833 }
834 #endif /* __cplusplus */
835 
836 #endif /* CS_COMMON_CS_TIME_H_ */
837 /*
838  * Copyright (c) 2015 Cesanta Software Limited
839  * All rights reserved
840  */
841 
842 /*
843  * === Memory Buffers
844  *
845  * Mbufs are mutable/growing memory buffers, like C++ strings.
846  * Mbuf can append data to the end of a buffer, or insert data into arbitrary
847  * position in the middle of a buffer. The buffer grows automatically when
848  * needed.
849  */
850 
851 #ifndef CS_COMMON_MBUF_H_
852 #define CS_COMMON_MBUF_H_
853 
854 #if defined(__cplusplus)
855 extern "C" {
856 #endif
857 
858 #include <stdlib.h>
859 
860 #ifndef MBUF_SIZE_MULTIPLIER
861 #define MBUF_SIZE_MULTIPLIER 1.5
862 #endif
863 
864  /* Memory buffer descriptor */
865  struct mbuf {
866  char *buf; /* Buffer pointer */
867  size_t len; /* Data length. Data is located between offset 0 and len. */
868  size_t size; /* Buffer size allocated by realloc(1). Must be >= len */
869  };
870 
871  /*
872  * Initialize an Mbuf.
873  * `initial_capacity` specifies the initial capacity of the mbuf.
874  */
875  void mbuf_init(struct mbuf *, size_t initial_capacity);
876 
877  /* Free the space allocated for the mbuffer and resets the mbuf structure. */
878  void mbuf_free(struct mbuf *);
879 
880  /*
881  * Appends data to the Mbuf.
882  *
883  * Return the number of bytes appended, or 0 if out of memory.
884  */
885  size_t mbuf_append(struct mbuf *, const void *data, size_t data_size);
886 
887  /*
888  * Insert data at a specified offset in the Mbuf.
889  *
890  * Existing data will be shifted forwards and the buffer will
891  * be grown if necessary.
892  * Return the number of bytes inserted.
893  */
894  size_t mbuf_insert(struct mbuf *, size_t, const void *, size_t);
895 
896  /* Remove `data_size` bytes from the beginning of the buffer. */
897  void mbuf_remove(struct mbuf *, size_t data_size);
898 
899  /*
900  * Resize an Mbuf.
901  *
902  * If `new_size` is smaller than buffer's `len`, the
903  * resize is not performed.
904  */
905  void mbuf_resize(struct mbuf *, size_t new_size);
906 
907  /* Shrink an Mbuf by resizing its `size` to `len`. */
908  void mbuf_trim(struct mbuf *);
909 
910 #if defined(__cplusplus)
911 }
912 #endif /* __cplusplus */
913 
914 #endif /* CS_COMMON_MBUF_H_ */
915 /*
916  * Copyright (c) 2014 Cesanta Software Limited
917  * All rights reserved
918  */
919 
920 #ifndef CS_COMMON_SHA1_H_
921 #define CS_COMMON_SHA1_H_
922 
923 #ifndef DISABLE_SHA1
924 
925 
926 #ifdef __cplusplus
927 extern "C" {
928 #endif /* __cplusplus */
929 
930  typedef struct {
931  uint32_t state[5];
932  uint32_t count[2];
933  unsigned char buffer[64];
934  } cs_sha1_ctx;
935 
936  void cs_sha1_init(cs_sha1_ctx *);
937  void cs_sha1_update(cs_sha1_ctx *, const unsigned char *data, uint32_t len);
938  void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *);
939  void cs_hmac_sha1(const unsigned char *key, size_t key_len,
940  const unsigned char *text, size_t text_len,
941  unsigned char out[20]);
942 #ifdef __cplusplus
943 }
944 #endif /* __cplusplus */
945 
946 #endif /* DISABLE_SHA1 */
947 
948 #endif /* CS_COMMON_SHA1_H_ */
949 /*
950  * Copyright (c) 2014 Cesanta Software Limited
951  * All rights reserved
952  */
953 
954 #ifndef CS_COMMON_MD5_H_
955 #define CS_COMMON_MD5_H_
956 
957 
958 #ifdef __cplusplus
959 extern "C" {
960 #endif /* __cplusplus */
961 
962  typedef struct MD5Context {
963  uint32_t buf[4];
964  uint32_t bits[2];
965  unsigned char in[64];
966  } MD5_CTX;
967 
968  void MD5_Init(MD5_CTX *c);
969  void MD5_Update(MD5_CTX *c, const unsigned char *data, size_t len);
970  void MD5_Final(unsigned char *md, MD5_CTX *c);
971 
972  /*
973  * Return stringified MD5 hash for NULL terminated list of pointer/length pairs.
974  * A length should be specified as size_t variable.
975  * Example:
976  *
977  * char buf[33];
978  * cs_md5(buf, "foo", (size_t) 3, "bar", (size_t) 3, NULL);
979  */
980  char *cs_md5(char buf[33], ...);
981 
982  /*
983  * Stringify binary data. Output buffer size must be 2 * size_of_input + 1
984  * because each byte of input takes 2 bytes in string representation
985  * plus 1 byte for the terminating \0 character.
986  */
987  void cs_to_hex(char *to, const unsigned char *p, size_t len);
988 
989 #ifdef __cplusplus
990 }
991 #endif /* __cplusplus */
992 
993 #endif /* CS_COMMON_MD5_H_ */
994 /*
995  * Copyright (c) 2014 Cesanta Software Limited
996  * All rights reserved
997  */
998 
999 #ifndef CS_COMMON_BASE64_H_
1000 #define CS_COMMON_BASE64_H_
1001 
1002 #ifndef DISABLE_BASE64
1003 
1004 #include <stdio.h>
1005 
1006 #ifdef __cplusplus
1007 extern "C" {
1008 #endif
1009 
1010  typedef void (*cs_base64_putc_t)(char, void *);
1011 
1012  struct cs_base64_ctx {
1013  /* cannot call it putc because it's a macro on some environments */
1015  unsigned char chunk[3];
1017  void *user_data;
1018  };
1019 
1020  void cs_base64_init(struct cs_base64_ctx *ctx, cs_base64_putc_t putc,
1021  void *user_data);
1022  void cs_base64_update(struct cs_base64_ctx *ctx, const char *str, size_t len);
1023  void cs_base64_finish(struct cs_base64_ctx *ctx);
1024 
1025  void cs_base64_encode(const unsigned char *src, int src_len, char *dst);
1026  void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len);
1027  int cs_base64_decode(const unsigned char *s, int len, char *dst);
1028 
1029 #ifdef __cplusplus
1030 }
1031 #endif
1032 
1033 #endif /* DISABLE_BASE64 */
1034 
1035 #endif /* CS_COMMON_BASE64_H_ */
1036 /*
1037  * Copyright (c) 2015 Cesanta Software Limited
1038  * All rights reserved
1039  */
1040 
1041 #ifndef CS_COMMON_STR_UTIL_H_
1042 #define CS_COMMON_STR_UTIL_H_
1043 
1044 #include <stdarg.h>
1045 #include <stdlib.h>
1046 
1047 #ifdef __cplusplus
1048 extern "C" {
1049 #endif
1050 
1051  size_t c_strnlen(const char *s, size_t maxlen);
1052  int c_snprintf(char *buf, size_t buf_size, const char *format, ...);
1053  int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap);
1054  /*
1055  * Find the first occurrence of find in s, where the search is limited to the
1056  * first slen characters of s.
1057  */
1058  const char *c_strnstr(const char *s, const char *find, size_t slen);
1059 
1060 #ifdef __cplusplus
1061 }
1062 #endif
1063 
1064 #endif /* CS_COMMON_STR_UTIL_H_ */
1065 /*
1066  * Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
1067  * Copyright (c) 2013 Cesanta Software Limited
1068  * All rights reserved
1069  *
1070  * This library is dual-licensed: you can redistribute it and/or modify
1071  * it under the terms of the GNU General Public License version 2 as
1072  * published by the Free Software Foundation. For the terms of this
1073  * license, see <http: *www.gnu.org/licenses/>.
1074  *
1075  * You are free to use this library under the terms of the GNU General
1076  * Public License, but WITHOUT ANY WARRANTY; without even the implied
1077  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1078  * See the GNU General Public License for more details.
1079  *
1080  * Alternatively, you can license this library under a commercial
1081  * license, as set out in <http://cesanta.com/products.html>.
1082  */
1083 
1084 #ifndef CS_MONGOOSE_DEPS_FROZEN_FROZEN_H_
1085 #define CS_MONGOOSE_DEPS_FROZEN_FROZEN_H_
1086 
1087 #ifdef __cplusplus
1088 extern "C" {
1089 #endif /* __cplusplus */
1090 
1091 #include <stdarg.h>
1092 
1093  enum json_type {
1094  JSON_TYPE_EOF = 0, /* End of parsed tokens marker */
1102  };
1103 
1104  struct json_token {
1105  const char *ptr; /* Points to the beginning of the token */
1106  int len; /* Token length */
1107  int num_desc; /* For arrays and object, total number of descendants */
1108  enum json_type type; /* Type of the token, possible values above */
1109  };
1110 
1111  /* Error codes */
1112 #define JSON_STRING_INVALID -1
1113 #define JSON_STRING_INCOMPLETE -2
1114 #define JSON_TOKEN_ARRAY_TOO_SMALL -3
1115 
1116  int parse_json(const char *json_string, int json_string_length,
1117  struct json_token *tokens_array, int size_of_tokens_array);
1118  struct json_token *parse_json2(const char *json_string, int string_length);
1119  struct json_token *find_json_token(struct json_token *toks, const char *path);
1120 
1121  int json_emit_long(char *buf, int buf_len, long value);
1122  int json_emit_double(char *buf, int buf_len, double value);
1123  int json_emit_quoted_str(char *buf, int buf_len, const char *str, int len);
1124  int json_emit_unquoted_str(char *buf, int buf_len, const char *str, int len);
1125  int json_emit(char *buf, int buf_len, const char *fmt, ...);
1126  int json_emit_va(char *buf, int buf_len, const char *fmt, va_list);
1127 
1128 #ifdef __cplusplus
1129 }
1130 #endif /* __cplusplus */
1131 
1132 #endif /* CS_MONGOOSE_DEPS_FROZEN_FROZEN_H_ */
1133 /*
1134  * Copyright (c) 2014 Cesanta Software Limited
1135  * All rights reserved
1136  * This software is dual-licensed: you can redistribute it and/or modify
1137  * it under the terms of the GNU General Public License version 2 as
1138  * published by the Free Software Foundation. For the terms of this
1139  * license, see <http://www.gnu.org/licenses/>.
1140  *
1141  * You are free to use this software under the terms of the GNU General
1142  * Public License, but WITHOUT ANY WARRANTY; without even the implied
1143  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1144  * See the GNU General Public License for more details.
1145  *
1146  * Alternatively, you can license this software under a commercial
1147  * license, as set out in <https://www.cesanta.com/license>.
1148  */
1149 
1150 /*
1151  * === Core: TCP/UDP/SSL
1152  *
1153  * NOTE: Mongoose manager is single threaded. It does not protect
1154  * its data structures by mutexes, therefore all functions that are dealing
1155  * with particular event manager should be called from the same thread,
1156  * with exception of `mg_broadcast()` function. It is fine to have different
1157  * event managers handled by different threads.
1158  */
1159 
1160 #ifndef CS_MONGOOSE_SRC_NET_H_
1161 #define CS_MONGOOSE_SRC_NET_H_
1162 
1163 #ifdef MG_ENABLE_JAVASCRIPT
1164 #define EXCLUDE_COMMON
1165 #include <v7.h>
1166 #endif
1167 
1168 
1169 #ifdef MG_ENABLE_SSL
1170 #ifdef __APPLE__
1171 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1172 #endif
1173 #include <openssl/ssl.h>
1174 #else
1175 typedef void *SSL;
1176 typedef void *SSL_CTX;
1177 #endif
1178 
1179 #ifndef MG_VPRINTF_BUFFER_SIZE
1180 #define MG_VPRINTF_BUFFER_SIZE 100
1181 #endif
1182 
1183 #ifdef MG_USE_READ_WRITE
1184 #define MG_RECV_FUNC(s, b, l, f) read(s, b, l)
1185 #define MG_SEND_FUNC(s, b, l, f) write(s, b, l)
1186 #else
1187 #define MG_RECV_FUNC(s, b, l, f) recv(s, b, l, f)
1188 #define MG_SEND_FUNC(s, b, l, f) send(s, b, l, f)
1189 #endif
1190 
1191 #ifdef __cplusplus
1192 extern "C" {
1193 #endif /* __cplusplus */
1194 
1196  struct sockaddr sa;
1197  struct sockaddr_in sin;
1198 #ifdef MG_ENABLE_IPV6
1199  struct sockaddr_in6 sin6;
1200 #else
1201  struct sockaddr sin6;
1202 #endif
1203  };
1204 
1205  /* Describes chunk of memory */
1206  struct mg_str {
1207  const char *p; /* Memory chunk pointer */
1208  size_t len; /* Memory chunk length */
1209  };
1210 
1211  struct mg_connection;
1212 
1213  /*
1214  * Callback function (event handler) prototype, must be defined by user.
1215  * Mongoose calls event handler, passing events defined below.
1216  */
1217  typedef void (*mg_event_handler_t)(struct mg_connection *, int ev, void *);
1218 
1219  /* Events. Meaning of event parameter (evp) is given in the comment. */
1220 #define MG_EV_POLL 0 /* Sent to each connection on each mg_mgr_poll() call */
1221 #define MG_EV_ACCEPT 1 /* New connection accepted. union socket_address * */
1222 #define MG_EV_CONNECT 2 /* connect() succeeded or failed. int * */
1223 #define MG_EV_RECV 3 /* Data has benn received. int *num_bytes */
1224 #define MG_EV_SEND 4 /* Data has been written to a socket. int *num_bytes */
1225 #define MG_EV_CLOSE 5 /* Connection is closed. NULL */
1226 #define MG_EV_TIMER 6 /* now >= conn->ev_timer_time. double * */
1227 
1228  /*
1229  * Mongoose event manager.
1230  */
1231  struct mg_mgr {
1233  const char *hexdump_file; /* Debug hexdump file path */
1234 #ifndef MG_DISABLE_SOCKETPAIR
1235  sock_t ctl[2]; /* Socketpair for mg_wakeup() */
1236 #endif
1237  void *user_data; /* User data */
1238  void *mgr_data; /* Implementation-specific event manager's data. */
1239 #ifdef MG_ENABLE_JAVASCRIPT
1240  struct v7 *v7;
1241 #endif
1242  };
1243 
1244  /*
1245  * Mongoose connection.
1246  */
1247  struct mg_connection {
1248  struct mg_connection *next, *prev; /* mg_mgr::active_connections linkage */
1249  struct mg_connection *listener; /* Set only for accept()-ed connections */
1250  struct mg_mgr *mgr; /* Pointer to containing manager */
1251 
1252  sock_t sock; /* Socket to the remote peer */
1253  int err;
1254  union socket_address sa; /* Remote peer address */
1255  size_t recv_mbuf_limit; /* Max size of recv buffer */
1256  struct mbuf recv_mbuf; /* Received data */
1257  struct mbuf send_mbuf; /* Data scheduled for sending */
1260  time_t last_io_time; /* Timestamp of the last socket IO */
1261  double ev_timer_time; /* Timestamp of the future MG_EV_TIMER */
1262  mg_event_handler_t proto_handler; /* Protocol-specific event handler */
1263  void *proto_data; /* Protocol-specific data */
1265  mg_event_handler_t handler; /* Event handler function */
1266  void *user_data; /* User-specific data */
1267  union {
1268  void *v;
1269  /*
1270  * the C standard is fussy about fitting function pointers into
1271  * void pointers, since some archs might have fat pointers for functions.
1272  */
1274  } priv_1; /* Used by mg_enable_multithreading() */
1275  void *priv_2; /* Used by mg_enable_multithreading() */
1276  void *mgr_data; /* Implementation-specific event manager's data. */
1277  unsigned long flags;
1278  /* Flags set by Mongoose */
1279 #define MG_F_LISTENING (1 << 0) /* This connection is listening */
1280 #define MG_F_UDP (1 << 1) /* This connection is UDP */
1281 #define MG_F_RESOLVING (1 << 2) /* Waiting for async resolver */
1282 #define MG_F_CONNECTING (1 << 3) /* connect() call in progress */
1283 #define MG_F_SSL_HANDSHAKE_DONE (1 << 4) /* SSL specific */
1284 #define MG_F_WANT_READ (1 << 5) /* SSL specific */
1285 #define MG_F_WANT_WRITE (1 << 6) /* SSL specific */
1286 #define MG_F_IS_WEBSOCKET (1 << 7) /* Websocket specific */
1287 
1288  /* Flags that are settable by user */
1289 #define MG_F_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */
1290 #define MG_F_CLOSE_IMMEDIATELY (1 << 11) /* Disconnect */
1291 #define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */
1292 #define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */
1293 
1294 #define MG_F_USER_1 (1 << 20) /* Flags left for application */
1295 #define MG_F_USER_2 (1 << 21)
1296 #define MG_F_USER_3 (1 << 22)
1297 #define MG_F_USER_4 (1 << 23)
1298 #define MG_F_USER_5 (1 << 24)
1299 #define MG_F_USER_6 (1 << 25)
1300  };
1301 
1302  /*
1303  * Initialize Mongoose manager. Side effect: ignores SIGPIPE signal.
1304  * `mgr->user_data` field will be initialized with `user_data` parameter.
1305  * That is an arbitrary pointer, where user code can associate some data
1306  * with the particular Mongoose manager. For example, a C++ wrapper class
1307  * could be written, in which case `user_data` can hold a pointer to the
1308  * class instance.
1309  */
1310  void mg_mgr_init(struct mg_mgr *mgr, void *user_data);
1311 
1312  /*
1313  * De-initializes Mongoose manager.
1314  *
1315  * Close and deallocate all active connections.
1316  */
1317  void mg_mgr_free(struct mg_mgr *);
1318 
1319  /*
1320  * This function performs the actual IO, and must be called in a loop
1321  * (an event loop). Returns the current timestamp.
1322  * `milli` is the maximum number of milliseconds to sleep.
1323  * `mg_mgr_poll()` checks all connection for IO readiness. If at least one
1324  * of the connections is IO-ready, `mg_mgr_poll()` triggers respective
1325  * event handlers and returns.
1326  */
1327  time_t mg_mgr_poll(struct mg_mgr *, int milli);
1328 
1329 #ifndef MG_DISABLE_SOCKETPAIR
1330  /*
1331  * Pass a message of a given length to all connections.
1332  *
1333  * Must be called from a thread that does NOT call `mg_mgr_poll()`.
1334  * Note that `mg_broadcast()` is the only function
1335  * that can be, and must be, called from a different (non-IO) thread.
1336  *
1337  * `func` callback function will be called by the IO thread for each
1338  * connection. When called, event would be `MG_EV_POLL`, and message will
1339  * be passed as `ev_data` pointer. Maximum message size is capped
1340  * by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes.
1341  */
1342  void mg_broadcast(struct mg_mgr *, mg_event_handler_t func, void *, size_t);
1343 #endif
1344 
1345  /*
1346  * Iterate over all active connections.
1347  *
1348  * Returns next connection from the list
1349  * of active connections, or `NULL` if there is no more connections. Below
1350  * is the iteration idiom:
1351  *
1352  * ```c
1353  * for (c = mg_next(srv, NULL); c != NULL; c = mg_next(srv, c)) {
1354  * // Do something with connection `c`
1355  * }
1356  * ```
1357  */
1358  struct mg_connection *mg_next(struct mg_mgr *, struct mg_connection *);
1359 
1360  /*
1361  * Optional parameters to `mg_add_sock_opt()`.
1362  *
1363  * `flags` is an initial `struct mg_connection::flags` bitmask to set,
1364  * see `MG_F_*` flags definitions.
1365  */
1367  void *user_data; /* Initial value for connection's user_data */
1368  unsigned int flags; /* Initial connection flags */
1369  const char **error_string; /* Placeholder for the error string */
1370  };
1371 
1372  /*
1373  * Create a connection, associate it with the given socket and event handler,
1374  * and add it to the manager.
1375  *
1376  * For more options see the `mg_add_sock_opt` variant.
1377  */
1378  struct mg_connection *mg_add_sock(struct mg_mgr *, sock_t, mg_event_handler_t);
1379 
1380  /*
1381  * Create a connection, associate it with the given socket and event handler,
1382  * and add to the manager.
1383  *
1384  * See the `mg_add_sock_opts` structure for a description of the options.
1385  */
1386  struct mg_connection *mg_add_sock_opt(struct mg_mgr *, sock_t,
1388  struct mg_add_sock_opts);
1389 
1390  /*
1391  * Optional parameters to `mg_bind_opt()`.
1392  *
1393  * `flags` is an initial `struct mg_connection::flags` bitmask to set,
1394  * see `MG_F_*` flags definitions.
1395  */
1396  struct mg_bind_opts {
1397  void *user_data; /* Initial value for connection's user_data */
1398  unsigned int flags; /* Extra connection flags */
1399  const char **error_string; /* Placeholder for the error string */
1400 #ifdef MG_ENABLE_SSL
1401  /* SSL settings. */
1402  const char *ssl_cert; /* Server certificate to present to clients */
1403  const char *ssl_ca_cert; /* Verify client certificates with this CA bundle */
1404 #endif
1405  };
1406 
1407  /*
1408  * Create listening connection.
1409  *
1410  * See `mg_bind_opt` for full documentation.
1411  */
1412  struct mg_connection *mg_bind(struct mg_mgr *, const char *,
1414  /*
1415  * Create listening connection.
1416  *
1417  * `address` parameter tells which address to bind to. It's format is the same
1418  * as for the `mg_connect()` call, where `HOST` part is optional. `address`
1419  * can be just a port number, e.g. `:8000`. To bind to a specific interface,
1420  * an IP address can be specified, e.g. `1.2.3.4:8000`. By default, a TCP
1421  * connection is created. To create UDP connection, prepend `udp://` prefix,
1422  * e.g. `udp://:8000`. To summarize, `address` paramer has following format:
1423  * `[PROTO://][IP_ADDRESS]:PORT`, where `PROTO` could be `tcp` or `udp`.
1424  *
1425  * See the `mg_bind_opts` structure for a description of the optional
1426  * parameters.
1427  *
1428  * Return a new listening connection, or `NULL` on error.
1429  * NOTE: Connection remains owned by the manager, do not free().
1430  */
1431  struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,
1433  struct mg_bind_opts opts);
1434 
1435  /* Optional parameters to `mg_connect_opt()` */
1437  void *user_data; /* Initial value for connection's user_data */
1438  unsigned int flags; /* Extra connection flags */
1439  const char **error_string; /* Placeholder for the error string */
1440 #ifdef MG_ENABLE_SSL
1441  /* SSL settings. */
1442  const char *ssl_cert; /* Client certificate to present to the server */
1443  const char *ssl_ca_cert; /* Verify server certificate using this CA bundle */
1444 
1445  /*
1446  * Server name verification. If ssl_ca_cert is set and the certificate has
1447  * passed verification, its subject will be verified against this string.
1448  * By default (if ssl_server_name is NULL) hostname part of the address will
1449  * be used. Wildcard matching is supported. A special value of "*" disables
1450  * name verification.
1451  */
1452  const char *ssl_server_name;
1453 #endif
1454  };
1455 
1456  /*
1457  * Connect to a remote host.
1458  *
1459  * See `mg_connect_opt()` for full documentation.
1460  */
1461  struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,
1463 
1464  /*
1465  * Connect to a remote host.
1466  *
1467  * `address` format is `[PROTO://]HOST:PORT`. `PROTO` could be `tcp` or `udp`.
1468  * `HOST` could be an IP address,
1469  * IPv6 address (if Mongoose is compiled with `-DMG_ENABLE_IPV6`), or a host
1470  * name. If `HOST` is a name, Mongoose will resolve it asynchronously. Examples
1471  * of valid addresses: `google.com:80`, `udp://1.2.3.4:53`, `10.0.0.1:443`,
1472  * `[::1]:80`
1473  *
1474  * See the `mg_connect_opts` structure for a description of the optional
1475  * parameters.
1476  *
1477  * Returns a new outbound connection, or `NULL` on error.
1478  *
1479  * NOTE: Connection remains owned by the manager, do not free().
1480  *
1481  * NOTE: To enable IPv6 addresses, `-DMG_ENABLE_IPV6` should be specified
1482  * in the compilation flags.
1483  *
1484  * NOTE: New connection will receive `MG_EV_CONNECT` as it's first event
1485  * which will report connect success status.
1486  * If asynchronous resolution fail, or `connect()` syscall fail for whatever
1487  * reason (e.g. with `ECONNREFUSED` or `ENETUNREACH`), then `MG_EV_CONNECT`
1488  * event report failure. Code example below:
1489  *
1490  * ```c
1491  * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
1492  * int connect_status;
1493  *
1494  * switch (ev) {
1495  * case MG_EV_CONNECT:
1496  * connect_status = * (int *) ev_data;
1497  * if (connect_status == 0) {
1498  * // Success
1499  * } else {
1500  * // Error
1501  * printf("connect() error: %s\n", strerror(connect_status));
1502  * }
1503  * break;
1504  * ...
1505  * }
1506  * }
1507  *
1508  * ...
1509  * mg_connect(mgr, "my_site.com:80", ev_handler);
1510  * ```
1511  */
1512  struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
1514  struct mg_connect_opts opts);
1515 
1516  /*
1517  * Enable SSL for a given connection.
1518  * `cert` is a server certificate file name for a listening connection,
1519  * or a client certificate file name for an outgoing connection.
1520  * Certificate files must be in PEM format. Server certificate file
1521  * must contain a certificate, concatenated with a private key, optionally
1522  * concatenated with parameters.
1523  * `ca_cert` is a CA certificate, or NULL if peer verification is not
1524  * required.
1525  * Return: NULL on success, or error message on error.
1526  */
1527  const char *mg_set_ssl(struct mg_connection *nc, const char *cert,
1528  const char *ca_cert);
1529 
1530  /*
1531  * Send data to the connection.
1532  *
1533  * Note that sending functions do not actually push data to the socket.
1534  * They just append data to the output buffer. MG_EV_SEND will be delivered when
1535  * the data has actually been pushed out.
1536  */
1537  void mg_send(struct mg_connection *, const void *buf, int len);
1538 
1539  /* Enables format string warnings for mg_printf */
1540 #if defined(__GNUC__)
1541  __attribute__((format(printf, 2, 3)))
1542 #endif
1543  /* don't separate from mg_printf declaration */
1544 
1545  /*
1546  * Send `printf`-style formatted data to the connection.
1547  *
1548  * See `mg_send` for more details on send semantics.
1549  */
1550  int mg_printf(struct mg_connection *, const char *fmt, ...);
1551 
1552  /* Same as `mg_printf()`, but takes `va_list ap` as an argument. */
1553  int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
1554 
1555  /*
1556  * Create a socket pair.
1557  * `sock_type` can be either `SOCK_STREAM` or `SOCK_DGRAM`.
1558  * Return 0 on failure, 1 on success.
1559  */
1560  int mg_socketpair(sock_t[2], int sock_type);
1561 
1562  /*
1563  * Convert domain name into IP address.
1564  *
1565  * This is a utility function. If compilation flags have
1566  * `-DMG_ENABLE_GETADDRINFO`, then `getaddrinfo()` call is used for name
1567  * resolution. Otherwise, `gethostbyname()` is used.
1568  *
1569  * CAUTION: this function can block.
1570  * Return 1 on success, 0 on failure.
1571  */
1572 #ifndef MG_DISABLE_SYNC_RESOLVER
1573  int mg_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
1574 #endif
1575 
1576  /*
1577  * Verify given IP address against the ACL.
1578  *
1579  * `remote_ip` - an IPv4 address to check, in host byte order
1580  * `acl` - a comma separated list of IP subnets: `x.x.x.x/x` or `x.x.x.x`.
1581  * Each subnet is
1582  * prepended by either a - or a + sign. A plus sign means allow, where a
1583  * minus sign means deny. If a subnet mask is omitted, such as `-1.2.3.4`,
1584  * this means to deny only that single IP address.
1585  * Subnet masks may vary from 0 to 32, inclusive. The default setting
1586  * is to allow all accesses. On each request the full list is traversed,
1587  * and the last match wins. Example:
1588  *
1589  * `-0.0.0.0/0,+192.168/16` - deny all acccesses, only allow 192.168/16 subnet
1590  *
1591  * To learn more about subnet masks, see the
1592  * link:https://en.wikipedia.org/wiki/Subnetwork[Wikipedia page on Subnetwork]
1593  *
1594  * Return -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed.
1595  */
1596  int mg_check_ip_acl(const char *acl, uint32_t remote_ip);
1597 
1598  /*
1599  * Enable multi-threaded handling for the given listening connection `nc`.
1600  * For each accepted connection, Mongoose will create a separate thread
1601  * and run event handler in that thread. Thus, if an event hanler is doing
1602  * a blocking call or some long computation, that will not slow down
1603  * other connections.
1604  */
1605  void mg_enable_multithreading(struct mg_connection *nc);
1606 
1607 #ifdef MG_ENABLE_JAVASCRIPT
1608  /*
1609  * Enable server-side JavaScript scripting.
1610  * Requires `-DMG_ENABLE_JAVASCRIPT` compilation flag, and V7 engine sources.
1611  * v7 instance must not be destroyed during manager's lifetime.
1612  * Return V7 error.
1613  */
1614  enum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,
1615  const char *init_js_file_name);
1616 #endif
1617 
1618  /*
1619  * Schedule MG_EV_TIMER event to be delivered at `timestamp` time.
1620  * `timestamp` is a UNIX time (a number of seconds since Epoch). It is
1621  * `double` instead of `time_t` to allow for sub-second precision.
1622  * Return the old timer value.
1623  *
1624  * Example: set connect timeout to 1.5 seconds:
1625  *
1626  * ```
1627  * c = mg_connect(&mgr, "cesanta.com", ev_handler);
1628  * mg_set_timer(c, mg_time() + 1.5);
1629  * ...
1630  *
1631  * void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
1632  * switch (ev) {
1633  * case MG_EV_CONNECT:
1634  * mg_set_timer(c, 0); // Clear connect timer
1635  * break;
1636  * case MG_EV_TIMER:
1637  * log("Connect timeout");
1638  * c->flags |= MG_F_CLOSE_IMMEDIATELY;
1639  * break;
1640  * ```
1641  */
1642  double mg_set_timer(struct mg_connection *c, double timestamp);
1643 
1644  /*
1645  * A sub-second precision version of time().
1646  */
1647  double mg_time();
1648 
1649 #ifdef __cplusplus
1650 }
1651 #endif /* __cplusplus */
1652 
1653 #endif /* CS_MONGOOSE_SRC_NET_H_ */
1654 /*
1655  * Copyright (c) 2014-2016 Cesanta Software Limited
1656  * All rights reserved
1657  */
1658 
1659 #ifndef CS_MONGOOSE_SRC_NET_IF_H_
1660 #define CS_MONGOOSE_SRC_NET_IF_H_
1661 
1662 /*
1663  * Internal async networking core interface.
1664  * Consists of calls made by the core, which should not block,
1665  * and callbacks back into the core ("..._cb").
1666  * Callbacks may (will) cause methods to be invoked from within,
1667  * but methods are not allowed to invoke callbacks inline.
1668  *
1669  * Implementation must ensure that only one callback is invoked at any time.
1670  */
1671 
1672 #ifdef __cplusplus
1673 extern "C" {
1674 #endif /* __cplusplus */
1675 
1676  /* Request that a TCP connection is made to the specified address. */
1677  void mg_if_connect_tcp(struct mg_connection *nc,
1678  const union socket_address *sa);
1679  /* Open a UDP socket. Doesn't actually connect anything. */
1680  void mg_if_connect_udp(struct mg_connection *nc);
1681  /* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */
1682  void mg_if_connect_cb(struct mg_connection *nc, int err);
1683 
1684  /* Set up a listening TCP socket on a given address. rv = 0 -> ok. */
1685  int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa);
1686 
1687  /*
1688  * Deliver a new TCP connection. Returns NULL in case on error (unable to
1689  * create connection, in which case interface state should be discarded.
1690  * This is phase 1 of the two-phase process - MG_EV_ACCEPT will be delivered
1691  * when mg_if_accept_tcp_cb is invoked.
1692  */
1694  void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,
1695  size_t sa_len);
1696 
1697  /* Request that a "listening" UDP socket be created. */
1698  int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa);
1699 
1700  /* Send functions for TCP and UDP. Sent data is copied before return. */
1701  void mg_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len);
1702  void mg_if_udp_send(struct mg_connection *nc, const void *buf, size_t len);
1703  /* Callback that reports that data has been put on the wire. */
1704  void mg_if_sent_cb(struct mg_connection *nc, int num_sent);
1705 
1706  /*
1707  * Receive callback.
1708  * buf must be heap-allocated and ownership is transferred to the core.
1709  * Core will acknowledge consumption by calling mg_if_recved.
1710  */
1711  void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len);
1712  void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
1713  union socket_address *sa, size_t sa_len);
1714  void mg_if_recved(struct mg_connection *nc, size_t len);
1715 
1716  /* Deliver a POLL event to the connection. */
1717  void mg_if_poll(struct mg_connection *nc, time_t now);
1718 
1719  /* Deliver a TIMER event to the connection. */
1720  void mg_if_timer(struct mg_connection *c, double now);
1721 
1722  /* Perform interface-related connection initialization. Return 1 on success. */
1723  int mg_if_create_conn(struct mg_connection *nc);
1724 
1725  /* Perform interface-related cleanup on connection before destruction. */
1726  void mg_if_destroy_conn(struct mg_connection *nc);
1727 
1728  void mg_close_conn(struct mg_connection *nc);
1729 
1730  /* Put connection's address into *sa, local (remote = 0) or remote. */
1731  void mg_if_get_conn_addr(struct mg_connection *nc, int remote,
1732  union socket_address *sa);
1733 
1734  /* Associate a socket to a connection. */
1735  void mg_sock_set(struct mg_connection *nc, sock_t sock);
1736 
1737 #ifdef __cplusplus
1738 }
1739 #endif /* __cplusplus */
1740 
1741 #endif /* CS_MONGOOSE_SRC_NET_IF_H_ */
1742 /*
1743  * Copyright (c) 2014 Cesanta Software Limited
1744  * All rights reserved
1745  */
1746 
1747 /*
1748  * === URI
1749  */
1750 
1751 #ifndef CS_MONGOOSE_SRC_URI_H_
1752 #define CS_MONGOOSE_SRC_URI_H_
1753 
1754 
1755 #ifdef __cplusplus
1756 extern "C" {
1757 #endif /* __cplusplus */
1758 
1759  /*
1760  * Parses an URI and fills string chunks with locations of the respective
1761  * uri components within the input uri string. NULL pointers will be
1762  * ignored.
1763  *
1764  * General syntax:
1765  *
1766  * [scheme://[user_info@]]host[:port][/path][?query][#fragment]
1767  *
1768  * Example:
1769  *
1770  * foo.com:80
1771  * tcp://foo.com:1234
1772  * http://foo.com:80/bar?baz=1
1773  * https://user:pw@foo.com:443/blah
1774  *
1775  * `path` will include the leading slash. `query` won't include the leading `?`.
1776  * `host` can contain embedded colons if surrounded by square brackets in order
1777  * to support IPv6 literal addresses.
1778  *
1779  *
1780  * Returns 0 on success, -1 on error.
1781  */
1782  int mg_parse_uri(struct mg_str uri, struct mg_str *scheme,
1783  struct mg_str *user_info, struct mg_str *host,
1784  unsigned int *port, struct mg_str *path, struct mg_str *query,
1785  struct mg_str *fragment);
1786 
1787  int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out);
1788 
1789 #ifdef __cplusplus
1790 }
1791 #endif /* __cplusplus */
1792 #endif /* CS_MONGOOSE_SRC_URI_H_ */
1793 /*
1794  * Copyright (c) 2014 Cesanta Software Limited
1795  * All rights reserved
1796  */
1797 
1798 /*
1799  * === Utilities
1800  */
1801 
1802 #ifndef CS_MONGOOSE_SRC_UTIL_H_
1803 #define CS_MONGOOSE_SRC_UTIL_H_
1804 
1805 #include <stdio.h>
1806 
1807 
1808 #ifdef __cplusplus
1809 extern "C" {
1810 #endif /* __cplusplus */
1811 
1812 #ifndef MAX_PATH_SIZE
1813 #define MAX_PATH_SIZE 500
1814 #endif
1815 
1816  /*
1817  * Fetch substring from input string `s`, `end` into `v`.
1818  * Skips initial delimiter characters. Records first non-delimiter character
1819  * as the beginning of substring `v`. Then scans the rest of the string
1820  * until a delimiter character or end-of-string is found.
1821  * `delimiters` is a 0-terminated string containing delimiter characters.
1822  * Either one of `delimiters` or `end_string` terminates the search.
1823  * Return an `s` pointer, advanced forward where parsing stopped.
1824  */
1825  const char *mg_skip(const char *s, const char *end_string,
1826  const char *delimiters, struct mg_str *v);
1827 
1828  /*
1829  * Cross-platform version of `strncasecmp()`.
1830  */
1831  int mg_ncasecmp(const char *s1, const char *s2, size_t len);
1832 
1833  /*
1834  * Cross-platform version of `strcasecmp()`.
1835  */
1836  int mg_casecmp(const char *s1, const char *s2);
1837 
1838  /*
1839  * Cross-platform version of `strcmp()` where where first string is
1840  * specified by `struct mg_str`.
1841  */
1842  int mg_vcmp(const struct mg_str *str2, const char *str1);
1843 
1844  /*
1845  * Cross-platform version of `strncasecmp()` where first string is
1846  * specified by `struct mg_str`.
1847  */
1848  int mg_vcasecmp(const struct mg_str *str2, const char *str1);
1849 
1850  /*
1851  * Decode base64-encoded string `s`, `len` into the destination `dst`.
1852  * Destination has to have enough space to hold decoded buffer.
1853  * Decoding stops either when all string has been decoded, or invalid
1854  * character appeared.
1855  * Destination is '\0'-terminated.
1856  * Return number of decoded characters. On success, that should be equal to
1857  * `len`. On error (invalid character) the return value is smaller then `len`.
1858  */
1859  int mg_base64_decode(const unsigned char *s, int len, char *dst);
1860 
1861  /*
1862  * Base64-encode chunk of memory `src`, `src_len` into the destination `dst`.
1863  * Destination has to have enough space to hold encoded buffer.
1864  * Destination is '\0'-terminated.
1865  */
1866  void mg_base64_encode(const unsigned char *src, int src_len, char *dst);
1867 
1868 #ifndef MG_DISABLE_FILESYSTEM
1869  /*
1870  * Perform a 64-bit `stat()` call against given file.
1871  *
1872  * `path` should be UTF8 encoded.
1873  *
1874  * Return value is the same as for `stat()` syscall.
1875  */
1876  int mg_stat(const char *path, cs_stat_t *st);
1877 
1878  /*
1879  * Open the given file and return a file stream.
1880  *
1881  * `path` and `mode` should be UTF8 encoded.
1882  *
1883  * Return value is the same as for the `fopen()` call.
1884  */
1885  FILE *mg_fopen(const char *path, const char *mode);
1886 
1887  /*
1888  * Open the given file and return a file stream.
1889  *
1890  * `path` should be UTF8 encoded.
1891  *
1892  * Return value is the same as for the `open()` syscall.
1893  */
1894  int mg_open(const char *path, int flag, int mode);
1895 #endif /* MG_DISABLE_FILESYSTEM */
1896 
1897 #if defined(_WIN32) && !defined(MG_ENABLE_THREADS)
1898 #define MG_ENABLE_THREADS
1899 #endif
1900 
1901 #ifdef MG_ENABLE_THREADS
1902  /*
1903  * Start a new detached thread.
1904  * Arguments and semantic is the same as pthead's `pthread_create()`.
1905  * `thread_func` is a thread function, `thread_func_param` is a parameter
1906  * that is passed to the thread function.
1907  */
1908  void *mg_start_thread(void *(*thread_func)(void *), void *thread_func_param);
1909 #endif
1910 
1911  void mg_set_close_on_exec(sock_t);
1912 
1913 #define MG_SOCK_STRINGIFY_IP 1
1914 #define MG_SOCK_STRINGIFY_PORT 2
1915 #define MG_SOCK_STRINGIFY_REMOTE 4
1916  /*
1917  * Convert connection's local or remote address into string.
1918  *
1919  * The `flags` parameter is a bit mask that controls the behavior,
1920  * see `MG_SOCK_STRINGIFY_*` definitions.
1921  *
1922  * - MG_SOCK_STRINGIFY_IP - print IP address
1923  * - MG_SOCK_STRINGIFY_PORT - print port number
1924  * - MG_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address
1925  *
1926  * If both port number and IP address are printed, they are separated by `:`.
1927  * If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported.
1928  */
1929  void mg_conn_addr_to_str(struct mg_connection *nc, char *buf, size_t len,
1930  int flags);
1931 #ifndef MG_DISABLE_SOCKET_IF /* Legacy interface. */
1932  void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
1933 #endif
1934 
1935  /*
1936  * Convert socket's address into string.
1937  *
1938  * `flags` is MG_SOCK_STRINGIFY_IP and/or MG_SOCK_STRINGIFY_PORT.
1939  */
1940  void mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
1941  int flags);
1942 
1943  /*
1944  * Generates human-readable hexdump of memory chunk.
1945  *
1946  * Takes a memory buffer `buf` of length `len` and creates a hex dump of that
1947  * buffer in `dst`. Generated output is a-la hexdump(1).
1948  * Return length of generated string, excluding terminating `\0`. If returned
1949  * length is bigger than `dst_len`, overflow bytes are discarded.
1950  */
1951  int mg_hexdump(const void *buf, int len, char *dst, int dst_len);
1952 
1953  /*
1954  * Generates human-readable hexdump of the data sent or received by connection.
1955  * `path` is a file name where hexdump should be written. `num_bytes` is
1956  * a number of bytes sent/received. `ev` is one of the `MG_*` events sent to
1957  * an event handler. This function is supposed to be called from the
1958  * event handler.
1959  */
1960  void mg_hexdump_connection(struct mg_connection *nc, const char *path,
1961  const void *buf, int num_bytes, int ev);
1962  /*
1963  * Print message to buffer. If buffer is large enough to hold the message,
1964  * return buffer. If buffer is to small, allocate large enough buffer on heap,
1965  * and return allocated buffer.
1966  * This is a supposed use case:
1967  *
1968  * char buf[5], *p = buf;
1969  * p = mg_avprintf(&p, sizeof(buf), "%s", "hi there");
1970  * use_p_somehow(p);
1971  * if (p != buf) {
1972  * free(p);
1973  * }
1974  *
1975  * The purpose of this is to avoid malloc-ing if generated strings are small.
1976  */
1977  int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
1978 
1979  /*
1980  * Return true if target platform is big endian.
1981  */
1982  int mg_is_big_endian(void);
1983 
1984  /*
1985  * A helper function for traversing a comma separated list of values.
1986  * It returns a list pointer shifted to the next value, or NULL if the end
1987  * of the list found.
1988  * Value is stored in val vector. If value has form "x=y", then eq_val
1989  * vector is initialized to point to the "y" part, and val vector length
1990  * is adjusted to point only to "x".
1991  * If list is just a comma separated list of entries, like "aa,bb,cc" then
1992  * `eq_val` will contain zero-length string.
1993  *
1994  * The purpose of this function is to parse comma separated string without
1995  * any copying/memory allocation.
1996  */
1997  const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
1998  struct mg_str *eq_val);
1999 
2000  /*
2001  * Match 0-terminated string (mg_match_prefix) or string with given length
2002  * mg_match_prefix_n against a glob pattern.
2003  * Match is case-insensitive. Return number of bytes matched, or -1 if no match.
2004  */
2005  int mg_match_prefix(const char *pattern, int pattern_len, const char *str);
2006  int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str);
2007 
2008  /*
2009  * A helper function for creating mg_str struct from plain C string.
2010  * `NULL` is allowed and becomes `{NULL, 0}`.
2011  */
2012  struct mg_str mg_mk_str(const char *s);
2013 
2014  /* Macro for initializing mg_str. */
2015 #define MG_MK_STR(str_literal) \
2016 { str_literal, sizeof(str_literal) - 1 }
2017 
2018 #ifdef __cplusplus
2019 }
2020 #endif /* __cplusplus */
2021 #endif /* CS_MONGOOSE_SRC_UTIL_H_ */
2022 /*
2023  * Copyright (c) 2014 Cesanta Software Limited
2024  * All rights reserved
2025  */
2026 
2027 /*
2028  * === HTTP + Websocket
2029  */
2030 
2031 #ifndef CS_MONGOOSE_SRC_HTTP_H_
2032 #define CS_MONGOOSE_SRC_HTTP_H_
2033 
2034 
2035 #ifdef __cplusplus
2036 extern "C" {
2037 #endif /* __cplusplus */
2038 
2039 #ifndef MG_MAX_HTTP_HEADERS
2040 #define MG_MAX_HTTP_HEADERS 20
2041 #endif
2042 
2043 #ifndef MG_MAX_HTTP_REQUEST_SIZE
2044 #define MG_MAX_HTTP_REQUEST_SIZE 1024
2045 #endif
2046 
2047 #ifndef MG_MAX_PATH
2048 #ifdef PATH_MAX
2049 #define MG_MAX_PATH PATH_MAX
2050 #else
2051 #define MG_MAX_PATH 256
2052 #endif
2053 #endif
2054 
2055 #ifndef MG_MAX_HTTP_SEND_MBUF
2056 #define MG_MAX_HTTP_SEND_MBUF 1024
2057 #endif
2058 
2059 #ifndef MG_WEBSOCKET_PING_INTERVAL_SECONDS
2060 #define MG_WEBSOCKET_PING_INTERVAL_SECONDS 5
2061 #endif
2062 
2063 #ifndef MG_CGI_ENVIRONMENT_SIZE
2064 #define MG_CGI_ENVIRONMENT_SIZE 8192
2065 #endif
2066 
2067 #ifndef MG_MAX_CGI_ENVIR_VARS
2068 #define MG_MAX_CGI_ENVIR_VARS 64
2069 #endif
2070 
2071 #ifndef MG_ENV_EXPORT_TO_CGI
2072 #define MG_ENV_EXPORT_TO_CGI "MONGOOSE_CGI"
2073 #endif
2074 
2075  /* HTTP message */
2076  struct http_message {
2077  struct mg_str message; /* Whole message: request line + headers + body */
2078 
2079  /* HTTP Request line (or HTTP response line) */
2080  struct mg_str method; /* "GET" */
2081  struct mg_str uri; /* "/my_file.html" */
2082  struct mg_str proto; /* "HTTP/1.1" -- for both request and response */
2083 
2084  /* For responses, code and response status message are set */
2087 
2088  /*
2089  * Query-string part of the URI. For example, for HTTP request
2090  * GET /foo/bar?param1=val1&param2=val2
2091  * | uri | query_string |
2092  *
2093  * Note that question mark character doesn't belong neither to the uri,
2094  * nor to the query_string
2095  */
2097 
2098  /* Headers */
2101 
2102  /* Message body */
2103  struct mg_str body; /* Zero-length for requests with no body */
2104  };
2105 
2106  /* WebSocket message */
2108  unsigned char *data;
2109  size_t size;
2110  unsigned char flags;
2111  };
2112 
2113  /* HTTP multipart part */
2115  const char *file_name;
2116  const char *var_name;
2117  struct mg_str data;
2118  int status; /* <0 on error */
2119  void *user_data;
2120  };
2121 
2122  /* HTTP and websocket events. void *ev_data is described in a comment. */
2123 #define MG_EV_HTTP_REQUEST 100 /* struct http_message * */
2124 #define MG_EV_HTTP_REPLY 101 /* struct http_message * */
2125 #define MG_EV_HTTP_CHUNK 102 /* struct http_message * */
2126 #define MG_EV_SSI_CALL 105 /* char * */
2127 
2128 #define MG_EV_WEBSOCKET_HANDSHAKE_REQUEST 111 /* NULL */
2129 #define MG_EV_WEBSOCKET_HANDSHAKE_DONE 112 /* NULL */
2130 #define MG_EV_WEBSOCKET_FRAME 113 /* struct websocket_message * */
2131 #define MG_EV_WEBSOCKET_CONTROL_FRAME 114 /* struct websocket_message * */
2132 
2133 #ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
2134 #define MG_EV_HTTP_MULTIPART_REQUEST 121 /* struct http_message */
2135 #define MG_EV_HTTP_PART_BEGIN 122 /* struct mg_http_multipart_part */
2136 #define MG_EV_HTTP_PART_DATA 123 /* struct mg_http_multipart_part */
2137 #define MG_EV_HTTP_PART_END 124 /* struct mg_http_multipart_part */
2138 #endif
2139 
2140  /*
2141  * Attach built-in HTTP event handler to the given connection.
2142  * User-defined event handler will receive following extra events:
2143  *
2144  * - MG_EV_HTTP_REQUEST: HTTP request has arrived. Parsed HTTP request
2145  * is passed as
2146  * `struct http_message` through the handler's `void *ev_data` pointer.
2147  * - MG_EV_HTTP_MULTIPART_REQUEST: A multipart POST request has received.
2148  * This event is sent before body is parsed. After this user
2149  * should expect a sequence of MG_EV_HTTP_PART_BEGIN/DATA/END requests.
2150  * This is also the last time when headers and other request fields are
2151  * accessible.
2152  * - MG_EV_HTTP_REPLY: HTTP reply has arrived. Parsed HTTP reply is passed as
2153  * `struct http_message` through the handler's `void *ev_data` pointer.
2154  * - MG_EV_HTTP_CHUNK: HTTP chunked-encoding chunk has arrived.
2155  * Parsed HTTP reply is passed as `struct http_message` through the
2156  * handler's `void *ev_data` pointer. `http_message::body` would contain
2157  * incomplete, reassembled HTTP body.
2158  * It will grow with every new chunk arrived, and
2159  * potentially can consume a lot of memory. An event handler may process
2160  * the body as chunks are coming, and signal Mongoose to delete processed
2161  * body by setting `MG_F_DELETE_CHUNK` in `mg_connection::flags`. When
2162  * the last zero chunk is received,
2163  * Mongoose sends `MG_EV_HTTP_REPLY` event with
2164  * full reassembled body (if handler did not signal to delete chunks) or
2165  * with empty body (if handler did signal to delete chunks).
2166  * - MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: server has received websocket handshake
2167  * request. `ev_data` contains parsed HTTP request.
2168  * - MG_EV_WEBSOCKET_HANDSHAKE_DONE: server has completed Websocket handshake.
2169  * `ev_data` is `NULL`.
2170  * - MG_EV_WEBSOCKET_FRAME: new websocket frame has arrived. `ev_data` is
2171  * `struct websocket_message *`
2172  * - MG_EV_HTTP_PART_BEGIN: new part of multipart message is started,
2173  * extra parameters are passed in mg_http_multipart_part
2174  * - MG_EV_HTTP_PART_DATA: new portion of data from multiparted message
2175  * no additional headers are available, only data and data size
2176  * - MG_EV_HTTP_PART_END: final boundary received, analogue to maybe used to
2177  * find the end of packet
2178  * Note: Mongoose should be compiled with MG_ENABLE_HTTP_STREAMING_MULTIPART
2179  * to enable MG_EV_HTTP_MULTIPART_REQUEST, MG_EV_HTTP_REQUEST_END,
2180  * MG_EV_HTTP_REQUEST_CANCEL, MG_EV_HTTP_PART_BEGIN, MG_EV_HTTP_PART_DATA,
2181  * MG_EV_HTTP_PART_END constants
2182  */
2184 
2185  /*
2186  * Send websocket handshake to the server.
2187  *
2188  * `nc` must be a valid connection, connected to a server. `uri` is an URI
2189  * to fetch, extra_headers` is extra HTTP headers to send or `NULL`.
2190  *
2191  * This function is intended to be used by websocket client.
2192  *
2193  * Note that the Host header is mandatory in HTTP/1.1 and must be
2194  * included in `extra_headers`. `mg_send_websocket_handshake2` offers
2195  * a better API for that.
2196  *
2197  * Deprecated in favour of `mg_send_websocket_handshake2`
2198  */
2199  void mg_send_websocket_handshake(struct mg_connection *nc, const char *uri,
2200  const char *extra_headers);
2201 
2202  /*
2203  * Send websocket handshake to the server.
2204  *
2205  * `nc` must be a valid connection, connected to a server. `uri` is an URI
2206  * to fetch, `host` goes into the `Host` header, `protocol` goes into the
2207  * `Sec-WebSocket-Proto` header (NULL to omit), extra_headers` is extra HTTP
2208  * headers to send or `NULL`.
2209  *
2210  * This function is intended to be used by websocket client.
2211  */
2212  void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path,
2213  const char *host, const char *protocol,
2214  const char *extra_headers);
2215 
2216  /*
2217  * Helper function that creates an outbound WebSocket connection.
2218  *
2219  * `url` is a URL to connect to. It must be properly URL-encoded, e.g. have
2220  * no spaces, etc. By default, `mg_connect_ws()` sends Connection and
2221  * Host headers. `extra_headers` is an extra HTTP headers to send, e.g.
2222  * `"User-Agent: my-app\r\n"`.
2223  * If `protocol` is not NULL, then a `Sec-WebSocket-Protocol` header is sent.
2224  *
2225  * Examples:
2226  *
2227  * ```c
2228  * nc1 = mg_connect_ws(mgr, ev_handler_1, "ws://echo.websocket.org", NULL,
2229  * NULL);
2230  * nc2 = mg_connect_ws(mgr, ev_handler_1, "wss://echo.websocket.org", NULL,
2231  * NULL);
2232  * nc3 = mg_connect_ws(mgr, ev_handler_1, "ws://api.cesanta.com",
2233  * "clubby.cesanta.com", NULL);
2234  * ```
2235  */
2236  struct mg_connection *mg_connect_ws(struct mg_mgr *mgr,
2237  mg_event_handler_t event_handler,
2238  const char *url, const char *protocol,
2239  const char *extra_headers);
2240 
2241  /*
2242  * Helper function that creates an outbound WebSocket connection
2243  *
2244  * Mostly identical to mg_connect_ws, but allows to provide extra parameters
2245  * (for example, SSL parameters
2246  */
2247  struct mg_connection *mg_connect_ws_opt(struct mg_mgr *mgr,
2249  struct mg_connect_opts opts,
2250  const char *url, const char *protocol,
2251  const char *extra_headers);
2252 
2253  /*
2254  * Send websocket frame to the remote end.
2255  *
2256  * `op_and_flags` specifies frame's type, one of:
2257  *
2258  * - WEBSOCKET_OP_CONTINUE
2259  * - WEBSOCKET_OP_TEXT
2260  * - WEBSOCKET_OP_BINARY
2261  * - WEBSOCKET_OP_CLOSE
2262  * - WEBSOCKET_OP_PING
2263  * - WEBSOCKET_OP_PONG
2264  *
2265  * Orred with one of the flags:
2266  *
2267  * - WEBSOCKET_DONT_FIN: Don't set the FIN flag on the frame to be sent.
2268  *
2269  * `data` and `data_len` contain frame data.
2270  */
2271  void mg_send_websocket_frame(struct mg_connection *nc, int op_and_flags,
2272  const void *data, size_t data_len);
2273 
2274  /*
2275  * Send multiple websocket frames.
2276  *
2277  * Like `mg_send_websocket_frame()`, but composes a frame from multiple buffers.
2278  */
2279  void mg_send_websocket_framev(struct mg_connection *nc, int op_and_flags,
2280  const struct mg_str *strings, int num_strings);
2281 
2282  /*
2283  * Send websocket frame to the remote end.
2284  *
2285  * Like `mg_send_websocket_frame()`, but allows to create formatted message
2286  * with `printf()`-like semantics.
2287  */
2288  void mg_printf_websocket_frame(struct mg_connection *nc, int op_and_flags,
2289  const char *fmt, ...);
2290 
2291  /*
2292  * Send buffer `buf` of size `len` to the client using chunked HTTP encoding.
2293  * This function first sends buffer size as hex number + newline, then
2294  * buffer itself, then newline. For example,
2295  * `mg_send_http_chunk(nc, "foo", 3)` whill append `3\r\nfoo\r\n` string to
2296  * the `nc->send_mbuf` output IO buffer.
2297  *
2298  * NOTE: HTTP header "Transfer-Encoding: chunked" should be sent prior to
2299  * using this function.
2300  *
2301  * NOTE: do not forget to send empty chunk at the end of the response,
2302  * to tell the client that everything was sent. Example:
2303  *
2304  * ```
2305  * mg_printf_http_chunk(nc, "%s", "my response!");
2306  * mg_send_http_chunk(nc, "", 0); // Tell the client we're finished
2307  * ```
2308  */
2309  void mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len);
2310 
2311  /*
2312  * Send printf-formatted HTTP chunk.
2313  * Functionality is similar to `mg_send_http_chunk()`.
2314  */
2315  void mg_printf_http_chunk(struct mg_connection *nc, const char *fmt, ...);
2316 
2317  /*
2318  * Send response status line.
2319  * If `extra_headers` is not NULL, then `extra_headers` are also sent
2320  * after the reponse line. `extra_headers` must NOT end end with new line.
2321  * Example:
2322  *
2323  * mg_send_response_line(nc, 200, "Access-Control-Allow-Origin: *");
2324  *
2325  * Will result in:
2326  *
2327  * HTTP/1.1 200 OK\r\n
2328  * Access-Control-Allow-Origin: *\r\n
2329  */
2330  void mg_send_response_line(struct mg_connection *c, int status_code,
2331  const char *extra_headers);
2332 
2333  /*
2334  * Send response line and headers.
2335  * This function sends response line with the `status_code`, and automatically
2336  * sends one header: either "Content-Length", or "Transfer-Encoding".
2337  * If `content_length` is negative, then "Transfer-Encoding: chunked" header
2338  * is sent, otherwise, "Content-Length" header is sent.
2339  *
2340  * NOTE: If `Transfer-Encoding` is `chunked`, then message body must be sent
2341  * using `mg_send_http_chunk()` or `mg_printf_http_chunk()` functions.
2342  * Otherwise, `mg_send()` or `mg_printf()` must be used.
2343  * Extra headers could be set through `extra_headers` - and note `extra_headers`
2344  * must NOT be terminated by a new line.
2345  */
2346  void mg_send_head(struct mg_connection *n, int status_code,
2347  int64_t content_length, const char *extra_headers);
2348 
2349  /*
2350  * Send printf-formatted HTTP chunk, escaping HTML tags.
2351  */
2352  void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
2353 
2354  /* Websocket opcodes, from http://tools.ietf.org/html/rfc6455 */
2355 #define WEBSOCKET_OP_CONTINUE 0
2356 #define WEBSOCKET_OP_TEXT 1
2357 #define WEBSOCKET_OP_BINARY 2
2358 #define WEBSOCKET_OP_CLOSE 8
2359 #define WEBSOCKET_OP_PING 9
2360 #define WEBSOCKET_OP_PONG 10
2361 
2362  /*
2363  * If set causes the FIN flag to not be set on outbound
2364  * frames. This enables sending multiple fragments of a single
2365  * logical message.
2366  *
2367  * The WebSocket protocol mandates that if the FIN flag of a data
2368  * frame is not set, the next frame must be a WEBSOCKET_OP_CONTINUE.
2369  * The last frame must have the FIN bit set.
2370  *
2371  * Note that mongoose will automatically defragment incoming messages,
2372  * so this flag is used only on outbound messages.
2373  */
2374 #define WEBSOCKET_DONT_FIN 0x100
2375 
2376  /*
2377  * Parse a HTTP message.
2378  *
2379  * `is_req` should be set to 1 if parsing request, 0 if reply.
2380  *
2381  * Return number of bytes parsed. If HTTP message is
2382  * incomplete, `0` is returned. On parse error, negative number is returned.
2383  */
2384  int mg_parse_http(const char *s, int n, struct http_message *hm, int is_req);
2385 
2386  /*
2387  * Search and return header `name` in parsed HTTP message `hm`.
2388  * If header is not found, NULL is returned. Example:
2389  *
2390  * struct mg_str *host_hdr = mg_get_http_header(hm, "Host");
2391  */
2392  struct mg_str *mg_get_http_header(struct http_message *hm, const char *name);
2393 
2394  /*
2395  * Parse HTTP header `hdr`. Find variable `var_name` and store it's value
2396  * in the buffer `buf`, `buf_size`. Return 0 if variable not found, non-zero
2397  * otherwise.
2398  *
2399  * This function is supposed to parse
2400  * cookies, authentication headers, etcetera. Example (error handling omitted):
2401  *
2402  * char user[20];
2403  * struct mg_str *hdr = mg_get_http_header(hm, "Authorization");
2404  * mg_http_parse_header(hdr, "username", user, sizeof(user));
2405  *
2406  * Return length of the variable's value. If buffer is not large enough,
2407  * or variable not found, 0 is returned.
2408  */
2409  int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,
2410  size_t buf_size);
2411 
2412  /*
2413  * Parse buffer `buf`, `buf_len` that contains multipart form data chunks.
2414  * Store chunk name in a `var_name`, `var_name_len` buffer.
2415  * If a chunk is an uploaded file, then `file_name`, `file_name_len` is
2416  * filled with an uploaded file name. `chunk`, `chunk_len`
2417  * points to the chunk data.
2418  *
2419  * Return: number of bytes to skip to the next chunk, or 0 if there are
2420  * no more chunks.
2421  *
2422  * Usage example:
2423  *
2424  * ```c
2425  * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
2426  * switch(ev) {
2427  * case MG_EV_HTTP_REQUEST: {
2428  * struct http_message *hm = (struct http_message *) ev_data;
2429  * char var_name[100], file_name[100];
2430  * const char *chunk;
2431  * size_t chunk_len, n1, n2;
2432  *
2433  * n1 = n2 = 0;
2434  * while ((n2 = mg_parse_multipart(hm->body.p + n1,
2435  * hm->body.len - n1,
2436  * var_name, sizeof(var_name),
2437  * file_name, sizeof(file_name),
2438  * &chunk, &chunk_len)) > 0) {
2439  * printf("var: %s, file_name: %s, size: %d, chunk: [%.*s]\n",
2440  * var_name, file_name, (int) chunk_len,
2441  * (int) chunk_len, chunk);
2442  * n1 += n2;
2443  * }
2444  * }
2445  * break;
2446  * ```
2447  */
2448  size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
2449  size_t var_name_len, char *file_name,
2450  size_t file_name_len, const char **chunk,
2451  size_t *chunk_len);
2452 
2453  /*
2454  * Fetch an HTTP form variable.
2455  *
2456  * Fetch a variable `name` from a `buf` into a buffer specified by
2457  * `dst`, `dst_len`. Destination is always zero-terminated. Return length
2458  * of a fetched variable. If not found, 0 is returned. `buf` must be
2459  * valid url-encoded buffer. If destination is too small, `-1` is returned.
2460  */
2461  int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst,
2462  size_t dst_len);
2463 
2464  /*
2465  * Decode URL-encoded string.
2466  *
2467  * Source string is specified by (`src`, `src_len`), and destination is
2468  * (`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then
2469  * `+` character is decoded as a blank space character. This function
2470  * guarantees to `\0`-terminate the destination. If destination is too small,
2471  * then source string is partially decoded and `-1` is returned. Otherwise,
2472  * a length of decoded string is returned, not counting final `\0`.
2473  */
2474  int mg_url_decode(const char *src, int src_len, char *dst, int dst_len,
2475  int is_form_url_encoded);
2476 
2477  /* Create Digest authentication header for client request. */
2478  int mg_http_create_digest_auth_header(char *buf, size_t buf_len,
2479  const char *method, const char *uri,
2480  const char *auth_domain, const char *user,
2481  const char *passwd);
2482 
2483  /*
2484  * Helper function that creates outbound HTTP connection.
2485  *
2486  * `url` is a URL to fetch. It must be properly URL-encoded, e.g. have
2487  * no spaces, etc. By default, `mg_connect_http()` sends Connection and
2488  * Host headers. `extra_headers` is an extra HTTP headers to send, e.g.
2489  * `"User-Agent: my-app\r\n"`.
2490  * If `post_data` is NULL, then GET request is created. Otherwise, POST request
2491  * is created with the specified POST data. Note that if the data being posted
2492  * is a form submission, the `Content-Type` header should be set accordingly
2493  * (see example below).
2494  *
2495  * Examples:
2496  *
2497  * ```c
2498  * nc1 = mg_connect_http(mgr, ev_handler_1, "http://www.google.com", NULL,
2499  * NULL);
2500  * nc2 = mg_connect_http(mgr, ev_handler_1, "https://github.com", NULL, NULL);
2501  * nc3 = mg_connect_http(
2502  * mgr, ev_handler_1, "my_server:8000/form_submit/",
2503  * "Content-Type: application/x-www-form-urlencoded\r\n",
2504  * "var_1=value_1&var_2=value_2");
2505  * ```
2506  */
2507  struct mg_connection *mg_connect_http(struct mg_mgr *mgr,
2508  mg_event_handler_t event_handler,
2509  const char *url,
2510  const char *extra_headers,
2511  const char *post_data);
2512 
2513  /*
2514  * Helper function that creates outbound HTTP connection.
2515  *
2516  * Mostly identical to mg_connect_http, but allows to provide extra parameters
2517  * (for example, SSL parameters
2518  */
2519  struct mg_connection *mg_connect_http_opt(struct mg_mgr *mgr,
2521  struct mg_connect_opts opts,
2522  const char *url,
2523  const char *extra_headers,
2524  const char *post_data);
2525  /*
2526  * This structure defines how `mg_serve_http()` works.
2527  * Best practice is to set only required settings, and leave the rest as NULL.
2528  */
2530  /* Path to web root directory */
2531  const char *document_root;
2532 
2533  /* List of index files. Default is "" */
2534  const char *index_files;
2535 
2536  /*
2537  * Leave as NULL to disable authentication.
2538  * To enable directory protection with authentication, set this to ".htpasswd"
2539  * Then, creating ".htpasswd" file in any directory automatically protects
2540  * it with digest authentication.
2541  * Use `mongoose` web server binary, or `htdigest` Apache utility to
2542  * create/manipulate passwords file.
2543  * Make sure `auth_domain` is set to a valid domain name.
2544  */
2546 
2547  /* Authorization domain (domain name of this web server) */
2548  const char *auth_domain;
2549 
2550  /*
2551  * Leave as NULL to disable authentication.
2552  * Normally, only selected directories in the document root are protected.
2553  * If absolutely every access to the web server needs to be authenticated,
2554  * regardless of the URI, set this option to the path to the passwords file.
2555  * Format of that file is the same as ".htpasswd" file. Make sure that file
2556  * is located outside document root to prevent people fetching it.
2557  */
2558  const char *global_auth_file;
2559 
2560  /* Set to "no" to disable directory listing. Enabled by default. */
2562 
2563  /* SSI files pattern. If not set, "**.shtml$|**.shtm$" is used. */
2564  const char *ssi_pattern;
2565 
2566  /* IP ACL. By default, NULL, meaning all IPs are allowed to connect */
2567  const char *ip_acl;
2568 
2569  /* URL rewrites.
2570  *
2571  * Comma-separated list of `uri_pattern=file_or_directory_path` rewrites.
2572  * When HTTP request is received, Mongoose constructs a file name from the
2573  * requested URI by combining `document_root` and the URI. However, if the
2574  * rewrite option is used and `uri_pattern` matches requested URI, then
2575  * `document_root` is ignored. Instead, `file_or_directory_path` is used,
2576  * which should be a full path name or a path relative to the web server's
2577  * current working directory. Note that `uri_pattern`, as all Mongoose
2578  * patterns, is a prefix pattern.
2579  *
2580  * If uri_pattern starts with `@` symbol, then Mongoose compares it with the
2581  * HOST header of the request. If they are equal, Mongoose sets document root
2582  * to `file_or_directory_path`, implementing virtual hosts support.
2583  * Example: `@foo.com=/document/root/for/foo.com`
2584  *
2585  * If `uri_pattern` starts with `%` symbol, then Mongoose compares it with
2586  * the listening port. If they match, then Mongoose issues a 301 redirect.
2587  * For example, to redirect all HTTP requests to the
2588  * HTTPS port, do `%80=https://my.site.com`. Note that the request URI is
2589  * automatically appended to the redirect location.
2590  */
2591  const char *url_rewrites;
2592 
2593  /* DAV document root. If NULL, DAV requests are going to fail. */
2594  const char *dav_document_root;
2595 
2596  /*
2597  * DAV passwords file. If NULL, DAV requests are going to fail.
2598  * If passwords file is set to "-", then DAV auth is disabled.
2599  */
2600  const char *dav_auth_file;
2601 
2602  /* Glob pattern for the files to hide. */
2603  const char *hidden_file_pattern;
2604 
2605  /* Set to non-NULL to enable CGI, e.g. **.cgi$|**.php$" */
2606  const char *cgi_file_pattern;
2607 
2608  /* If not NULL, ignore CGI script hashbang and use this interpreter */
2609  const char *cgi_interpreter;
2610 
2611  /*
2612  * Comma-separated list of Content-Type overrides for path suffixes, e.g.
2613  * ".txt=text/plain; charset=utf-8,.c=text/plain"
2614  */
2615  const char *custom_mime_types;
2616 
2617  /*
2618  * Extra HTTP headers to add to each server response.
2619  * Example: to enable CORS, set this to "Access-Control-Allow-Origin: *".
2620  */
2621  const char *extra_headers;
2622  };
2623 
2624  /*
2625  * Serve given HTTP request according to the `options`.
2626  *
2627  * Example code snippet:
2628  *
2629  * ```c
2630  * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
2631  * struct http_message *hm = (struct http_message *) ev_data;
2632  * struct mg_serve_http_opts opts = { .document_root = "/var/www" }; // C99
2633  *
2634  * switch (ev) {
2635  * case MG_EV_HTTP_REQUEST:
2636  * mg_serve_http(nc, hm, opts);
2637  * break;
2638  * default:
2639  * break;
2640  * }
2641  * }
2642  * ```
2643  */
2644  void mg_serve_http(struct mg_connection *nc, struct http_message *hm,
2645  struct mg_serve_http_opts opts);
2646 
2647  /*
2648  * Register callback for specified http endpoint
2649  * Note: if callback is registered it is called instead of
2650  * callback provided in mg_bind
2651  *
2652  * Example code snippet:
2653  *
2654  * ```c
2655  * static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
2656  * (void) ev; (void) ev_data;
2657  * mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello1]");
2658  * nc->flags |= MG_F_SEND_AND_CLOSE;
2659  * }
2660  *
2661  * static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
2662  * (void) ev; (void) ev_data;
2663  * mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello2]");
2664  * nc->flags |= MG_F_SEND_AND_CLOSE;
2665  * }
2666  *
2667  * void init() {
2668  * nc = mg_bind(&mgr, local_addr, cb1);
2669  * mg_register_http_endpoint(nc, "/hello1", handle_hello1);
2670  * mg_register_http_endpoint(nc, "/hello1/hello2", handle_hello2);
2671  * }
2672  * ```
2673  */
2674  void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,
2676 
2677 #ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
2678 
2679  /* Callback prototype for `mg_file_upload_handler()`. */
2680  typedef struct mg_str (*mg_fu_fname_fn)(struct mg_connection *nc,
2681  struct mg_str fname);
2682 
2683  /*
2684  * File upload handler.
2685  * This handler can be used to implement file uploads with minimum code.
2686  * This handler will process MG_EV_HTTP_PART_* events and store file data into
2687  * a local file.
2688  * `local_name_fn` will be invoked with whatever name was provided by the client
2689  * and will expect the name of the local file to open. Return value of NULL will
2690  * abort file upload (client will get a "403 Forbidden" response). If non-null,
2691  * the returned string must be heap-allocated and will be freed by the caller.
2692  * Exception: it is ok to return the same string verbatim.
2693  *
2694  * Example:
2695  *
2696  * ```c
2697  * struct mg_str upload_fname(struct mg_connection *nc, struct mg_str fname) {
2698  * // Just return the same filename. Do not actually do this except in test!
2699  * // fname is user-controlled and needs to be sanitized.
2700  * return fname;
2701  * }
2702  * void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
2703  * switch (ev) {
2704  * ...
2705  * case MG_EV_HTTP_PART_BEGIN:
2706  * case MG_EV_HTTP_PART_DATA:
2707  * case MG_EV_HTTP_PART_END:
2708  * mg_file_upload_handler(nc, ev, ev_data, upload_fname);
2709  * break;
2710  * }
2711  * }
2712  * ```
2713  */
2714  void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
2715  mg_fu_fname_fn local_name_fn);
2716 #endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */
2717 
2718  /*
2719  * Authenticate HTTP request against opened passwords file.
2720  * Returns 1 if authenticated, 0 otherwise.
2721  */
2722  int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain,
2723  FILE *fp);
2724 
2725 #ifdef __cplusplus
2726 }
2727 #endif /* __cplusplus */
2728 #endif /* CS_MONGOOSE_SRC_HTTP_H_ */
2729 /*
2730  * Copyright (c) 2014 Cesanta Software Limited
2731  * All rights reserved
2732  */
2733 
2734 /*
2735  * === JSON-RPC
2736  */
2737 
2738 #ifndef CS_MONGOOSE_SRC_JSON_RPC_H_
2739 #define CS_MONGOOSE_SRC_JSON_RPC_H_
2740 
2741 #ifdef __cplusplus
2742 extern "C" {
2743 #endif /* __cplusplus */
2744 
2745  /* JSON-RPC request */
2747  struct json_token *message; /* Whole RPC message */
2748  struct json_token *id; /* Message ID */
2749  struct json_token *method; /* Method name */
2750  struct json_token *params; /* Method params */
2751  };
2752 
2753  /* JSON-RPC response */
2754  struct mg_rpc_reply {
2755  struct json_token *message; /* Whole RPC message */
2756  struct json_token *id; /* Message ID */
2757  struct json_token *result; /* Remote call result */
2758  };
2759 
2760  /* JSON-RPC error */
2761  struct mg_rpc_error {
2762  struct json_token *message; /* Whole RPC message */
2763  struct json_token *id; /* Message ID */
2764  struct json_token *error_code; /* error.code */
2765  struct json_token *error_message; /* error.message */
2766  struct json_token *error_data; /* error.data, can be NULL */
2767  };
2768 
2769  /*
2770  * Parse JSON-RPC reply contained in `buf`, `len` into JSON tokens array
2771  * `toks`, `max_toks`. If buffer contains valid reply, `reply` structure is
2772  * populated. The result of RPC call is located in `reply.result`. On error,
2773  * `error` structure is populated. Returns: the result of calling
2774  * `parse_json(buf, len, toks, max_toks)`:
2775  *
2776  * On success, an offset inside `json_string` is returned
2777  * where parsing has finished. On failure, a negative number is
2778  * returned, one of:
2779  *
2780  * - `#define JSON_STRING_INVALID -1`
2781  * - `#define JSON_STRING_INCOMPLETE -2`
2782  * - `#define JSON_TOKEN_ARRAY_TOO_SMALL -3`
2783  */
2784  int mg_rpc_parse_reply(const char *buf, int len, struct json_token *toks,
2785  int max_toks, struct mg_rpc_reply *,
2786  struct mg_rpc_error *);
2787 
2788  /*
2789  * Create JSON-RPC request in a given buffer.
2790  *
2791  * Return length of the request, which
2792  * can be larger then `len` that indicates an overflow.
2793  * `params_fmt` format string should conform to `json_emit()` API,
2794  * see https://github.com/cesanta/frozen
2795  */
2796  int mg_rpc_create_request(char *buf, int len, const char *method,
2797  const char *id, const char *params_fmt, ...);
2798 
2799  /*
2800  * Create JSON-RPC reply in a given buffer.
2801  *
2802  * Return length of the reply, which
2803  * can be larger then `len` that indicates an overflow.
2804  * `result_fmt` format string should conform to `json_emit()` API,
2805  * see https://github.com/cesanta/frozen
2806  */
2807  int mg_rpc_create_reply(char *buf, int len, const struct mg_rpc_request *req,
2808  const char *result_fmt, ...);
2809 
2810  /*
2811  * Create JSON-RPC error reply in a given buffer.
2812  *
2813  * Return length of the error, which
2814  * can be larger then `len` that indicates an overflow.
2815  * `fmt` format string should conform to `json_emit()` API,
2816  * see https://github.com/cesanta/frozen
2817  */
2818  int mg_rpc_create_error(char *buf, int len, struct mg_rpc_request *req,
2819  int code, const char *message, const char *fmt, ...);
2820 
2821  /* JSON-RPC standard error codes */
2822 #define JSON_RPC_PARSE_ERROR (-32700)
2823 #define JSON_RPC_INVALID_REQUEST_ERROR (-32600)
2824 #define JSON_RPC_METHOD_NOT_FOUND_ERROR (-32601)
2825 #define JSON_RPC_INVALID_PARAMS_ERROR (-32602)
2826 #define JSON_RPC_INTERNAL_ERROR (-32603)
2827 #define JSON_RPC_SERVER_ERROR (-32000)
2828 
2829  /*
2830  * Create JSON-RPC error in a given buffer.
2831  *
2832  * Return length of the error, which
2833  * can be larger then `len` that indicates an overflow. See
2834  * JSON_RPC_*_ERROR definitions for standard error values:
2835  *
2836  * - `#define JSON_RPC_PARSE_ERROR (-32700)`
2837  * - `#define JSON_RPC_INVALID_REQUEST_ERROR (-32600)`
2838  * - `#define JSON_RPC_METHOD_NOT_FOUND_ERROR (-32601)`
2839  * - `#define JSON_RPC_INVALID_PARAMS_ERROR (-32602)`
2840  * - `#define JSON_RPC_INTERNAL_ERROR (-32603)`
2841  * - `#define JSON_RPC_SERVER_ERROR (-32000)`
2842  */
2843  int mg_rpc_create_std_error(char *buf, int len, struct mg_rpc_request *req,
2844  int code);
2845 
2846  typedef int (*mg_rpc_handler_t)(char *buf, int len, struct mg_rpc_request *req);
2847 
2848  /*
2849  * Dispatches a JSON-RPC request.
2850  *
2851  * Parses JSON-RPC request contained in `buf`, `len`.
2852  * Then, dispatches the request to the correct handler method.
2853  * Valid method names should be specified in NULL
2854  * terminated array `methods`, and corresponding handlers in `handlers`.
2855  * Result is put in `dst`, `dst_len`. Return: length of the result, which
2856  * can be larger then `dst_len` that indicates an overflow.
2857  * Overflown bytes are not written to the buffer.
2858  * If method is not found, an error is automatically generated.
2859  */
2860  int mg_rpc_dispatch(const char *buf, int, char *dst, int dst_len,
2861  const char **methods, mg_rpc_handler_t *handlers);
2862 
2863 #ifdef __cplusplus
2864 }
2865 #endif /* __cplusplus */
2866 #endif /* CS_MONGOOSE_SRC_JSON_RPC_H_ */
2867 /*
2868  * Copyright (c) 2014 Cesanta Software Limited
2869  * All rights reserved
2870  * This software is dual-licensed: you can redistribute it and/or modify
2871  * it under the terms of the GNU General Public License version 2 as
2872  * published by the Free Software Foundation. For the terms of this
2873  * license, see <http://www.gnu.org/licenses/>.
2874  *
2875  * You are free to use this software under the terms of the GNU General
2876  * Public License, but WITHOUT ANY WARRANTY; without even the implied
2877  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
2878  * See the GNU General Public License for more details.
2879  *
2880  * Alternatively, you can license this software under a commercial
2881  * license, as set out in <https://www.cesanta.com/license>.
2882  */
2883 
2884 /*
2885  * === MQTT
2886  */
2887 
2888 #ifndef CS_MONGOOSE_SRC_MQTT_H_
2889 #define CS_MONGOOSE_SRC_MQTT_H_
2890 
2891 
2893  int cmd;
2894  struct mg_str payload;
2895  int qos;
2896  uint8_t connack_ret_code; /* connack */
2897  uint16_t message_id; /* puback */
2898  char *topic;
2899 };
2900 
2902  const char *topic;
2903  uint8_t qos;
2904 };
2905 
2907  unsigned char flags; /* connection flags */
2908  uint16_t keep_alive;
2909  const char *will_topic;
2910  const char *will_message;
2911  const char *user_name;
2912  const char *password;
2913 };
2914 
2915 /* Message types */
2916 #define MG_MQTT_CMD_CONNECT 1
2917 #define MG_MQTT_CMD_CONNACK 2
2918 #define MG_MQTT_CMD_PUBLISH 3
2919 #define MG_MQTT_CMD_PUBACK 4
2920 #define MG_MQTT_CMD_PUBREC 5
2921 #define MG_MQTT_CMD_PUBREL 6
2922 #define MG_MQTT_CMD_PUBCOMP 7
2923 #define MG_MQTT_CMD_SUBSCRIBE 8
2924 #define MG_MQTT_CMD_SUBACK 9
2925 #define MG_MQTT_CMD_UNSUBSCRIBE 10
2926 #define MG_MQTT_CMD_UNSUBACK 11
2927 #define MG_MQTT_CMD_PINGREQ 12
2928 #define MG_MQTT_CMD_PINGRESP 13
2929 #define MG_MQTT_CMD_DISCONNECT 14
2930 
2931 /* MQTT event types */
2932 #define MG_MQTT_EVENT_BASE 200
2933 #define MG_EV_MQTT_CONNECT (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_CONNECT)
2934 #define MG_EV_MQTT_CONNACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_CONNACK)
2935 #define MG_EV_MQTT_PUBLISH (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBLISH)
2936 #define MG_EV_MQTT_PUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBACK)
2937 #define MG_EV_MQTT_PUBREC (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBREC)
2938 #define MG_EV_MQTT_PUBREL (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBREL)
2939 #define MG_EV_MQTT_PUBCOMP (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBCOMP)
2940 #define MG_EV_MQTT_SUBSCRIBE (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_SUBSCRIBE)
2941 #define MG_EV_MQTT_SUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_SUBACK)
2942 #define MG_EV_MQTT_UNSUBSCRIBE (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_UNSUBSCRIBE)
2943 #define MG_EV_MQTT_UNSUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_UNSUBACK)
2944 #define MG_EV_MQTT_PINGREQ (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PINGREQ)
2945 #define MG_EV_MQTT_PINGRESP (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PINGRESP)
2946 #define MG_EV_MQTT_DISCONNECT (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_DISCONNECT)
2947 
2948 /* Message flags */
2949 #define MG_MQTT_RETAIN 0x1
2950 #define MG_MQTT_DUP 0x4
2951 #define MG_MQTT_QOS(qos) ((qos) << 1)
2952 #define MG_MQTT_GET_QOS(flags) (((flags) &0x6) >> 1)
2953 #define MG_MQTT_SET_QOS(flags, qos) (flags) = ((flags) & ~0x6) | ((qos) << 1)
2954 
2955 /* Connection flags */
2956 #define MG_MQTT_CLEAN_SESSION 0x02
2957 #define MG_MQTT_HAS_WILL 0x04
2958 #define MG_MQTT_WILL_RETAIN 0x20
2959 #define MG_MQTT_HAS_PASSWORD 0x40
2960 #define MG_MQTT_HAS_USER_NAME 0x80
2961 #define MG_MQTT_GET_WILL_QOS(flags) (((flags) &0x18) >> 3)
2962 #define MG_MQTT_SET_WILL_QOS(flags, qos) \
2963 (flags) = ((flags) & ~0x18) | ((qos) << 3)
2964 
2965 /* CONNACK return codes */
2966 #define MG_EV_MQTT_CONNACK_ACCEPTED 0
2967 #define MG_EV_MQTT_CONNACK_UNACCEPTABLE_VERSION 1
2968 #define MG_EV_MQTT_CONNACK_IDENTIFIER_REJECTED 2
2969 #define MG_EV_MQTT_CONNACK_SERVER_UNAVAILABLE 3
2970 #define MG_EV_MQTT_CONNACK_BAD_AUTH 4
2971 #define MG_EV_MQTT_CONNACK_NOT_AUTHORIZED 5
2972 
2973 #ifdef __cplusplus
2974 extern "C" {
2975 #endif /* __cplusplus */
2976 
2977  /*
2978  * Attach built-in MQTT event handler to the given connection.
2979  *
2980  * The user-defined event handler will receive following extra events:
2981  *
2982  * - MG_EV_MQTT_CONNACK
2983  * - MG_EV_MQTT_PUBLISH
2984  * - MG_EV_MQTT_PUBACK
2985  * - MG_EV_MQTT_PUBREC
2986  * - MG_EV_MQTT_PUBREL
2987  * - MG_EV_MQTT_PUBCOMP
2988  * - MG_EV_MQTT_SUBACK
2989  */
2990  void mg_set_protocol_mqtt(struct mg_connection *nc);
2991 
2992  /* Send MQTT handshake. */
2993  void mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id);
2994 
2995  /* Send MQTT handshake with optional parameters. */
2996  void mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id,
2998 
2999  /* Publish a message to a given topic. */
3000  void mg_mqtt_publish(struct mg_connection *nc, const char *topic,
3001  uint16_t message_id, int flags, const void *data,
3002  size_t len);
3003 
3004  /* Subscribe to a bunch of topics. */
3005  void mg_mqtt_subscribe(struct mg_connection *nc,
3006  const struct mg_mqtt_topic_expression *topics,
3007  size_t topics_len, uint16_t message_id);
3008 
3009  /* Unsubscribe from a bunch of topics. */
3010  void mg_mqtt_unsubscribe(struct mg_connection *nc, char **topics,
3011  size_t topics_len, uint16_t message_id);
3012 
3013  /* Send a DISCONNECT command. */
3014  void mg_mqtt_disconnect(struct mg_connection *nc);
3015 
3016  /* Send a CONNACK command with a given `return_code`. */
3017  void mg_mqtt_connack(struct mg_connection *nc, uint8_t return_code);
3018 
3019  /* Send a PUBACK command with a given `message_id`. */
3020  void mg_mqtt_puback(struct mg_connection *nc, uint16_t message_id);
3021 
3022  /* Send a PUBREC command with a given `message_id`. */
3023  void mg_mqtt_pubrec(struct mg_connection *nc, uint16_t message_id);
3024 
3025  /* Send a PUBREL command with a given `message_id`. */
3026  void mg_mqtt_pubrel(struct mg_connection *nc, uint16_t message_id);
3027 
3028  /* Send a PUBCOMP command with a given `message_id`. */
3029  void mg_mqtt_pubcomp(struct mg_connection *nc, uint16_t message_id);
3030 
3031  /*
3032  * Send a SUBACK command with a given `message_id`
3033  * and a sequence of granted QoSs.
3034  */
3035  void mg_mqtt_suback(struct mg_connection *nc, uint8_t *qoss, size_t qoss_len,
3036  uint16_t message_id);
3037 
3038  /* Send a UNSUBACK command with a given `message_id`. */
3039  void mg_mqtt_unsuback(struct mg_connection *nc, uint16_t message_id);
3040 
3041  /* Send a PINGREQ command. */
3042  void mg_mqtt_ping(struct mg_connection *nc);
3043 
3044  /* Send a PINGRESP command. */
3045  void mg_mqtt_pong(struct mg_connection *nc);
3046 
3047  /*
3048  * Extract the next topic expression from a SUBSCRIBE command payload.
3049  *
3050  * Topic expression name will point to a string in the payload buffer.
3051  * Return the pos of the next topic expression or -1 when the list
3052  * of topics is exhausted.
3053  */
3055  struct mg_str *topic, uint8_t *qos, int pos);
3056 
3057 #ifdef __cplusplus
3058 }
3059 #endif /* __cplusplus */
3060 
3061 #endif /* CS_MONGOOSE_SRC_MQTT_H_ */
3062 /*
3063  * Copyright (c) 2014 Cesanta Software Limited
3064  * All rights reserved
3065  * This software is dual-licensed: you can redistribute it and/or modify
3066  * it under the terms of the GNU General Public License version 2 as
3067  * published by the Free Software Foundation. For the terms of this
3068  * license, see <http://www.gnu.org/licenses/>.
3069  *
3070  * You are free to use this software under the terms of the GNU General
3071  * Public License, but WITHOUT ANY WARRANTY; without even the implied
3072  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
3073  * See the GNU General Public License for more details.
3074  *
3075  * Alternatively, you can license this software under a commercial
3076  * license, as set out in <https://www.cesanta.com/license>.
3077  */
3078 
3079 /*
3080  * === MQTT Broker
3081  */
3082 
3083 #ifndef CS_MONGOOSE_SRC_MQTT_BROKER_H_
3084 #define CS_MONGOOSE_SRC_MQTT_BROKER_H_
3085 
3086 #ifdef MG_ENABLE_MQTT_BROKER
3087 
3088 
3089 #ifdef __cplusplus
3090 extern "C" {
3091 #endif /* __cplusplus */
3092 
3093 #define MG_MQTT_MAX_SESSION_SUBSCRIPTIONS 512;
3094 
3095  struct mg_mqtt_broker;
3096 
3097  /* MQTT session (Broker side). */
3098  struct mg_mqtt_session {
3099  struct mg_mqtt_broker *brk; /* Broker */
3100  struct mg_mqtt_session *next, *prev; /* mg_mqtt_broker::sessions linkage */
3101  struct mg_connection *nc; /* Connection with the client */
3102  size_t num_subscriptions; /* Size of `subscriptions` array */
3103  struct mg_mqtt_topic_expression *subscriptions;
3104  void *user_data; /* User data */
3105  };
3106 
3107  /* MQTT broker. */
3108  struct mg_mqtt_broker {
3109  struct mg_mqtt_session *sessions; /* Session list */
3110  void *user_data; /* User data */
3111  };
3112 
3113  /* Initialize a MQTT broker. */
3114  void mg_mqtt_broker_init(struct mg_mqtt_broker *brk, void *user_data);
3115 
3116  /*
3117  * Process a MQTT broker message.
3118  *
3119  * Listening connection expects a pointer to an initialized `mg_mqtt_broker`
3120  * structure in the `user_data` field.
3121  *
3122  * Basic usage:
3123  *
3124  * ```c
3125  * mg_mqtt_broker_init(&brk, NULL);
3126  *
3127  * if ((nc = mg_bind(&mgr, address, mg_mqtt_broker)) == NULL) {
3128  * // fail;
3129  * }
3130  * nc->user_data = &brk;
3131  * ```
3132  *
3133  * New incoming connections will receive a `mg_mqtt_session` structure
3134  * in the connection `user_data`. The original `user_data` will be stored
3135  * in the `user_data` field of the session structure. This allows the user
3136  * handler to store user data before `mg_mqtt_broker` creates the session.
3137  *
3138  * Since only the MG_EV_ACCEPT message is processed by the listening socket,
3139  * for most events the `user_data` will thus point to a `mg_mqtt_session`.
3140  */
3141  void mg_mqtt_broker(struct mg_connection *brk, int ev, void *data);
3142 
3143  /*
3144  * Iterate over all mqtt sessions connections. Example:
3145  *
3146  * ```c
3147  * struct mg_mqtt_session *s;
3148  * for (s = mg_mqtt_next(brk, NULL); s != NULL; s = mg_mqtt_next(brk, s)) {
3149  * // Do something
3150  * }
3151  * ```
3152  */
3153  struct mg_mqtt_session *mg_mqtt_next(struct mg_mqtt_broker *brk,
3154  struct mg_mqtt_session *s);
3155 
3156 #ifdef __cplusplus
3157 }
3158 #endif /* __cplusplus */
3159 
3160 #endif /* MG_ENABLE_MQTT_BROKER */
3161 #endif /* CS_MONGOOSE_SRC_MQTT_BROKER_H_ */
3162 /*
3163  * Copyright (c) 2014 Cesanta Software Limited
3164  * All rights reserved
3165  */
3166 
3167 /*
3168  * === DNS
3169  */
3170 
3171 #ifndef CS_MONGOOSE_SRC_DNS_H_
3172 #define CS_MONGOOSE_SRC_DNS_H_
3173 
3174 
3175 #ifdef __cplusplus
3176 extern "C" {
3177 #endif /* __cplusplus */
3178 
3179 #define MG_DNS_A_RECORD 0x01 /* Lookup IP address */
3180 #define MG_DNS_CNAME_RECORD 0x05 /* Lookup CNAME */
3181 #define MG_DNS_AAAA_RECORD 0x1c /* Lookup IPv6 address */
3182 #define MG_DNS_MX_RECORD 0x0f /* Lookup mail server for domain */
3183 
3184 #define MG_MAX_DNS_QUESTIONS 32
3185 #define MG_MAX_DNS_ANSWERS 32
3186 
3187 #define MG_DNS_MESSAGE 100 /* High-level DNS message event */
3188 
3193  };
3194 
3195  /* DNS resource record. */
3197  struct mg_str name; /* buffer with compressed name */
3198  int rtype;
3199  int rclass;
3200  int ttl;
3202  struct mg_str rdata; /* protocol data (can be a compressed name) */
3203  };
3204 
3205  /* DNS message (request and response). */
3207  struct mg_str pkt; /* packet body */
3208  uint16_t flags;
3209  uint16_t transaction_id;
3214  };
3215 
3217  struct mg_dns_message *msg, int query, struct mg_dns_resource_record *prev);
3218 
3219  /*
3220  * Parse the record data from a DNS resource record.
3221  *
3222  * - A: struct in_addr *ina
3223  * - AAAA: struct in6_addr *ina
3224  * - CNAME: char buffer
3225  *
3226  * Returns -1 on error.
3227  *
3228  * TODO(mkm): MX
3229  */
3231  struct mg_dns_resource_record *rr, void *data,
3232  size_t data_len);
3233 
3234  /*
3235  * Send a DNS query to the remote end.
3236  */
3237  void mg_send_dns_query(struct mg_connection *nc, const char *name,
3238  int query_type);
3239 
3240  /*
3241  * Insert a DNS header to an IO buffer.
3242  *
3243  * Return number of bytes inserted.
3244  */
3245  int mg_dns_insert_header(struct mbuf *io, size_t pos,
3246  struct mg_dns_message *msg);
3247 
3248  /*
3249  * Append already encoded questions from an existing message.
3250  *
3251  * This is useful when generating a DNS reply message which includes
3252  * all question records.
3253  *
3254  * Return number of appened bytes.
3255  */
3256  int mg_dns_copy_questions(struct mbuf *io, struct mg_dns_message *msg);
3257 
3258  /*
3259  * Encode and append a DNS resource record to an IO buffer.
3260  *
3261  * The record metadata is taken from the `rr` parameter, while the name and data
3262  * are taken from the parameters, encoded in the appropriate format depending on
3263  * record type, and stored in the IO buffer. The encoded values might contain
3264  * offsets within the IO buffer. It's thus important that the IO buffer doesn't
3265  * get trimmed while a sequence of records are encoded while preparing a DNS
3266  *reply.
3267  *
3268  * This function doesn't update the `name` and `rdata` pointers in the `rr`
3269  *struct
3270  * because they might be invalidated as soon as the IO buffer grows again.
3271  *
3272  * Return the number of bytes appened or -1 in case of error.
3273  */
3274  int mg_dns_encode_record(struct mbuf *io, struct mg_dns_resource_record *rr,
3275  const char *name, size_t nlen, const void *rdata,
3276  size_t rlen);
3277 
3278  /* Low-level: parses a DNS response. */
3279  int mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg);
3280 
3281  /*
3282  * Uncompress a DNS compressed name.
3283  *
3284  * The containing dns message is required because the compressed encoding
3285  * and reference suffixes present elsewhere in the packet.
3286  *
3287  * If name is less than `dst_len` characters long, the remainder
3288  * of `dst` is terminated with `\0' characters. Otherwise, `dst` is not
3289  *terminated.
3290  *
3291  * If `dst_len` is 0 `dst` can be NULL.
3292  * Return the uncompressed name length.
3293  */
3294  size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name,
3295  char *dst, int dst_len);
3296 
3297  /*
3298  * Attach built-in DNS event handler to the given listening connection.
3299  *
3300  * DNS event handler parses incoming UDP packets, treating them as DNS
3301  * requests. If incoming packet gets successfully parsed by the DNS event
3302  * handler, a user event handler will receive `MG_DNS_REQUEST` event, with
3303  * `ev_data` pointing to the parsed `struct mg_dns_message`.
3304  *
3305  * See
3306  * [captive_dns_server](https://github.com/cesanta/mongoose/tree/master/examples/captive_dns_server)
3307  * example on how to handle DNS request and send DNS reply.
3308  */
3309  void mg_set_protocol_dns(struct mg_connection *nc);
3310 
3311 #ifdef __cplusplus
3312 }
3313 #endif /* __cplusplus */
3314 #endif /* CS_MONGOOSE_SRC_DNS_H_ */
3315 /*
3316  * Copyright (c) 2014 Cesanta Software Limited
3317  * All rights reserved
3318  */
3319 
3320 /*
3321  * === DNS server
3322  *
3323  * Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`.
3324  */
3325 
3326 #ifndef CS_MONGOOSE_SRC_DNS_SERVER_H_
3327 #define CS_MONGOOSE_SRC_DNS_SERVER_H_
3328 
3329 #ifdef MG_ENABLE_DNS_SERVER
3330 
3331 
3332 #ifdef __cplusplus
3333 extern "C" {
3334 #endif /* __cplusplus */
3335 
3336 #define MG_DNS_SERVER_DEFAULT_TTL 3600
3337 
3338  struct mg_dns_reply {
3339  struct mg_dns_message *msg;
3340  struct mbuf *io;
3341  size_t start;
3342  };
3343 
3344  /*
3345  * Create a DNS reply.
3346  *
3347  * The reply will be based on an existing query message `msg`.
3348  * The query body will be appended to the output buffer.
3349  * "reply + recursion allowed" will be added to the message flags and
3350  * message's num_answers will be set to 0.
3351  *
3352  * Answer records can be appended with `mg_dns_send_reply` or by lower
3353  * level function defined in the DNS API.
3354  *
3355  * In order to send the reply use `mg_dns_send_reply`.
3356  * It's possible to use a connection's send buffer as reply buffers,
3357  * and it will work for both UDP and TCP connections.
3358  *
3359  * Example:
3360  *
3361  * ```c
3362  * reply = mg_dns_create_reply(&nc->send_mbuf, msg);
3363  * for (i = 0; i < msg->num_questions; i++) {
3364  * rr = &msg->questions[i];
3365  * if (rr->rtype == MG_DNS_A_RECORD) {
3366  * mg_dns_reply_record(&reply, rr, 3600, &dummy_ip_addr, 4);
3367  * }
3368  * }
3369  * mg_dns_send_reply(nc, &reply);
3370  * ```
3371  */
3372  struct mg_dns_reply mg_dns_create_reply(struct mbuf *io,
3373  struct mg_dns_message *msg);
3374 
3375  /*
3376  * Append a DNS reply record to the IO buffer and to the DNS message.
3377  *
3378  * The message num_answers field will be incremented. It's caller's duty
3379  * to ensure num_answers is propertly initialized.
3380  *
3381  * Returns -1 on error.
3382  */
3383  int mg_dns_reply_record(struct mg_dns_reply *reply,
3384  struct mg_dns_resource_record *question,
3385  const char *name, int rtype, int ttl, const void *rdata,
3386  size_t rdata_len);
3387 
3388  /*
3389  * Send a DNS reply through a connection.
3390  *
3391  * The DNS data is stored in an IO buffer pointed by reply structure in `r`.
3392  * This function mutates the content of that buffer in order to ensure that
3393  * the DNS header reflects size and flags of the mssage, that might have been
3394  * updated either with `mg_dns_reply_record` or by direct manipulation of
3395  * `r->message`.
3396  *
3397  * Once sent, the IO buffer will be trimmed unless the reply IO buffer
3398  * is the connection's send buffer and the connection is not in UDP mode.
3399  */
3400  void mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r);
3401 
3402 #ifdef __cplusplus
3403 }
3404 #endif /* __cplusplus */
3405 
3406 #endif /* MG_ENABLE_DNS_SERVER */
3407 #endif /* CS_MONGOOSE_SRC_DNS_SERVER_H_ */
3408 /*
3409  * Copyright (c) 2014 Cesanta Software Limited
3410  * All rights reserved
3411  */
3412 
3413 /*
3414  * === Asynchronouns DNS resolver
3415  */
3416 
3417 #ifndef CS_MONGOOSE_SRC_RESOLV_H_
3418 #define CS_MONGOOSE_SRC_RESOLV_H_
3419 
3420 
3421 #ifdef __cplusplus
3422 extern "C" {
3423 #endif /* __cplusplus */
3424 
3430  };
3431 
3432  typedef void (*mg_resolve_callback_t)(struct mg_dns_message *dns_message,
3433  void *user_data, enum mg_resolve_err);
3434 
3435  /* Options for `mg_resolve_async_opt`. */
3437  const char *nameserver_url;
3438  int max_retries; /* defaults to 2 if zero */
3439  int timeout; /* in seconds; defaults to 5 if zero */
3440  int accept_literal; /* pseudo-resolve literal ipv4 and ipv6 addrs */
3441  int only_literal; /* only resolves literal addrs; sync cb invocation */
3442  struct mg_connection **dns_conn; /* return DNS connection */
3443  };
3444 
3445  /* See `mg_resolve_async_opt()` */
3446  int mg_resolve_async(struct mg_mgr *mgr, const char *name, int query,
3447  mg_resolve_callback_t cb, void *data);
3448 
3449  /*
3450  * Resolved a DNS name asynchronously.
3451  *
3452  * Upon successful resolution, the user callback will be invoked
3453  * with the full DNS response message and a pointer to the user's
3454  * context `data`.
3455  *
3456  * In case of timeout while performing the resolution the callback
3457  * will receive a NULL `msg`.
3458  *
3459  * The DNS answers can be extracted with `mg_next_record` and
3460  * `mg_dns_parse_record_data`:
3461  *
3462  * [source,c]
3463  * ----
3464  * struct in_addr ina;
3465  * struct mg_dns_resource_record *rr = mg_next_record(msg, MG_DNS_A_RECORD,
3466  * NULL);
3467  * mg_dns_parse_record_data(msg, rr, &ina, sizeof(ina));
3468  * ----
3469  */
3470  int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
3471  mg_resolve_callback_t cb, void *data,
3472  struct mg_resolve_async_opts opts);
3473 
3474  /*
3475  * Resolve a name from `/etc/hosts`.
3476  *
3477  * Returns 0 on success, -1 on failure.
3478  */
3479  int mg_resolve_from_hosts_file(const char *host, union socket_address *usa);
3480 
3481 #ifdef __cplusplus
3482 }
3483 #endif /* __cplusplus */
3484 #endif /* CS_MONGOOSE_SRC_RESOLV_H_ */
3485 /*
3486  * Copyright (c) 2015 Cesanta Software Limited
3487  * All rights reserved
3488  * This software is dual-licensed: you can redistribute it and/or modify
3489  * it under the terms of the GNU General Public License version 2 as
3490  * published by the Free Software Foundation. For the terms of this
3491  * license, see <http://www.gnu.org/licenses/>.
3492  *
3493  * You are free to use this software under the terms of the GNU General
3494  * Public License, but WITHOUT ANY WARRANTY; without even the implied
3495  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
3496  * See the GNU General Public License for more details.
3497  *
3498  * Alternatively, you can license this software under a commercial
3499  * license, as set out in <https://www.cesanta.com/license>.
3500  */
3501 
3502 /*
3503  * === CoAP
3504  *
3505  * CoAP message format:
3506  *
3507  * ```
3508  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
3509  * |Ver| T | TKL | Code | Message ID | Token (if any, TKL bytes) ...
3510  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
3511  * | Options (if any) ... |1 1 1 1 1 1 1 1| Payload (if any) ...
3512  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
3513  * ```
3514  */
3515 
3516 #ifndef CS_MONGOOSE_SRC_COAP_H_
3517 #define CS_MONGOOSE_SRC_COAP_H_
3518 
3519 #ifdef MG_ENABLE_COAP
3520 
3521 #define MG_COAP_MSG_TYPE_FIELD 0x2
3522 #define MG_COAP_CODE_CLASS_FIELD 0x4
3523 #define MG_COAP_CODE_DETAIL_FIELD 0x8
3524 #define MG_COAP_MSG_ID_FIELD 0x10
3525 #define MG_COAP_TOKEN_FIELD 0x20
3526 #define MG_COAP_OPTIOMG_FIELD 0x40
3527 #define MG_COAP_PAYLOAD_FIELD 0x80
3528 
3529 #define MG_COAP_ERROR 0x10000
3530 #define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)
3531 #define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)
3532 #define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)
3533 #define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)
3534 
3535 #define MG_COAP_MSG_CON 0
3536 #define MG_COAP_MSG_NOC 1
3537 #define MG_COAP_MSG_ACK 2
3538 #define MG_COAP_MSG_RST 3
3539 #define MG_COAP_MSG_MAX 3
3540 
3541 #define MG_COAP_CODECLASS_REQUEST 0
3542 #define MG_COAP_CODECLASS_RESP_OK 2
3543 #define MG_COAP_CODECLASS_CLIENT_ERR 4
3544 #define MG_COAP_CODECLASS_SRV_ERR 5
3545 
3546 #define MG_COAP_EVENT_BASE 300
3547 #define MG_EV_COAP_CON (MG_COAP_EVENT_BASE + MG_COAP_MSG_CON)
3548 #define MG_EV_COAP_NOC (MG_COAP_EVENT_BASE + MG_COAP_MSG_NOC)
3549 #define MG_EV_COAP_ACK (MG_COAP_EVENT_BASE + MG_COAP_MSG_ACK)
3550 #define MG_EV_COAP_RST (MG_COAP_EVENT_BASE + MG_COAP_MSG_RST)
3551 
3552 /*
3553  * CoAP options.
3554  * Use mg_coap_add_option and mg_coap_free_options
3555  * for creation and destruction.
3556  */
3557 struct mg_coap_option {
3558  struct mg_coap_option *next;
3559  uint32_t number;
3560  struct mg_str value;
3561 };
3562 
3563 /* CoAP message. See RFC 7252 for details. */
3564 struct mg_coap_message {
3565  uint32_t flags;
3566  uint8_t msg_type;
3567  uint8_t code_class;
3568  uint8_t code_detail;
3569  uint16_t msg_id;
3570  struct mg_str token;
3571  struct mg_coap_option *options;
3572  struct mg_str payload;
3573  struct mg_coap_option *optiomg_tail;
3574 };
3575 
3576 #ifdef __cplusplus
3577 extern "C" {
3578 #endif /* __cplusplus */
3579 
3580  /* Set CoAP protocol handler - trigger CoAP specific events */
3581  int mg_set_protocol_coap(struct mg_connection *nc);
3582 
3583  /*
3584  * Add new option to mg_coap_message structure.
3585  * Returns pointer to the newly created option.
3586  */
3587  struct mg_coap_option *mg_coap_add_option(struct mg_coap_message *cm,
3588  uint32_t number, char *value,
3589  size_t len);
3590 
3591  /*
3592  * Free the memory allocated for options,
3593  * if cm paramater doesn't contain any option does nothing.
3594  */
3595  void mg_coap_free_options(struct mg_coap_message *cm);
3596 
3597  /*
3598  * Compose CoAP message from `mg_coap_message`
3599  * and send it into `nc` connection.
3600  * Return 0 on success. On error, it is a bitmask:
3601  *
3602  * - `#define MG_COAP_ERROR 0x10000`
3603  * - `#define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)`
3604  * - `#define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)`
3605  * - `#define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)`
3606  * - `#define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)`
3607  */
3608  uint32_t mg_coap_send_message(struct mg_connection *nc,
3609  struct mg_coap_message *cm);
3610 
3611  /*
3612  * Compose CoAP acknowledgement from `mg_coap_message`
3613  * and send it into `nc` connection.
3614  * Return value: see `mg_coap_send_message()`
3615  */
3616  uint32_t mg_coap_send_ack(struct mg_connection *nc, uint16_t msg_id);
3617 
3618  /*
3619  * Parse COAP message and fills mg_coap_message and returns cm->flags.
3620  * This is a helper function.
3621  *
3622  * NOTE: usually CoAP work over UDP, so lack of data means format error,
3623  * but in theory it is possible to use CoAP over TCP (according to RFC)
3624  *
3625  * The caller have to check results and treat COAP_NOT_ENOUGH_DATA according to
3626  * underlying protocol:
3627  *
3628  * - in case of UDP COAP_NOT_ENOUGH_DATA means COAP_FORMAT_ERROR,
3629  * - in case of TCP client can try to receive more data
3630  *
3631  * Return value: see `mg_coap_send_message()`
3632  */
3633  uint32_t mg_coap_parse(struct mbuf *io, struct mg_coap_message *cm);
3634 
3635  /*
3636  * Composes CoAP message from mg_coap_message structure.
3637  * This is a helper function.
3638  * Return value: see `mg_coap_send_message()`
3639  */
3640  uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io);
3641 
3642 #ifdef __cplusplus
3643 }
3644 #endif /* __cplusplus */
3645 
3646 #endif /* MG_ENABLE_COAP */
3647 
3648 #endif /* CS_MONGOOSE_SRC_COAP_H_ */