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