MIDAS
Loading...
Searching...
No Matches
mongoose614.h
Go to the documentation of this file.
1#ifdef MG_MODULE_LINES
2#line 1 "mongoose/src/mg_common.h"
3#endif
4/*
5 * Copyright (c) 2004-2013 Sergey Lyubka
6 * Copyright (c) 2013-2015 Cesanta Software Limited
7 * All rights reserved
8 *
9 * This software is dual-licensed: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. For the terms of this
12 * license, see <http://www.gnu.org/licenses/>.
13 *
14 * You are free to use this software under the terms of the GNU General
15 * Public License, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 * See the GNU General Public License for more details.
18 *
19 * Alternatively, you can license this software under a commercial
20 * license, as set out in <https://www.cesanta.com/license>.
21 */
22
23#ifndef CS_MONGOOSE_SRC_COMMON_H_
24#define CS_MONGOOSE_SRC_COMMON_H_
25
26#define MG_VERSION "6.14"
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#endif /* CS_MONGOOSE_SRC_COMMON_H_ */
34#ifdef MG_MODULE_LINES
35#line 1 "common/platform.h"
36#endif
37#ifndef CS_COMMON_PLATFORM_H_
38#define CS_COMMON_PLATFORM_H_
39
40/*
41 * For the "custom" platform, includes and dependencies can be
42 * provided through mg_locals.h.
43 */
44#define CS_P_CUSTOM 0
45#define CS_P_UNIX 1
46#define CS_P_WINDOWS 2
47#define CS_P_ESP32 15
48#define CS_P_ESP8266 3
49#define CS_P_CC3100 6
50#define CS_P_CC3200 4
51#define CS_P_CC3220 17
52#define CS_P_MSP432 5
53#define CS_P_TM4C129 14
54#define CS_P_MBED 7
55#define CS_P_WINCE 8
56#define CS_P_NXP_LPC 13
57#define CS_P_NXP_KINETIS 9
58#define CS_P_NRF51 12
59#define CS_P_NRF52 10
60#define CS_P_PIC32 11
61#define CS_P_STM32 16
62/* Next id: 18 */
63
64/* If not specified explicitly, we guess platform by defines. */
65#ifndef CS_PLATFORM
66
67#if defined(TARGET_IS_MSP432P4XX) || defined(__MSP432P401R__)
68#define CS_PLATFORM CS_P_MSP432
69#elif defined(cc3200) || defined(TARGET_IS_CC3200)
70#define CS_PLATFORM CS_P_CC3200
71#elif defined(cc3220) || defined(TARGET_IS_CC3220)
72#define CS_PLATFORM CS_P_CC3220
73#elif defined(__unix__) || defined(__APPLE__)
74#define CS_PLATFORM CS_P_UNIX
75#elif defined(WINCE)
76#define CS_PLATFORM CS_P_WINCE
77#elif defined(_WIN32)
78#define CS_PLATFORM CS_P_WINDOWS
79#elif defined(__MBED__)
80#define CS_PLATFORM CS_P_MBED
81#elif defined(__USE_LPCOPEN)
82#define CS_PLATFORM CS_P_NXP_LPC
83#elif defined(FRDM_K64F) || defined(FREEDOM)
84#define CS_PLATFORM CS_P_NXP_KINETIS
85#elif defined(PIC32)
86#define CS_PLATFORM CS_P_PIC32
87#elif defined(ESP_PLATFORM)
88#define CS_PLATFORM CS_P_ESP32
89#elif defined(ICACHE_FLASH)
90#define CS_PLATFORM CS_P_ESP8266
91#elif defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || \
92 defined(TARGET_IS_TM4C129_RA2)
93#define CS_PLATFORM CS_P_TM4C129
94#elif defined(STM32)
95#define CS_PLATFORM CS_P_STM32
96#endif
97
98#ifndef CS_PLATFORM
99#error "CS_PLATFORM is not specified and we couldn't guess it."
100#endif
101
102#endif /* !defined(CS_PLATFORM) */
103
104#define MG_NET_IF_SOCKET 1
105#define MG_NET_IF_SIMPLELINK 2
106#define MG_NET_IF_LWIP_LOW_LEVEL 3
107#define MG_NET_IF_PIC32 4
108#define MG_NET_IF_NULL 5
109
110#define MG_SSL_IF_OPENSSL 1
111#define MG_SSL_IF_MBEDTLS 2
112#define MG_SSL_IF_SIMPLELINK 3
113
114/* Amalgamated: #include "common/platforms/platform_unix.h" */
115/* Amalgamated: #include "common/platforms/platform_windows.h" */
116/* Amalgamated: #include "common/platforms/platform_esp32.h" */
117/* Amalgamated: #include "common/platforms/platform_esp8266.h" */
118/* Amalgamated: #include "common/platforms/platform_cc3100.h" */
119/* Amalgamated: #include "common/platforms/platform_cc3200.h" */
120/* Amalgamated: #include "common/platforms/platform_cc3220.h" */
121/* Amalgamated: #include "common/platforms/platform_mbed.h" */
122/* Amalgamated: #include "common/platforms/platform_nrf51.h" */
123/* Amalgamated: #include "common/platforms/platform_nrf52.h" */
124/* Amalgamated: #include "common/platforms/platform_wince.h" */
125/* Amalgamated: #include "common/platforms/platform_nxp_lpc.h" */
126/* Amalgamated: #include "common/platforms/platform_nxp_kinetis.h" */
127/* Amalgamated: #include "common/platforms/platform_pic32.h" */
128/* Amalgamated: #include "common/platforms/platform_stm32.h" */
129
130/* Common stuff */
131
132#if !defined(PRINTF_LIKE)
133#if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__)
134#define PRINTF_LIKE(f, a) __attribute__((format(printf, f, a)))
135#else
136#define PRINTF_LIKE(f, a)
137#endif
138#endif
139
140#if !defined(WEAK)
141#if (defined(__GNUC__) || defined(__clang__) || \
142 defined(__TI_COMPILER_VERSION__)) && \
143 !defined(_WIN32)
144#define WEAK __attribute__((weak))
145#else
146#define WEAK
147#endif
148#endif
149
150#ifdef __GNUC__
151#define NORETURN __attribute__((noreturn))
152#define NOINLINE __attribute__((noinline))
153#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
154#define NOINSTR __attribute__((no_instrument_function))
155#define DO_NOT_WARN_UNUSED __attribute__((unused))
156#else
157#define NORETURN
158#define NOINLINE
159#define WARN_UNUSED_RESULT
160#define NOINSTR
161#define DO_NOT_WARN_UNUSED
162#endif /* __GNUC__ */
163
164#ifndef ARRAY_SIZE
165#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
166#endif
167
168#endif /* CS_COMMON_PLATFORM_H_ */
169#ifdef MG_MODULE_LINES
170#line 1 "common/platforms/platform_windows.h"
171#endif
172#ifndef CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_
173#define CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_
174#if CS_PLATFORM == CS_P_WINDOWS
175
176/*
177 * MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
178 * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
179 * MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
180 * MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
181 * MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
182 * MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
183 * MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio 2003)
184 * MSVC++ 7.0 _MSC_VER == 1300
185 * MSVC++ 6.0 _MSC_VER == 1200
186 * MSVC++ 5.0 _MSC_VER == 1100
187 */
188#ifdef _MSC_VER
189#pragma warning(disable : 4127) /* FD_SET() emits warning, disable it */
190#pragma warning(disable : 4204) /* missing c99 support */
191#endif
192
193#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
194#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
195#endif
196
197#ifndef _CRT_SECURE_NO_WARNINGS
198#define _CRT_SECURE_NO_WARNINGS
199#endif
200
201#include <assert.h>
202#include <direct.h>
203#include <errno.h>
204#include <fcntl.h>
205#include <io.h>
206#include <limits.h>
207#include <signal.h>
208#include <stddef.h>
209#include <stdio.h>
210#include <stdlib.h>
211#include <sys/stat.h>
212#include <time.h>
213#include <ctype.h>
214
215#ifdef _MSC_VER
216#pragma comment(lib, "ws2_32.lib") /* Linking with winsock library */
217#endif
218
219#include <winsock2.h>
220#include <ws2tcpip.h>
221#include <windows.h>
222#include <process.h>
223
224#if _MSC_VER < 1700
225typedef int bool;
226#else
227#include <stdbool.h>
228#endif
229
230#if defined(_MSC_VER) && _MSC_VER >= 1800
231#define strdup _strdup
232#endif
233
234#ifndef EINPROGRESS
235#define EINPROGRESS WSAEINPROGRESS
236#endif
237#ifndef EWOULDBLOCK
238#define EWOULDBLOCK WSAEWOULDBLOCK
239#endif
240#ifndef __func__
241#define STRX(x) #x
242#define STR(x) STRX(x)
243#define __func__ __FILE__ ":" STR(__LINE__)
244#endif
245#define snprintf _snprintf
246#define vsnprintf _vsnprintf
247#define to64(x) _atoi64(x)
248#if !defined(__MINGW32__) && !defined(__MINGW64__)
249#define popen(x, y) _popen((x), (y))
250#define pclose(x) _pclose(x)
251#define fileno _fileno
252#endif
253#if defined(_MSC_VER) && _MSC_VER >= 1400
254#define fseeko(x, y, z) _fseeki64((x), (y), (z))
255#else
256#define fseeko(x, y, z) fseek((x), (y), (z))
257#endif
258#if defined(_MSC_VER) && _MSC_VER <= 1200
259typedef unsigned long uintptr_t;
260typedef long intptr_t;
261#endif
262typedef int socklen_t;
263#if _MSC_VER >= 1700
264#include <stdint.h>
265#else
266typedef signed char int8_t;
267typedef unsigned char uint8_t;
268typedef int int32_t;
269typedef unsigned int uint32_t;
270typedef short int16_t;
271typedef unsigned short uint16_t;
272typedef __int64 int64_t;
273typedef unsigned __int64 uint64_t;
274#endif
275typedef SOCKET sock_t;
276typedef uint32_t in_addr_t;
277#ifndef UINT16_MAX
278#define UINT16_MAX 65535
279#endif
280#ifndef UINT32_MAX
281#define UINT32_MAX 4294967295
282#endif
283#ifndef pid_t
284#define pid_t HANDLE
285#endif
286#define INT64_FMT "I64d"
287#define INT64_X_FMT "I64x"
288#define SIZE_T_FMT "Iu"
289typedef struct _stati64 cs_stat_t;
290#ifndef S_ISDIR
291#define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
292#endif
293#ifndef S_ISREG
294#define S_ISREG(x) (((x) &_S_IFMT) == _S_IFREG)
295#endif
296#define DIRSEP '\\'
297#define CS_DEFINE_DIRENT
298
299#ifndef va_copy
300#ifdef __va_copy
301#define va_copy __va_copy
302#else
303#define va_copy(x, y) (x) = (y)
304#endif
305#endif
306
307#ifndef MG_MAX_HTTP_REQUEST_SIZE
308#define MG_MAX_HTTP_REQUEST_SIZE 8192
309#endif
310
311#ifndef MG_MAX_HTTP_SEND_MBUF
312#define MG_MAX_HTTP_SEND_MBUF 4096
313#endif
314
315#ifndef MG_MAX_HTTP_HEADERS
316#define MG_MAX_HTTP_HEADERS 40
317#endif
318
319#ifndef CS_ENABLE_STDIO
320#define CS_ENABLE_STDIO 1
321#endif
322
323#ifndef MG_ENABLE_BROADCAST
324#define MG_ENABLE_BROADCAST 1
325#endif
326
327#ifndef MG_ENABLE_DIRECTORY_LISTING
328#define MG_ENABLE_DIRECTORY_LISTING 1
329#endif
330
331#ifndef MG_ENABLE_FILESYSTEM
332#define MG_ENABLE_FILESYSTEM 1
333#endif
334
335#ifndef MG_ENABLE_HTTP_CGI
336#define MG_ENABLE_HTTP_CGI MG_ENABLE_FILESYSTEM
337#endif
338
339#ifndef MG_NET_IF
340#define MG_NET_IF MG_NET_IF_SOCKET
341#endif
342
343unsigned int sleep(unsigned int seconds);
344
345/* https://stackoverflow.com/questions/16647819/timegm-cross-platform */
346#define timegm _mkgmtime
347
348#define gmtime_r(a, b) \
349 do { \
350 *(b) = *gmtime(a); \
351 } while (0)
352
353#endif /* CS_PLATFORM == CS_P_WINDOWS */
354#endif /* CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_ */
355#ifdef MG_MODULE_LINES
356#line 1 "common/platforms/platform_unix.h"
357#endif
358#ifndef CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_
359#define CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_
360#if CS_PLATFORM == CS_P_UNIX
361
362#ifndef _XOPEN_SOURCE
363#define _XOPEN_SOURCE 600
364#endif
365
366/* <inttypes.h> wants this for C++ */
367#ifndef __STDC_FORMAT_MACROS
368#define __STDC_FORMAT_MACROS
369#endif
370
371/* C++ wants that for INT64_MAX */
372#ifndef __STDC_LIMIT_MACROS
373#define __STDC_LIMIT_MACROS
374#endif
375
376/* Enable fseeko() and ftello() functions */
377#ifndef _LARGEFILE_SOURCE
378#define _LARGEFILE_SOURCE
379#endif
380
381/* Enable 64-bit file offsets */
382#ifndef _FILE_OFFSET_BITS
383#define _FILE_OFFSET_BITS 64
384#endif
385
386#include <arpa/inet.h>
387#include <assert.h>
388#include <ctype.h>
389#include <dirent.h>
390#include <errno.h>
391#include <fcntl.h>
392#include <inttypes.h>
393#include <stdint.h>
394#include <limits.h>
395#include <math.h>
396#include <netdb.h>
397#include <netinet/in.h>
398#include <pthread.h>
399#include <signal.h>
400#include <stdarg.h>
401#include <stdbool.h>
402#include <stdio.h>
403#include <stdlib.h>
404#include <string.h>
405#include <sys/param.h>
406#include <sys/socket.h>
407#include <sys/select.h>
408#include <sys/stat.h>
409#include <sys/time.h>
410#include <sys/types.h>
411#include <unistd.h>
412
413#ifdef __APPLE__
414#include <machine/endian.h>
415#ifndef BYTE_ORDER
416#define LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN
417#define BIG_ENDIAN __DARWIN_BIG_ENDIAN
418#define PDP_ENDIAN __DARWIN_PDP_ENDIAN
419#define BYTE_ORDER __DARWIN_BYTE_ORDER
420#endif
421#endif
422
423/*
424 * osx correctly avoids defining strtoll when compiling in strict ansi mode.
425 * c++ 11 standard defines strtoll as well.
426 * We require strtoll, and if your embedded pre-c99 compiler lacks one, please
427 * implement a shim.
428 */
429#if !(defined(__cplusplus) && __cplusplus >= 201103L) && \
430 !(defined(__DARWIN_C_LEVEL) && __DARWIN_C_LEVEL >= 200809L)
431long long strtoll(const char *, char **, int);
432#endif
433
434typedef int sock_t;
435#define INVALID_SOCKET (-1)
436#define SIZE_T_FMT "zu"
437typedef struct stat cs_stat_t;
438#define DIRSEP '/'
439#define to64(x) strtoll(x, NULL, 10)
440#define INT64_FMT PRId64
441#define INT64_X_FMT PRIx64
442
443#ifndef __cdecl
444#define __cdecl
445#endif
446
447#ifndef va_copy
448#ifdef __va_copy
449#define va_copy __va_copy
450#else
451#define va_copy(x, y) (x) = (y)
452#endif
453#endif
454
455#define closesocket(x) close(x)
456
457#ifndef MG_MAX_HTTP_REQUEST_SIZE
458#define MG_MAX_HTTP_REQUEST_SIZE 8192
459#endif
460
461#ifndef MG_MAX_HTTP_SEND_MBUF
462#define MG_MAX_HTTP_SEND_MBUF 4096
463#endif
464
465#ifndef MG_MAX_HTTP_HEADERS
466#define MG_MAX_HTTP_HEADERS 40
467#endif
468
469#ifndef CS_ENABLE_STDIO
470#define CS_ENABLE_STDIO 1
471#endif
472
473#ifndef MG_ENABLE_BROADCAST
474#define MG_ENABLE_BROADCAST 1
475#endif
476
477#ifndef MG_ENABLE_DIRECTORY_LISTING
478#define MG_ENABLE_DIRECTORY_LISTING 1
479#endif
480
481#ifndef MG_ENABLE_FILESYSTEM
482#define MG_ENABLE_FILESYSTEM 1
483#endif
484
485#ifndef MG_ENABLE_HTTP_CGI
486#define MG_ENABLE_HTTP_CGI MG_ENABLE_FILESYSTEM
487#endif
488
489#ifndef MG_NET_IF
490#define MG_NET_IF MG_NET_IF_SOCKET
491#endif
492
493#ifndef MG_HOSTS_FILE_NAME
494#define MG_HOSTS_FILE_NAME "/etc/hosts"
495#endif
496
497#ifndef MG_RESOLV_CONF_FILE_NAME
498#define MG_RESOLV_CONF_FILE_NAME "/etc/resolv.conf"
499#endif
500
501#endif /* CS_PLATFORM == CS_P_UNIX */
502#endif /* CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_ */
503#ifdef MG_MODULE_LINES
504#line 1 "common/platforms/platform_esp32.h"
505#endif
506/*
507 * Copyright (c) 2014-2018 Cesanta Software Limited
508 * All rights reserved
509 *
510 * Licensed under the Apache License, Version 2.0 (the ""License"");
511 * you may not use this file except in compliance with the License.
512 * You may obtain a copy of the License at
513 *
514 * http://www.apache.org/licenses/LICENSE-2.0
515 *
516 * Unless required by applicable law or agreed to in writing, software
517 * distributed under the License is distributed on an ""AS IS"" BASIS,
518 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
519 * See the License for the specific language governing permissions and
520 * limitations under the License.
521 */
522
523#ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_
524#define CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_
525#if CS_PLATFORM == CS_P_ESP32
526
527#include <assert.h>
528#include <ctype.h>
529#include <dirent.h>
530#include <fcntl.h>
531#include <inttypes.h>
532#include <machine/endian.h>
533#include <stdbool.h>
534#include <stdint.h>
535#include <string.h>
536#include <sys/stat.h>
537#include <sys/time.h>
538
539#define SIZE_T_FMT "u"
540typedef struct stat cs_stat_t;
541#define DIRSEP '/'
542#define to64(x) strtoll(x, NULL, 10)
543#define INT64_FMT PRId64
544#define INT64_X_FMT PRIx64
545#define __cdecl
546#define _FILE_OFFSET_BITS 32
547
548#define MG_LWIP 1
549
550#ifndef MG_NET_IF
551#define MG_NET_IF MG_NET_IF_SOCKET
552#endif
553
554#ifndef CS_ENABLE_STDIO
555#define CS_ENABLE_STDIO 1
556#endif
557
558#endif /* CS_PLATFORM == CS_P_ESP32 */
559#endif /* CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_ */
560#ifdef MG_MODULE_LINES
561#line 1 "common/platforms/platform_esp8266.h"
562#endif
563/*
564 * Copyright (c) 2014-2018 Cesanta Software Limited
565 * All rights reserved
566 *
567 * Licensed under the Apache License, Version 2.0 (the ""License"");
568 * you may not use this file except in compliance with the License.
569 * You may obtain a copy of the License at
570 *
571 * http://www.apache.org/licenses/LICENSE-2.0
572 *
573 * Unless required by applicable law or agreed to in writing, software
574 * distributed under the License is distributed on an ""AS IS"" BASIS,
575 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
576 * See the License for the specific language governing permissions and
577 * limitations under the License.
578 */
579
580#ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_
581#define CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_
582#if CS_PLATFORM == CS_P_ESP8266
583
584#include <assert.h>
585#include <ctype.h>
586#include <fcntl.h>
587#include <inttypes.h>
588#include <machine/endian.h>
589#include <stdbool.h>
590#include <string.h>
591#include <sys/stat.h>
592#include <sys/time.h>
593
594#define SIZE_T_FMT "u"
595typedef struct stat cs_stat_t;
596#define DIRSEP '/'
597#if !defined(MGOS_VFS_DEFINE_DIRENT)
598#define CS_DEFINE_DIRENT
599#endif
600
601#define to64(x) strtoll(x, NULL, 10)
602#define INT64_FMT PRId64
603#define INT64_X_FMT PRIx64
604#define __cdecl
605#define _FILE_OFFSET_BITS 32
606
607#define MG_LWIP 1
608
609/* struct timeval is defined in sys/time.h. */
610#define LWIP_TIMEVAL_PRIVATE 0
611
612#ifndef MG_NET_IF
613#include <lwip/opt.h>
614#if LWIP_SOCKET /* RTOS SDK has LWIP sockets */
615#define MG_NET_IF MG_NET_IF_SOCKET
616#else
617#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
618#endif
619#endif
620
621#ifndef CS_ENABLE_STDIO
622#define CS_ENABLE_STDIO 1
623#endif
624
625#define inet_ntop(af, src, dst, size) \
626 (((af) == AF_INET) ? ipaddr_ntoa_r((const ip_addr_t *) (src), (dst), (size)) \
627 : NULL)
628#define inet_pton(af, src, dst) \
629 (((af) == AF_INET) ? ipaddr_aton((src), (ip_addr_t *) (dst)) : 0)
630
631#endif /* CS_PLATFORM == CS_P_ESP8266 */
632#endif /* CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_ */
633#ifdef MG_MODULE_LINES
634#line 1 "common/platforms/platform_cc3100.h"
635#endif
636/*
637 * Copyright (c) 2014-2018 Cesanta Software Limited
638 * All rights reserved
639 *
640 * Licensed under the Apache License, Version 2.0 (the ""License"");
641 * you may not use this file except in compliance with the License.
642 * You may obtain a copy of the License at
643 *
644 * http://www.apache.org/licenses/LICENSE-2.0
645 *
646 * Unless required by applicable law or agreed to in writing, software
647 * distributed under the License is distributed on an ""AS IS"" BASIS,
648 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
649 * See the License for the specific language governing permissions and
650 * limitations under the License.
651 */
652
653#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_
654#define CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_
655#if CS_PLATFORM == CS_P_CC3100
656
657#include <assert.h>
658#include <ctype.h>
659#include <errno.h>
660#include <inttypes.h>
661#include <stdint.h>
662#include <string.h>
663#include <time.h>
664
665#define MG_NET_IF MG_NET_IF_SIMPLELINK
666#define MG_SSL_IF MG_SSL_IF_SIMPLELINK
667
668/*
669 * CC3100 SDK and STM32 SDK include headers w/out path, just like
670 * #include "simplelink.h". As result, we have to add all required directories
671 * into Makefile IPATH and do the same thing (include w/out path)
672 */
673
674#include <simplelink.h>
675#include <netapp.h>
676#undef timeval
677
678typedef int sock_t;
679#define INVALID_SOCKET (-1)
680
681#define to64(x) strtoll(x, NULL, 10)
682#define INT64_FMT PRId64
683#define INT64_X_FMT PRIx64
684#define SIZE_T_FMT "u"
685
686#define SOMAXCONN 8
687
688const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
689char *inet_ntoa(struct in_addr in);
690int inet_pton(int af, const char *src, void *dst);
691
692#endif /* CS_PLATFORM == CS_P_CC3100 */
693#endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_ */
694#ifdef MG_MODULE_LINES
695#line 1 "common/platforms/platform_cc3200.h"
696#endif
697/*
698 * Copyright (c) 2014-2018 Cesanta Software Limited
699 * All rights reserved
700 *
701 * Licensed under the Apache License, Version 2.0 (the ""License"");
702 * you may not use this file except in compliance with the License.
703 * You may obtain a copy of the License at
704 *
705 * http://www.apache.org/licenses/LICENSE-2.0
706 *
707 * Unless required by applicable law or agreed to in writing, software
708 * distributed under the License is distributed on an ""AS IS"" BASIS,
709 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
710 * See the License for the specific language governing permissions and
711 * limitations under the License.
712 */
713
714#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
715#define CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
716#if CS_PLATFORM == CS_P_CC3200
717
718#include <assert.h>
719#include <ctype.h>
720#include <errno.h>
721#include <inttypes.h>
722#include <stdbool.h>
723#include <stdint.h>
724#include <string.h>
725#include <time.h>
726
727#ifndef __TI_COMPILER_VERSION__
728#include <fcntl.h>
729#include <sys/time.h>
730#endif
731
732#define MG_NET_IF MG_NET_IF_SIMPLELINK
733#define MG_SSL_IF MG_SSL_IF_SIMPLELINK
734
735/* Only SPIFFS supports directories, SLFS does not. */
736#if defined(CC3200_FS_SPIFFS) && !defined(MG_ENABLE_DIRECTORY_LISTING)
737#define MG_ENABLE_DIRECTORY_LISTING 1
738#endif
739
740/* Amalgamated: #include "common/platforms/simplelink/cs_simplelink.h" */
741
742typedef int sock_t;
743#define INVALID_SOCKET (-1)
744#define SIZE_T_FMT "u"
745typedef struct stat cs_stat_t;
746#define DIRSEP '/'
747#define to64(x) strtoll(x, NULL, 10)
748#define INT64_FMT PRId64
749#define INT64_X_FMT PRIx64
750#define __cdecl
751
752#define fileno(x) -1
753
754/* Some functions we implement for Mongoose. */
755
756#ifdef __cplusplus
757extern "C" {
758#endif
759
760#ifdef __TI_COMPILER_VERSION__
761struct SlTimeval_t;
762#define timeval SlTimeval_t
763int gettimeofday(struct timeval *t, void *tz);
764int settimeofday(const struct timeval *tv, const void *tz);
765
766int asprintf(char **strp, const char *fmt, ...);
767
768#endif
769
770/* TI's libc does not have stat & friends, add them. */
771#ifdef __TI_COMPILER_VERSION__
772
773#include <file.h>
774
775typedef unsigned int mode_t;
776typedef size_t _off_t;
777typedef long ssize_t;
778
779struct stat {
780 int st_ino;
782 int st_nlink;
785};
786
787int _stat(const char *pathname, struct stat *st);
788int stat(const char *pathname, struct stat *st);
789
790#define __S_IFMT 0170000
791
792#define __S_IFDIR 0040000
793#define __S_IFCHR 0020000
794#define __S_IFREG 0100000
795
796#define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
797
798#define S_IFDIR __S_IFDIR
799#define S_IFCHR __S_IFCHR
800#define S_IFREG __S_IFREG
801#define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
802#define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
803
804/* 5.x series compilers don't have va_copy, 16.x do. */
805#if __TI_COMPILER_VERSION__ < 16000000
806#define va_copy(apc, ap) ((apc) = (ap))
807#endif
808
809#endif /* __TI_COMPILER_VERSION__ */
810
811#ifdef CC3200_FS_SLFS
812#define MG_FS_SLFS
813#endif
814
815#if (defined(CC3200_FS_SPIFFS) || defined(CC3200_FS_SLFS)) && \
816 !defined(MG_ENABLE_FILESYSTEM)
817#define MG_ENABLE_FILESYSTEM 1
818#define CS_DEFINE_DIRENT
819#endif
820
821#ifndef CS_ENABLE_STDIO
822#define CS_ENABLE_STDIO 1
823#endif
824
825#ifdef __cplusplus
826}
827#endif
828
829#endif /* CS_PLATFORM == CS_P_CC3200 */
830#endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ */
831#ifdef MG_MODULE_LINES
832#line 1 "common/platforms/platform_cc3220.h"
833#endif
834/*
835 * Copyright (c) 2014-2018 Cesanta Software Limited
836 * All rights reserved
837 *
838 * Licensed under the Apache License, Version 2.0 (the ""License"");
839 * you may not use this file except in compliance with the License.
840 * You may obtain a copy of the License at
841 *
842 * http://www.apache.org/licenses/LICENSE-2.0
843 *
844 * Unless required by applicable law or agreed to in writing, software
845 * distributed under the License is distributed on an ""AS IS"" BASIS,
846 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
847 * See the License for the specific language governing permissions and
848 * limitations under the License.
849 */
850
851#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3220_H_
852#define CS_COMMON_PLATFORMS_PLATFORM_CC3220_H_
853#if CS_PLATFORM == CS_P_CC3220
854
855#include <assert.h>
856#include <ctype.h>
857#include <errno.h>
858#include <inttypes.h>
859#include <stdbool.h>
860#include <stdint.h>
861#include <string.h>
862#include <time.h>
863
864#ifndef __TI_COMPILER_VERSION__
865#include <fcntl.h>
866#include <sys/time.h>
867#endif
868
869#define MG_NET_IF MG_NET_IF_SIMPLELINK
870#ifndef MG_SSL_IF
871#define MG_SSL_IF MG_SSL_IF_SIMPLELINK
872#endif
873
874/* Only SPIFFS supports directories, SLFS does not. */
875#if defined(CC3220_FS_SPIFFS) && !defined(MG_ENABLE_DIRECTORY_LISTING)
876#define MG_ENABLE_DIRECTORY_LISTING 1
877#endif
878
879/* Amalgamated: #include "common/platforms/simplelink/cs_simplelink.h" */
880
881typedef int sock_t;
882#define INVALID_SOCKET (-1)
883#define SIZE_T_FMT "u"
884typedef struct stat cs_stat_t;
885#define DIRSEP '/'
886#define to64(x) strtoll(x, NULL, 10)
887#define INT64_FMT PRId64
888#define INT64_X_FMT PRIx64
889#define __cdecl
890
891#define fileno(x) -1
892
893/* Some functions we implement for Mongoose. */
894
895#ifdef __cplusplus
896extern "C" {
897#endif
898
899#ifdef __TI_COMPILER_VERSION__
900struct SlTimeval_t;
901#define timeval SlTimeval_t
902int gettimeofday(struct timeval *t, void *tz);
903int settimeofday(const struct timeval *tv, const void *tz);
904
905int asprintf(char **strp, const char *fmt, ...);
906
907#endif
908
909/* TI's libc does not have stat & friends, add them. */
910#ifdef __TI_COMPILER_VERSION__
911
912#include <file.h>
913
914typedef unsigned int mode_t;
915typedef size_t _off_t;
916typedef long ssize_t;
917
918struct stat {
919 int st_ino;
921 int st_nlink;
924};
925
926int _stat(const char *pathname, struct stat *st);
927int stat(const char *pathname, struct stat *st);
928
929#define __S_IFMT 0170000
930
931#define __S_IFDIR 0040000
932#define __S_IFCHR 0020000
933#define __S_IFREG 0100000
934
935#define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
936
937#define S_IFDIR __S_IFDIR
938#define S_IFCHR __S_IFCHR
939#define S_IFREG __S_IFREG
940#define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
941#define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
942
943#endif /* __TI_COMPILER_VERSION__ */
944
945#ifndef CS_ENABLE_STDIO
946#define CS_ENABLE_STDIO 1
947#endif
948
949#ifdef __cplusplus
950}
951#endif
952
953#endif /* CS_PLATFORM == CS_P_CC3220 */
954#endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ */
955#ifdef MG_MODULE_LINES
956#line 1 "common/platforms/platform_msp432.h"
957#endif
958/*
959 * Copyright (c) 2014-2018 Cesanta Software Limited
960 * All rights reserved
961 *
962 * Licensed under the Apache License, Version 2.0 (the ""License"");
963 * you may not use this file except in compliance with the License.
964 * You may obtain a copy of the License at
965 *
966 * http://www.apache.org/licenses/LICENSE-2.0
967 *
968 * Unless required by applicable law or agreed to in writing, software
969 * distributed under the License is distributed on an ""AS IS"" BASIS,
970 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
971 * See the License for the specific language governing permissions and
972 * limitations under the License.
973 */
974
975#ifndef CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
976#define CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
977#if CS_PLATFORM == CS_P_MSP432
978
979#include <assert.h>
980#include <ctype.h>
981#include <errno.h>
982#include <inttypes.h>
983#include <stdint.h>
984#include <string.h>
985#include <time.h>
986
987#ifndef __TI_COMPILER_VERSION__
988#include <fcntl.h>
989#include <sys/time.h>
990#endif
991
992#define MG_NET_IF MG_NET_IF_SIMPLELINK
993#define MG_SSL_IF MG_SSL_IF_SIMPLELINK
994
995/* Amalgamated: #include "common/platforms/simplelink/cs_simplelink.h" */
996
997typedef int sock_t;
998#define INVALID_SOCKET (-1)
999#define SIZE_T_FMT "u"
1000typedef struct stat cs_stat_t;
1001#define DIRSEP '/'
1002#define to64(x) strtoll(x, NULL, 10)
1003#define INT64_FMT PRId64
1004#define INT64_X_FMT PRIx64
1005#define __cdecl
1006
1007#define fileno(x) -1
1008
1009/* Some functions we implement for Mongoose. */
1010
1011#ifdef __cplusplus
1012extern "C" {
1013#endif
1014
1015#ifdef __TI_COMPILER_VERSION__
1016struct SlTimeval_t;
1017#define timeval SlTimeval_t
1018int gettimeofday(struct timeval *t, void *tz);
1019#endif
1020
1021/* TI's libc does not have stat & friends, add them. */
1022#ifdef __TI_COMPILER_VERSION__
1023
1024#include <file.h>
1025
1026typedef unsigned int mode_t;
1027typedef size_t _off_t;
1028typedef long ssize_t;
1029
1030struct stat {
1031 int st_ino;
1033 int st_nlink;
1035 off_t st_size;
1036};
1037
1038int _stat(const char *pathname, struct stat *st);
1039#define stat(a, b) _stat(a, b)
1040
1041#define __S_IFMT 0170000
1042
1043#define __S_IFDIR 0040000
1044#define __S_IFCHR 0020000
1045#define __S_IFREG 0100000
1046
1047#define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
1048
1049#define S_IFDIR __S_IFDIR
1050#define S_IFCHR __S_IFCHR
1051#define S_IFREG __S_IFREG
1052#define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
1053#define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
1054
1055/* As of 5.2.7, TI compiler does not support va_copy() yet. */
1056#define va_copy(apc, ap) ((apc) = (ap))
1057
1058#endif /* __TI_COMPILER_VERSION__ */
1059
1060#ifndef CS_ENABLE_STDIO
1061#define CS_ENABLE_STDIO 1
1062#endif
1063
1064#if (defined(CC3200_FS_SPIFFS) || defined(CC3200_FS_SLFS)) && \
1065 !defined(MG_ENABLE_FILESYSTEM)
1066#define MG_ENABLE_FILESYSTEM 1
1067#endif
1068
1069#ifdef __cplusplus
1070}
1071#endif
1072
1073#endif /* CS_PLATFORM == CS_P_MSP432 */
1074#endif /* CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_ */
1075#ifdef MG_MODULE_LINES
1076#line 1 "common/platforms/platform_tm4c129.h"
1077#endif
1078/*
1079 * Copyright (c) 2014-2018 Cesanta Software Limited
1080 * All rights reserved
1081 *
1082 * Licensed under the Apache License, Version 2.0 (the ""License"");
1083 * you may not use this file except in compliance with the License.
1084 * You may obtain a copy of the License at
1085 *
1086 * http://www.apache.org/licenses/LICENSE-2.0
1087 *
1088 * Unless required by applicable law or agreed to in writing, software
1089 * distributed under the License is distributed on an ""AS IS"" BASIS,
1090 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1091 * See the License for the specific language governing permissions and
1092 * limitations under the License.
1093 */
1094
1095#ifndef CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_
1096#define CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_
1097#if CS_PLATFORM == CS_P_TM4C129
1098
1099#include <assert.h>
1100#include <ctype.h>
1101#include <errno.h>
1102#include <inttypes.h>
1103#include <stdint.h>
1104#include <string.h>
1105#include <time.h>
1106
1107#ifndef __TI_COMPILER_VERSION__
1108#include <fcntl.h>
1109#include <sys/time.h>
1110#endif
1111
1112#define SIZE_T_FMT "u"
1113typedef struct stat cs_stat_t;
1114#define DIRSEP '/'
1115#define to64(x) strtoll(x, NULL, 10)
1116#define INT64_FMT PRId64
1117#define INT64_X_FMT PRIx64
1118#define __cdecl
1119
1120#ifndef MG_NET_IF
1121#include <lwip/opt.h>
1122#if LWIP_SOCKET
1123#define MG_NET_IF MG_NET_IF_SOCKET
1124#else
1125#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1126#endif
1127#define MG_LWIP 1
1128#elif MG_NET_IF == MG_NET_IF_SIMPLELINK
1129/* Amalgamated: #include "common/platforms/simplelink/cs_simplelink.h" */
1130#endif
1131
1132#ifndef CS_ENABLE_STDIO
1133#define CS_ENABLE_STDIO 1
1134#endif
1135
1136#ifdef __TI_COMPILER_VERSION__
1137/* As of 5.2.8, TI compiler does not support va_copy() yet. */
1138#define va_copy(apc, ap) ((apc) = (ap))
1139#endif /* __TI_COMPILER_VERSION__ */
1140
1141#ifdef __cplusplus
1142}
1143#endif
1144
1145#endif /* CS_PLATFORM == CS_P_TM4C129 */
1146#endif /* CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_ */
1147#ifdef MG_MODULE_LINES
1148#line 1 "common/platforms/platform_mbed.h"
1149#endif
1150/*
1151 * Copyright (c) 2014-2018 Cesanta Software Limited
1152 * All rights reserved
1153 *
1154 * Licensed under the Apache License, Version 2.0 (the ""License"");
1155 * you may not use this file except in compliance with the License.
1156 * You may obtain a copy of the License at
1157 *
1158 * http://www.apache.org/licenses/LICENSE-2.0
1159 *
1160 * Unless required by applicable law or agreed to in writing, software
1161 * distributed under the License is distributed on an ""AS IS"" BASIS,
1162 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1163 * See the License for the specific language governing permissions and
1164 * limitations under the License.
1165 */
1166
1167#ifndef CS_COMMON_PLATFORMS_PLATFORM_MBED_H_
1168#define CS_COMMON_PLATFORMS_PLATFORM_MBED_H_
1169#if CS_PLATFORM == CS_P_MBED
1170
1171/*
1172 * mbed.h contains C++ code (e.g. templates), thus, it should be processed
1173 * only if included directly to startup file (ex: main.cpp)
1174 */
1175#ifdef __cplusplus
1176/* Amalgamated: #include "mbed.h" */
1177#endif /* __cplusplus */
1178
1179#include <assert.h>
1180#include <ctype.h>
1181#include <errno.h>
1182#include <inttypes.h>
1183#include <stdint.h>
1184#include <string.h>
1185#include <time.h>
1186#include <sys/stat.h>
1187#include <sys/types.h>
1188#include <fcntl.h>
1189#include <stdio.h>
1190
1191typedef struct stat cs_stat_t;
1192#define DIRSEP '/'
1193
1194#ifndef CS_ENABLE_STDIO
1195#define CS_ENABLE_STDIO 1
1196#endif
1197
1198/*
1199 * mbed can be compiled with the ARM compiler which
1200 * just doesn't come with a gettimeofday shim
1201 * because it's a BSD API and ARM targets embedded
1202 * non-unix platforms.
1203 */
1204#if defined(__ARMCC_VERSION) || defined(__ICCARM__)
1205#define _TIMEVAL_DEFINED
1206#define gettimeofday _gettimeofday
1207
1208/* copied from GCC on ARM; for some reason useconds are signed */
1209typedef long suseconds_t; /* microseconds (signed) */
1210struct timeval {
1211 time_t tv_sec; /* seconds */
1212 suseconds_t tv_usec; /* and microseconds */
1213};
1214
1215#endif
1216
1217#if MG_NET_IF == MG_NET_IF_SIMPLELINK
1218
1219#define MG_SIMPLELINK_NO_OSI 1
1220
1221#include <simplelink.h>
1222
1223typedef int sock_t;
1224#define INVALID_SOCKET (-1)
1225
1226#define to64(x) strtoll(x, NULL, 10)
1227#define INT64_FMT PRId64
1228#define INT64_X_FMT PRIx64
1229#define SIZE_T_FMT "u"
1230
1231#define SOMAXCONN 8
1232
1233const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
1234char *inet_ntoa(struct in_addr in);
1235int inet_pton(int af, const char *src, void *dst);
1236int inet_aton(const char *cp, struct in_addr *inp);
1237in_addr_t inet_addr(const char *cp);
1238
1239#endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK */
1240
1241#endif /* CS_PLATFORM == CS_P_MBED */
1242#endif /* CS_COMMON_PLATFORMS_PLATFORM_MBED_H_ */
1243#ifdef MG_MODULE_LINES
1244#line 1 "common/platforms/platform_nrf51.h"
1245#endif
1246/*
1247 * Copyright (c) 2014-2018 Cesanta Software Limited
1248 * All rights reserved
1249 *
1250 * Licensed under the Apache License, Version 2.0 (the ""License"");
1251 * you may not use this file except in compliance with the License.
1252 * You may obtain a copy of the License at
1253 *
1254 * http://www.apache.org/licenses/LICENSE-2.0
1255 *
1256 * Unless required by applicable law or agreed to in writing, software
1257 * distributed under the License is distributed on an ""AS IS"" BASIS,
1258 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1259 * See the License for the specific language governing permissions and
1260 * limitations under the License.
1261 */
1262#ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_
1263#define CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_
1264#if CS_PLATFORM == CS_P_NRF51
1265
1266#include <assert.h>
1267#include <ctype.h>
1268#include <inttypes.h>
1269#include <stdint.h>
1270#include <string.h>
1271#include <time.h>
1272
1273#define to64(x) strtoll(x, NULL, 10)
1274
1275#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1276#define MG_LWIP 1
1277#define MG_ENABLE_IPV6 1
1278
1279/*
1280 * For ARM C Compiler, make lwip to export `struct timeval`; for other
1281 * compilers, suppress it.
1282 */
1283#if !defined(__ARMCC_VERSION)
1284#define LWIP_TIMEVAL_PRIVATE 0
1285#else
1286struct timeval;
1287int gettimeofday(struct timeval *tp, void *tzp);
1288#endif
1289
1290#define INT64_FMT PRId64
1291#define SIZE_T_FMT "u"
1292
1293/*
1294 * ARM C Compiler doesn't have strdup, so we provide it
1295 */
1296#define CS_ENABLE_STRDUP defined(__ARMCC_VERSION)
1297
1298#endif /* CS_PLATFORM == CS_P_NRF51 */
1299#endif /* CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_ */
1300#ifdef MG_MODULE_LINES
1301#line 1 "common/platforms/platform_nrf52.h"
1302#endif
1303/*
1304 * Copyright (c) 2014-2018 Cesanta Software Limited
1305 * All rights reserved
1306 *
1307 * Licensed under the Apache License, Version 2.0 (the ""License"");
1308 * you may not use this file except in compliance with the License.
1309 * You may obtain a copy of the License at
1310 *
1311 * http://www.apache.org/licenses/LICENSE-2.0
1312 *
1313 * Unless required by applicable law or agreed to in writing, software
1314 * distributed under the License is distributed on an ""AS IS"" BASIS,
1315 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1316 * See the License for the specific language governing permissions and
1317 * limitations under the License.
1318 */
1319#ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_
1320#define CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_
1321#if CS_PLATFORM == CS_P_NRF52
1322
1323#include <assert.h>
1324#include <ctype.h>
1325#include <errno.h>
1326#include <inttypes.h>
1327#include <stdbool.h>
1328#include <stdint.h>
1329#include <string.h>
1330#include <time.h>
1331
1332#define to64(x) strtoll(x, NULL, 10)
1333
1334#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1335#define MG_LWIP 1
1336#define MG_ENABLE_IPV6 1
1337
1338#if !defined(ENOSPC)
1339#define ENOSPC 28 /* No space left on device */
1340#endif
1341
1342/*
1343 * For ARM C Compiler, make lwip to export `struct timeval`; for other
1344 * compilers, suppress it.
1345 */
1346#if !defined(__ARMCC_VERSION)
1347#define LWIP_TIMEVAL_PRIVATE 0
1348#endif
1349
1350#define INT64_FMT PRId64
1351#define SIZE_T_FMT "u"
1352
1353/*
1354 * ARM C Compiler doesn't have strdup, so we provide it
1355 */
1356#define CS_ENABLE_STRDUP defined(__ARMCC_VERSION)
1357
1358#endif /* CS_PLATFORM == CS_P_NRF52 */
1359#endif /* CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_ */
1360#ifdef MG_MODULE_LINES
1361#line 1 "common/platforms/simplelink/cs_simplelink.h"
1362#endif
1363/*
1364 * Copyright (c) 2014-2018 Cesanta Software Limited
1365 * All rights reserved
1366 *
1367 * Licensed under the Apache License, Version 2.0 (the ""License"");
1368 * you may not use this file except in compliance with the License.
1369 * You may obtain a copy of the License at
1370 *
1371 * http://www.apache.org/licenses/LICENSE-2.0
1372 *
1373 * Unless required by applicable law or agreed to in writing, software
1374 * distributed under the License is distributed on an ""AS IS"" BASIS,
1375 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1376 * See the License for the specific language governing permissions and
1377 * limitations under the License.
1378 */
1379
1380#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
1381#define CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
1382
1383#if defined(MG_NET_IF) && MG_NET_IF == MG_NET_IF_SIMPLELINK
1384
1385/* If simplelink.h is already included, all bets are off. */
1386#if !defined(__SIMPLELINK_H__)
1387
1388#include <stdbool.h>
1389
1390#ifndef __TI_COMPILER_VERSION__
1391#undef __CONCAT
1392#undef FD_CLR
1393#undef FD_ISSET
1394#undef FD_SET
1395#undef FD_SETSIZE
1396#undef FD_ZERO
1397#undef fd_set
1398#endif
1399
1400#if CS_PLATFORM == CS_P_CC3220
1401#include <ti/drivers/net/wifi/porting/user.h>
1402#include <ti/drivers/net/wifi/simplelink.h>
1403#include <ti/drivers/net/wifi/sl_socket.h>
1404#include <ti/drivers/net/wifi/netapp.h>
1405#else
1406/* We want to disable SL_INC_STD_BSD_API_NAMING, so we include user.h ourselves
1407 * and undef it. */
1408#define PROVISIONING_API_H_
1409#include <simplelink/user.h>
1410#undef PROVISIONING_API_H_
1411#undef SL_INC_STD_BSD_API_NAMING
1412
1413#include <simplelink/include/simplelink.h>
1414#include <simplelink/include/netapp.h>
1415#endif /* CS_PLATFORM == CS_P_CC3220 */
1416
1417/* Now define only the subset of the BSD API that we use.
1418 * Notably, close(), read() and write() are not defined. */
1419#define AF_INET SL_AF_INET
1420
1421#define socklen_t SlSocklen_t
1422#define sockaddr SlSockAddr_t
1423#define sockaddr_in SlSockAddrIn_t
1424#define in_addr SlInAddr_t
1425
1426#define SOCK_STREAM SL_SOCK_STREAM
1427#define SOCK_DGRAM SL_SOCK_DGRAM
1428
1429#define htonl sl_Htonl
1430#define ntohl sl_Ntohl
1431#define htons sl_Htons
1432#define ntohs sl_Ntohs
1433
1434#ifndef EACCES
1435#define EACCES SL_EACCES
1436#endif
1437#ifndef EAFNOSUPPORT
1438#define EAFNOSUPPORT SL_EAFNOSUPPORT
1439#endif
1440#ifndef EAGAIN
1441#define EAGAIN SL_EAGAIN
1442#endif
1443#ifndef EBADF
1444#define EBADF SL_EBADF
1445#endif
1446#ifndef EINVAL
1447#define EINVAL SL_EINVAL
1448#endif
1449#ifndef ENOMEM
1450#define ENOMEM SL_ENOMEM
1451#endif
1452#ifndef EWOULDBLOCK
1453#define EWOULDBLOCK SL_EWOULDBLOCK
1454#endif
1455
1456#define SOMAXCONN 8
1457
1458#ifdef __cplusplus
1459extern "C" {
1460#endif
1461
1462const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
1463char *inet_ntoa(struct in_addr in);
1464int inet_pton(int af, const char *src, void *dst);
1465
1466struct mg_mgr;
1467struct mg_connection;
1468
1469typedef void (*mg_init_cb)(struct mg_mgr *mgr);
1471
1472void mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg);
1473
1474int sl_fs_init(void);
1475
1476void sl_restart_cb(struct mg_mgr *mgr);
1477
1478int sl_set_ssl_opts(int sock, struct mg_connection *nc);
1479
1480#ifdef __cplusplus
1481}
1482#endif
1483
1484#endif /* !defined(__SIMPLELINK_H__) */
1485
1486/* Compatibility with older versions of SimpleLink */
1487#if SL_MAJOR_VERSION_NUM < 2
1488
1489#define SL_ERROR_BSD_EAGAIN SL_EAGAIN
1490#define SL_ERROR_BSD_EALREADY SL_EALREADY
1491#define SL_ERROR_BSD_ENOPROTOOPT SL_ENOPROTOOPT
1492#define SL_ERROR_BSD_ESECDATEERROR SL_ESECDATEERROR
1493#define SL_ERROR_BSD_ESECSNOVERIFY SL_ESECSNOVERIFY
1494#define SL_ERROR_FS_FAILED_TO_ALLOCATE_MEM SL_FS_ERR_FAILED_TO_ALLOCATE_MEM
1495#define SL_ERROR_FS_FILE_HAS_NOT_BEEN_CLOSE_CORRECTLY \
1496 SL_FS_FILE_HAS_NOT_BEEN_CLOSE_CORRECTLY
1497#define SL_ERROR_FS_FILE_NAME_EXIST SL_FS_FILE_NAME_EXIST
1498#define SL_ERROR_FS_FILE_NOT_EXISTS SL_FS_ERR_FILE_NOT_EXISTS
1499#define SL_ERROR_FS_NO_AVAILABLE_NV_INDEX SL_FS_ERR_NO_AVAILABLE_NV_INDEX
1500#define SL_ERROR_FS_NOT_ENOUGH_STORAGE_SPACE SL_FS_ERR_NO_AVAILABLE_BLOCKS
1501#define SL_ERROR_FS_NOT_SUPPORTED SL_FS_ERR_NOT_SUPPORTED
1502#define SL_ERROR_FS_WRONG_FILE_NAME SL_FS_WRONG_FILE_NAME
1503#define SL_ERROR_FS_INVALID_HANDLE SL_FS_ERR_INVALID_HANDLE
1504#define SL_NETCFG_MAC_ADDRESS_GET SL_MAC_ADDRESS_GET
1505#define SL_SOCKET_FD_ZERO SL_FD_ZERO
1506#define SL_SOCKET_FD_SET SL_FD_SET
1507#define SL_SOCKET_FD_ISSET SL_FD_ISSET
1508#define SL_SO_SECURE_DOMAIN_NAME_VERIFICATION SO_SECURE_DOMAIN_NAME_VERIFICATION
1509
1510#define SL_FS_READ FS_MODE_OPEN_READ
1511#define SL_FS_WRITE FS_MODE_OPEN_WRITE
1512
1513#define SL_FI_FILE_SIZE(fi) ((fi).FileLen)
1514#define SL_FI_FILE_MAX_SIZE(fi) ((fi).AllocatedLen)
1515
1516#define SlDeviceVersion_t SlVersionFull
1517#define sl_DeviceGet sl_DevGet
1518#define SL_DEVICE_GENERAL SL_DEVICE_GENERAL_CONFIGURATION
1519#define SL_LEN_TYPE _u8
1520#define SL_OPT_TYPE _u8
1521
1522#else /* SL_MAJOR_VERSION_NUM >= 2 */
1523
1524#define FS_MODE_OPEN_CREATE(max_size, flag) \
1525 (SL_FS_CREATE | SL_FS_CREATE_MAX_SIZE(max_size))
1526#define SL_FI_FILE_SIZE(fi) ((fi).Len)
1527#define SL_FI_FILE_MAX_SIZE(fi) ((fi).MaxSize)
1528
1529#define SL_LEN_TYPE _u16
1530#define SL_OPT_TYPE _u16
1531
1532#endif /* SL_MAJOR_VERSION_NUM < 2 */
1533
1534int slfs_open(const unsigned char *fname, uint32_t flags, uint32_t *token);
1535
1536#endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK */
1537
1538#endif /* CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_ */
1539#ifdef MG_MODULE_LINES
1540#line 1 "common/platforms/platform_wince.h"
1541#endif
1542#ifndef CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_
1543#define CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_
1544
1545#if CS_PLATFORM == CS_P_WINCE
1546
1547/*
1548 * MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
1549 * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
1550 * MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
1551 * MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
1552 * MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
1553 * MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
1554 * MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio 2003)
1555 * MSVC++ 7.0 _MSC_VER == 1300
1556 * MSVC++ 6.0 _MSC_VER == 1200
1557 * MSVC++ 5.0 _MSC_VER == 1100
1558 */
1559#pragma warning(disable : 4127) /* FD_SET() emits warning, disable it */
1560#pragma warning(disable : 4204) /* missing c99 support */
1561
1562#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
1563#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
1564#endif
1565
1566#ifndef _CRT_SECURE_NO_WARNINGS
1567#define _CRT_SECURE_NO_WARNINGS
1568#endif
1569
1570#include <assert.h>
1571#include <limits.h>
1572#include <stddef.h>
1573#include <stdio.h>
1574#include <stdlib.h>
1575#include <time.h>
1576
1577#pragma comment(lib, "ws2.lib") /* Linking with WinCE winsock library */
1578
1579#include <winsock2.h>
1580#include <ws2tcpip.h>
1581#include <windows.h>
1582
1583#define strdup _strdup
1584
1585#ifndef EINPROGRESS
1586#define EINPROGRESS WSAEINPROGRESS
1587#endif
1588
1589#ifndef EWOULDBLOCK
1590#define EWOULDBLOCK WSAEWOULDBLOCK
1591#endif
1592
1593#ifndef EAGAIN
1594#define EAGAIN EWOULDBLOCK
1595#endif
1596
1597#ifndef __func__
1598#define STRX(x) #x
1599#define STR(x) STRX(x)
1600#define __func__ __FILE__ ":" STR(__LINE__)
1601#endif
1602
1603#define snprintf _snprintf
1604#define fileno _fileno
1605#define vsnprintf _vsnprintf
1606#define sleep(x) Sleep((x) *1000)
1607#define to64(x) _atoi64(x)
1608#define rmdir _rmdir
1609
1610#if defined(_MSC_VER) && _MSC_VER >= 1400
1611#define fseeko(x, y, z) _fseeki64((x), (y), (z))
1612#else
1613#define fseeko(x, y, z) fseek((x), (y), (z))
1614#endif
1615
1616typedef int socklen_t;
1617
1618#if _MSC_VER >= 1700
1619#include <stdint.h>
1620#else
1621typedef signed char int8_t;
1622typedef unsigned char uint8_t;
1623typedef int int32_t;
1624typedef unsigned int uint32_t;
1625typedef short int16_t;
1626typedef unsigned short uint16_t;
1627typedef __int64 int64_t;
1628typedef unsigned __int64 uint64_t;
1629#endif
1630
1631typedef SOCKET sock_t;
1632typedef uint32_t in_addr_t;
1633
1634#ifndef UINT16_MAX
1635#define UINT16_MAX 65535
1636#endif
1637
1638#ifndef UINT32_MAX
1639#define UINT32_MAX 4294967295
1640#endif
1641
1642#ifndef pid_t
1643#define pid_t HANDLE
1644#endif
1645
1646#define INT64_FMT "I64d"
1647#define INT64_X_FMT "I64x"
1648/* TODO(alashkin): check if this is correct */
1649#define SIZE_T_FMT "u"
1650
1651#define DIRSEP '\\'
1652#define CS_DEFINE_DIRENT
1653
1654#ifndef va_copy
1655#ifdef __va_copy
1656#define va_copy __va_copy
1657#else
1658#define va_copy(x, y) (x) = (y)
1659#endif
1660#endif
1661
1662#ifndef MG_MAX_HTTP_REQUEST_SIZE
1663#define MG_MAX_HTTP_REQUEST_SIZE 8192
1664#endif
1665
1666#ifndef MG_MAX_HTTP_SEND_MBUF
1667#define MG_MAX_HTTP_SEND_MBUF 4096
1668#endif
1669
1670#ifndef MG_MAX_HTTP_HEADERS
1671#define MG_MAX_HTTP_HEADERS 40
1672#endif
1673
1674#ifndef CS_ENABLE_STDIO
1675#define CS_ENABLE_STDIO 1
1676#endif
1677
1678#define abort() DebugBreak();
1679
1680#ifndef BUFSIZ
1681#define BUFSIZ 4096
1682#endif
1683/*
1684 * Explicitly disabling MG_ENABLE_THREADS for WinCE
1685 * because they are enabled for _WIN32 by default
1686 */
1687#ifndef MG_ENABLE_THREADS
1688#define MG_ENABLE_THREADS 0
1689#endif
1690
1691#ifndef MG_ENABLE_FILESYSTEM
1692#define MG_ENABLE_FILESYSTEM 1
1693#endif
1694
1695#ifndef MG_NET_IF
1696#define MG_NET_IF MG_NET_IF_SOCKET
1697#endif
1698
1699typedef struct _stati64 {
1703} cs_stat_t;
1704
1705/*
1706 * WinCE 6.0 has a lot of useful definitions in ATL (not windows.h) headers
1707 * use #ifdefs to avoid conflicts
1708 */
1709
1710#ifndef ENOENT
1711#define ENOENT ERROR_PATH_NOT_FOUND
1712#endif
1713
1714#ifndef EACCES
1715#define EACCES ERROR_ACCESS_DENIED
1716#endif
1717
1718#ifndef ENOMEM
1719#define ENOMEM ERROR_NOT_ENOUGH_MEMORY
1720#endif
1721
1722#ifndef _UINTPTR_T_DEFINED
1723typedef unsigned int *uintptr_t;
1724#endif
1725
1726#define _S_IFREG 2
1727#define _S_IFDIR 4
1728
1729#ifndef S_ISDIR
1730#define S_ISDIR(x) (((x) &_S_IFDIR) != 0)
1731#endif
1732
1733#ifndef S_ISREG
1734#define S_ISREG(x) (((x) &_S_IFREG) != 0)
1735#endif
1736
1737int open(const char *filename, int oflag, int pmode);
1738int _wstati64(const wchar_t *path, cs_stat_t *st);
1739const char *strerror();
1740
1741#endif /* CS_PLATFORM == CS_P_WINCE */
1742#endif /* CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_ */
1743#ifdef MG_MODULE_LINES
1744#line 1 "common/platforms/platform_nxp_lpc.h"
1745#endif
1746/*
1747 * Copyright (c) 2014-2018 Cesanta Software Limited
1748 * All rights reserved
1749 *
1750 * Licensed under the Apache License, Version 2.0 (the ""License"");
1751 * you may not use this file except in compliance with the License.
1752 * You may obtain a copy of the License at
1753 *
1754 * http://www.apache.org/licenses/LICENSE-2.0
1755 *
1756 * Unless required by applicable law or agreed to in writing, software
1757 * distributed under the License is distributed on an ""AS IS"" BASIS,
1758 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1759 * See the License for the specific language governing permissions and
1760 * limitations under the License.
1761 */
1762
1763#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_
1764#define CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_
1765
1766#if CS_PLATFORM == CS_P_NXP_LPC
1767
1768#include <ctype.h>
1769#include <stdint.h>
1770#include <string.h>
1771
1772#define SIZE_T_FMT "u"
1773typedef struct stat cs_stat_t;
1774#define INT64_FMT "lld"
1775#define INT64_X_FMT "llx"
1776#define __cdecl
1777
1778#define MG_LWIP 1
1779
1780#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1781
1782/*
1783 * LPCXpress comes with 3 C library implementations: Newlib, NewlibNano and
1784 *Redlib.
1785 * See https://community.nxp.com/message/630860 for more details.
1786 *
1787 * Redlib is the default and lacks certain things, so we provide them.
1788 */
1789#ifdef __REDLIB_INTERFACE_VERSION__
1790
1791/* Let LWIP define timeval for us. */
1792#define LWIP_TIMEVAL_PRIVATE 1
1793
1794#define va_copy(d, s) __builtin_va_copy(d, s)
1795
1796#define CS_ENABLE_TO64 1
1797#define to64(x) cs_to64(x)
1798
1799#define CS_ENABLE_STRDUP 1
1800
1801#else
1802
1803#include <sys/time.h>
1804#define LWIP_TIMEVAL_PRIVATE 0
1805#define to64(x) strtoll(x, NULL, 10)
1806
1807#endif
1808
1809#endif /* CS_PLATFORM == CS_P_NXP_LPC */
1810#endif /* CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_ */
1811#ifdef MG_MODULE_LINES
1812#line 1 "common/platforms/platform_nxp_kinetis.h"
1813#endif
1814/*
1815 * Copyright (c) 2014-2018 Cesanta Software Limited
1816 * All rights reserved
1817 *
1818 * Licensed under the Apache License, Version 2.0 (the ""License"");
1819 * you may not use this file except in compliance with the License.
1820 * You may obtain a copy of the License at
1821 *
1822 * http://www.apache.org/licenses/LICENSE-2.0
1823 *
1824 * Unless required by applicable law or agreed to in writing, software
1825 * distributed under the License is distributed on an ""AS IS"" BASIS,
1826 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1827 * See the License for the specific language governing permissions and
1828 * limitations under the License.
1829 */
1830
1831#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_
1832#define CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_
1833
1834#if CS_PLATFORM == CS_P_NXP_KINETIS
1835
1836#include <ctype.h>
1837#include <inttypes.h>
1838#include <string.h>
1839#include <sys/time.h>
1840
1841#define SIZE_T_FMT "u"
1842typedef struct stat cs_stat_t;
1843#define to64(x) strtoll(x, NULL, 10)
1844#define INT64_FMT "lld"
1845#define INT64_X_FMT "llx"
1846#define __cdecl
1847
1848#define MG_LWIP 1
1849
1850#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1851
1852/* struct timeval is defined in sys/time.h. */
1853#define LWIP_TIMEVAL_PRIVATE 0
1854
1855#endif /* CS_PLATFORM == CS_P_NXP_KINETIS */
1856#endif /* CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_ */
1857#ifdef MG_MODULE_LINES
1858#line 1 "common/platforms/platform_pic32.h"
1859#endif
1860/*
1861 * Copyright (c) 2014-2018 Cesanta Software Limited
1862 * All rights reserved
1863 *
1864 * Licensed under the Apache License, Version 2.0 (the ""License"");
1865 * you may not use this file except in compliance with the License.
1866 * You may obtain a copy of the License at
1867 *
1868 * http://www.apache.org/licenses/LICENSE-2.0
1869 *
1870 * Unless required by applicable law or agreed to in writing, software
1871 * distributed under the License is distributed on an ""AS IS"" BASIS,
1872 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1873 * See the License for the specific language governing permissions and
1874 * limitations under the License.
1875 */
1876
1877#ifndef CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_
1878#define CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_
1879
1880#if CS_PLATFORM == CS_P_PIC32
1881
1882#define MG_NET_IF MG_NET_IF_PIC32
1883
1884#include <stdint.h>
1885#include <time.h>
1886#include <ctype.h>
1887#include <stdlib.h>
1888
1889#include <system_config.h>
1890#include <system_definitions.h>
1891
1892#include <sys/types.h>
1893
1894typedef TCP_SOCKET sock_t;
1895#define to64(x) strtoll(x, NULL, 10)
1896
1897#define SIZE_T_FMT "lu"
1898#define INT64_FMT "lld"
1899
1900#ifndef CS_ENABLE_STDIO
1901#define CS_ENABLE_STDIO 1
1902#endif
1903
1904char *inet_ntoa(struct in_addr in);
1905
1906#endif /* CS_PLATFORM == CS_P_PIC32 */
1907
1908#endif /* CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_ */
1909#ifdef MG_MODULE_LINES
1910#line 1 "common/platforms/platform_stm32.h"
1911#endif
1912/*
1913 * Copyright (c) 2014-2018 Cesanta Software Limited
1914 * All rights reserved
1915 *
1916 * Licensed under the Apache License, Version 2.0 (the ""License"");
1917 * you may not use this file except in compliance with the License.
1918 * You may obtain a copy of the License at
1919 *
1920 * http://www.apache.org/licenses/LICENSE-2.0
1921 *
1922 * Unless required by applicable law or agreed to in writing, software
1923 * distributed under the License is distributed on an ""AS IS"" BASIS,
1924 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1925 * See the License for the specific language governing permissions and
1926 * limitations under the License.
1927 */
1928
1929#ifndef CS_COMMON_PLATFORMS_PLATFORM_STM32_H_
1930#define CS_COMMON_PLATFORMS_PLATFORM_STM32_H_
1931#if CS_PLATFORM == CS_P_STM32
1932
1933#include <ctype.h>
1934#include <errno.h>
1935#include <fcntl.h>
1936#include <stdint.h>
1937#include <stdio.h>
1938#include <string.h>
1939#include <sys/stat.h>
1940#include <sys/time.h>
1941#include <sys/types.h>
1942#include <unistd.h>
1943#include <dirent.h>
1944
1945#include <stm32_sdk_hal.h>
1946
1947#define to64(x) strtoll(x, NULL, 10)
1948#define INT64_FMT "lld"
1949#define SIZE_T_FMT "u"
1950typedef struct stat cs_stat_t;
1951#define DIRSEP '/'
1952
1953#ifndef CS_ENABLE_STDIO
1954#define CS_ENABLE_STDIO 1
1955#endif
1956
1957#ifndef MG_ENABLE_FILESYSTEM
1958#define MG_ENABLE_FILESYSTEM 1
1959#endif
1960
1961#endif /* CS_PLATFORM == CS_P_STM32 */
1962#endif /* CS_COMMON_PLATFORMS_PLATFORM_STM32_H_ */
1963#ifdef MG_MODULE_LINES
1964#line 1 "common/platforms/lwip/mg_lwip.h"
1965#endif
1966/*
1967 * Copyright (c) 2014-2018 Cesanta Software Limited
1968 * All rights reserved
1969 *
1970 * Licensed under the Apache License, Version 2.0 (the ""License"");
1971 * you may not use this file except in compliance with the License.
1972 * You may obtain a copy of the License at
1973 *
1974 * http://www.apache.org/licenses/LICENSE-2.0
1975 *
1976 * Unless required by applicable law or agreed to in writing, software
1977 * distributed under the License is distributed on an ""AS IS"" BASIS,
1978 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1979 * See the License for the specific language governing permissions and
1980 * limitations under the License.
1981 */
1982
1983#ifndef CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
1984#define CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
1985
1986#ifndef MG_LWIP
1987#define MG_LWIP 0
1988#endif
1989
1990#if MG_LWIP
1991
1992/*
1993 * When compiling for nRF5x chips with arm-none-eabi-gcc, it has BYTE_ORDER
1994 * already defined, so in order to avoid warnings in lwip, we have to undefine
1995 * it.
1996 *
1997 * TODO: Check if in the future versions of nRF5 SDK that changes.
1998 * Current version of nRF51 SDK: 0.8.0
1999 * nRF5 SDK: 0.9.0
2000 */
2001#if CS_PLATFORM == CS_P_NRF51 || CS_PLATFORM == CS_P_NRF52
2002#undef BYTE_ORDER
2003#endif
2004
2005#include <lwip/opt.h>
2006#include <lwip/err.h>
2007#include <lwip/ip_addr.h>
2008#include <lwip/inet.h>
2009#include <lwip/netdb.h>
2010#include <lwip/dns.h>
2011
2012#ifndef LWIP_PROVIDE_ERRNO
2013#include <errno.h>
2014#endif
2015
2016#if LWIP_SOCKET
2017#include <lwip/sockets.h>
2018#else
2019/* We really need the definitions from sockets.h. */
2020#undef LWIP_SOCKET
2021#define LWIP_SOCKET 1
2022#include <lwip/sockets.h>
2023#undef LWIP_SOCKET
2024#define LWIP_SOCKET 0
2025#endif
2026
2027#define INVALID_SOCKET (-1)
2028#define SOMAXCONN 10
2029typedef int sock_t;
2030
2031#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
2032struct mg_mgr;
2033struct mg_connection;
2035 int interval, int count);
2036#endif
2037
2038/* For older version of LWIP */
2039#ifndef ipX_2_ip
2040#define ipX_2_ip(x) (x)
2041#endif
2042
2043#endif /* MG_LWIP */
2044
2045#endif /* CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_ */
2046#ifdef MG_MODULE_LINES
2047#line 1 "common/cs_md5.h"
2048#endif
2049/*
2050 * Copyright (c) 2014-2018 Cesanta Software Limited
2051 * All rights reserved
2052 *
2053 * Licensed under the Apache License, Version 2.0 (the ""License"");
2054 * you may not use this file except in compliance with the License.
2055 * You may obtain a copy of the License at
2056 *
2057 * http://www.apache.org/licenses/LICENSE-2.0
2058 *
2059 * Unless required by applicable law or agreed to in writing, software
2060 * distributed under the License is distributed on an ""AS IS"" BASIS,
2061 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2062 * See the License for the specific language governing permissions and
2063 * limitations under the License.
2064 */
2065
2066#ifndef CS_COMMON_MD5_H_
2067#define CS_COMMON_MD5_H_
2068
2069/* Amalgamated: #include "common/platform.h" */
2070
2071#ifndef CS_DISABLE_MD5
2072#define CS_DISABLE_MD5 0
2073#endif
2074
2075#ifdef __cplusplus
2076extern "C" {
2077#endif /* __cplusplus */
2078
2079typedef struct {
2081 uint32_t bits[2];
2082 unsigned char in[64];
2083} cs_md5_ctx;
2084
2085void cs_md5_init(cs_md5_ctx *c);
2086void cs_md5_update(cs_md5_ctx *c, const unsigned char *data, size_t len);
2087void cs_md5_final(unsigned char *md, cs_md5_ctx *c);
2088
2089#ifdef __cplusplus
2090}
2091#endif /* __cplusplus */
2092
2093#endif /* CS_COMMON_MD5_H_ */
2094#ifdef MG_MODULE_LINES
2095#line 1 "common/cs_sha1.h"
2096#endif
2097/*
2098 * Copyright (c) 2014-2018 Cesanta Software Limited
2099 * All rights reserved
2100 *
2101 * Licensed under the Apache License, Version 2.0 (the ""License"");
2102 * you may not use this file except in compliance with the License.
2103 * You may obtain a copy of the License at
2104 *
2105 * http://www.apache.org/licenses/LICENSE-2.0
2106 *
2107 * Unless required by applicable law or agreed to in writing, software
2108 * distributed under the License is distributed on an ""AS IS"" BASIS,
2109 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2110 * See the License for the specific language governing permissions and
2111 * limitations under the License.
2112 */
2113
2114#ifndef CS_COMMON_SHA1_H_
2115#define CS_COMMON_SHA1_H_
2116
2117#ifndef CS_DISABLE_SHA1
2118#define CS_DISABLE_SHA1 0
2119#endif
2120
2121#if !CS_DISABLE_SHA1
2122
2123/* Amalgamated: #include "common/platform.h" */
2124
2125#ifdef __cplusplus
2126extern "C" {
2127#endif /* __cplusplus */
2128
2129typedef struct {
2130 uint32_t state[5];
2131 uint32_t count[2];
2132 unsigned char buffer[64];
2133} cs_sha1_ctx;
2134
2136void cs_sha1_update(cs_sha1_ctx *, const unsigned char *data, uint32_t len);
2137void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *);
2138void cs_hmac_sha1(const unsigned char *key, size_t key_len,
2139 const unsigned char *text, size_t text_len,
2140 unsigned char out[20]);
2141#ifdef __cplusplus
2142}
2143#endif /* __cplusplus */
2144
2145#endif /* CS_DISABLE_SHA1 */
2146
2147#endif /* CS_COMMON_SHA1_H_ */
2148#ifdef MG_MODULE_LINES
2149#line 1 "common/cs_time.h"
2150#endif
2151/*
2152 * Copyright (c) 2014-2018 Cesanta Software Limited
2153 * All rights reserved
2154 *
2155 * Licensed under the Apache License, Version 2.0 (the ""License"");
2156 * you may not use this file except in compliance with the License.
2157 * You may obtain a copy of the License at
2158 *
2159 * http://www.apache.org/licenses/LICENSE-2.0
2160 *
2161 * Unless required by applicable law or agreed to in writing, software
2162 * distributed under the License is distributed on an ""AS IS"" BASIS,
2163 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2164 * See the License for the specific language governing permissions and
2165 * limitations under the License.
2166 */
2167
2168#ifndef CS_COMMON_CS_TIME_H_
2169#define CS_COMMON_CS_TIME_H_
2170
2171#include <time.h>
2172
2173/* Amalgamated: #include "common/platform.h" */
2174
2175#ifdef __cplusplus
2176extern "C" {
2177#endif /* __cplusplus */
2178
2179/* Sub-second granularity time(). */
2180double cs_time(void);
2181
2182/*
2183 * Similar to (non-standard) timegm, converts broken-down time into the number
2184 * of seconds since Unix Epoch.
2185 */
2186double cs_timegm(const struct tm *tm);
2187
2188#ifdef __cplusplus
2189}
2190#endif /* __cplusplus */
2191
2192#endif /* CS_COMMON_CS_TIME_H_ */
2193#ifdef MG_MODULE_LINES
2194#line 1 "common/mg_str.h"
2195#endif
2196/*
2197 * Copyright (c) 2014-2018 Cesanta Software Limited
2198 * All rights reserved
2199 *
2200 * Licensed under the Apache License, Version 2.0 (the ""License"");
2201 * you may not use this file except in compliance with the License.
2202 * You may obtain a copy of the License at
2203 *
2204 * http://www.apache.org/licenses/LICENSE-2.0
2205 *
2206 * Unless required by applicable law or agreed to in writing, software
2207 * distributed under the License is distributed on an ""AS IS"" BASIS,
2208 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2209 * See the License for the specific language governing permissions and
2210 * limitations under the License.
2211 */
2212
2213#ifndef CS_COMMON_MG_STR_H_
2214#define CS_COMMON_MG_STR_H_
2215
2216#include <stddef.h>
2217
2218#ifdef __cplusplus
2219extern "C" {
2220#endif
2221
2222/* Describes chunk of memory */
2223struct mg_str {
2224 const char *p; /* Memory chunk pointer */
2225 size_t len; /* Memory chunk length */
2226};
2227
2228/*
2229 * Helper function for creating mg_str struct from plain C string.
2230 * `NULL` is allowed and becomes `{NULL, 0}`.
2231 */
2232struct mg_str mg_mk_str(const char *s);
2233
2234/*
2235 * Like `mg_mk_str`, but takes string length explicitly.
2236 */
2237struct mg_str mg_mk_str_n(const char *s, size_t len);
2238
2239/* Macro for initializing mg_str. */
2240#define MG_MK_STR(str_literal) \
2241 { str_literal, sizeof(str_literal) - 1 }
2242#define MG_MK_STR_N(str_literal, len) \
2243 { str_literal, len }
2244#define MG_NULL_STR \
2245 { NULL, 0 }
2246
2247/*
2248 * Cross-platform version of `strcmp()` where where first string is
2249 * specified by `struct mg_str`.
2250 */
2251int mg_vcmp(const struct mg_str *str2, const char *str1);
2252
2253/*
2254 * Cross-platform version of `strncasecmp()` where first string is
2255 * specified by `struct mg_str`.
2256 */
2257int mg_vcasecmp(const struct mg_str *str2, const char *str1);
2258
2259/* Creates a copy of s (heap-allocated). */
2261
2262/*
2263 * Creates a copy of s (heap-allocated).
2264 * Resulting string is NUL-terminated (but NUL is not included in len).
2265 */
2267
2268/*
2269 * Locates character in a string.
2270 */
2271const char *mg_strchr(const struct mg_str s, int c);
2272
2273/*
2274 * Compare two `mg_str`s; return value is the same as `strcmp`.
2275 */
2276int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
2277
2278/*
2279 * Like `mg_strcmp`, but compares at most `n` characters.
2280 */
2281int mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n);
2282
2283/*
2284 * Free the string (assuming it was heap allocated).
2285 */
2286void mg_strfree(struct mg_str *s);
2287
2288/*
2289 * Finds the first occurrence of a substring `needle` in the `haystack`.
2290 */
2291const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle);
2292
2293/* Strip whitespace at the start and the end of s */
2295
2296/* Returns 1 if s starts with the given prefix. */
2297int mg_str_starts_with(struct mg_str s, struct mg_str prefix);
2298
2299#ifdef __cplusplus
2300}
2301#endif
2302
2303#endif /* CS_COMMON_MG_STR_H_ */
2304#ifdef MG_MODULE_LINES
2305#line 1 "common/mbuf.h"
2306#endif
2307/*
2308 * Copyright (c) 2014-2018 Cesanta Software Limited
2309 * All rights reserved
2310 *
2311 * Licensed under the Apache License, Version 2.0 (the ""License"");
2312 * you may not use this file except in compliance with the License.
2313 * You may obtain a copy of the License at
2314 *
2315 * http://www.apache.org/licenses/LICENSE-2.0
2316 *
2317 * Unless required by applicable law or agreed to in writing, software
2318 * distributed under the License is distributed on an ""AS IS"" BASIS,
2319 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2320 * See the License for the specific language governing permissions and
2321 * limitations under the License.
2322 */
2323
2324/*
2325 * Mbufs are mutable/growing memory buffers, like C++ strings.
2326 * Mbuf can append data to the end of a buffer or insert data into arbitrary
2327 * position in the middle of a buffer. The buffer grows automatically when
2328 * needed.
2329 */
2330
2331#ifndef CS_COMMON_MBUF_H_
2332#define CS_COMMON_MBUF_H_
2333
2334#include <stdlib.h>
2335/* Amalgamated: #include "common/platform.h" */
2336
2337#if defined(__cplusplus)
2338extern "C" {
2339#endif
2340
2341#ifndef MBUF_SIZE_MULTIPLIER
2342#define MBUF_SIZE_MULTIPLIER 1.5
2343#endif
2344
2345#ifndef MBUF_SIZE_MAX_HEADROOM
2346#ifdef BUFSIZ
2347#define MBUF_SIZE_MAX_HEADROOM BUFSIZ
2348#else
2349#define MBUF_SIZE_MAX_HEADROOM 1024
2350#endif
2351#endif
2352
2353/* Memory buffer descriptor */
2354struct mbuf {
2355 char *buf; /* Buffer pointer */
2356 size_t len; /* Data length. Data is located between offset 0 and len. */
2357 size_t size; /* Buffer size allocated by realloc(1). Must be >= len */
2358};
2359
2360/*
2361 * Initialises an Mbuf.
2362 * `initial_capacity` specifies the initial capacity of the mbuf.
2363 */
2364void mbuf_init(struct mbuf *, size_t initial_capacity);
2365
2366/* Frees the space allocated for the mbuffer and resets the mbuf structure. */
2367void mbuf_free(struct mbuf *);
2368
2369/*
2370 * Appends data to the Mbuf.
2371 *
2372 * Returns the number of bytes appended or 0 if out of memory.
2373 */
2374size_t mbuf_append(struct mbuf *, const void *data, size_t data_size);
2375
2376/*
2377 * Appends data to the Mbuf and frees it (data must be heap-allocated).
2378 *
2379 * Returns the number of bytes appended or 0 if out of memory.
2380 * data is freed irrespective of return value.
2381 */
2382size_t mbuf_append_and_free(struct mbuf *, void *data, size_t data_size);
2383
2384/*
2385 * Inserts data at a specified offset in the Mbuf.
2386 *
2387 * Existing data will be shifted forwards and the buffer will
2388 * be grown if necessary.
2389 * Returns the number of bytes inserted.
2390 */
2391size_t mbuf_insert(struct mbuf *, size_t, const void *, size_t);
2392
2393/* Removes `data_size` bytes from the beginning of the buffer. */
2394void mbuf_remove(struct mbuf *, size_t data_size);
2395
2396/*
2397 * Resizes an Mbuf.
2398 *
2399 * If `new_size` is smaller than buffer's `len`, the
2400 * resize is not performed.
2401 */
2402void mbuf_resize(struct mbuf *, size_t new_size);
2403
2404/* Moves the state from one mbuf to the other. */
2405void mbuf_move(struct mbuf *from, struct mbuf *to);
2406
2407/* Removes all the data from mbuf (if any). */
2408void mbuf_clear(struct mbuf *);
2409
2410/* Shrinks an Mbuf by resizing its `size` to `len`. */
2411void mbuf_trim(struct mbuf *);
2412
2413#if defined(__cplusplus)
2414}
2415#endif /* __cplusplus */
2416
2417#endif /* CS_COMMON_MBUF_H_ */
2418#ifdef MG_MODULE_LINES
2419#line 1 "common/cs_base64.h"
2420#endif
2421/*
2422 * Copyright (c) 2014-2018 Cesanta Software Limited
2423 * All rights reserved
2424 *
2425 * Licensed under the Apache License, Version 2.0 (the ""License"");
2426 * you may not use this file except in compliance with the License.
2427 * You may obtain a copy of the License at
2428 *
2429 * http://www.apache.org/licenses/LICENSE-2.0
2430 *
2431 * Unless required by applicable law or agreed to in writing, software
2432 * distributed under the License is distributed on an ""AS IS"" BASIS,
2433 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2434 * See the License for the specific language governing permissions and
2435 * limitations under the License.
2436 */
2437
2438#ifndef CS_COMMON_CS_BASE64_H_
2439#define CS_COMMON_CS_BASE64_H_
2440
2441#ifndef DISABLE_BASE64
2442#define DISABLE_BASE64 0
2443#endif
2444
2445#if !DISABLE_BASE64
2446
2447#include <stdio.h>
2448
2449#ifdef __cplusplus
2450extern "C" {
2451#endif
2452
2453typedef void (*cs_base64_putc_t)(char, void *);
2454
2455struct cs_base64_ctx {
2456 /* cannot call it putc because it's a macro on some environments */
2458 unsigned char chunk[3];
2459 int chunk_size;
2460 void *user_data;
2461};
2462
2464 void *user_data);
2465void cs_base64_update(struct cs_base64_ctx *ctx, const char *str, size_t len);
2466void cs_base64_finish(struct cs_base64_ctx *ctx);
2467
2468void cs_base64_encode(const unsigned char *src, int src_len, char *dst);
2469void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len);
2470
2471/*
2472 * Decodes a base64 string `s` length `len` into `dst`.
2473 * `dst` must have enough space to hold the result.
2474 * `*dec_len` will contain the resulting length of the string in `dst`
2475 * while return value will return number of processed bytes in `src`.
2476 * Return value == len indicates successful processing of all the data.
2477 */
2478int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len);
2479
2480#ifdef __cplusplus
2481}
2482#endif
2483
2484#endif /* DISABLE_BASE64 */
2485
2486#endif /* CS_COMMON_CS_BASE64_H_ */
2487#ifdef MG_MODULE_LINES
2488#line 1 "common/str_util.h"
2489#endif
2490/*
2491 * Copyright (c) 2014-2018 Cesanta Software Limited
2492 * All rights reserved
2493 *
2494 * Licensed under the Apache License, Version 2.0 (the ""License"");
2495 * you may not use this file except in compliance with the License.
2496 * You may obtain a copy of the License at
2497 *
2498 * http://www.apache.org/licenses/LICENSE-2.0
2499 *
2500 * Unless required by applicable law or agreed to in writing, software
2501 * distributed under the License is distributed on an ""AS IS"" BASIS,
2502 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2503 * See the License for the specific language governing permissions and
2504 * limitations under the License.
2505 */
2506
2507#ifndef CS_COMMON_STR_UTIL_H_
2508#define CS_COMMON_STR_UTIL_H_
2509
2510#include <stdarg.h>
2511#include <stdlib.h>
2512
2513/* Amalgamated: #include "common/mg_str.h" */
2514/* Amalgamated: #include "common/platform.h" */
2515
2516#ifndef CS_ENABLE_STRDUP
2517#define CS_ENABLE_STRDUP 0
2518#endif
2519
2520#ifndef CS_ENABLE_TO64
2521#define CS_ENABLE_TO64 0
2522#endif
2523
2524/*
2525 * Expands to a string representation of its argument: e.g.
2526 * `CS_STRINGIFY_LIT(5) expands to "5"`
2527 */
2528#if !defined(_MSC_VER) || _MSC_VER >= 1900
2529#define CS_STRINGIFY_LIT(...) #__VA_ARGS__
2530#else
2531#define CS_STRINGIFY_LIT(x) #x
2532#endif
2533
2534/*
2535 * Expands to a string representation of its argument, which is allowed
2536 * to be a macro: e.g.
2537 *
2538 * #define FOO 123
2539 * CS_STRINGIFY_MACRO(FOO)
2540 *
2541 * expands to 123.
2542 */
2543#define CS_STRINGIFY_MACRO(x) CS_STRINGIFY_LIT(x)
2544
2545#ifdef __cplusplus
2546extern "C" {
2547#endif
2548
2549/*
2550 * Equivalent of standard `strnlen()`.
2551 */
2552size_t c_strnlen(const char *s, size_t maxlen);
2553
2554/*
2555 * Equivalent of standard `snprintf()`.
2556 */
2557int c_snprintf(char *buf, size_t buf_size, const char *format, ...)
2558 PRINTF_LIKE(3, 4);
2559
2560/*
2561 * Equivalent of standard `vsnprintf()`.
2562 */
2563int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap);
2564
2565/*
2566 * Find the first occurrence of find in s, where the search is limited to the
2567 * first slen characters of s.
2568 */
2569const char *c_strnstr(const char *s, const char *find, size_t slen);
2570
2571/*
2572 * Stringify binary data. Output buffer size must be 2 * size_of_input + 1
2573 * because each byte of input takes 2 bytes in string representation
2574 * plus 1 byte for the terminating \0 character.
2575 */
2576void cs_to_hex(char *to, const unsigned char *p, size_t len);
2577
2578/*
2579 * Convert stringified binary data back to binary.
2580 * Does the reverse of `cs_to_hex()`.
2581 */
2582void cs_from_hex(char *to, const char *p, size_t len);
2583
2584#if CS_ENABLE_STRDUP
2585/*
2586 * Equivalent of standard `strdup()`, defined if only `CS_ENABLE_STRDUP` is 1.
2587 */
2588char *strdup(const char *src);
2589#endif
2590
2591#if CS_ENABLE_TO64
2592#include <stdint.h>
2593/*
2594 * Simple string -> int64 conversion routine.
2595 */
2596int64_t cs_to64(const char *s);
2597#endif
2598
2599/*
2600 * Cross-platform version of `strncasecmp()`.
2601 */
2602int mg_ncasecmp(const char *s1, const char *s2, size_t len);
2603
2604/*
2605 * Cross-platform version of `strcasecmp()`.
2606 */
2607int mg_casecmp(const char *s1, const char *s2);
2608
2609/*
2610 * Prints message to the buffer. If the buffer is large enough to hold the
2611 * message, it returns buffer. If buffer is to small, it allocates a large
2612 * enough buffer on heap and returns allocated buffer.
2613 * This is a supposed use case:
2614 *
2615 * ```c
2616 * char buf[5], *p = buf;
2617 * mg_avprintf(&p, sizeof(buf), "%s", "hi there");
2618 * use_p_somehow(p);
2619 * if (p != buf) {
2620 * free(p);
2621 * }
2622 * ```
2623 *
2624 * The purpose of this is to avoid malloc-ing if generated strings are small.
2625 */
2626int mg_asprintf(char **buf, size_t size, const char *fmt, ...)
2627 PRINTF_LIKE(3, 4);
2628
2629/* Same as mg_asprintf, but takes varargs list. */
2630int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
2631
2632/*
2633 * A helper function for traversing a comma separated list of values.
2634 * It returns a list pointer shifted to the next value or NULL if the end
2635 * of the list found.
2636 * The value is stored in a val vector. If the value has a form "x=y", then
2637 * eq_val vector is initialised to point to the "y" part, and val vector length
2638 * is adjusted to point only to "x".
2639 * If the list is just a comma separated list of entries, like "aa,bb,cc" then
2640 * `eq_val` will contain zero-length string.
2641 *
2642 * The purpose of this function is to parse comma separated string without
2643 * any copying/memory allocation.
2644 */
2645const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
2646 struct mg_str *eq_val);
2647
2648/*
2649 * Like `mg_next_comma_list_entry()`, but takes `list` as `struct mg_str`.
2650 * NB: Test return value's .p, not .len. On last itreation that yields result
2651 * .len will be 0 but .p will not. When finished, .p will be NULL.
2652 */
2654 struct mg_str *eq_val);
2655
2656/*
2657 * Matches 0-terminated string (mg_match_prefix) or string with given length
2658 * mg_match_prefix_n against a glob pattern. Glob syntax:
2659 * ```
2660 * - * matches zero or more characters until a slash character /
2661 * - ** matches zero or more characters
2662 * - ? Matches exactly one character which is not a slash /
2663 * - | or , divides alternative patterns
2664 * - any other character matches itself
2665 * ```
2666 * Match is case-insensitive. Return number of bytes matched.
2667 * Examples:
2668 * ```
2669 * mg_match_prefix("a*f", len, "abcdefgh") == 6
2670 * mg_match_prefix("a*f", len, "abcdexgh") == 0
2671 * mg_match_prefix("a*f|de*,xy", len, "defgh") == 5
2672 * mg_match_prefix("?*", len, "abc") == 3
2673 * mg_match_prefix("?*", len, "") == 0
2674 * ```
2675 */
2676size_t mg_match_prefix(const char *pattern, int pattern_len, const char *str);
2677
2678/*
2679 * Like `mg_match_prefix()`, but takes `pattern` and `str` as `struct mg_str`.
2680 */
2681size_t mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str);
2682
2683#ifdef __cplusplus
2684}
2685#endif
2686
2687#endif /* CS_COMMON_STR_UTIL_H_ */
2688#ifdef MG_MODULE_LINES
2689#line 1 "common/queue.h"
2690#endif
2691/* clang-format off */
2692/*-
2693 * Copyright (c) 1991, 1993
2694 * The Regents of the University of California. All rights reserved.
2695 *
2696 * Redistribution and use in source and binary forms, with or without
2697 * modification, are permitted provided that the following conditions
2698 * are met:
2699 * 1. Redistributions of source code must retain the above copyright
2700 * notice, this list of conditions and the following disclaimer.
2701 * 2. Redistributions in binary form must reproduce the above copyright
2702 * notice, this list of conditions and the following disclaimer in the
2703 * documentation and/or other materials provided with the distribution.
2704 * 4. Neither the name of the University nor the names of its contributors
2705 * may be used to endorse or promote products derived from this software
2706 * without specific prior written permission.
2707 *
2708 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2709 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2710 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2711 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2712 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2713 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2714 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2715 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2716 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2717 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2718 * SUCH DAMAGE.
2719 *
2720 * @(#)queue.h 8.5 (Berkeley) 8/20/94
2721 * $FreeBSD$
2722 */
2723
2724#ifndef _SYS_QUEUE_H_
2725#define _SYS_QUEUE_H_
2726
2727/*
2728 * This file defines four types of data structures: singly-linked lists,
2729 * singly-linked tail queues, lists and tail queues.
2730 *
2731 * A singly-linked list is headed by a single forward pointer. The elements
2732 * are singly linked for minimum space and pointer manipulation overhead at
2733 * the expense of O(n) removal for arbitrary elements. New elements can be
2734 * added to the list after an existing element or at the head of the list.
2735 * Elements being removed from the head of the list should use the explicit
2736 * macro for this purpose for optimum efficiency. A singly-linked list may
2737 * only be traversed in the forward direction. Singly-linked lists are ideal
2738 * for applications with large datasets and few or no removals or for
2739 * implementing a LIFO queue.
2740 *
2741 * A singly-linked tail queue is headed by a pair of pointers, one to the
2742 * head of the list and the other to the tail of the list. The elements are
2743 * singly linked for minimum space and pointer manipulation overhead at the
2744 * expense of O(n) removal for arbitrary elements. New elements can be added
2745 * to the list after an existing element, at the head of the list, or at the
2746 * end of the list. Elements being removed from the head of the tail queue
2747 * should use the explicit macro for this purpose for optimum efficiency.
2748 * A singly-linked tail queue may only be traversed in the forward direction.
2749 * Singly-linked tail queues are ideal for applications with large datasets
2750 * and few or no removals or for implementing a FIFO queue.
2751 *
2752 * A list is headed by a single forward pointer (or an array of forward
2753 * pointers for a hash table header). The elements are doubly linked
2754 * so that an arbitrary element can be removed without a need to
2755 * traverse the list. New elements can be added to the list before
2756 * or after an existing element or at the head of the list. A list
2757 * may be traversed in either direction.
2758 *
2759 * A tail queue is headed by a pair of pointers, one to the head of the
2760 * list and the other to the tail of the list. The elements are doubly
2761 * linked so that an arbitrary element can be removed without a need to
2762 * traverse the list. New elements can be added to the list before or
2763 * after an existing element, at the head of the list, or at the end of
2764 * the list. A tail queue may be traversed in either direction.
2765 *
2766 * For details on the use of these macros, see the queue(3) manual page.
2767 *
2768 *
2769 * SLIST LIST STAILQ TAILQ
2770 * _HEAD + + + +
2771 * _CLASS_HEAD + + + +
2772 * _HEAD_INITIALIZER + + + +
2773 * _ENTRY + + + +
2774 * _CLASS_ENTRY + + + +
2775 * _INIT + + + +
2776 * _EMPTY + + + +
2777 * _FIRST + + + +
2778 * _NEXT + + + +
2779 * _PREV - + - +
2780 * _LAST - - + +
2781 * _FOREACH + + + +
2782 * _FOREACH_FROM + + + +
2783 * _FOREACH_SAFE + + + +
2784 * _FOREACH_FROM_SAFE + + + +
2785 * _FOREACH_REVERSE - - - +
2786 * _FOREACH_REVERSE_FROM - - - +
2787 * _FOREACH_REVERSE_SAFE - - - +
2788 * _FOREACH_REVERSE_FROM_SAFE - - - +
2789 * _INSERT_HEAD + + + +
2790 * _INSERT_BEFORE - + - +
2791 * _INSERT_AFTER + + + +
2792 * _INSERT_TAIL - - + +
2793 * _CONCAT - - + +
2794 * _REMOVE_AFTER + - + -
2795 * _REMOVE_HEAD + - + -
2796 * _REMOVE + + + +
2797 * _SWAP + + + +
2798 *
2799 */
2800#ifdef QUEUE_MACRO_DEBUG
2801/* Store the last 2 places the queue element or head was altered */
2802struct qm_trace {
2803 unsigned long lastline;
2804 unsigned long prevline;
2805 const char *lastfile;
2806 const char *prevfile;
2807};
2808
2809#define TRACEBUF struct qm_trace trace;
2810#define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } ,
2811#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
2812#define QMD_SAVELINK(name, link) void **name = (void *)&(link)
2813
2814#define QMD_TRACE_HEAD(head) do { \
2815 (head)->trace.prevline = (head)->trace.lastline; \
2816 (head)->trace.prevfile = (head)->trace.lastfile; \
2817 (head)->trace.lastline = __LINE__; \
2818 (head)->trace.lastfile = __FILE__; \
2819} while (0)
2820
2821#define QMD_TRACE_ELEM(elem) do { \
2822 (elem)->trace.prevline = (elem)->trace.lastline; \
2823 (elem)->trace.prevfile = (elem)->trace.lastfile; \
2824 (elem)->trace.lastline = __LINE__; \
2825 (elem)->trace.lastfile = __FILE__; \
2826} while (0)
2827
2828#else
2829#define QMD_TRACE_ELEM(elem)
2830#define QMD_TRACE_HEAD(head)
2831#define QMD_SAVELINK(name, link)
2832#define TRACEBUF
2833#define TRACEBUF_INITIALIZER
2834#define TRASHIT(x)
2835#endif /* QUEUE_MACRO_DEBUG */
2836
2837#ifdef __cplusplus
2838/*
2839 * In C++ there can be structure lists and class lists:
2840 */
2841#define QUEUE_TYPEOF(type) type
2842#else
2843#define QUEUE_TYPEOF(type) struct type
2844#endif
2845
2846/*
2847 * Singly-linked List declarations.
2848 */
2849#define SLIST_HEAD(name, type) \
2850struct name { \
2851 struct type *slh_first; /* first element */ \
2852}
2853
2854#define SLIST_CLASS_HEAD(name, type) \
2855struct name { \
2856 class type *slh_first; /* first element */ \
2857}
2858
2859#define SLIST_HEAD_INITIALIZER(head) \
2860 { NULL }
2861
2862#define SLIST_ENTRY(type) \
2863struct { \
2864 struct type *sle_next; /* next element */ \
2865}
2866
2867#define SLIST_CLASS_ENTRY(type) \
2868struct { \
2869 class type *sle_next; /* next element */ \
2870}
2871
2872/*
2873 * Singly-linked List functions.
2874 */
2875#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
2876
2877#define SLIST_FIRST(head) ((head)->slh_first)
2878
2879#define SLIST_FOREACH(var, head, field) \
2880 for ((var) = SLIST_FIRST((head)); \
2881 (var); \
2882 (var) = SLIST_NEXT((var), field))
2883
2884#define SLIST_FOREACH_FROM(var, head, field) \
2885 for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \
2886 (var); \
2887 (var) = SLIST_NEXT((var), field))
2888
2889#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
2890 for ((var) = SLIST_FIRST((head)); \
2891 (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
2892 (var) = (tvar))
2893
2894#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \
2895 for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \
2896 (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
2897 (var) = (tvar))
2898
2899#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
2900 for ((varp) = &SLIST_FIRST((head)); \
2901 ((var) = *(varp)) != NULL; \
2902 (varp) = &SLIST_NEXT((var), field))
2903
2904#define SLIST_INIT(head) do { \
2905 SLIST_FIRST((head)) = NULL; \
2906} while (0)
2907
2908#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
2909 SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
2910 SLIST_NEXT((slistelm), field) = (elm); \
2911} while (0)
2912
2913#define SLIST_INSERT_HEAD(head, elm, field) do { \
2914 SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
2915 SLIST_FIRST((head)) = (elm); \
2916} while (0)
2917
2918#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
2919
2920#define SLIST_REMOVE(head, elm, type, field) do { \
2921 QMD_SAVELINK(oldnext, (elm)->field.sle_next); \
2922 if (SLIST_FIRST((head)) == (elm)) { \
2923 SLIST_REMOVE_HEAD((head), field); \
2924 } \
2925 else { \
2926 QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head); \
2927 while (SLIST_NEXT(curelm, field) != (elm)) \
2928 curelm = SLIST_NEXT(curelm, field); \
2929 SLIST_REMOVE_AFTER(curelm, field); \
2930 } \
2931 TRASHIT(*oldnext); \
2932} while (0)
2933
2934#define SLIST_REMOVE_AFTER(elm, field) do { \
2935 SLIST_NEXT(elm, field) = \
2936 SLIST_NEXT(SLIST_NEXT(elm, field), field); \
2937} while (0)
2938
2939#define SLIST_REMOVE_HEAD(head, field) do { \
2940 SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
2941} while (0)
2942
2943#define SLIST_SWAP(head1, head2, type) do { \
2944 QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \
2945 SLIST_FIRST(head1) = SLIST_FIRST(head2); \
2946 SLIST_FIRST(head2) = swap_first; \
2947} while (0)
2948
2949/*
2950 * Singly-linked Tail queue declarations.
2951 */
2952#define STAILQ_HEAD(name, type) \
2953struct name { \
2954 struct type *stqh_first;/* first element */ \
2955 struct type **stqh_last;/* addr of last next element */ \
2956}
2957
2958#define STAILQ_CLASS_HEAD(name, type) \
2959struct name { \
2960 class type *stqh_first; /* first element */ \
2961 class type **stqh_last; /* addr of last next element */ \
2962}
2963
2964#define STAILQ_HEAD_INITIALIZER(head) \
2965 { NULL, &(head).stqh_first }
2966
2967#define STAILQ_ENTRY(type) \
2968struct { \
2969 struct type *stqe_next; /* next element */ \
2970}
2971
2972#define STAILQ_CLASS_ENTRY(type) \
2973struct { \
2974 class type *stqe_next; /* next element */ \
2975}
2976
2977/*
2978 * Singly-linked Tail queue functions.
2979 */
2980#define STAILQ_CONCAT(head1, head2) do { \
2981 if (!STAILQ_EMPTY((head2))) { \
2982 *(head1)->stqh_last = (head2)->stqh_first; \
2983 (head1)->stqh_last = (head2)->stqh_last; \
2984 STAILQ_INIT((head2)); \
2985 } \
2986} while (0)
2987
2988#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
2989
2990#define STAILQ_FIRST(head) ((head)->stqh_first)
2991
2992#define STAILQ_FOREACH(var, head, field) \
2993 for((var) = STAILQ_FIRST((head)); \
2994 (var); \
2995 (var) = STAILQ_NEXT((var), field))
2996
2997#define STAILQ_FOREACH_FROM(var, head, field) \
2998 for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \
2999 (var); \
3000 (var) = STAILQ_NEXT((var), field))
3001
3002#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
3003 for ((var) = STAILQ_FIRST((head)); \
3004 (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
3005 (var) = (tvar))
3006
3007#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
3008 for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \
3009 (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
3010 (var) = (tvar))
3011
3012#define STAILQ_INIT(head) do { \
3013 STAILQ_FIRST((head)) = NULL; \
3014 (head)->stqh_last = &STAILQ_FIRST((head)); \
3015} while (0)
3016
3017#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
3018 if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
3019 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
3020 STAILQ_NEXT((tqelm), field) = (elm); \
3021} while (0)
3022
3023#define STAILQ_INSERT_HEAD(head, elm, field) do { \
3024 if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
3025 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
3026 STAILQ_FIRST((head)) = (elm); \
3027} while (0)
3028
3029#define STAILQ_INSERT_TAIL(head, elm, field) do { \
3030 STAILQ_NEXT((elm), field) = NULL; \
3031 *(head)->stqh_last = (elm); \
3032 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
3033} while (0)
3034
3035#define STAILQ_LAST(head, type, field) \
3036 (STAILQ_EMPTY((head)) ? NULL : \
3037 __containerof((head)->stqh_last, \
3038 QUEUE_TYPEOF(type), field.stqe_next))
3039
3040#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
3041
3042#define STAILQ_REMOVE(head, elm, type, field) do { \
3043 QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \
3044 if (STAILQ_FIRST((head)) == (elm)) { \
3045 STAILQ_REMOVE_HEAD((head), field); \
3046 } \
3047 else { \
3048 QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head); \
3049 while (STAILQ_NEXT(curelm, field) != (elm)) \
3050 curelm = STAILQ_NEXT(curelm, field); \
3051 STAILQ_REMOVE_AFTER(head, curelm, field); \
3052 } \
3053 TRASHIT(*oldnext); \
3054} while (0)
3055
3056#define STAILQ_REMOVE_AFTER(head, elm, field) do { \
3057 if ((STAILQ_NEXT(elm, field) = \
3058 STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
3059 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
3060} while (0)
3061
3062#define STAILQ_REMOVE_HEAD(head, field) do { \
3063 if ((STAILQ_FIRST((head)) = \
3064 STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
3065 (head)->stqh_last = &STAILQ_FIRST((head)); \
3066} while (0)
3067
3068#define STAILQ_SWAP(head1, head2, type) do { \
3069 QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1); \
3070 QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last; \
3071 STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \
3072 (head1)->stqh_last = (head2)->stqh_last; \
3073 STAILQ_FIRST(head2) = swap_first; \
3074 (head2)->stqh_last = swap_last; \
3075 if (STAILQ_EMPTY(head1)) \
3076 (head1)->stqh_last = &STAILQ_FIRST(head1); \
3077 if (STAILQ_EMPTY(head2)) \
3078 (head2)->stqh_last = &STAILQ_FIRST(head2); \
3079} while (0)
3080
3081
3082/*
3083 * List declarations.
3084 */
3085#define LIST_HEAD(name, type) \
3086struct name { \
3087 struct type *lh_first; /* first element */ \
3088}
3089
3090#define LIST_CLASS_HEAD(name, type) \
3091struct name { \
3092 class type *lh_first; /* first element */ \
3093}
3094
3095#define LIST_HEAD_INITIALIZER(head) \
3096 { NULL }
3097
3098#define LIST_ENTRY(type) \
3099struct { \
3100 struct type *le_next; /* next element */ \
3101 struct type **le_prev; /* address of previous next element */ \
3102}
3103
3104#define LIST_CLASS_ENTRY(type) \
3105struct { \
3106 class type *le_next; /* next element */ \
3107 class type **le_prev; /* address of previous next element */ \
3108}
3109
3110/*
3111 * List functions.
3112 */
3113
3114#if (defined(_KERNEL) && defined(INVARIANTS))
3115#define QMD_LIST_CHECK_HEAD(head, field) do { \
3116 if (LIST_FIRST((head)) != NULL && \
3117 LIST_FIRST((head))->field.le_prev != \
3118 &LIST_FIRST((head))) \
3119 panic("Bad list head %p first->prev != head", (head)); \
3120} while (0)
3121
3122#define QMD_LIST_CHECK_NEXT(elm, field) do { \
3123 if (LIST_NEXT((elm), field) != NULL && \
3124 LIST_NEXT((elm), field)->field.le_prev != \
3125 &((elm)->field.le_next)) \
3126 panic("Bad link elm %p next->prev != elm", (elm)); \
3127} while (0)
3128
3129#define QMD_LIST_CHECK_PREV(elm, field) do { \
3130 if (*(elm)->field.le_prev != (elm)) \
3131 panic("Bad link elm %p prev->next != elm", (elm)); \
3132} while (0)
3133#else
3134#define QMD_LIST_CHECK_HEAD(head, field)
3135#define QMD_LIST_CHECK_NEXT(elm, field)
3136#define QMD_LIST_CHECK_PREV(elm, field)
3137#endif /* (_KERNEL && INVARIANTS) */
3138
3139#define LIST_EMPTY(head) ((head)->lh_first == NULL)
3140
3141#define LIST_FIRST(head) ((head)->lh_first)
3142
3143#define LIST_FOREACH(var, head, field) \
3144 for ((var) = LIST_FIRST((head)); \
3145 (var); \
3146 (var) = LIST_NEXT((var), field))
3147
3148#define LIST_FOREACH_FROM(var, head, field) \
3149 for ((var) = ((var) ? (var) : LIST_FIRST((head))); \
3150 (var); \
3151 (var) = LIST_NEXT((var), field))
3152
3153#define LIST_FOREACH_SAFE(var, head, field, tvar) \
3154 for ((var) = LIST_FIRST((head)); \
3155 (var) && ((tvar) = LIST_NEXT((var), field), 1); \
3156 (var) = (tvar))
3157
3158#define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \
3159 for ((var) = ((var) ? (var) : LIST_FIRST((head))); \
3160 (var) && ((tvar) = LIST_NEXT((var), field), 1); \
3161 (var) = (tvar))
3162
3163#define LIST_INIT(head) do { \
3164 LIST_FIRST((head)) = NULL; \
3165} while (0)
3166
3167#define LIST_INSERT_AFTER(listelm, elm, field) do { \
3168 QMD_LIST_CHECK_NEXT(listelm, field); \
3169 if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
3170 LIST_NEXT((listelm), field)->field.le_prev = \
3171 &LIST_NEXT((elm), field); \
3172 LIST_NEXT((listelm), field) = (elm); \
3173 (elm)->field.le_prev = &LIST_NEXT((listelm), field); \
3174} while (0)
3175
3176#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
3177 QMD_LIST_CHECK_PREV(listelm, field); \
3178 (elm)->field.le_prev = (listelm)->field.le_prev; \
3179 LIST_NEXT((elm), field) = (listelm); \
3180 *(listelm)->field.le_prev = (elm); \
3181 (listelm)->field.le_prev = &LIST_NEXT((elm), field); \
3182} while (0)
3183
3184#define LIST_INSERT_HEAD(head, elm, field) do { \
3185 QMD_LIST_CHECK_HEAD((head), field); \
3186 if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
3187 LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
3188 LIST_FIRST((head)) = (elm); \
3189 (elm)->field.le_prev = &LIST_FIRST((head)); \
3190} while (0)
3191
3192#define LIST_NEXT(elm, field) ((elm)->field.le_next)
3193
3194#define LIST_PREV(elm, head, type, field) \
3195 ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \
3196 __containerof((elm)->field.le_prev, \
3197 QUEUE_TYPEOF(type), field.le_next))
3198
3199#define LIST_REMOVE(elm, field) do { \
3200 QMD_SAVELINK(oldnext, (elm)->field.le_next); \
3201 QMD_SAVELINK(oldprev, (elm)->field.le_prev); \
3202 QMD_LIST_CHECK_NEXT(elm, field); \
3203 QMD_LIST_CHECK_PREV(elm, field); \
3204 if (LIST_NEXT((elm), field) != NULL) \
3205 LIST_NEXT((elm), field)->field.le_prev = \
3206 (elm)->field.le_prev; \
3207 *(elm)->field.le_prev = LIST_NEXT((elm), field); \
3208 TRASHIT(*oldnext); \
3209 TRASHIT(*oldprev); \
3210} while (0)
3211
3212#define LIST_SWAP(head1, head2, type, field) do { \
3213 QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \
3214 LIST_FIRST((head1)) = LIST_FIRST((head2)); \
3215 LIST_FIRST((head2)) = swap_tmp; \
3216 if ((swap_tmp = LIST_FIRST((head1))) != NULL) \
3217 swap_tmp->field.le_prev = &LIST_FIRST((head1)); \
3218 if ((swap_tmp = LIST_FIRST((head2))) != NULL) \
3219 swap_tmp->field.le_prev = &LIST_FIRST((head2)); \
3220} while (0)
3221
3222/*
3223 * Tail queue declarations.
3224 */
3225#define TAILQ_HEAD(name, type) \
3226struct name { \
3227 struct type *tqh_first; /* first element */ \
3228 struct type **tqh_last; /* addr of last next element */ \
3229 TRACEBUF \
3230}
3231
3232#define TAILQ_CLASS_HEAD(name, type) \
3233struct name { \
3234 class type *tqh_first; /* first element */ \
3235 class type **tqh_last; /* addr of last next element */ \
3236 TRACEBUF \
3237}
3238
3239#define TAILQ_HEAD_INITIALIZER(head) \
3240 { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
3241
3242#define TAILQ_ENTRY(type) \
3243struct { \
3244 struct type *tqe_next; /* next element */ \
3245 struct type **tqe_prev; /* address of previous next element */ \
3246 TRACEBUF \
3247}
3248
3249#define TAILQ_CLASS_ENTRY(type) \
3250struct { \
3251 class type *tqe_next; /* next element */ \
3252 class type **tqe_prev; /* address of previous next element */ \
3253 TRACEBUF \
3254}
3255
3256/*
3257 * Tail queue functions.
3258 */
3259#if (defined(_KERNEL) && defined(INVARIANTS))
3260#define QMD_TAILQ_CHECK_HEAD(head, field) do { \
3261 if (!TAILQ_EMPTY(head) && \
3262 TAILQ_FIRST((head))->field.tqe_prev != \
3263 &TAILQ_FIRST((head))) \
3264 panic("Bad tailq head %p first->prev != head", (head)); \
3265} while (0)
3266
3267#define QMD_TAILQ_CHECK_TAIL(head, field) do { \
3268 if (*(head)->tqh_last != NULL) \
3269 panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \
3270} while (0)
3271
3272#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \
3273 if (TAILQ_NEXT((elm), field) != NULL && \
3274 TAILQ_NEXT((elm), field)->field.tqe_prev != \
3275 &((elm)->field.tqe_next)) \
3276 panic("Bad link elm %p next->prev != elm", (elm)); \
3277} while (0)
3278
3279#define QMD_TAILQ_CHECK_PREV(elm, field) do { \
3280 if (*(elm)->field.tqe_prev != (elm)) \
3281 panic("Bad link elm %p prev->next != elm", (elm)); \
3282} while (0)
3283#else
3284#define QMD_TAILQ_CHECK_HEAD(head, field)
3285#define QMD_TAILQ_CHECK_TAIL(head, headname)
3286#define QMD_TAILQ_CHECK_NEXT(elm, field)
3287#define QMD_TAILQ_CHECK_PREV(elm, field)
3288#endif /* (_KERNEL && INVARIANTS) */
3289
3290#define TAILQ_CONCAT(head1, head2, field) do { \
3291 if (!TAILQ_EMPTY(head2)) { \
3292 *(head1)->tqh_last = (head2)->tqh_first; \
3293 (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
3294 (head1)->tqh_last = (head2)->tqh_last; \
3295 TAILQ_INIT((head2)); \
3296 QMD_TRACE_HEAD(head1); \
3297 QMD_TRACE_HEAD(head2); \
3298 } \
3299} while (0)
3300
3301#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
3302
3303#define TAILQ_FIRST(head) ((head)->tqh_first)
3304
3305#define TAILQ_FOREACH(var, head, field) \
3306 for ((var) = TAILQ_FIRST((head)); \
3307 (var); \
3308 (var) = TAILQ_NEXT((var), field))
3309
3310#define TAILQ_FOREACH_FROM(var, head, field) \
3311 for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
3312 (var); \
3313 (var) = TAILQ_NEXT((var), field))
3314
3315#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
3316 for ((var) = TAILQ_FIRST((head)); \
3317 (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
3318 (var) = (tvar))
3319
3320#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
3321 for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
3322 (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
3323 (var) = (tvar))
3324
3325#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
3326 for ((var) = TAILQ_LAST((head), headname); \
3327 (var); \
3328 (var) = TAILQ_PREV((var), headname, field))
3329
3330#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \
3331 for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
3332 (var); \
3333 (var) = TAILQ_PREV((var), headname, field))
3334
3335#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
3336 for ((var) = TAILQ_LAST((head), headname); \
3337 (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
3338 (var) = (tvar))
3339
3340#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
3341 for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
3342 (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
3343 (var) = (tvar))
3344
3345#define TAILQ_INIT(head) do { \
3346 TAILQ_FIRST((head)) = NULL; \
3347 (head)->tqh_last = &TAILQ_FIRST((head)); \
3348 QMD_TRACE_HEAD(head); \
3349} while (0)
3350
3351#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
3352 QMD_TAILQ_CHECK_NEXT(listelm, field); \
3353 if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
3354 TAILQ_NEXT((elm), field)->field.tqe_prev = \
3355 &TAILQ_NEXT((elm), field); \
3356 else { \
3357 (head)->tqh_last = &TAILQ_NEXT((elm), field); \
3358 QMD_TRACE_HEAD(head); \
3359 } \
3360 TAILQ_NEXT((listelm), field) = (elm); \
3361 (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
3362 QMD_TRACE_ELEM(&(elm)->field); \
3363 QMD_TRACE_ELEM(&(listelm)->field); \
3364} while (0)
3365
3366#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
3367 QMD_TAILQ_CHECK_PREV(listelm, field); \
3368 (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
3369 TAILQ_NEXT((elm), field) = (listelm); \
3370 *(listelm)->field.tqe_prev = (elm); \
3371 (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
3372 QMD_TRACE_ELEM(&(elm)->field); \
3373 QMD_TRACE_ELEM(&(listelm)->field); \
3374} while (0)
3375
3376#define TAILQ_INSERT_HEAD(head, elm, field) do { \
3377 QMD_TAILQ_CHECK_HEAD(head, field); \
3378 if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
3379 TAILQ_FIRST((head))->field.tqe_prev = \
3380 &TAILQ_NEXT((elm), field); \
3381 else \
3382 (head)->tqh_last = &TAILQ_NEXT((elm), field); \
3383 TAILQ_FIRST((head)) = (elm); \
3384 (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
3385 QMD_TRACE_HEAD(head); \
3386 QMD_TRACE_ELEM(&(elm)->field); \
3387} while (0)
3388
3389#define TAILQ_INSERT_TAIL(head, elm, field) do { \
3390 QMD_TAILQ_CHECK_TAIL(head, field); \
3391 TAILQ_NEXT((elm), field) = NULL; \
3392 (elm)->field.tqe_prev = (head)->tqh_last; \
3393 *(head)->tqh_last = (elm); \
3394 (head)->tqh_last = &TAILQ_NEXT((elm), field); \
3395 QMD_TRACE_HEAD(head); \
3396 QMD_TRACE_ELEM(&(elm)->field); \
3397} while (0)
3398
3399#define TAILQ_LAST(head, headname) \
3400 (*(((struct headname *)((head)->tqh_last))->tqh_last))
3401
3402#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
3403
3404#define TAILQ_PREV(elm, headname, field) \
3405 (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
3406
3407#define TAILQ_REMOVE(head, elm, field) do { \
3408 QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \
3409 QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \
3410 QMD_TAILQ_CHECK_NEXT(elm, field); \
3411 QMD_TAILQ_CHECK_PREV(elm, field); \
3412 if ((TAILQ_NEXT((elm), field)) != NULL) \
3413 TAILQ_NEXT((elm), field)->field.tqe_prev = \
3414 (elm)->field.tqe_prev; \
3415 else { \
3416 (head)->tqh_last = (elm)->field.tqe_prev; \
3417 QMD_TRACE_HEAD(head); \
3418 } \
3419 *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
3420 TRASHIT(*oldnext); \
3421 TRASHIT(*oldprev); \
3422 QMD_TRACE_ELEM(&(elm)->field); \
3423} while (0)
3424
3425#define TAILQ_SWAP(head1, head2, type, field) do { \
3426 QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \
3427 QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \
3428 (head1)->tqh_first = (head2)->tqh_first; \
3429 (head1)->tqh_last = (head2)->tqh_last; \
3430 (head2)->tqh_first = swap_first; \
3431 (head2)->tqh_last = swap_last; \
3432 if ((swap_first = (head1)->tqh_first) != NULL) \
3433 swap_first->field.tqe_prev = &(head1)->tqh_first; \
3434 else \
3435 (head1)->tqh_last = &(head1)->tqh_first; \
3436 if ((swap_first = (head2)->tqh_first) != NULL) \
3437 swap_first->field.tqe_prev = &(head2)->tqh_first; \
3438 else \
3439 (head2)->tqh_last = &(head2)->tqh_first; \
3440} while (0)
3441
3442#endif /* !_SYS_QUEUE_H_ */
3443#ifdef MG_MODULE_LINES
3444#line 1 "mongoose/src/mg_features.h"
3445#endif
3446/*
3447 * Copyright (c) 2014-2016 Cesanta Software Limited
3448 * All rights reserved
3449 */
3450
3451#ifndef CS_MONGOOSE_SRC_FEATURES_H_
3452#define CS_MONGOOSE_SRC_FEATURES_H_
3453
3454#ifndef MG_DISABLE_HTTP_DIGEST_AUTH
3455#define MG_DISABLE_HTTP_DIGEST_AUTH 0
3456#endif
3457
3458#ifndef MG_DISABLE_HTTP_KEEP_ALIVE
3459#define MG_DISABLE_HTTP_KEEP_ALIVE 0
3460#endif
3461
3462#ifndef MG_DISABLE_PFS
3463#define MG_DISABLE_PFS 0
3464#endif
3465
3466#ifndef MG_DISABLE_WS_RANDOM_MASK
3467#define MG_DISABLE_WS_RANDOM_MASK 0
3468#endif
3469
3470#ifndef MG_ENABLE_ASYNC_RESOLVER
3471#define MG_ENABLE_ASYNC_RESOLVER 1
3472#endif
3473
3474#ifndef MG_ENABLE_BROADCAST
3475#define MG_ENABLE_BROADCAST 0
3476#endif
3477
3478#ifndef MG_ENABLE_COAP
3479#define MG_ENABLE_COAP 0
3480#endif
3481
3482#ifndef MG_ENABLE_DEBUG
3483#define MG_ENABLE_DEBUG 0
3484#endif
3485
3486#ifndef MG_ENABLE_DIRECTORY_LISTING
3487#define MG_ENABLE_DIRECTORY_LISTING 0
3488#endif
3489
3490#ifndef MG_ENABLE_DNS
3491#define MG_ENABLE_DNS 1
3492#endif
3493
3494#ifndef MG_ENABLE_DNS_SERVER
3495#define MG_ENABLE_DNS_SERVER 0
3496#endif
3497
3498#ifndef MG_ENABLE_FAKE_DAVLOCK
3499#define MG_ENABLE_FAKE_DAVLOCK 0
3500#endif
3501
3502#ifndef MG_ENABLE_FILESYSTEM
3503#define MG_ENABLE_FILESYSTEM 0
3504#endif
3505
3506#ifndef MG_ENABLE_GETADDRINFO
3507#define MG_ENABLE_GETADDRINFO 0
3508#endif
3509
3510#ifndef MG_ENABLE_HEXDUMP
3511#define MG_ENABLE_HEXDUMP CS_ENABLE_STDIO
3512#endif
3513
3514#ifndef MG_ENABLE_HTTP
3515#define MG_ENABLE_HTTP 1
3516#endif
3517
3518#ifndef MG_ENABLE_HTTP_CGI
3519#define MG_ENABLE_HTTP_CGI 0
3520#endif
3521
3522#ifndef MG_ENABLE_HTTP_SSI
3523#define MG_ENABLE_HTTP_SSI MG_ENABLE_FILESYSTEM
3524#endif
3525
3526#ifndef MG_ENABLE_HTTP_SSI_EXEC
3527#define MG_ENABLE_HTTP_SSI_EXEC 0
3528#endif
3529
3530#ifndef MG_ENABLE_HTTP_STREAMING_MULTIPART
3531#define MG_ENABLE_HTTP_STREAMING_MULTIPART 0
3532#endif
3533
3534#ifndef MG_ENABLE_HTTP_WEBDAV
3535#define MG_ENABLE_HTTP_WEBDAV 0
3536#endif
3537
3538#ifndef MG_ENABLE_HTTP_WEBSOCKET
3539#define MG_ENABLE_HTTP_WEBSOCKET MG_ENABLE_HTTP
3540#endif
3541
3542#ifndef MG_ENABLE_IPV6
3543#define MG_ENABLE_IPV6 0
3544#endif
3545
3546#ifndef MG_ENABLE_MQTT
3547#define MG_ENABLE_MQTT 1
3548#endif
3549
3550#ifndef MG_ENABLE_SOCKS
3551#define MG_ENABLE_SOCKS 0
3552#endif
3553
3554#ifndef MG_ENABLE_MQTT_BROKER
3555#define MG_ENABLE_MQTT_BROKER 0
3556#endif
3557
3558#ifndef MG_ENABLE_SSL
3559#define MG_ENABLE_SSL 0
3560#endif
3561
3562#ifndef MG_ENABLE_SYNC_RESOLVER
3563#define MG_ENABLE_SYNC_RESOLVER 0
3564#endif
3565
3566#ifndef MG_ENABLE_STDIO
3567#define MG_ENABLE_STDIO CS_ENABLE_STDIO
3568#endif
3569
3570#ifndef MG_NET_IF
3571#define MG_NET_IF MG_NET_IF_SOCKET
3572#endif
3573
3574#ifndef MG_SSL_IF
3575#define MG_SSL_IF MG_SSL_IF_OPENSSL
3576#endif
3577
3578#ifndef MG_ENABLE_THREADS /* ifdef-ok */
3579#ifdef _WIN32
3580#define MG_ENABLE_THREADS 1
3581#else
3582#define MG_ENABLE_THREADS 0
3583#endif
3584#endif
3585
3586#if MG_ENABLE_DEBUG && !defined(CS_ENABLE_DEBUG)
3587#define CS_ENABLE_DEBUG 1
3588#endif
3589
3590/* MQTT broker requires MQTT */
3591#if MG_ENABLE_MQTT_BROKER && !MG_ENABLE_MQTT
3592#undef MG_ENABLE_MQTT
3593#define MG_ENABLE_MQTT 1
3594#endif
3595
3596#ifndef MG_ENABLE_HTTP_URL_REWRITES
3597#define MG_ENABLE_HTTP_URL_REWRITES \
3598 (CS_PLATFORM == CS_P_WINDOWS || CS_PLATFORM == CS_P_UNIX)
3599#endif
3600
3601#ifndef MG_ENABLE_SNTP
3602#define MG_ENABLE_SNTP 0
3603#endif
3604
3605#ifndef MG_ENABLE_EXTRA_ERRORS_DESC
3606#define MG_ENABLE_EXTRA_ERRORS_DESC 0
3607#endif
3608
3609#ifndef MG_ENABLE_CALLBACK_USERDATA
3610#define MG_ENABLE_CALLBACK_USERDATA 0
3611#endif
3612
3613#if MG_ENABLE_CALLBACK_USERDATA
3614#define MG_UD_ARG(ud) , ud
3615#define MG_CB(cb, ud) cb, ud
3616#else
3617#define MG_UD_ARG(ud)
3618#define MG_CB(cb, ud) cb
3619#endif
3620
3621#endif /* CS_MONGOOSE_SRC_FEATURES_H_ */
3622#ifdef MG_MODULE_LINES
3623#line 1 "mongoose/src/mg_net_if.h"
3624#endif
3625/*
3626 * Copyright (c) 2014-2016 Cesanta Software Limited
3627 * All rights reserved
3628 */
3629
3630#ifndef CS_MONGOOSE_SRC_NET_IF_H_
3631#define CS_MONGOOSE_SRC_NET_IF_H_
3632
3633/* Amalgamated: #include "common/platform.h" */
3634
3635/*
3636 * Internal async networking core interface.
3637 * Consists of calls made by the core, which should not block,
3638 * and callbacks back into the core ("..._cb").
3639 * Callbacks may (will) cause methods to be invoked from within,
3640 * but methods are not allowed to invoke callbacks inline.
3641 *
3642 * Implementation must ensure that only one callback is invoked at any time.
3643 */
3644
3645#ifdef __cplusplus
3646extern "C" {
3647#endif /* __cplusplus */
3648
3649#define MG_MAIN_IFACE 0
3650
3651struct mg_mgr;
3652struct mg_connection;
3653union socket_address;
3654
3655struct mg_iface_vtable;
3656
3657struct mg_iface {
3658 struct mg_mgr *mgr;
3659 void *data; /* Implementation-specific data */
3661};
3662
3664 void (*init)(struct mg_iface *iface);
3665 void (*free)(struct mg_iface *iface);
3668 time_t (*poll)(struct mg_iface *iface, int timeout_ms);
3669
3670 /* Set up a listening TCP socket on a given address. rv = 0 -> ok. */
3671 int (*listen_tcp)(struct mg_connection *nc, union socket_address *sa);
3672 /* Request that a "listening" UDP socket be created. */
3673 int (*listen_udp)(struct mg_connection *nc, union socket_address *sa);
3674
3675 /* Request that a TCP connection is made to the specified address. */
3676 void (*connect_tcp)(struct mg_connection *nc, const union socket_address *sa);
3677 /* Open a UDP socket. Doesn't actually connect anything. */
3679
3680 /* Send functions for TCP and UDP. Sent data is copied before return. */
3681 int (*tcp_send)(struct mg_connection *nc, const void *buf, size_t len);
3682 int (*udp_send)(struct mg_connection *nc, const void *buf, size_t len);
3683
3684 int (*tcp_recv)(struct mg_connection *nc, void *buf, size_t len);
3685 int (*udp_recv)(struct mg_connection *nc, void *buf, size_t len,
3686 union socket_address *sa, size_t *sa_len);
3687
3688 /* Perform interface-related connection initialization. Return 1 on ok. */
3690 /* Perform interface-related cleanup on connection before destruction. */
3692
3693 /* Associate a socket to a connection. */
3694 void (*sock_set)(struct mg_connection *nc, sock_t sock);
3695
3696 /* Put connection's address into *sa, local (remote = 0) or remote. */
3698 union socket_address *sa);
3699};
3700
3701extern const struct mg_iface_vtable *mg_ifaces[];
3702extern int mg_num_ifaces;
3703
3704/* Creates a new interface instance. */
3706 struct mg_mgr *mgr);
3707
3708/*
3709 * Find an interface with a given implementation. The search is started from
3710 * interface `from`, exclusive. Returns NULL if none is found.
3711 */
3712struct mg_iface *mg_find_iface(struct mg_mgr *mgr,
3713 const struct mg_iface_vtable *vtable,
3714 struct mg_iface *from);
3715/*
3716 * Deliver a new TCP connection. Returns NULL in case on error (unable to
3717 * create connection, in which case interface state should be discarded.
3718 * This is phase 1 of the two-phase process - MG_EV_ACCEPT will be delivered
3719 * when mg_if_accept_tcp_cb is invoked.
3720 */
3722void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,
3723 size_t sa_len);
3724
3725/* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */
3726void mg_if_connect_cb(struct mg_connection *nc, int err);
3727/*
3728 * Callback that tells the core that data can be received.
3729 * Core will use tcp/udp_recv to retrieve the data.
3730 */
3731void mg_if_can_recv_cb(struct mg_connection *nc);
3732void mg_if_can_send_cb(struct mg_connection *nc);
3733/*
3734 * Receive callback.
3735 * buf must be heap-allocated and ownership is transferred to the core.
3736 */
3737void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
3738 union socket_address *sa, size_t sa_len);
3739
3740/* void mg_if_close_conn(struct mg_connection *nc); */
3741
3742/* Deliver a POLL event to the connection. */
3743int mg_if_poll(struct mg_connection *nc, double now);
3744
3745/*
3746 * Return minimal timer value amoung connections in the manager.
3747 * Returns 0 if there aren't any timers.
3748 */
3749double mg_mgr_min_timer(const struct mg_mgr *mgr);
3750
3751#ifdef __cplusplus
3752}
3753#endif /* __cplusplus */
3754
3755#endif /* CS_MONGOOSE_SRC_NET_IF_H_ */
3756#ifdef MG_MODULE_LINES
3757#line 1 "mongoose/src/mg_ssl_if.h"
3758#endif
3759/*
3760 * Copyright (c) 2014-2016 Cesanta Software Limited
3761 * All rights reserved
3762 */
3763
3764#ifndef CS_MONGOOSE_SRC_SSL_IF_H_
3765#define CS_MONGOOSE_SRC_SSL_IF_H_
3766
3767#if MG_ENABLE_SSL
3768
3769#ifdef __cplusplus
3770extern "C" {
3771#endif /* __cplusplus */
3772
3773struct mg_ssl_if_ctx;
3774struct mg_connection;
3775
3776void mg_ssl_if_init();
3777
3778enum mg_ssl_if_result {
3779 MG_SSL_OK = 0,
3780 MG_SSL_WANT_READ = -1,
3781 MG_SSL_WANT_WRITE = -2,
3782 MG_SSL_ERROR = -3,
3783};
3784
3785struct mg_ssl_if_conn_params {
3786 const char *cert;
3787 const char *key;
3788 const char *ca_cert;
3789 const char *server_name;
3790 const char *cipher_suites;
3791 const char *psk_identity;
3792 const char *psk_key;
3793};
3794
3796 struct mg_connection *nc, const struct mg_ssl_if_conn_params *params,
3797 const char **err_msg);
3799 struct mg_connection *lc);
3801void mg_ssl_if_conn_free(struct mg_connection *nc);
3802
3804int mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t buf_size);
3805int mg_ssl_if_write(struct mg_connection *nc, const void *data, size_t len);
3806
3807#ifdef __cplusplus
3808}
3809#endif /* __cplusplus */
3810
3811#endif /* MG_ENABLE_SSL */
3812
3813#endif /* CS_MONGOOSE_SRC_SSL_IF_H_ */
3814#ifdef MG_MODULE_LINES
3815#line 1 "mongoose/src/mg_net.h"
3816#endif
3817/*
3818 * Copyright (c) 2014 Cesanta Software Limited
3819 * All rights reserved
3820 * This software is dual-licensed: you can redistribute it and/or modify
3821 * it under the terms of the GNU General Public License version 2 as
3822 * published by the Free Software Foundation. For the terms of this
3823 * license, see <http://www.gnu.org/licenses/>.
3824 *
3825 * You are free to use this software under the terms of the GNU General
3826 * Public License, but WITHOUT ANY WARRANTY; without even the implied
3827 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
3828 * See the GNU General Public License for more details.
3829 *
3830 * Alternatively, you can license this software under a commercial
3831 * license, as set out in <https://www.cesanta.com/license>.
3832 */
3833
3834/*
3835 * === Core API: TCP/UDP/SSL
3836 *
3837 * NOTE: Mongoose manager is single threaded. It does not protect
3838 * its data structures by mutexes, therefore all functions that are dealing
3839 * with a particular event manager should be called from the same thread,
3840 * with exception of the `mg_broadcast()` function. It is fine to have different
3841 * event managers handled by different threads.
3842 */
3843
3844#ifndef CS_MONGOOSE_SRC_NET_H_
3845#define CS_MONGOOSE_SRC_NET_H_
3846
3847/* Amalgamated: #include "mg_common.h" */
3848/* Amalgamated: #include "mg_net_if.h" */
3849/* Amalgamated: #include "common/mbuf.h" */
3850
3851#ifndef MG_VPRINTF_BUFFER_SIZE
3852#define MG_VPRINTF_BUFFER_SIZE 100
3853#endif
3854
3855#ifdef MG_USE_READ_WRITE
3856#define MG_RECV_FUNC(s, b, l, f) read(s, b, l)
3857#define MG_SEND_FUNC(s, b, l, f) write(s, b, l)
3858#else
3859#define MG_RECV_FUNC(s, b, l, f) recv(s, b, l, f)
3860#define MG_SEND_FUNC(s, b, l, f) send(s, b, l, f)
3861#endif
3862
3863#ifdef __cplusplus
3864extern "C" {
3865#endif /* __cplusplus */
3866
3867union socket_address {
3868 struct sockaddr sa;
3869 struct sockaddr_in sin;
3870#if MG_ENABLE_IPV6
3871 struct sockaddr_in6 sin6;
3872#else
3873 struct sockaddr sin6;
3874#endif
3875};
3876
3877struct mg_connection;
3878
3879/*
3880 * Callback function (event handler) prototype. Must be defined by the user.
3881 * Mongoose calls the event handler, passing the events defined below.
3882 */
3883typedef void (*mg_event_handler_t)(struct mg_connection *nc, int ev,
3884 void *ev_data MG_UD_ARG(void *user_data));
3885
3886/* Events. Meaning of event parameter (evp) is given in the comment. */
3887#define MG_EV_POLL 0 /* Sent to each connection on each mg_mgr_poll() call */
3888#define MG_EV_ACCEPT 1 /* New connection accepted. union socket_address * */
3889#define MG_EV_CONNECT 2 /* connect() succeeded or failed. int * */
3890#define MG_EV_RECV 3 /* Data has been received. int *num_bytes */
3891#define MG_EV_SEND 4 /* Data has been written to a socket. int *num_bytes */
3892#define MG_EV_CLOSE 5 /* Connection is closed. NULL */
3893#define MG_EV_TIMER 6 /* now >= conn->ev_timer_time. double * */
3894
3895/*
3896 * Mongoose event manager.
3897 */
3898struct mg_mgr {
3900#if MG_ENABLE_HEXDUMP
3901 const char *hexdump_file; /* Debug hexdump file path */
3902#endif
3903#if MG_ENABLE_BROADCAST
3904 sock_t ctl[2]; /* Socketpair for mg_broadcast() */
3905#endif
3906 void *user_data; /* User data */
3909 struct mg_iface **ifaces; /* network interfaces */
3910 const char *nameserver; /* DNS server to use */
3911};
3912
3913/*
3914 * Mongoose connection.
3915 */
3916struct mg_connection {
3917 struct mg_connection *next, *prev; /* mg_mgr::active_connections linkage */
3918 struct mg_connection *listener; /* Set only for accept()-ed connections */
3919 struct mg_mgr *mgr; /* Pointer to containing manager */
3920
3921 sock_t sock; /* Socket to the remote peer */
3922 int err;
3923 union socket_address sa; /* Remote peer address */
3924 size_t recv_mbuf_limit; /* Max size of recv buffer */
3925 struct mbuf recv_mbuf; /* Received data */
3926 struct mbuf send_mbuf; /* Data scheduled for sending */
3927 time_t last_io_time; /* Timestamp of the last socket IO */
3928 double ev_timer_time; /* Timestamp of the future MG_EV_TIMER */
3929#if MG_ENABLE_SSL
3930 void *ssl_if_data; /* SSL library data. */
3931#endif
3932 mg_event_handler_t proto_handler; /* Protocol-specific event handler */
3933 void *proto_data; /* Protocol-specific data */
3935 mg_event_handler_t handler; /* Event handler function */
3936 void *user_data; /* User-specific data */
3937 union {
3938 void *v;
3939 /*
3940 * the C standard is fussy about fitting function pointers into
3941 * void pointers, since some archs might have fat pointers for functions.
3942 */
3945 void *priv_2;
3946 void *mgr_data; /* Implementation-specific event manager's data. */
3948 unsigned long flags;
3949/* Flags set by Mongoose */
3950#define MG_F_LISTENING (1 << 0) /* This connection is listening */
3951#define MG_F_UDP (1 << 1) /* This connection is UDP */
3952#define MG_F_RESOLVING (1 << 2) /* Waiting for async resolver */
3953#define MG_F_CONNECTING (1 << 3) /* connect() call in progress */
3954#define MG_F_SSL (1 << 4) /* SSL is enabled on the connection */
3955#define MG_F_SSL_HANDSHAKE_DONE (1 << 5) /* SSL hanshake has completed */
3956#define MG_F_WANT_READ (1 << 6) /* SSL specific */
3957#define MG_F_WANT_WRITE (1 << 7) /* SSL specific */
3958#define MG_F_IS_WEBSOCKET (1 << 8) /* Websocket specific */
3959#define MG_F_RECV_AND_CLOSE (1 << 9) /* Drain rx and close the connection. */
3960
3961/* Flags that are settable by user */
3962#define MG_F_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */
3963#define MG_F_CLOSE_IMMEDIATELY (1 << 11) /* Disconnect */
3964#define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */
3965#define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */
3966#define MG_F_ENABLE_BROADCAST (1 << 14) /* Allow broadcast address usage */
3967
3968#define MG_F_USER_1 (1 << 20) /* Flags left for application */
3969#define MG_F_USER_2 (1 << 21)
3970#define MG_F_USER_3 (1 << 22)
3971#define MG_F_USER_4 (1 << 23)
3972#define MG_F_USER_5 (1 << 24)
3973#define MG_F_USER_6 (1 << 25)
3974};
3975
3976/*
3977 * Initialise Mongoose manager. Side effect: ignores SIGPIPE signal.
3978 * `mgr->user_data` field will be initialised with a `user_data` parameter.
3979 * That is an arbitrary pointer, where the user code can associate some data
3980 * with the particular Mongoose manager. For example, a C++ wrapper class
3981 * could be written in which case `user_data` can hold a pointer to the
3982 * class instance.
3983 */
3984void mg_mgr_init(struct mg_mgr *mgr, void *user_data);
3985
3986/*
3987 * Optional parameters to `mg_mgr_init_opt()`.
3988 *
3989 * If `main_iface` is not NULL, it will be used as the main interface in the
3990 * default interface set. The pointer will be free'd by `mg_mgr_free`.
3991 * Otherwise, the main interface will be autodetected based on the current
3992 * platform.
3993 *
3994 * If `num_ifaces` is 0 and `ifaces` is NULL, the default interface set will be
3995 * used.
3996 * This is an advanced option, as it requires you to construct a full interface
3997 * set, including special networking interfaces required by some optional
3998 * features such as TCP tunneling. Memory backing `ifaces` and each of the
3999 * `num_ifaces` pointers it contains will be reclaimed by `mg_mgr_free`.
4000 */
4004 const struct mg_iface_vtable **ifaces;
4005 const char *nameserver;
4006};
4007
4008/*
4009 * Like `mg_mgr_init` but with more options.
4010 *
4011 * Notably, this allows you to create a manger and choose
4012 * dynamically which networking interface implementation to use.
4013 */
4014void mg_mgr_init_opt(struct mg_mgr *mgr, void *user_data,
4015 struct mg_mgr_init_opts opts);
4016
4017/*
4018 * De-initialises Mongoose manager.
4019 *
4020 * Closes and deallocates all active connections.
4021 */
4022void mg_mgr_free(struct mg_mgr *mgr);
4023
4024/*
4025 * This function performs the actual IO and must be called in a loop
4026 * (an event loop). It returns number of user events generated (except POLLs).
4027 * `milli` is the maximum number of milliseconds to sleep.
4028 * `mg_mgr_poll()` checks all connections for IO readiness. If at least one
4029 * of the connections is IO-ready, `mg_mgr_poll()` triggers the respective
4030 * event handlers and returns.
4031 */
4032int mg_mgr_poll(struct mg_mgr *mgr, int milli);
4033
4034#if MG_ENABLE_BROADCAST
4035/*
4036 * Passes a message of a given length to all connections.
4037 *
4038 * Must be called from a thread that does NOT call `mg_mgr_poll()`.
4039 * Note that `mg_broadcast()` is the only function
4040 * that can be, and must be, called from a different (non-IO) thread.
4041 *
4042 * `func` callback function will be called by the IO thread for each
4043 * connection. When called, the event will be `MG_EV_POLL`, and a message will
4044 * be passed as the `ev_data` pointer. Maximum message size is capped
4045 * by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes by default.
4046 */
4047void mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data,
4048 size_t len);
4049#endif
4050
4051/*
4052 * Iterates over all active connections.
4053 *
4054 * Returns the next connection from the list
4055 * of active connections or `NULL` if there are no more connections. Below
4056 * is the iteration idiom:
4057 *
4058 * ```c
4059 * for (c = mg_next(srv, NULL); c != NULL; c = mg_next(srv, c)) {
4060 * // Do something with connection `c`
4061 * }
4062 * ```
4063 */
4064struct mg_connection *mg_next(struct mg_mgr *mgr, struct mg_connection *c);
4065
4066/*
4067 * Optional parameters to `mg_add_sock_opt()`.
4068 *
4069 * `flags` is an initial `struct mg_connection::flags` bitmask to set,
4070 * see `MG_F_*` flags definitions.
4071 */
4072struct mg_add_sock_opts {
4073 void *user_data; /* Initial value for connection's user_data */
4074 unsigned int flags; /* Initial connection flags */
4075 const char **error_string; /* Placeholder for the error string */
4076 struct mg_iface *iface; /* Interface instance */
4077};
4078
4079/*
4080 * Creates a connection, associates it with the given socket and event handler
4081 * and adds it to the manager.
4082 *
4083 * For more options see the `mg_add_sock_opt` variant.
4084 */
4087 void *user_data));
4088
4089/*
4090 * Creates a connection, associates it with the given socket and event handler
4091 * and adds to the manager.
4092 *
4093 * See the `mg_add_sock_opts` structure for a description of the options.
4094 */
4097 void *user_data),
4098 struct mg_add_sock_opts opts);
4099
4100/*
4101 * Optional parameters to `mg_bind_opt()`.
4102 *
4103 * `flags` is an initial `struct mg_connection::flags` bitmask to set,
4104 * see `MG_F_*` flags definitions.
4105 */
4106struct mg_bind_opts {
4107 void *user_data; /* Initial value for connection's user_data */
4108 unsigned int flags; /* Extra connection flags */
4109 const char **error_string; /* Placeholder for the error string */
4110 struct mg_iface *iface; /* Interface instance */
4111#if MG_ENABLE_SSL
4112 /*
4113 * SSL settings.
4114 *
4115 * Server certificate to present to clients or client certificate to
4116 * present to tunnel dispatcher (for tunneled connections).
4117 */
4118 const char *ssl_cert;
4119 /* Private key corresponding to the certificate. If ssl_cert is set but
4120 * ssl_key is not, ssl_cert is used. */
4121 const char *ssl_key;
4122 /* CA bundle used to verify client certificates or tunnel dispatchers. */
4123 const char *ssl_ca_cert;
4124 /* Colon-delimited list of acceptable cipher suites.
4125 * Names depend on the library used, for example:
4126 *
4127 * ECDH-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256 (OpenSSL)
4128 * TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256
4129 * (mbedTLS)
4130 *
4131 * For OpenSSL the list can be obtained by running "openssl ciphers".
4132 * For mbedTLS, names can be found in library/ssl_ciphersuites.c
4133 * If NULL, a reasonable default is used.
4134 */
4135 const char *ssl_cipher_suites;
4136#endif
4137};
4138
4139/*
4140 * Creates a listening connection.
4141 *
4142 * See `mg_bind_opt` for full documentation.
4143 */
4144struct mg_connection *mg_bind(struct mg_mgr *mgr, const char *address,
4146 void *user_data));
4147/*
4148 * Creates a listening connection.
4149 *
4150 * The `address` parameter specifies which address to bind to. It's format is
4151 * the same as for the `mg_connect()` call, where `HOST` part is optional.
4152 * `address` can be just a port number, e.g. `:8000`. To bind to a specific
4153 * interface, an IP address can be specified, e.g. `1.2.3.4:8000`. By default,
4154 * a TCP connection is created. To create UDP connection, prepend `udp://`
4155 * prefix, e.g. `udp://:8000`. To summarize, `address` parameter has following
4156 * format: `[PROTO://][IP_ADDRESS]:PORT`, where `PROTO` could be `tcp` or
4157 * `udp`.
4158 *
4159 * See the `mg_bind_opts` structure for a description of the optional
4160 * parameters.
4161 *
4162 * Returns a new listening connection or `NULL` on error.
4163 * NOTE: The connection remains owned by the manager, do not free().
4164 */
4165struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,
4167 void *user_data),
4168 struct mg_bind_opts opts);
4169
4170/* Optional parameters to `mg_connect_opt()` */
4171struct mg_connect_opts {
4172 void *user_data; /* Initial value for connection's user_data */
4173 unsigned int flags; /* Extra connection flags */
4174 const char **error_string; /* Placeholder for the error string */
4175 struct mg_iface *iface; /* Interface instance */
4176 const char *nameserver; /* DNS server to use, NULL for default */
4177#if MG_ENABLE_SSL
4178 /*
4179 * SSL settings.
4180 * Client certificate to present to the server.
4181 */
4182 const char *ssl_cert;
4183 /*
4184 * Private key corresponding to the certificate.
4185 * If ssl_cert is set but ssl_key is not, ssl_cert is used.
4186 */
4187 const char *ssl_key;
4188 /*
4189 * Verify server certificate using this CA bundle. If set to "*", then SSL
4190 * is enabled but no cert verification is performed.
4191 */
4192 const char *ssl_ca_cert;
4193 /* Colon-delimited list of acceptable cipher suites.
4194 * Names depend on the library used, for example:
4195 *
4196 * ECDH-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256 (OpenSSL)
4197 * TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256
4198 * (mbedTLS)
4199 *
4200 * For OpenSSL the list can be obtained by running "openssl ciphers".
4201 * For mbedTLS, names can be found in library/ssl_ciphersuites.c
4202 * If NULL, a reasonable default is used.
4203 */
4204 const char *ssl_cipher_suites;
4205 /*
4206 * Server name verification. If ssl_ca_cert is set and the certificate has
4207 * passed verification, its subject will be verified against this string.
4208 * By default (if ssl_server_name is NULL) hostname part of the address will
4209 * be used. Wildcard matching is supported. A special value of "*" disables
4210 * name verification.
4211 */
4212 const char *ssl_server_name;
4213 /*
4214 * PSK identity and key. Identity is a NUL-terminated string and key is a hex
4215 * string. Key must be either 16 or 32 bytes (32 or 64 hex digits) for AES-128
4216 * or AES-256 respectively.
4217 * Note: Default list of cipher suites does not include PSK suites, if you
4218 * want to use PSK you will need to set ssl_cipher_suites as well.
4219 */
4220 const char *ssl_psk_identity;
4221 const char *ssl_psk_key;
4222#endif
4223};
4224
4225/*
4226 * Connects to a remote host.
4227 *
4228 * See `mg_connect_opt()` for full documentation.
4229 */
4230struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,
4232 void *user_data));
4233
4234/*
4235 * Connects to a remote host.
4236 *
4237 * The `address` format is `[PROTO://]HOST:PORT`. `PROTO` could be `tcp` or
4238 * `udp`. `HOST` could be an IP address,
4239 * IPv6 address (if Mongoose is compiled with `-DMG_ENABLE_IPV6`) or a host
4240 * name. If `HOST` is a name, Mongoose will resolve it asynchronously. Examples
4241 * of valid addresses: `google.com:80`, `udp://1.2.3.4:53`, `10.0.0.1:443`,
4242 * `[::1]:80`
4243 *
4244 * See the `mg_connect_opts` structure for a description of the optional
4245 * parameters.
4246 *
4247 * Returns a new outbound connection or `NULL` on error.
4248 *
4249 * NOTE: The connection remains owned by the manager, do not free().
4250 *
4251 * NOTE: To enable IPv6 addresses `-DMG_ENABLE_IPV6` should be specified
4252 * in the compilation flags.
4253 *
4254 * NOTE: The new connection will receive `MG_EV_CONNECT` as its first event
4255 * which will report the connect success status.
4256 * If the asynchronous resolution fails or the `connect()` syscall fails for
4257 * whatever reason (e.g. with `ECONNREFUSED` or `ENETUNREACH`), then
4258 * `MG_EV_CONNECT` event will report failure. Code example below:
4259 *
4260 * ```c
4261 * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
4262 * int connect_status;
4263 *
4264 * switch (ev) {
4265 * case MG_EV_CONNECT:
4266 * connect_status = * (int *) ev_data;
4267 * if (connect_status == 0) {
4268 * // Success
4269 * } else {
4270 * // Error
4271 * printf("connect() error: %s\n", strerror(connect_status));
4272 * }
4273 * break;
4274 * ...
4275 * }
4276 * }
4277 *
4278 * ...
4279 * mg_connect(mgr, "my_site.com:80", ev_handler);
4280 * ```
4281 */
4282struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
4284 void *user_data),
4285 struct mg_connect_opts opts);
4286
4287#if MG_ENABLE_SSL && MG_NET_IF != MG_NET_IF_SIMPLELINK
4288/*
4289 * Note: This function is deprecated. Please, use SSL options in
4290 * mg_connect_opt.
4291 *
4292 * Enables SSL for a given connection.
4293 * `cert` is a server certificate file name for a listening connection
4294 * or a client certificate file name for an outgoing connection.
4295 * The certificate files must be in PEM format. The server certificate file
4296 * must contain a certificate, concatenated with a private key, optionally
4297 * concatenated with DH parameters.
4298 * `ca_cert` is a CA certificate or NULL if peer verification is not
4299 * required.
4300 * Return: NULL on success or error message on error.
4301 */
4302const char *mg_set_ssl(struct mg_connection *nc, const char *cert,
4303 const char *ca_cert);
4304#endif
4305
4306/*
4307 * Sends data to the connection.
4308 *
4309 * Note that sending functions do not actually push data to the socket.
4310 * They just append data to the output buffer. MG_EV_SEND will be delivered when
4311 * the data has actually been pushed out.
4312 */
4313void mg_send(struct mg_connection *, const void *buf, int len);
4314
4315/* Enables format string warnings for mg_printf */
4316#if defined(__GNUC__)
4317__attribute__((format(printf, 2, 3)))
4318#endif
4319/* don't separate from mg_printf declaration */
4320
4321/*
4322 * Sends `printf`-style formatted data to the connection.
4323 *
4324 * See `mg_send` for more details on send semantics.
4325 */
4326int mg_printf(struct mg_connection *, const char *fmt, ...);
4327
4328/* Same as `mg_printf()`, but takes `va_list ap` as an argument. */
4329int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
4330
4331/*
4332 * Creates a socket pair.
4333 * `sock_type` can be either `SOCK_STREAM` or `SOCK_DGRAM`.
4334 * Returns 0 on failure and 1 on success.
4335 */
4336int mg_socketpair(sock_t[2], int sock_type);
4337
4338#if MG_ENABLE_SYNC_RESOLVER
4339/*
4340 * Convert domain name into IP address.
4341 *
4342 * This is a utility function. If compilation flags have
4343 * `-DMG_ENABLE_GETADDRINFO`, then `getaddrinfo()` call is used for name
4344 * resolution. Otherwise, `gethostbyname()` is used.
4345 *
4346 * CAUTION: this function can block.
4347 * Return 1 on success, 0 on failure.
4348 */
4349int mg_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
4350#endif
4351
4352/*
4353 * Verify given IP address against the ACL.
4354 *
4355 * `remote_ip` - an IPv4 address to check, in host byte order
4356 * `acl` - a comma separated list of IP subnets: `x.x.x.x/x` or `x.x.x.x`.
4357 * Each subnet is
4358 * prepended by either a - or a + sign. A plus sign means allow, where a
4359 * minus sign means deny. If a subnet mask is omitted, such as `-1.2.3.4`,
4360 * it means that only that single IP address is denied.
4361 * Subnet masks may vary from 0 to 32, inclusive. The default setting
4362 * is to allow all access. On each request the full list is traversed,
4363 * and the last match wins. Example:
4364 *
4365 * `-0.0.0.0/0,+192.168/16` - deny all accesses, only allow 192.168/16 subnet
4366 *
4367 * To learn more about subnet masks, see this
4368 * link:https://en.wikipedia.org/wiki/Subnetwork[Wikipedia page on Subnetwork].
4369 *
4370 * Returns -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed.
4371 */
4372int mg_check_ip_acl(const char *acl, uint32_t remote_ip);
4373
4374/*
4375 * Schedules an MG_EV_TIMER event to be delivered at `timestamp` time.
4376 * `timestamp` is UNIX time (the number of seconds since Epoch). It is
4377 * `double` instead of `time_t` to allow for sub-second precision.
4378 * Returns the old timer value.
4379 *
4380 * Example: set the connect timeout to 1.5 seconds:
4381 *
4382 * ```
4383 * c = mg_connect(&mgr, "cesanta.com", ev_handler);
4384 * mg_set_timer(c, mg_time() + 1.5);
4385 * ...
4386 *
4387 * void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
4388 * switch (ev) {
4389 * case MG_EV_CONNECT:
4390 * mg_set_timer(c, 0); // Clear connect timer
4391 * break;
4392 * case MG_EV_TIMER:
4393 * log("Connect timeout");
4394 * c->flags |= MG_F_CLOSE_IMMEDIATELY;
4395 * break;
4396 * ```
4397 */
4398double mg_set_timer(struct mg_connection *c, double timestamp);
4399
4400/*
4401 * A sub-second precision version of time().
4402 */
4403double mg_time(void);
4404
4405#ifdef __cplusplus
4406}
4407#endif /* __cplusplus */
4408
4409#endif /* CS_MONGOOSE_SRC_NET_H_ */
4410#ifdef MG_MODULE_LINES
4411#line 1 "mongoose/src/mg_uri.h"
4412#endif
4413/*
4414 * Copyright (c) 2014 Cesanta Software Limited
4415 * All rights reserved
4416 */
4417
4418/*
4419 * === URI
4420 */
4421
4422#ifndef CS_MONGOOSE_SRC_URI_H_
4423#define CS_MONGOOSE_SRC_URI_H_
4424
4425/* Amalgamated: #include "mg_net.h" */
4426
4427#ifdef __cplusplus
4428extern "C" {
4429#endif /* __cplusplus */
4430
4431/*
4432 * Parses an URI and fills string chunks with locations of the respective
4433 * uri components within the input uri string. NULL pointers will be
4434 * ignored.
4435 *
4436 * General syntax:
4437 *
4438 * [scheme://[user_info@]]host[:port][/path][?query][#fragment]
4439 *
4440 * Example:
4441 *
4442 * foo.com:80
4443 * tcp://foo.com:1234
4444 * http://foo.com:80/bar?baz=1
4445 * https://user:pw@foo.com:443/blah
4446 *
4447 * `path` will include the leading slash. `query` won't include the leading `?`.
4448 * `host` can contain embedded colons if surrounded by square brackets in order
4449 * to support IPv6 literal addresses.
4450 *
4451 *
4452 * Returns 0 on success, -1 on error.
4453 */
4454int mg_parse_uri(const struct mg_str uri, struct mg_str *scheme,
4455 struct mg_str *user_info, struct mg_str *host,
4456 unsigned int *port, struct mg_str *path, struct mg_str *query,
4457 struct mg_str *fragment);
4458
4459/*
4460 * Assemble URI from parts. Any of the inputs can be NULL or zero-length mg_str.
4461 *
4462 * If normalize_path is true, path is normalized by resolving relative refs.
4463 *
4464 * Result is a heap-allocated string (uri->p must be free()d after use).
4465 *
4466 * Returns 0 on success, -1 on error.
4467 */
4468int mg_assemble_uri(const struct mg_str *scheme, const struct mg_str *user_info,
4469 const struct mg_str *host, unsigned int port,
4470 const struct mg_str *path, const struct mg_str *query,
4471 const struct mg_str *fragment, int normalize_path,
4472 struct mg_str *uri);
4473
4474int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out);
4475
4476#ifdef __cplusplus
4477}
4478#endif /* __cplusplus */
4479#endif /* CS_MONGOOSE_SRC_URI_H_ */
4480#ifdef MG_MODULE_LINES
4481#line 1 "mongoose/src/mg_util.h"
4482#endif
4483/*
4484 * Copyright (c) 2014 Cesanta Software Limited
4485 * All rights reserved
4486 */
4487
4488/*
4489 * === Utility API
4490 */
4491
4492#ifndef CS_MONGOOSE_SRC_UTIL_H_
4493#define CS_MONGOOSE_SRC_UTIL_H_
4494
4495#include <stdio.h>
4496
4497/* Amalgamated: #include "mg_common.h" */
4498/* Amalgamated: #include "mg_net_if.h" */
4499
4500#ifdef __cplusplus
4501extern "C" {
4502#endif /* __cplusplus */
4503
4504#ifndef MG_MAX_PATH
4505#ifdef PATH_MAX
4506#define MG_MAX_PATH PATH_MAX
4507#else
4508#define MG_MAX_PATH 256
4509#endif
4510#endif
4511
4512/*
4513 * Fetches substring from input string `s`, `end` into `v`.
4514 * Skips initial delimiter characters. Records first non-delimiter character
4515 * at the beginning of substring `v`. Then scans the rest of the string
4516 * until a delimiter character or end-of-string is found.
4517 * `delimiters` is a 0-terminated string containing delimiter characters.
4518 * Either one of `delimiters` or `end_string` terminates the search.
4519 * Returns an `s` pointer, advanced forward where parsing has stopped.
4520 */
4521const char *mg_skip(const char *s, const char *end_string,
4522 const char *delimiters, struct mg_str *v);
4523
4524/*
4525 * Decodes base64-encoded string `s`, `len` into the destination `dst`.
4526 * The destination has to have enough space to hold the decoded buffer.
4527 * Decoding stops either when all strings have been decoded or invalid an
4528 * character appeared.
4529 * Destination is '\0'-terminated.
4530 * Returns the number of decoded characters. On success, that should be equal
4531 * to `len`. On error (invalid character) the return value is smaller then
4532 * `len`.
4533 */
4534int mg_base64_decode(const unsigned char *s, int len, char *dst);
4535
4536/*
4537 * Base64-encode chunk of memory `src`, `src_len` into the destination `dst`.
4538 * Destination has to have enough space to hold encoded buffer.
4539 * Destination is '\0'-terminated.
4540 */
4541void mg_base64_encode(const unsigned char *src, int src_len, char *dst);
4542
4543#if MG_ENABLE_FILESYSTEM
4544/*
4545 * Performs a 64-bit `stat()` call against a given file.
4546 *
4547 * `path` should be UTF8 encoded.
4548 *
4549 * Return value is the same as for `stat()` syscall.
4550 */
4551int mg_stat(const char *path, cs_stat_t *st);
4552
4553/*
4554 * Opens the given file and returns a file stream.
4555 *
4556 * `path` and `mode` should be UTF8 encoded.
4557 *
4558 * Return value is the same as for the `fopen()` call.
4559 */
4560FILE *mg_fopen(const char *path, const char *mode);
4561
4562/*
4563 * Opens the given file and returns a file stream.
4564 *
4565 * `path` should be UTF8 encoded.
4566 *
4567 * Return value is the same as for the `open()` syscall.
4568 */
4569int mg_open(const char *path, int flag, int mode);
4570
4571/*
4572 * Reads data from the given file stream.
4573 *
4574 * Return value is a number of bytes readen.
4575 */
4576size_t mg_fread(void *ptr, size_t size, size_t count, FILE *f);
4577
4578/*
4579 * Writes data to the given file stream.
4580 *
4581 * Return value is a number of bytes wtitten.
4582 */
4583size_t mg_fwrite(const void *ptr, size_t size, size_t count, FILE *f);
4584
4585#endif /* MG_ENABLE_FILESYSTEM */
4586
4587#if MG_ENABLE_THREADS
4588/*
4589 * Starts a new detached thread.
4590 * Arguments and semantics are the same as pthead's `pthread_create()`.
4591 * `thread_func` is a thread function, `thread_func_param` is a parameter
4592 * that is passed to the thread function.
4593 */
4594void *mg_start_thread(void *(*thread_func)(void *), void *thread_func_param);
4595#endif
4596
4598
4599#define MG_SOCK_STRINGIFY_IP 1
4600#define MG_SOCK_STRINGIFY_PORT 2
4601#define MG_SOCK_STRINGIFY_REMOTE 4
4602/*
4603 * Converts a connection's local or remote address into string.
4604 *
4605 * The `flags` parameter is a bit mask that controls the behaviour,
4606 * see `MG_SOCK_STRINGIFY_*` definitions.
4607 *
4608 * - MG_SOCK_STRINGIFY_IP - print IP address
4609 * - MG_SOCK_STRINGIFY_PORT - print port number
4610 * - MG_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address
4611 *
4612 * If both port number and IP address are printed, they are separated by `:`.
4613 * If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported.
4614 * Return length of the stringified address.
4615 */
4616int mg_conn_addr_to_str(struct mg_connection *c, char *buf, size_t len,
4617 int flags);
4618#if MG_NET_IF == MG_NET_IF_SOCKET
4619/* Legacy interface. */
4620void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
4621#endif
4622
4623/*
4624 * Convert the socket's address into string.
4625 *
4626 * `flags` is MG_SOCK_STRINGIFY_IP and/or MG_SOCK_STRINGIFY_PORT.
4627 */
4628int mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
4629 int flags);
4630
4631#if MG_ENABLE_HEXDUMP
4632/*
4633 * Generates a human-readable hexdump of memory chunk.
4634 *
4635 * Takes a memory buffer `buf` of length `len` and creates a hex dump of that
4636 * buffer in `dst`. The generated output is a-la hexdump(1).
4637 * Returns the length of generated string, excluding terminating `\0`. If
4638 * returned length is bigger than `dst_len`, the overflow bytes are discarded.
4639 */
4640int mg_hexdump(const void *buf, int len, char *dst, int dst_len);
4641
4642/* Same as mg_hexdump, but with output going to file instead of a buffer. */
4643void mg_hexdumpf(FILE *fp, const void *buf, int len);
4644
4645/*
4646 * Generates human-readable hexdump of the data sent or received by the
4647 * connection. `path` is a file name where hexdump should be written.
4648 * `num_bytes` is a number of bytes sent/received. `ev` is one of the `MG_*`
4649 * events sent to an event handler. This function is supposed to be called from
4650 * the event handler.
4651 */
4652void mg_hexdump_connection(struct mg_connection *nc, const char *path,
4653 const void *buf, int num_bytes, int ev);
4654#endif
4655
4656/*
4657 * Returns true if target platform is big endian.
4658 */
4659int mg_is_big_endian(void);
4660
4661/*
4662 * Use with cs_base64_init/update/finish in order to write out base64 in chunks.
4663 */
4664void mg_mbuf_append_base64_putc(char ch, void *user_data);
4665
4666/*
4667 * Encode `len` bytes starting at `data` as base64 and append them to an mbuf.
4668 */
4669void mg_mbuf_append_base64(struct mbuf *mbuf, const void *data, size_t len);
4670
4671/*
4672 * Generate a Basic Auth header and appends it to buf.
4673 * If pass is NULL, then user is expected to contain the credentials pair
4674 * already encoded as `user:pass`.
4675 */
4676void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass,
4677 struct mbuf *buf);
4678
4679/*
4680 * URL-escape the specified string.
4681 * All characters acept letters, numbers and characters listed in
4682 * `safe` are escaped. If `hex_upper`is true, `A-F` are used for hex digits.
4683 * Input need not be NUL-terminated, but the returned string is.
4684 * Returned string is heap-allocated and must be free()'d.
4685 */
4686#define MG_URL_ENCODE_F_SPACE_AS_PLUS (1 << 0)
4687#define MG_URL_ENCODE_F_UPPERCASE_HEX (1 << 1)
4690
4691/* Same as `mg_url_encode_opt(src, "._-$,;~()/", 0)`. */
4693
4694#ifdef __cplusplus
4695}
4696#endif /* __cplusplus */
4697#endif /* CS_MONGOOSE_SRC_UTIL_H_ */
4698#ifdef MG_MODULE_LINES
4699#line 1 "mongoose/src/mg_http.h"
4700#endif
4701/*
4702 * Copyright (c) 2014 Cesanta Software Limited
4703 * All rights reserved
4704 */
4705
4706/*
4707 * === Common API reference
4708 */
4709
4710#ifndef CS_MONGOOSE_SRC_HTTP_H_
4711#define CS_MONGOOSE_SRC_HTTP_H_
4712
4713#if MG_ENABLE_HTTP
4714
4715/* Amalgamated: #include "mg_net.h" */
4716/* Amalgamated: #include "common/mg_str.h" */
4717
4718#ifdef __cplusplus
4719extern "C" {
4720#endif /* __cplusplus */
4721
4722#ifndef MG_MAX_HTTP_HEADERS
4723#define MG_MAX_HTTP_HEADERS 20
4724#endif
4725
4726#ifndef MG_MAX_HTTP_REQUEST_SIZE
4727#define MG_MAX_HTTP_REQUEST_SIZE 1024
4728#endif
4729
4730#ifndef MG_MAX_HTTP_SEND_MBUF
4731#define MG_MAX_HTTP_SEND_MBUF 1024
4732#endif
4733
4734#ifndef MG_CGI_ENVIRONMENT_SIZE
4735#define MG_CGI_ENVIRONMENT_SIZE 8192
4736#endif
4737
4738/* HTTP message */
4739struct http_message {
4740 struct mg_str message; /* Whole message: request line + headers + body */
4741 struct mg_str body; /* Message body. 0-length for requests with no body */
4742
4743 /* HTTP Request line (or HTTP response line) */
4744 struct mg_str method; /* "GET" */
4745 struct mg_str uri; /* "/my_file.html" */
4746 struct mg_str proto; /* "HTTP/1.1" -- for both request and response */
4747
4748 /* For responses, code and response status message are set */
4749 int resp_code;
4750 struct mg_str resp_status_msg;
4751
4752 /*
4753 * Query-string part of the URI. For example, for HTTP request
4754 * GET /foo/bar?param1=val1&param2=val2
4755 * | uri | query_string |
4756 *
4757 * Note that question mark character doesn't belong neither to the uri,
4758 * nor to the query_string
4759 */
4760 struct mg_str query_string;
4761
4762 /* Headers */
4765};
4766
4767#if MG_ENABLE_HTTP_WEBSOCKET
4768/* WebSocket message */
4769struct websocket_message {
4770 unsigned char *data;
4771 size_t size;
4772 unsigned char flags;
4773};
4774#endif
4775
4776/* HTTP multipart part */
4778 const char *file_name;
4779 const char *var_name;
4780 struct mg_str data;
4781 int status; /* <0 on error */
4782 void *user_data;
4783 /*
4784 * User handler can indicate how much of the data was consumed
4785 * by setting this variable. By default, it is assumed that all
4786 * data has been consumed by the handler.
4787 * If not all data was consumed, user's handler will be invoked again later
4788 * with the remainder.
4789 */
4791};
4792
4793/* SSI call context */
4795 struct http_message *req; /* The request being processed. */
4796 struct mg_str file; /* Filesystem path of the file being processed. */
4797 struct mg_str arg; /* The argument passed to the tag: <!-- call arg -->. */
4798};
4799
4800/* HTTP and websocket events. void *ev_data is described in a comment. */
4801#define MG_EV_HTTP_REQUEST 100 /* struct http_message * */
4802#define MG_EV_HTTP_REPLY 101 /* struct http_message * */
4803#define MG_EV_HTTP_CHUNK 102 /* struct http_message * */
4804#define MG_EV_SSI_CALL 105 /* char * */
4805#define MG_EV_SSI_CALL_CTX 106 /* struct mg_ssi_call_ctx * */
4806
4807#if MG_ENABLE_HTTP_WEBSOCKET
4808#define MG_EV_WEBSOCKET_HANDSHAKE_REQUEST 111 /* struct http_message * */
4809#define MG_EV_WEBSOCKET_HANDSHAKE_DONE 112 /* struct http_message * */
4810#define MG_EV_WEBSOCKET_FRAME 113 /* struct websocket_message * */
4811#define MG_EV_WEBSOCKET_CONTROL_FRAME 114 /* struct websocket_message * */
4812#endif
4813
4814#if MG_ENABLE_HTTP_STREAMING_MULTIPART
4815#define MG_EV_HTTP_MULTIPART_REQUEST 121 /* struct http_message */
4816#define MG_EV_HTTP_PART_BEGIN 122 /* struct mg_http_multipart_part */
4817#define MG_EV_HTTP_PART_DATA 123 /* struct mg_http_multipart_part */
4818#define MG_EV_HTTP_PART_END 124 /* struct mg_http_multipart_part */
4819/* struct mg_http_multipart_part */
4820#define MG_EV_HTTP_MULTIPART_REQUEST_END 125
4821#endif
4822
4823/*
4824 * Attaches a built-in HTTP event handler to the given connection.
4825 * The user-defined event handler will receive following extra events:
4826 *
4827 * - MG_EV_HTTP_REQUEST: HTTP request has arrived. Parsed HTTP request
4828 * is passed as
4829 * `struct http_message` through the handler's `void *ev_data` pointer.
4830 * - MG_EV_HTTP_REPLY: The HTTP reply has arrived. The parsed HTTP reply is
4831 * passed as `struct http_message` through the handler's `void *ev_data`
4832 * pointer.
4833 * - MG_EV_HTTP_CHUNK: The HTTP chunked-encoding chunk has arrived.
4834 * The parsed HTTP reply is passed as `struct http_message` through the
4835 * handler's `void *ev_data` pointer. `http_message::body` would contain
4836 * incomplete, reassembled HTTP body.
4837 * It will grow with every new chunk that arrives, and it can
4838 * potentially consume a lot of memory. An event handler may process
4839 * the body as chunks are coming, and signal Mongoose to delete processed
4840 * body by setting `MG_F_DELETE_CHUNK` in `mg_connection::flags`. When
4841 * the last zero chunk is received,
4842 * Mongoose sends `MG_EV_HTTP_REPLY` event with
4843 * full reassembled body (if handler did not signal to delete chunks) or
4844 * with empty body (if handler did signal to delete chunks).
4845 * - MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: server has received the WebSocket
4846 * handshake request. `ev_data` contains parsed HTTP request.
4847 * - MG_EV_WEBSOCKET_HANDSHAKE_DONE: server has completed the WebSocket
4848 * handshake. `ev_data` is a `struct http_message` containing the
4849 * client's request (server mode) or server's response (client).
4850 * In client mode handler can examine `resp_code`, which should be 101.
4851 * - MG_EV_WEBSOCKET_FRAME: new WebSocket frame has arrived. `ev_data` is
4852 * `struct websocket_message *`
4853 *
4854 * When compiled with MG_ENABLE_HTTP_STREAMING_MULTIPART, Mongoose parses
4855 * multipart requests and splits them into separate events:
4856 * - MG_EV_HTTP_MULTIPART_REQUEST: Start of the request.
4857 * This event is sent before body is parsed. After this, the user
4858 * should expect a sequence of PART_BEGIN/DATA/END requests.
4859 * This is also the last time when headers and other request fields are
4860 * accessible.
4861 * - MG_EV_HTTP_PART_BEGIN: Start of a part of a multipart message.
4862 * Argument: mg_http_multipart_part with var_name and file_name set
4863 * (if present). No data is passed in this message.
4864 * - MG_EV_HTTP_PART_DATA: new portion of data from the multipart message.
4865 * Argument: mg_http_multipart_part. var_name and file_name are preserved,
4866 * data is available in mg_http_multipart_part.data.
4867 * - MG_EV_HTTP_PART_END: End of the current part. var_name, file_name are
4868 * the same, no data in the message. If status is 0, then the part is
4869 * properly terminated with a boundary, status < 0 means that connection
4870 * was terminated.
4871 * - MG_EV_HTTP_MULTIPART_REQUEST_END: End of the multipart request.
4872 * Argument: mg_http_multipart_part, var_name and file_name are NULL,
4873 * status = 0 means request was properly closed, < 0 means connection
4874 * was terminated (note: in this case both PART_END and REQUEST_END are
4875 * delivered).
4876 */
4878
4879#if MG_ENABLE_HTTP_WEBSOCKET
4880/*
4881 * Send websocket handshake to the server.
4882 *
4883 * `nc` must be a valid connection, connected to a server. `uri` is an URI
4884 * to fetch, extra_headers` is extra HTTP headers to send or `NULL`.
4885 *
4886 * This function is intended to be used by websocket client.
4887 *
4888 * Note that the Host header is mandatory in HTTP/1.1 and must be
4889 * included in `extra_headers`. `mg_send_websocket_handshake2` offers
4890 * a better API for that.
4891 *
4892 * Deprecated in favour of `mg_send_websocket_handshake2`
4893 */
4894void mg_send_websocket_handshake(struct mg_connection *nc, const char *uri,
4895 const char *extra_headers);
4896
4897/*
4898 * Send websocket handshake to the server.
4899 *
4900 * `nc` must be a valid connection, connected to a server. `uri` is an URI
4901 * to fetch, `host` goes into the `Host` header, `protocol` goes into the
4902 * `Sec-WebSocket-Proto` header (NULL to omit), extra_headers` is extra HTTP
4903 * headers to send or `NULL`.
4904 *
4905 * This function is intended to be used by websocket client.
4906 */
4907void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path,
4908 const char *host, const char *protocol,
4909 const char *extra_headers);
4910
4911/* Like mg_send_websocket_handshake2 but also passes basic auth header */
4912void mg_send_websocket_handshake3(struct mg_connection *nc, const char *path,
4913 const char *host, const char *protocol,
4914 const char *extra_headers, const char *user,
4915 const char *pass);
4916
4917/* Same as mg_send_websocket_handshake3 but with strings not necessarily
4918 * NUL-temrinated */
4920 const struct mg_str path,
4921 const struct mg_str host,
4922 const struct mg_str protocol,
4923 const struct mg_str extra_headers,
4924 const struct mg_str user,
4925 const struct mg_str pass);
4926
4927/*
4928 * Helper function that creates an outbound WebSocket connection.
4929 *
4930 * `url` is a URL to connect to. It must be properly URL-encoded, e.g. have
4931 * no spaces, etc. By default, `mg_connect_ws()` sends Connection and
4932 * Host headers. `extra_headers` is an extra HTTP header to send, e.g.
4933 * `"User-Agent: my-app\r\n"`.
4934 * If `protocol` is not NULL, then a `Sec-WebSocket-Protocol` header is sent.
4935 *
4936 * Examples:
4937 *
4938 * ```c
4939 * nc1 = mg_connect_ws(mgr, ev_handler_1, "ws://echo.websocket.org", NULL,
4940 * NULL);
4941 * nc2 = mg_connect_ws(mgr, ev_handler_1, "wss://echo.websocket.org", NULL,
4942 * NULL);
4943 * nc3 = mg_connect_ws(mgr, ev_handler_1, "ws://api.cesanta.com",
4944 * "clubby.cesanta.com", NULL);
4945 * ```
4946 */
4948 MG_CB(mg_event_handler_t event_handler,
4949 void *user_data),
4950 const char *url, const char *protocol,
4951 const char *extra_headers);
4952
4953/*
4954 * Helper function that creates an outbound WebSocket connection
4955 *
4956 * Mostly identical to `mg_connect_ws`, but allows to provide extra parameters
4957 * (for example, SSL parameters)
4958 */
4961 struct mg_connect_opts opts, const char *url, const char *protocol,
4962 const char *extra_headers);
4963
4964/*
4965 * Send WebSocket frame to the remote end.
4966 *
4967 * `op_and_flags` specifies the frame's type. It's one of:
4968 *
4969 * - WEBSOCKET_OP_CONTINUE
4970 * - WEBSOCKET_OP_TEXT
4971 * - WEBSOCKET_OP_BINARY
4972 * - WEBSOCKET_OP_CLOSE
4973 * - WEBSOCKET_OP_PING
4974 * - WEBSOCKET_OP_PONG
4975 *
4976 * Orred with one of the flags:
4977 *
4978 * - WEBSOCKET_DONT_FIN: Don't set the FIN flag on the frame to be sent.
4979 *
4980 * `data` and `data_len` contain frame data.
4981 */
4983 const void *data, size_t data_len);
4984
4985/*
4986 * Like `mg_send_websocket_frame()`, but composes a single frame from multiple
4987 * buffers.
4988 */
4990 const struct mg_str *strings, int num_strings);
4991
4992/*
4993 * Sends WebSocket frame to the remote end.
4994 *
4995 * Like `mg_send_websocket_frame()`, but allows to create formatted messages
4996 * with `printf()`-like semantics.
4997 */
4999 const char *fmt, ...);
5000
5001/* Websocket opcodes, from http://tools.ietf.org/html/rfc6455 */
5002#define WEBSOCKET_OP_CONTINUE 0
5003#define WEBSOCKET_OP_TEXT 1
5004#define WEBSOCKET_OP_BINARY 2
5005#define WEBSOCKET_OP_CLOSE 8
5006#define WEBSOCKET_OP_PING 9
5007#define WEBSOCKET_OP_PONG 10
5008
5009/*
5010 * If set causes the FIN flag to not be set on outbound
5011 * frames. This enables sending multiple fragments of a single
5012 * logical message.
5013 *
5014 * The WebSocket protocol mandates that if the FIN flag of a data
5015 * frame is not set, the next frame must be a WEBSOCKET_OP_CONTINUE.
5016 * The last frame must have the FIN bit set.
5017 *
5018 * Note that mongoose will automatically defragment incoming messages,
5019 * so this flag is used only on outbound messages.
5020 */
5021#define WEBSOCKET_DONT_FIN 0x100
5022
5023#endif /* MG_ENABLE_HTTP_WEBSOCKET */
5024
5025/*
5026 * Decodes a URL-encoded string.
5027 *
5028 * Source string is specified by (`src`, `src_len`), and destination is
5029 * (`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then
5030 * `+` character is decoded as a blank space character. This function
5031 * guarantees to NUL-terminate the destination. If destination is too small,
5032 * then the source string is partially decoded and `-1` is returned.
5033 *Otherwise,
5034 * a length of the decoded string is returned, not counting final NUL.
5035 */
5036int mg_url_decode(const char *src, int src_len, char *dst, int dst_len,
5038
5039extern void mg_hash_md5_v(size_t num_msgs, const uint8_t *msgs[],
5040 const size_t *msg_lens, uint8_t *digest);
5041extern void mg_hash_sha1_v(size_t num_msgs, const uint8_t *msgs[],
5042 const size_t *msg_lens, uint8_t *digest);
5043
5044/*
5045 * Flags for `mg_http_is_authorized()`.
5046 */
5047#define MG_AUTH_FLAG_IS_DIRECTORY (1 << 0)
5048#define MG_AUTH_FLAG_IS_GLOBAL_PASS_FILE (1 << 1)
5049#define MG_AUTH_FLAG_ALLOW_MISSING_FILE (1 << 2)
5050
5051/*
5052 * Checks whether an http request is authorized. `domain` is the authentication
5053 * realm, `passwords_file` is a htdigest file (can be created e.g. with
5054 * `htdigest` utility). If either `domain` or `passwords_file` is NULL, this
5055 * function always returns 1; otherwise checks the authentication in the
5056 * http request and returns 1 only if there is a match; 0 otherwise.
5057 */
5059 const char *domain, const char *passwords_file,
5060 int flags);
5061
5062/*
5063 * Sends 401 Unauthorized response.
5064 */
5066 const char *domain);
5067
5068#ifdef __cplusplus
5069}
5070#endif /* __cplusplus */
5071
5072#endif /* MG_ENABLE_HTTP */
5073
5074#endif /* CS_MONGOOSE_SRC_HTTP_H_ */
5075#ifdef MG_MODULE_LINES
5076#line 1 "mongoose/src/mg_http_server.h"
5077#endif
5078/*
5079 * === Server API reference
5080 */
5081
5082#ifndef CS_MONGOOSE_SRC_HTTP_SERVER_H_
5083#define CS_MONGOOSE_SRC_HTTP_SERVER_H_
5084
5085#if MG_ENABLE_HTTP
5086
5087#ifdef __cplusplus
5088extern "C" {
5089#endif /* __cplusplus */
5090
5091/*
5092 * Parses a HTTP message.
5093 *
5094 * `is_req` should be set to 1 if parsing a request, 0 if reply.
5095 *
5096 * Returns the number of bytes parsed. If HTTP message is
5097 * incomplete `0` is returned. On parse error, a negative number is returned.
5098 */
5099int mg_parse_http(const char *s, int n, struct http_message *hm, int is_req);
5100
5101/*
5102 * Searches and returns the header `name` in parsed HTTP message `hm`.
5103 * If header is not found, NULL is returned. Example:
5104 *
5105 * struct mg_str *host_hdr = mg_get_http_header(hm, "Host");
5106 */
5107struct mg_str *mg_get_http_header(struct http_message *hm, const char *name);
5108
5109/*
5110 * Parses the HTTP header `hdr`. Finds variable `var_name` and stores its value
5111 * in the buffer `*buf`, `buf_size`. If the buffer size is not enough,
5112 * allocates a buffer of required size and writes it to `*buf`, similar to
5113 * asprintf(). The caller should always check whether the buffer was updated,
5114 * and free it if so.
5115 *
5116 * This function is supposed to parse cookies, authentication headers, etc.
5117 * Example (error handling omitted):
5118 *
5119 * char user_buf[20];
5120 * char *user = user_buf;
5121 * struct mg_str *hdr = mg_get_http_header(hm, "Authorization");
5122 * mg_http_parse_header2(hdr, "username", &user, sizeof(user_buf));
5123 * // ... do something useful with user
5124 * if (user != user_buf) {
5125 * free(user);
5126 * }
5127 *
5128 * Returns the length of the variable's value. If variable is not found, 0 is
5129 * returned.
5130 */
5131int mg_http_parse_header2(struct mg_str *hdr, const char *var_name, char **buf,
5132 size_t buf_size);
5133
5134/*
5135 * DEPRECATED: use mg_http_parse_header2() instead.
5136 *
5137 * Same as mg_http_parse_header2(), but takes buffer as a `char *` (instead of
5138 * `char **`), and thus it cannot allocate a new buffer if the provided one
5139 * is not enough, and just returns 0 in that case.
5140 */
5141int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,
5142 size_t buf_size)
5143#ifdef __GNUC__
5145#endif
5146 ;
5147
5148/*
5149 * Gets and parses the Authorization: Basic header
5150 * Returns -1 if no Authorization header is found, or if
5151 * mg_parse_http_basic_auth
5152 * fails parsing the resulting header.
5153 */
5154int mg_get_http_basic_auth(struct http_message *hm, char *user, size_t user_len,
5155 char *pass, size_t pass_len);
5156
5157/*
5158 * Parses the Authorization: Basic header
5159 * Returns -1 iif the authorization type is not "Basic" or any other error such
5160 * as incorrectly encoded base64 user password pair.
5161 */
5162int mg_parse_http_basic_auth(struct mg_str *hdr, char *user, size_t user_len,
5163 char *pass, size_t pass_len);
5164
5165/*
5166 * Parses the buffer `buf`, `buf_len` that contains multipart form data chunks.
5167 * Stores the chunk name in a `var_name`, `var_name_len` buffer.
5168 * If a chunk is an uploaded file, then `file_name`, `file_name_len` is
5169 * filled with an uploaded file name. `chunk`, `chunk_len`
5170 * points to the chunk data.
5171 *
5172 * Return: number of bytes to skip to the next chunk or 0 if there are
5173 * no more chunks.
5174 *
5175 * Usage example:
5176 *
5177 * ```c
5178 * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
5179 * switch(ev) {
5180 * case MG_EV_HTTP_REQUEST: {
5181 * struct http_message *hm = (struct http_message *) ev_data;
5182 * char var_name[100], file_name[100];
5183 * const char *chunk;
5184 * size_t chunk_len, n1, n2;
5185 *
5186 * n1 = n2 = 0;
5187 * while ((n2 = mg_parse_multipart(hm->body.p + n1,
5188 * hm->body.len - n1,
5189 * var_name, sizeof(var_name),
5190 * file_name, sizeof(file_name),
5191 * &chunk, &chunk_len)) > 0) {
5192 * printf("var: %s, file_name: %s, size: %d, chunk: [%.*s]\n",
5193 * var_name, file_name, (int) chunk_len,
5194 * (int) chunk_len, chunk);
5195 * n1 += n2;
5196 * }
5197 * }
5198 * break;
5199 * ```
5200 */
5201size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
5202 size_t var_name_len, char *file_name,
5203 size_t file_name_len, const char **chunk,
5204 size_t *chunk_len);
5205
5206/*
5207 * Fetches a HTTP form variable.
5208 *
5209 * Fetches a variable `name` from a `buf` into a buffer specified by `dst`,
5210 * `dst_len`. The destination is always zero-terminated. Returns the length of
5211 * a fetched variable. If not found, 0 is returned. `buf` must be valid
5212 * url-encoded buffer. If destination is too small or an error occured,
5213 * negative number is returned.
5214 */
5215int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst,
5216 size_t dst_len);
5217
5218#if MG_ENABLE_FILESYSTEM
5219/*
5220 * This structure defines how `mg_serve_http()` works.
5221 * Best practice is to set only required settings, and leave the rest as NULL.
5222 */
5223struct mg_serve_http_opts {
5224 /* Path to web root directory */
5225 const char *document_root;
5226
5227 /* List of index files. Default is "" */
5228 const char *index_files;
5229
5230 /*
5231 * Leave as NULL to disable authentication.
5232 * To enable directory protection with authentication, set this to ".htpasswd"
5233 * Then, creating ".htpasswd" file in any directory automatically protects
5234 * it with digest authentication.
5235 * Use `mongoose` web server binary, or `htdigest` Apache utility to
5236 * create/manipulate passwords file.
5237 * Make sure `auth_domain` is set to a valid domain name.
5238 */
5239 const char *per_directory_auth_file;
5240
5241 /* Authorization domain (domain name of this web server) */
5242 const char *auth_domain;
5243
5244 /*
5245 * Leave as NULL to disable authentication.
5246 * Normally, only selected directories in the document root are protected.
5247 * If absolutely every access to the web server needs to be authenticated,
5248 * regardless of the URI, set this option to the path to the passwords file.
5249 * Format of that file is the same as ".htpasswd" file. Make sure that file
5250 * is located outside document root to prevent people fetching it.
5251 */
5252 const char *global_auth_file;
5253
5254 /* Set to "no" to disable directory listing. Enabled by default. */
5255 const char *enable_directory_listing;
5256
5257 /*
5258 * SSI files pattern. If not set, "**.shtml$|**.shtm$" is used.
5259 *
5260 * All files that match ssi_pattern are treated as SSI.
5261 *
5262 * Server Side Includes (SSI) is a simple interpreted server-side scripting
5263 * language which is most commonly used to include the contents of a file
5264 * into a web page. It can be useful when it is desirable to include a common
5265 * piece of code throughout a website, for example, headers and footers.
5266 *
5267 * In order for a webpage to recognize an SSI-enabled HTML file, the
5268 * filename should end with a special extension, by default the extension
5269 * should be either .shtml or .shtm
5270 *
5271 * Unknown SSI directives are silently ignored by Mongoose. Currently,
5272 * the following SSI directives are supported:
5273 * &lt;!--#include FILE_TO_INCLUDE --&gt;
5274 * &lt;!--#exec "COMMAND_TO_EXECUTE" --&gt;
5275 * &lt;!--#call COMMAND --&gt;
5276 *
5277 * Note that &lt;!--#include ...> directive supports three path
5278 *specifications:
5279 *
5280 * &lt;!--#include virtual="path" --&gt; Path is relative to web server root
5281 * &lt;!--#include abspath="path" --&gt; Path is absolute or relative to the
5282 * web server working dir
5283 * &lt;!--#include file="path" --&gt;, Path is relative to current document
5284 * &lt;!--#include "path" --&gt;
5285 *
5286 * The include directive may be used to include the contents of a file or
5287 * the result of running a CGI script.
5288 *
5289 * The exec directive is used to execute
5290 * a command on a server, and show command's output. Example:
5291 *
5292 * &lt;!--#exec "ls -l" --&gt;
5293 *
5294 * The call directive is a way to invoke a C handler from the HTML page.
5295 * On each occurence of &lt;!--#call COMMAND OPTIONAL_PARAMS> directive,
5296 * Mongoose calls a registered event handler with MG_EV_SSI_CALL event,
5297 * and event parameter will point to the COMMAND OPTIONAL_PARAMS string.
5298 * An event handler can output any text, for example by calling
5299 * `mg_printf()`. This is a flexible way of generating a web page on
5300 * server side by calling a C event handler. Example:
5301 *
5302 * &lt;!--#call foo --&gt; ... &lt;!--#call bar --&gt;
5303 *
5304 * In the event handler:
5305 * case MG_EV_SSI_CALL: {
5306 * const char *param = (const char *) ev_data;
5307 * if (strcmp(param, "foo") == 0) {
5308 * mg_printf(c, "hello from foo");
5309 * } else if (strcmp(param, "bar") == 0) {
5310 * mg_printf(c, "hello from bar");
5311 * }
5312 * break;
5313 * }
5314 */
5315 const char *ssi_pattern;
5316
5317 /* IP ACL. By default, NULL, meaning all IPs are allowed to connect */
5318 const char *ip_acl;
5319
5320#if MG_ENABLE_HTTP_URL_REWRITES
5321 /* URL rewrites.
5322 *
5323 * Comma-separated list of `uri_pattern=url_file_or_directory_path` rewrites.
5324 * When HTTP request is received, Mongoose constructs a file name from the
5325 * requested URI by combining `document_root` and the URI. However, if the
5326 * rewrite option is used and `uri_pattern` matches requested URI, then
5327 * `document_root` is ignored. Instead, `url_file_or_directory_path` is used,
5328 * which should be a full path name or a path relative to the web server's
5329 * current working directory. It can also be an URI (http:// or https://)
5330 * in which case mongoose will behave as a reverse proxy for that destination.
5331 *
5332 * Note that `uri_pattern`, as all Mongoose patterns, is a prefix pattern.
5333 *
5334 * If uri_pattern starts with `@` symbol, then Mongoose compares it with the
5335 * HOST header of the request. If they are equal, Mongoose sets document root
5336 * to `file_or_directory_path`, implementing virtual hosts support.
5337 * Example: `@foo.com=/document/root/for/foo.com`
5338 *
5339 * If `uri_pattern` starts with `%` symbol, then Mongoose compares it with
5340 * the listening port. If they match, then Mongoose issues a 301 redirect.
5341 * For example, to redirect all HTTP requests to the
5342 * HTTPS port, do `%80=https://my.site.com`. Note that the request URI is
5343 * automatically appended to the redirect location.
5344 */
5345 const char *url_rewrites;
5346#endif
5347
5348 /* DAV document root. If NULL, DAV requests are going to fail. */
5349 const char *dav_document_root;
5350
5351 /*
5352 * DAV passwords file. If NULL, DAV requests are going to fail.
5353 * If passwords file is set to "-", then DAV auth is disabled.
5354 */
5355 const char *dav_auth_file;
5356
5357 /* Glob pattern for the files to hide. */
5358 const char *hidden_file_pattern;
5359
5360 /* Set to non-NULL to enable CGI, e.g. **.cgi$|**.php$" */
5361 const char *cgi_file_pattern;
5362
5363 /* If not NULL, ignore CGI script hashbang and use this interpreter */
5364 const char *cgi_interpreter;
5365
5366 /*
5367 * Comma-separated list of Content-Type overrides for path suffixes, e.g.
5368 * ".txt=text/plain; charset=utf-8,.c=text/plain"
5369 */
5370 const char *custom_mime_types;
5371
5372 /*
5373 * Extra HTTP headers to add to each server response.
5374 * Example: to enable CORS, set this to "Access-Control-Allow-Origin: *".
5375 */
5376 const char *extra_headers;
5377};
5378
5379/*
5380 * Serves given HTTP request according to the `options`.
5381 *
5382 * Example code snippet:
5383 *
5384 * ```c
5385 * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
5386 * struct http_message *hm = (struct http_message *) ev_data;
5387 * struct mg_serve_http_opts opts = { .document_root = "/var/www" }; // C99
5388 *
5389 * switch (ev) {
5390 * case MG_EV_HTTP_REQUEST:
5391 * mg_serve_http(nc, hm, opts);
5392 * break;
5393 * default:
5394 * break;
5395 * }
5396 * }
5397 * ```
5398 */
5399void mg_serve_http(struct mg_connection *nc, struct http_message *hm,
5400 struct mg_serve_http_opts opts);
5401
5402/*
5403 * Serves a specific file with a given MIME type and optional extra headers.
5404 *
5405 * Example code snippet:
5406 *
5407 * ```c
5408 * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
5409 * switch (ev) {
5410 * case MG_EV_HTTP_REQUEST: {
5411 * struct http_message *hm = (struct http_message *) ev_data;
5412 * mg_http_serve_file(nc, hm, "file.txt",
5413 * mg_mk_str("text/plain"), mg_mk_str(""));
5414 * break;
5415 * }
5416 * ...
5417 * }
5418 * }
5419 * ```
5420 */
5421void mg_http_serve_file(struct mg_connection *nc, struct http_message *hm,
5422 const char *path, const struct mg_str mime_type,
5423 const struct mg_str extra_headers);
5424
5425#if MG_ENABLE_HTTP_STREAMING_MULTIPART
5426
5427/* Callback prototype for `mg_file_upload_handler()`. */
5428typedef struct mg_str (*mg_fu_fname_fn)(struct mg_connection *nc,
5429 struct mg_str fname);
5430
5431/*
5432 * File upload handler.
5433 * This handler can be used to implement file uploads with minimum code.
5434 * This handler will process MG_EV_HTTP_PART_* events and store file data into
5435 * a local file.
5436 * `local_name_fn` will be invoked with whatever name was provided by the client
5437 * and will expect the name of the local file to open. A return value of NULL
5438 * will abort file upload (client will get a "403 Forbidden" response). If
5439 * non-null, the returned string must be heap-allocated and will be freed by
5440 * the caller.
5441 * Exception: it is ok to return the same string verbatim.
5442 *
5443 * Example:
5444 *
5445 * ```c
5446 * struct mg_str upload_fname(struct mg_connection *nc, struct mg_str fname) {
5447 * // Just return the same filename. Do not actually do this except in test!
5448 * // fname is user-controlled and needs to be sanitized.
5449 * return fname;
5450 * }
5451 * void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
5452 * switch (ev) {
5453 * ...
5454 * case MG_EV_HTTP_PART_BEGIN:
5455 * case MG_EV_HTTP_PART_DATA:
5456 * case MG_EV_HTTP_PART_END:
5457 * mg_file_upload_handler(nc, ev, ev_data, upload_fname);
5458 * break;
5459 * }
5460 * }
5461 * ```
5462 */
5463void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
5465 MG_UD_ARG(void *user_data));
5466#endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */
5467#endif /* MG_ENABLE_FILESYSTEM */
5468
5469/*
5470 * Registers a callback for a specified http endpoint
5471 * Note: if callback is registered it is called instead of the
5472 * callback provided in mg_bind
5473 *
5474 * Example code snippet:
5475 *
5476 * ```c
5477 * static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
5478 * (void) ev; (void) ev_data;
5479 * mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello1]");
5480 * nc->flags |= MG_F_SEND_AND_CLOSE;
5481 * }
5482 *
5483 * static void handle_hello2(struct mg_connection *nc, int ev, void *ev_data) {
5484 * (void) ev; (void) ev_data;
5485 * mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello2]");
5486 * nc->flags |= MG_F_SEND_AND_CLOSE;
5487 * }
5488 *
5489 * void init() {
5490 * nc = mg_bind(&mgr, local_addr, cb1);
5491 * mg_register_http_endpoint(nc, "/hello1", handle_hello1);
5492 * mg_register_http_endpoint(nc, "/hello1/hello2", handle_hello2);
5493 * }
5494 * ```
5495 */
5497 MG_CB(mg_event_handler_t handler,
5498 void *user_data));
5499
5502 /* Authorization domain (realm) */
5503 const char *auth_domain;
5504 const char *auth_file;
5505};
5506
5508 const char *uri_path,
5509 mg_event_handler_t handler,
5511
5512/*
5513 * Authenticates a HTTP request against an opened password file.
5514 * Returns 1 if authenticated, 0 otherwise.
5515 */
5516int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain,
5517 FILE *fp);
5518
5519/*
5520 * Authenticates given response params against an opened password file.
5521 * Returns 1 if authenticated, 0 otherwise.
5522 *
5523 * It's used by mg_http_check_digest_auth().
5524 */
5525int mg_check_digest_auth(struct mg_str method, struct mg_str uri,
5526 struct mg_str username, struct mg_str cnonce,
5527 struct mg_str response, struct mg_str qop,
5528 struct mg_str nc, struct mg_str nonce,
5529 struct mg_str auth_domain, FILE *fp);
5530
5531/*
5532 * Sends buffer `buf` of size `len` to the client using chunked HTTP encoding.
5533 * This function sends the buffer size as hex number + newline first, then
5534 * the buffer itself, then the newline. For example,
5535 * `mg_send_http_chunk(nc, "foo", 3)` will append the `3\r\nfoo\r\n` string
5536 * to the `nc->send_mbuf` output IO buffer.
5537 *
5538 * NOTE: The HTTP header "Transfer-Encoding: chunked" should be sent prior to
5539 * using this function.
5540 *
5541 * NOTE: do not forget to send an empty chunk at the end of the response,
5542 * to tell the client that everything was sent. Example:
5543 *
5544 * ```
5545 * mg_printf_http_chunk(nc, "%s", "my response!");
5546 * mg_send_http_chunk(nc, "", 0); // Tell the client we're finished
5547 * ```
5548 */
5549void mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len);
5550
5551/*
5552 * Sends a printf-formatted HTTP chunk.
5553 * Functionality is similar to `mg_send_http_chunk()`.
5554 */
5555void mg_printf_http_chunk(struct mg_connection *nc, const char *fmt, ...);
5556
5557/*
5558 * Sends the response status line.
5559 * If `extra_headers` is not NULL, then `extra_headers` are also sent
5560 * after the response line. `extra_headers` must NOT end end with new line.
5561 * Example:
5562 *
5563 * mg_send_response_line(nc, 200, "Access-Control-Allow-Origin: *");
5564 *
5565 * Will result in:
5566 *
5567 * HTTP/1.1 200 OK\r\n
5568 * Access-Control-Allow-Origin: *\r\n
5569 */
5570void mg_send_response_line(struct mg_connection *nc, int status_code,
5571 const char *extra_headers);
5572
5573/*
5574 * Sends an error response. If reason is NULL, the message will be inferred
5575 * from the error code (if supported).
5576 */
5577void mg_http_send_error(struct mg_connection *nc, int code, const char *reason);
5578
5579/*
5580 * Sends a redirect response.
5581 * `status_code` should be either 301 or 302 and `location` point to the
5582 * new location.
5583 * If `extra_headers` is not empty, then `extra_headers` are also sent
5584 * after the response line. `extra_headers` must NOT end end with new line.
5585 *
5586 * Example:
5587 *
5588 * mg_http_send_redirect(nc, 302, mg_mk_str("/login"), mg_mk_str(NULL));
5589 */
5590void mg_http_send_redirect(struct mg_connection *nc, int status_code,
5591 const struct mg_str location,
5592 const struct mg_str extra_headers);
5593
5594/*
5595 * Sends the response line and headers.
5596 * This function sends the response line with the `status_code`, and
5597 * automatically
5598 * sends one header: either "Content-Length" or "Transfer-Encoding".
5599 * If `content_length` is negative, then "Transfer-Encoding: chunked" header
5600 * is sent, otherwise, "Content-Length" header is sent.
5601 *
5602 * NOTE: If `Transfer-Encoding` is `chunked`, then message body must be sent
5603 * using `mg_send_http_chunk()` or `mg_printf_http_chunk()` functions.
5604 * Otherwise, `mg_send()` or `mg_printf()` must be used.
5605 * Extra headers could be set through `extra_headers`. Note `extra_headers`
5606 * must NOT be terminated by a new line.
5607 */
5608void mg_send_head(struct mg_connection *n, int status_code,
5609 int64_t content_length, const char *extra_headers);
5610
5611/*
5612 * Sends a printf-formatted HTTP chunk, escaping HTML tags.
5613 */
5614void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
5615
5616#if MG_ENABLE_HTTP_URL_REWRITES
5617/*
5618 * Proxies a given request to a given upstream http server. The path prefix
5619 * in `mount` will be stripped of the path requested to the upstream server,
5620 * e.g. if mount is /api and upstream is http://localhost:8001/foo
5621 * then an incoming request to /api/bar will cause a request to
5622 * http://localhost:8001/foo/bar
5623 *
5624 * EXPERIMENTAL API. Please use http_serve_http + url_rewrites if a static
5625 * mapping is good enough.
5626 */
5627void mg_http_reverse_proxy(struct mg_connection *nc,
5628 const struct http_message *hm, struct mg_str mount,
5629 struct mg_str upstream);
5630#endif
5631
5632#ifdef __cplusplus
5633}
5634#endif /* __cplusplus */
5635
5636#endif /* MG_ENABLE_HTTP */
5637
5638#endif /* CS_MONGOOSE_SRC_HTTP_SERVER_H_ */
5639#ifdef MG_MODULE_LINES
5640#line 1 "mongoose/src/mg_http_client.h"
5641#endif
5642/*
5643 * === Client API reference
5644 */
5645
5646#ifndef CS_MONGOOSE_SRC_HTTP_CLIENT_H_
5647#define CS_MONGOOSE_SRC_HTTP_CLIENT_H_
5648
5649#ifdef __cplusplus
5650extern "C" {
5651#endif /* __cplusplus */
5652
5653/*
5654 * Helper function that creates an outbound HTTP connection.
5655 *
5656 * `url` is the URL to fetch. It must be properly URL-encoded, e.g. have
5657 * no spaces, etc. By default, `mg_connect_http()` sends the Connection and
5658 * Host headers. `extra_headers` is an extra HTTP header to send, e.g.
5659 * `"User-Agent: my-app\r\n"`.
5660 * If `post_data` is NULL, then a GET request is created. Otherwise, a POST
5661 * request is created with the specified POST data. Note that if the data being
5662 * posted is a form submission, the `Content-Type` header should be set
5663 * accordingly (see example below).
5664 *
5665 * Examples:
5666 *
5667 * ```c
5668 * nc1 = mg_connect_http(mgr, ev_handler_1, "http://www.google.com", NULL,
5669 * NULL);
5670 * nc2 = mg_connect_http(mgr, ev_handler_1, "https://github.com", NULL, NULL);
5671 * nc3 = mg_connect_http(
5672 * mgr, ev_handler_1, "my_server:8000/form_submit/",
5673 * "Content-Type: application/x-www-form-urlencoded\r\n",
5674 * "var_1=value_1&var_2=value_2");
5675 * ```
5676 */
5678 struct mg_mgr *mgr,
5679 MG_CB(mg_event_handler_t event_handler, void *user_data), const char *url,
5680 const char *extra_headers, const char *post_data);
5681
5682/*
5683 * Helper function that creates an outbound HTTP connection.
5684 *
5685 * Mostly identical to mg_connect_http, but allows you to provide extra
5686 *parameters
5687 * (for example, SSL parameters)
5688 */
5691 struct mg_connect_opts opts, const char *url, const char *extra_headers,
5692 const char *post_data);
5693
5694/* Creates digest authentication header for a client request. */
5696 const char *method, const char *uri,
5697 const char *auth_domain, const char *user,
5698 const char *passwd, const char *nonce);
5699
5700#ifdef __cplusplus
5701}
5702#endif /* __cplusplus */
5703#endif /* CS_MONGOOSE_SRC_HTTP_CLIENT_H_ */
5704#ifdef MG_MODULE_LINES
5705#line 1 "mongoose/src/mg_mqtt.h"
5706#endif
5707/*
5708 * Copyright (c) 2014 Cesanta Software Limited
5709 * All rights reserved
5710 * This software is dual-licensed: you can redistribute it and/or modify
5711 * it under the terms of the GNU General Public License version 2 as
5712 * published by the Free Software Foundation. For the terms of this
5713 * license, see <http://www.gnu.org/licenses/>.
5714 *
5715 * You are free to use this software under the terms of the GNU General
5716 * Public License, but WITHOUT ANY WARRANTY; without even the implied
5717 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5718 * See the GNU General Public License for more details.
5719 *
5720 * Alternatively, you can license this software under a commercial
5721 * license, as set out in <https://www.cesanta.com/license>.
5722 */
5723
5724/*
5725 * === MQTT API reference
5726 */
5727
5728#ifndef CS_MONGOOSE_SRC_MQTT_H_
5729#define CS_MONGOOSE_SRC_MQTT_H_
5730
5731/* Amalgamated: #include "mg_net.h" */
5732
5733struct mg_mqtt_message {
5734 int cmd;
5735 int qos;
5736 int len; /* message length in the IO buffer */
5738 struct mg_str payload;
5739
5740 uint8_t connack_ret_code; /* connack */
5741 uint16_t message_id; /* puback */
5742
5743 /* connect */
5753};
5754
5756 const char *topic;
5757 uint8_t qos;
5758};
5759
5761 unsigned char flags; /* connection flags */
5763 const char *will_topic;
5764 const char *will_message;
5765 const char *user_name;
5766 const char *password;
5767};
5768
5769/* mg_mqtt_proto_data should be in header to allow external access to it */
5774
5775/* Message types */
5776#define MG_MQTT_CMD_CONNECT 1
5777#define MG_MQTT_CMD_CONNACK 2
5778#define MG_MQTT_CMD_PUBLISH 3
5779#define MG_MQTT_CMD_PUBACK 4
5780#define MG_MQTT_CMD_PUBREC 5
5781#define MG_MQTT_CMD_PUBREL 6
5782#define MG_MQTT_CMD_PUBCOMP 7
5783#define MG_MQTT_CMD_SUBSCRIBE 8
5784#define MG_MQTT_CMD_SUBACK 9
5785#define MG_MQTT_CMD_UNSUBSCRIBE 10
5786#define MG_MQTT_CMD_UNSUBACK 11
5787#define MG_MQTT_CMD_PINGREQ 12
5788#define MG_MQTT_CMD_PINGRESP 13
5789#define MG_MQTT_CMD_DISCONNECT 14
5790
5791/* MQTT event types */
5792#define MG_MQTT_EVENT_BASE 200
5793#define MG_EV_MQTT_CONNECT (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_CONNECT)
5794#define MG_EV_MQTT_CONNACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_CONNACK)
5795#define MG_EV_MQTT_PUBLISH (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBLISH)
5796#define MG_EV_MQTT_PUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBACK)
5797#define MG_EV_MQTT_PUBREC (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBREC)
5798#define MG_EV_MQTT_PUBREL (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBREL)
5799#define MG_EV_MQTT_PUBCOMP (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBCOMP)
5800#define MG_EV_MQTT_SUBSCRIBE (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_SUBSCRIBE)
5801#define MG_EV_MQTT_SUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_SUBACK)
5802#define MG_EV_MQTT_UNSUBSCRIBE (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_UNSUBSCRIBE)
5803#define MG_EV_MQTT_UNSUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_UNSUBACK)
5804#define MG_EV_MQTT_PINGREQ (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PINGREQ)
5805#define MG_EV_MQTT_PINGRESP (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PINGRESP)
5806#define MG_EV_MQTT_DISCONNECT (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_DISCONNECT)
5807
5808/* Message flags */
5809#define MG_MQTT_RETAIN 0x1
5810#define MG_MQTT_DUP 0x4
5811#define MG_MQTT_QOS(qos) ((qos) << 1)
5812#define MG_MQTT_GET_QOS(flags) (((flags) &0x6) >> 1)
5813#define MG_MQTT_SET_QOS(flags, qos) (flags) = ((flags) & ~0x6) | ((qos) << 1)
5814
5815/* Connection flags */
5816#define MG_MQTT_CLEAN_SESSION 0x02
5817#define MG_MQTT_HAS_WILL 0x04
5818#define MG_MQTT_WILL_RETAIN 0x20
5819#define MG_MQTT_HAS_PASSWORD 0x40
5820#define MG_MQTT_HAS_USER_NAME 0x80
5821#define MG_MQTT_GET_WILL_QOS(flags) (((flags) &0x18) >> 3)
5822#define MG_MQTT_SET_WILL_QOS(flags, qos) \
5823 (flags) = ((flags) & ~0x18) | ((qos) << 3)
5824
5825/* CONNACK return codes */
5826#define MG_EV_MQTT_CONNACK_ACCEPTED 0
5827#define MG_EV_MQTT_CONNACK_UNACCEPTABLE_VERSION 1
5828#define MG_EV_MQTT_CONNACK_IDENTIFIER_REJECTED 2
5829#define MG_EV_MQTT_CONNACK_SERVER_UNAVAILABLE 3
5830#define MG_EV_MQTT_CONNACK_BAD_AUTH 4
5831#define MG_EV_MQTT_CONNACK_NOT_AUTHORIZED 5
5832
5833#ifdef __cplusplus
5834extern "C" {
5835#endif /* __cplusplus */
5836
5837/*
5838 * Attaches a built-in MQTT event handler to the given connection.
5839 *
5840 * The user-defined event handler will receive following extra events:
5841 *
5842 * - MG_EV_MQTT_CONNACK
5843 * - MG_EV_MQTT_PUBLISH
5844 * - MG_EV_MQTT_PUBACK
5845 * - MG_EV_MQTT_PUBREC
5846 * - MG_EV_MQTT_PUBREL
5847 * - MG_EV_MQTT_PUBCOMP
5848 * - MG_EV_MQTT_SUBACK
5849 */
5850void mg_set_protocol_mqtt(struct mg_connection *nc);
5851
5852/* Sends an MQTT handshake. */
5853void mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id);
5854
5855/* Sends an MQTT handshake with optional parameters. */
5856void mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id,
5858
5859/* Publishes a message to a given topic. */
5860void mg_mqtt_publish(struct mg_connection *nc, const char *topic,
5861 uint16_t message_id, int flags, const void *data,
5862 size_t len);
5863
5864/* Subscribes to a bunch of topics. */
5865void mg_mqtt_subscribe(struct mg_connection *nc,
5866 const struct mg_mqtt_topic_expression *topics,
5867 size_t topics_len, uint16_t message_id);
5868
5869/* Unsubscribes from a bunch of topics. */
5870void mg_mqtt_unsubscribe(struct mg_connection *nc, char **topics,
5871 size_t topics_len, uint16_t message_id);
5872
5873/* Sends a DISCONNECT command. */
5874void mg_mqtt_disconnect(struct mg_connection *nc);
5875
5876/* Sends a CONNACK command with a given `return_code`. */
5878
5879/* Sends a PUBACK command with a given `message_id`. */
5880void mg_mqtt_puback(struct mg_connection *nc, uint16_t message_id);
5881
5882/* Sends a PUBREC command with a given `message_id`. */
5883void mg_mqtt_pubrec(struct mg_connection *nc, uint16_t message_id);
5884
5885/* Sends a PUBREL command with a given `message_id`. */
5886void mg_mqtt_pubrel(struct mg_connection *nc, uint16_t message_id);
5887
5888/* Sends a PUBCOMP command with a given `message_id`. */
5889void mg_mqtt_pubcomp(struct mg_connection *nc, uint16_t message_id);
5890
5891/*
5892 * Sends a SUBACK command with a given `message_id`
5893 * and a sequence of granted QoSs.
5894 */
5895void mg_mqtt_suback(struct mg_connection *nc, uint8_t *qoss, size_t qoss_len,
5896 uint16_t message_id);
5897
5898/* Sends a UNSUBACK command with a given `message_id`. */
5899void mg_mqtt_unsuback(struct mg_connection *nc, uint16_t message_id);
5900
5901/* Sends a PINGREQ command. */
5902void mg_mqtt_ping(struct mg_connection *nc);
5903
5904/* Sends a PINGRESP command. */
5905void mg_mqtt_pong(struct mg_connection *nc);
5906
5907/*
5908 * Extracts the next topic expression from a SUBSCRIBE command payload.
5909 *
5910 * The topic expression name will point to a string in the payload buffer.
5911 * Returns the pos of the next topic expression or -1 when the list
5912 * of topics is exhausted.
5913 */
5915 struct mg_str *topic, uint8_t *qos, int pos);
5916
5917/*
5918 * Matches a topic against a topic expression
5919 *
5920 * Returns 1 if it matches; 0 otherwise.
5921 */
5923
5924/*
5925 * Same as `mg_mqtt_match_topic_expression()`, but takes `exp` as a
5926 * NULL-terminated string.
5927 */
5928int mg_mqtt_vmatch_topic_expression(const char *exp, struct mg_str topic);
5929
5930#ifdef __cplusplus
5931}
5932#endif /* __cplusplus */
5933
5934#endif /* CS_MONGOOSE_SRC_MQTT_H_ */
5935#ifdef MG_MODULE_LINES
5936#line 1 "mongoose/src/mg_mqtt_server.h"
5937#endif
5938/*
5939 * Copyright (c) 2014 Cesanta Software Limited
5940 * All rights reserved
5941 * This software is dual-licensed: you can redistribute it and/or modify
5942 * it under the terms of the GNU General Public License version 2 as
5943 * published by the Free Software Foundation. For the terms of this
5944 * license, see <http://www.gnu.org/licenses/>.
5945 *
5946 * You are free to use this software under the terms of the GNU General
5947 * Public License, but WITHOUT ANY WARRANTY; without even the implied
5948 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5949 * See the GNU General Public License for more details.
5950 *
5951 * Alternatively, you can license this software under a commercial
5952 * license, as set out in <https://www.cesanta.com/license>.
5953 */
5954
5955/*
5956 * === MQTT Server API reference
5957 */
5958
5959#ifndef CS_MONGOOSE_SRC_MQTT_BROKER_H_
5960#define CS_MONGOOSE_SRC_MQTT_BROKER_H_
5961
5962#if MG_ENABLE_MQTT_BROKER
5963
5964/* Amalgamated: #include "common/queue.h" */
5965/* Amalgamated: #include "mg_mqtt.h" */
5966
5967#ifdef __cplusplus
5968extern "C" {
5969#endif /* __cplusplus */
5970
5971#ifndef MG_MQTT_MAX_SESSION_SUBSCRIPTIONS
5972#define MG_MQTT_MAX_SESSION_SUBSCRIPTIONS 512
5973#endif
5974
5975struct mg_mqtt_broker;
5976
5977/* MQTT session (Broker side). */
5978struct mg_mqtt_session {
5979 struct mg_mqtt_broker *brk; /* Broker */
5980 LIST_ENTRY(mg_mqtt_session) link; /* mg_mqtt_broker::sessions linkage */
5981 struct mg_connection *nc; /* Connection with the client */
5982 size_t num_subscriptions; /* Size of `subscriptions` array */
5983 void *user_data; /* User data */
5985};
5986
5987/* MQTT broker. */
5988struct mg_mqtt_broker {
5989 LIST_HEAD(_mg_sesshead, mg_mqtt_session) sessions; /* Session list */
5990 void *user_data; /* User data */
5991};
5992
5993/* Initialises a MQTT broker. */
5994void mg_mqtt_broker_init(struct mg_mqtt_broker *brk, void *user_data);
5995
5996/*
5997 * Processes a MQTT broker message.
5998 *
5999 * The listening connection expects a pointer to an initialised
6000 * `mg_mqtt_broker` structure in the `user_data` field.
6001 *
6002 * Basic usage:
6003 *
6004 * ```c
6005 * mg_mqtt_broker_init(&brk, NULL);
6006 *
6007 * if ((nc = mg_bind(&mgr, address, mg_mqtt_broker)) == NULL) {
6008 * // fail;
6009 * }
6010 * nc->user_data = &brk;
6011 * ```
6012 *
6013 * New incoming connections will receive a `mg_mqtt_session` structure
6014 * in the connection `user_data`. The original `user_data` will be stored
6015 * in the `user_data` field of the session structure. This allows the user
6016 * handler to store user data before `mg_mqtt_broker` creates the session.
6017 *
6018 * Since only the MG_EV_ACCEPT message is processed by the listening socket,
6019 * for most events the `user_data` will thus point to a `mg_mqtt_session`.
6020 */
6021void mg_mqtt_broker(struct mg_connection *brk, int ev, void *data);
6022
6023/*
6024 * Iterates over all MQTT session connections. Example:
6025 *
6026 * ```c
6027 * struct mg_mqtt_session *s;
6028 * for (s = mg_mqtt_next(brk, NULL); s != NULL; s = mg_mqtt_next(brk, s)) {
6029 * // Do something
6030 * }
6031 * ```
6032 */
6034 struct mg_mqtt_session *s);
6035
6036#ifdef __cplusplus
6037}
6038#endif /* __cplusplus */
6039
6040#endif /* MG_ENABLE_MQTT_BROKER */
6041#endif /* CS_MONGOOSE_SRC_MQTT_BROKER_H_ */
6042#ifdef MG_MODULE_LINES
6043#line 1 "mongoose/src/mg_dns.h"
6044#endif
6045/*
6046 * Copyright (c) 2014 Cesanta Software Limited
6047 * All rights reserved
6048 */
6049
6050/*
6051 * === DNS API reference
6052 */
6053
6054#ifndef CS_MONGOOSE_SRC_DNS_H_
6055#define CS_MONGOOSE_SRC_DNS_H_
6056
6057/* Amalgamated: #include "mg_net.h" */
6058
6059#ifdef __cplusplus
6060extern "C" {
6061#endif /* __cplusplus */
6062
6063#define MG_DNS_A_RECORD 0x01 /* Lookup IP address */
6064#define MG_DNS_CNAME_RECORD 0x05 /* Lookup CNAME */
6065#define MG_DNS_PTR_RECORD 0x0c /* Lookup PTR */
6066#define MG_DNS_TXT_RECORD 0x10 /* Lookup TXT */
6067#define MG_DNS_AAAA_RECORD 0x1c /* Lookup IPv6 address */
6068#define MG_DNS_SRV_RECORD 0x21 /* Lookup SRV */
6069#define MG_DNS_MX_RECORD 0x0f /* Lookup mail server for domain */
6070#define MG_DNS_ANY_RECORD 0xff
6071#define MG_DNS_NSEC_RECORD 0x2f
6072
6073#define MG_MAX_DNS_QUESTIONS 32
6074#define MG_MAX_DNS_ANSWERS 32
6075
6076#define MG_DNS_MESSAGE 100 /* High-level DNS message event */
6077
6083
6084/* DNS resource record. */
6086 struct mg_str name; /* buffer with compressed name */
6087 int rtype;
6088 int rclass;
6089 int ttl;
6091 struct mg_str rdata; /* protocol data (can be a compressed name) */
6092};
6093
6094/* DNS message (request and response). */
6095struct mg_dns_message {
6096 struct mg_str pkt; /* packet body */
6099 int num_questions;
6100 int num_answers;
6103};
6104
6106 struct mg_dns_message *msg, int query, struct mg_dns_resource_record *prev);
6107
6108/*
6109 * Parses the record data from a DNS resource record.
6110 *
6111 * - A: struct in_addr *ina
6112 * - AAAA: struct in6_addr *ina
6113 * - CNAME: char buffer
6114 *
6115 * Returns -1 on error.
6116 *
6117 * TODO(mkm): MX
6118 */
6120 struct mg_dns_resource_record *rr, void *data,
6121 size_t data_len);
6122
6123/*
6124 * Sends a DNS query to the remote end.
6125 */
6126void mg_send_dns_query(struct mg_connection *nc, const char *name,
6127 int query_type);
6128
6129/*
6130 * Inserts a DNS header to an IO buffer.
6131 *
6132 * Returns the number of bytes inserted.
6133 */
6134int mg_dns_insert_header(struct mbuf *io, size_t pos,
6135 struct mg_dns_message *msg);
6136
6137/*
6138 * Appends already encoded questions from an existing message.
6139 *
6140 * This is useful when generating a DNS reply message which includes
6141 * all question records.
6142 *
6143 * Returns the number of appended bytes.
6144 */
6146
6147/*
6148 * Encodes and appends a DNS resource record to an IO buffer.
6149 *
6150 * The record metadata is taken from the `rr` parameter, while the name and data
6151 * are taken from the parameters, encoded in the appropriate format depending on
6152 * record type and stored in the IO buffer. The encoded values might contain
6153 * offsets within the IO buffer. It's thus important that the IO buffer doesn't
6154 * get trimmed while a sequence of records are encoded while preparing a DNS
6155 * reply.
6156 *
6157 * This function doesn't update the `name` and `rdata` pointers in the `rr`
6158 * struct because they might be invalidated as soon as the IO buffer grows
6159 * again.
6160 *
6161 * Returns the number of bytes appended or -1 in case of error.
6162 */
6164 const char *name, size_t nlen, const void *rdata,
6165 size_t rlen);
6166
6167/*
6168 * Encodes a DNS name.
6169 */
6170int mg_dns_encode_name(struct mbuf *io, const char *name, size_t len);
6171
6172/* Low-level: parses a DNS response. */
6173int mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg);
6174
6175/*
6176 * Uncompresses a DNS compressed name.
6177 *
6178 * The containing DNS message is required because of the compressed encoding
6179 * and reference suffixes present elsewhere in the packet.
6180 *
6181 * If the name is less than `dst_len` characters long, the remainder
6182 * of `dst` is terminated with `\0` characters. Otherwise, `dst` is not
6183 * terminated.
6184 *
6185 * If `dst_len` is 0 `dst` can be NULL.
6186 * Returns the uncompressed name length.
6187 */
6188size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name,
6189 char *dst, int dst_len);
6190
6191/*
6192 * Attaches a built-in DNS event handler to the given listening connection.
6193 *
6194 * The DNS event handler parses the incoming UDP packets, treating them as DNS
6195 * requests. If an incoming packet gets successfully parsed by the DNS event
6196 * handler, a user event handler will receive an `MG_DNS_REQUEST` event, with
6197 * `ev_data` pointing to the parsed `struct mg_dns_message`.
6198 *
6199 * See
6200 * [captive_dns_server](https://github.com/cesanta/mongoose/tree/master/examples/captive_dns_server)
6201 * example on how to handle DNS request and send DNS reply.
6202 */
6203void mg_set_protocol_dns(struct mg_connection *nc);
6204
6205#ifdef __cplusplus
6206}
6207#endif /* __cplusplus */
6208#endif /* CS_MONGOOSE_SRC_DNS_H_ */
6209#ifdef MG_MODULE_LINES
6210#line 1 "mongoose/src/mg_dns_server.h"
6211#endif
6212/*
6213 * Copyright (c) 2014 Cesanta Software Limited
6214 * All rights reserved
6215 */
6216
6217/*
6218 * === DNS server API reference
6219 *
6220 * Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`.
6221 */
6222
6223#ifndef CS_MONGOOSE_SRC_DNS_SERVER_H_
6224#define CS_MONGOOSE_SRC_DNS_SERVER_H_
6225
6226#if MG_ENABLE_DNS_SERVER
6227
6228/* Amalgamated: #include "mg_dns.h" */
6229
6230#ifdef __cplusplus
6231extern "C" {
6232#endif /* __cplusplus */
6233
6234#define MG_DNS_SERVER_DEFAULT_TTL 3600
6235
6236struct mg_dns_reply {
6237 struct mg_dns_message *msg;
6238 struct mbuf *io;
6239 size_t start;
6240};
6241
6242/*
6243 * Creates a DNS reply.
6244 *
6245 * The reply will be based on an existing query message `msg`.
6246 * The query body will be appended to the output buffer.
6247 * "reply + recursion allowed" will be added to the message flags and the
6248 * message's num_answers will be set to 0.
6249 *
6250 * Answer records can be appended with `mg_dns_send_reply` or by lower
6251 * level function defined in the DNS API.
6252 *
6253 * In order to send a reply use `mg_dns_send_reply`.
6254 * It's possible to use a connection's send buffer as reply buffer,
6255 * and it will work for both UDP and TCP connections.
6256 *
6257 * Example:
6258 *
6259 * ```c
6260 * reply = mg_dns_create_reply(&nc->send_mbuf, msg);
6261 * for (i = 0; i < msg->num_questions; i++) {
6262 * rr = &msg->questions[i];
6263 * if (rr->rtype == MG_DNS_A_RECORD) {
6264 * mg_dns_reply_record(&reply, rr, 3600, &dummy_ip_addr, 4);
6265 * }
6266 * }
6267 * mg_dns_send_reply(nc, &reply);
6268 * ```
6269 */
6271 struct mg_dns_message *msg);
6272
6273/*
6274 * Appends a DNS reply record to the IO buffer and to the DNS message.
6275 *
6276 * The message's num_answers field will be incremented. It's the caller's duty
6277 * to ensure num_answers is properly initialised.
6278 *
6279 * Returns -1 on error.
6280 */
6283 const char *name, int rtype, int ttl, const void *rdata,
6284 size_t rdata_len);
6285
6286/*
6287 * Sends a DNS reply through a connection.
6288 *
6289 * The DNS data is stored in an IO buffer pointed by reply structure in `r`.
6290 * This function mutates the content of that buffer in order to ensure that
6291 * the DNS header reflects the size and flags of the message, that might have
6292 * been updated either with `mg_dns_reply_record` or by direct manipulation of
6293 * `r->message`.
6294 *
6295 * Once sent, the IO buffer will be trimmed unless the reply IO buffer
6296 * is the connection's send buffer and the connection is not in UDP mode.
6297 */
6298void mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r);
6299
6300#ifdef __cplusplus
6301}
6302#endif /* __cplusplus */
6303
6304#endif /* MG_ENABLE_DNS_SERVER */
6305#endif /* CS_MONGOOSE_SRC_DNS_SERVER_H_ */
6306#ifdef MG_MODULE_LINES
6307#line 1 "mongoose/src/mg_resolv.h"
6308#endif
6309/*
6310 * Copyright (c) 2014 Cesanta Software Limited
6311 * All rights reserved
6312 */
6313
6314/*
6315 * === API reference
6316 */
6317
6318#ifndef CS_MONGOOSE_SRC_RESOLV_H_
6319#define CS_MONGOOSE_SRC_RESOLV_H_
6320
6321/* Amalgamated: #include "mg_dns.h" */
6322
6323#ifdef __cplusplus
6324extern "C" {
6325#endif /* __cplusplus */
6326
6333
6335 void *user_data, enum mg_resolve_err);
6336
6337/* Options for `mg_resolve_async_opt`. */
6338struct mg_resolve_async_opts {
6339 const char *nameserver;
6340 int max_retries; /* defaults to 2 if zero */
6341 int timeout; /* in seconds; defaults to 5 if zero */
6342 int accept_literal; /* pseudo-resolve literal ipv4 and ipv6 addrs */
6343 int only_literal; /* only resolves literal addrs; sync cb invocation */
6344 struct mg_connection **dns_conn; /* return DNS connection */
6345};
6346
6347/* See `mg_resolve_async_opt()` */
6348int mg_resolve_async(struct mg_mgr *mgr, const char *name, int query,
6349 mg_resolve_callback_t cb, void *data);
6350
6351/* Set default DNS server */
6352void mg_set_nameserver(struct mg_mgr *mgr, const char *nameserver);
6353
6354/*
6355 * Resolved a DNS name asynchronously.
6356 *
6357 * Upon successful resolution, the user callback will be invoked
6358 * with the full DNS response message and a pointer to the user's
6359 * context `data`.
6360 *
6361 * In case of timeout while performing the resolution the callback
6362 * will receive a NULL `msg`.
6363 *
6364 * The DNS answers can be extracted with `mg_next_record` and
6365 * `mg_dns_parse_record_data`:
6366 *
6367 * [source,c]
6368 * ----
6369 * struct in_addr ina;
6370 * struct mg_dns_resource_record *rr = mg_next_record(msg, MG_DNS_A_RECORD,
6371 * NULL);
6372 * mg_dns_parse_record_data(msg, rr, &ina, sizeof(ina));
6373 * ----
6374 */
6375int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
6376 mg_resolve_callback_t cb, void *data,
6378
6379/*
6380 * Resolve a name from `/etc/hosts`.
6381 *
6382 * Returns 0 on success, -1 on failure.
6383 */
6384int mg_resolve_from_hosts_file(const char *host, union socket_address *usa);
6385
6386#ifdef __cplusplus
6387}
6388#endif /* __cplusplus */
6389#endif /* CS_MONGOOSE_SRC_RESOLV_H_ */
6390#ifdef MG_MODULE_LINES
6391#line 1 "mongoose/src/mg_coap.h"
6392#endif
6393/*
6394 * Copyright (c) 2015 Cesanta Software Limited
6395 * All rights reserved
6396 * This software is dual-licensed: you can redistribute it and/or modify
6397 * it under the terms of the GNU General Public License version 2 as
6398 * published by the Free Software Foundation. For the terms of this
6399 * license, see <http://www.gnu.org/licenses/>.
6400 *
6401 * You are free to use this software under the terms of the GNU General
6402 * Public License, but WITHOUT ANY WARRANTY; without even the implied
6403 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
6404 * See the GNU General Public License for more details.
6405 *
6406 * Alternatively, you can license this software under a commercial
6407 * license, as set out in <https://www.cesanta.com/license>.
6408 */
6409
6410/*
6411 * === CoAP API reference
6412 *
6413 * CoAP message format:
6414 *
6415 * ```
6416 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
6417 * |Ver| T | TKL | Code | Message ID | Token (if any, TKL bytes) ...
6418 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
6419 * | Options (if any) ... |1 1 1 1 1 1 1 1| Payload (if any) ...
6420 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
6421 * ```
6422 */
6423
6424#ifndef CS_MONGOOSE_SRC_COAP_H_
6425#define CS_MONGOOSE_SRC_COAP_H_
6426
6427#if MG_ENABLE_COAP
6428
6429#define MG_COAP_MSG_TYPE_FIELD 0x2
6430#define MG_COAP_CODE_CLASS_FIELD 0x4
6431#define MG_COAP_CODE_DETAIL_FIELD 0x8
6432#define MG_COAP_MSG_ID_FIELD 0x10
6433#define MG_COAP_TOKEN_FIELD 0x20
6434#define MG_COAP_OPTIOMG_FIELD 0x40
6435#define MG_COAP_PAYLOAD_FIELD 0x80
6436
6437#define MG_COAP_ERROR 0x10000
6438#define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)
6439#define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)
6440#define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)
6441#define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)
6442
6443#define MG_COAP_MSG_CON 0
6444#define MG_COAP_MSG_NOC 1
6445#define MG_COAP_MSG_ACK 2
6446#define MG_COAP_MSG_RST 3
6447#define MG_COAP_MSG_MAX 3
6448
6449#define MG_COAP_CODECLASS_REQUEST 0
6450#define MG_COAP_CODECLASS_RESP_OK 2
6451#define MG_COAP_CODECLASS_CLIENT_ERR 4
6452#define MG_COAP_CODECLASS_SRV_ERR 5
6453
6454#define MG_COAP_EVENT_BASE 300
6455#define MG_EV_COAP_CON (MG_COAP_EVENT_BASE + MG_COAP_MSG_CON)
6456#define MG_EV_COAP_NOC (MG_COAP_EVENT_BASE + MG_COAP_MSG_NOC)
6457#define MG_EV_COAP_ACK (MG_COAP_EVENT_BASE + MG_COAP_MSG_ACK)
6458#define MG_EV_COAP_RST (MG_COAP_EVENT_BASE + MG_COAP_MSG_RST)
6459
6460/*
6461 * CoAP options.
6462 * Use mg_coap_add_option and mg_coap_free_options
6463 * for creation and destruction.
6464 */
6465struct mg_coap_option {
6466 struct mg_coap_option *next;
6467 uint32_t number;
6468 struct mg_str value;
6469};
6470
6471/* CoAP message. See RFC 7252 for details. */
6472struct mg_coap_message {
6473 uint32_t flags;
6478 struct mg_str token;
6479 struct mg_coap_option *options;
6480 struct mg_str payload;
6482};
6483
6484#ifdef __cplusplus
6485extern "C" {
6486#endif /* __cplusplus */
6487
6488/* Sets CoAP protocol handler - triggers CoAP specific events. */
6489int mg_set_protocol_coap(struct mg_connection *nc);
6490
6491/*
6492 * Adds a new option to mg_coap_message structure.
6493 * Returns pointer to the newly created option.
6494 * Note: options must be freed by using mg_coap_free_options
6495 */
6497 uint32_t number, char *value,
6498 size_t len);
6499
6500/*
6501 * Frees the memory allocated for options.
6502 * If the cm parameter doesn't contain any option it does nothing.
6503 */
6505
6506/*
6507 * Composes a CoAP message from `mg_coap_message`
6508 * and sends it into `nc` connection.
6509 * Returns 0 on success. On error, it is a bitmask:
6510 *
6511 * - `#define MG_COAP_ERROR 0x10000`
6512 * - `#define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)`
6513 * - `#define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)`
6514 * - `#define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)`
6515 * - `#define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)`
6516 */
6518 struct mg_coap_message *cm);
6519
6520/*
6521 * Composes CoAP acknowledgement from `mg_coap_message`
6522 * and sends it into `nc` connection.
6523 * Return value: see `mg_coap_send_message()`
6524 */
6526
6527/*
6528 * Parses CoAP message and fills mg_coap_message and returns cm->flags.
6529 * This is a helper function.
6530 *
6531 * NOTE: usually CoAP works over UDP, so lack of data means format error.
6532 * But, in theory, it is possible to use CoAP over TCP (according to RFC)
6533 *
6534 * The caller has to check results and treat COAP_NOT_ENOUGH_DATA according to
6535 * underlying protocol:
6536 *
6537 * - in case of UDP COAP_NOT_ENOUGH_DATA means COAP_FORMAT_ERROR,
6538 * - in case of TCP client can try to receive more data
6539 *
6540 * Return value: see `mg_coap_send_message()`
6541 */
6543
6544/*
6545 * Composes CoAP message from mg_coap_message structure.
6546 * This is a helper function.
6547 * Return value: see `mg_coap_send_message()`
6548 */
6550
6551#ifdef __cplusplus
6552}
6553#endif /* __cplusplus */
6554
6555#endif /* MG_ENABLE_COAP */
6556
6557#endif /* CS_MONGOOSE_SRC_COAP_H_ */
6558#ifdef MG_MODULE_LINES
6559#line 1 "mongoose/src/mg_sntp.h"
6560#endif
6561/*
6562 * Copyright (c) 2016 Cesanta Software Limited
6563 * All rights reserved
6564 */
6565
6566#ifndef CS_MONGOOSE_SRC_SNTP_H_
6567#define CS_MONGOOSE_SRC_SNTP_H_
6568
6569#if MG_ENABLE_SNTP
6570
6571#define MG_SNTP_EVENT_BASE 500
6572
6573/*
6574 * Received reply from time server. Event handler parameter contains
6575 * pointer to mg_sntp_message structure
6576 */
6577#define MG_SNTP_REPLY (MG_SNTP_EVENT_BASE + 1)
6578
6579/* Received malformed SNTP packet */
6580#define MG_SNTP_MALFORMED_REPLY (MG_SNTP_EVENT_BASE + 2)
6581
6582/* Failed to get time from server (timeout etc) */
6583#define MG_SNTP_FAILED (MG_SNTP_EVENT_BASE + 3)
6584
6585struct mg_sntp_message {
6586 /* if server sends this flags, user should not send requests to it */
6587 int kiss_of_death;
6588 /* usual mg_time */
6589 double time;
6590};
6591
6592/* Establishes connection to given sntp server */
6593struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr,
6594 MG_CB(mg_event_handler_t event_handler,
6595 void *user_data),
6596 const char *sntp_server_name);
6597
6598/* Sends time request to given connection */
6600
6601/*
6602 * Helper function
6603 * Establishes connection to time server, tries to send request
6604 * repeats sending SNTP_ATTEMPTS times every SNTP_TIMEOUT sec
6605 * (if needed)
6606 * See sntp_client example
6607 */
6609 mg_event_handler_t event_handler,
6610 const char *sntp_server_name);
6611
6612#endif
6613
6614#endif /* CS_MONGOOSE_SRC_SNTP_H_ */
6615#ifdef MG_MODULE_LINES
6616#line 1 "mongoose/src/mg_socks.h"
6617#endif
6618/*
6619 * Copyright (c) 2017 Cesanta Software Limited
6620 * All rights reserved
6621 */
6622
6623#ifndef CS_MONGOOSE_SRC_SOCKS_H_
6624#define CS_MONGOOSE_SRC_SOCKS_H_
6625
6626#if MG_ENABLE_SOCKS
6627
6628#define MG_SOCKS_VERSION 5
6629
6630#define MG_SOCKS_HANDSHAKE_DONE MG_F_USER_1
6631#define MG_SOCKS_CONNECT_DONE MG_F_USER_2
6632
6633/* SOCKS5 handshake methods */
6635 MG_SOCKS_HANDSHAKE_NOAUTH = 0, /* Handshake method - no authentication */
6636 MG_SOCKS_HANDSHAKE_GSSAPI = 1, /* Handshake method - GSSAPI auth */
6637 MG_SOCKS_HANDSHAKE_USERPASS = 2, /* Handshake method - user/password auth */
6638 MG_SOCKS_HANDSHAKE_FAILURE = 0xff, /* Handshake method - failure */
6639};
6640
6641/* SOCKS5 commands */
6642enum mg_socks_command {
6643 MG_SOCKS_CMD_CONNECT = 1, /* Command: CONNECT */
6644 MG_SOCKS_CMD_BIND = 2, /* Command: BIND */
6645 MG_SOCKS_CMD_UDP_ASSOCIATE = 3, /* Command: UDP ASSOCIATE */
6646};
6647
6648/* SOCKS5 address types */
6650 MG_SOCKS_ADDR_IPV4 = 1, /* Address type: IPv4 */
6651 MG_SOCKS_ADDR_DOMAIN = 3, /* Address type: Domain name */
6652 MG_SOCKS_ADDR_IPV6 = 4, /* Address type: IPv6 */
6653};
6654
6655/* SOCKS5 response codes */
6656enum mg_socks_response {
6657 MG_SOCKS_SUCCESS = 0, /* Response: success */
6658 MG_SOCKS_FAILURE = 1, /* Response: failure */
6659 MG_SOCKS_NOT_ALLOWED = 2, /* Response: connection not allowed */
6660 MG_SOCKS_NET_UNREACHABLE = 3, /* Response: network unreachable */
6661 MG_SOCKS_HOST_UNREACHABLE = 4, /* Response: network unreachable */
6662 MG_SOCKS_CONN_REFUSED = 5, /* Response: network unreachable */
6663 MG_SOCKS_TTL_EXPIRED = 6, /* Response: network unreachable */
6664 MG_SOCKS_CMD_NOT_SUPPORTED = 7, /* Response: network unreachable */
6665 MG_SOCKS_ADDR_NOT_SUPPORTED = 8, /* Response: network unreachable */
6666};
6667
6668#ifdef __cplusplus
6669extern "C" {
6670#endif /* __cplusplus */
6671
6672/* Turn the connection into the SOCKS server */
6674
6675/* Create socks tunnel for the client connection */
6676struct mg_iface *mg_socks_mk_iface(struct mg_mgr *, const char *proxy_addr);
6677
6678#ifdef __cplusplus
6679}
6680#endif /* __cplusplus */
6681
6682#endif
6683#endif
int mg_start_thread(mg_thread_func_t f, void *p)
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded)
int(* mg_event_handler_t)(struct mg_event *event)
Definition mongoose4.h:70
int mg_mgr_poll(struct mg_mgr *mgr, int milli)
struct mg_str message
Definition mongoose6.h:2068
void mg_mqtt_ping(struct mg_connection *nc)
void mg_set_protocol_mqtt(struct mg_connection *nc)
void * user_data
Definition mongoose6.h:1396
void mg_mgr_free(struct mg_mgr *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)
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 * user_data
Definition mongoose6.h:1265
struct mg_str header_names[MG_MAX_HTTP_HEADERS]
Definition mongoose6.h:2090
int int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap)
struct mg_str payload
Definition mongoose6.h:2878
int int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap)
int mg_stat(const char *path, cs_stat_t *st)
const char * global_auth_file
Definition mongoose6.h:2549
const char * ssi_pattern
Definition mongoose6.h:2555
const char * var_name
Definition mongoose6.h:2107
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)
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
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)
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(* 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 *mgr, struct mg_connection *c)
int mg_resolve_async(struct mg_mgr *mgr, const char *name, int query, mg_resolve_callback_t cb, void *data)
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)
void mg_send_response_line(struct mg_connection *nc, 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
int mg_open(const char *path, int flag, int mode)
struct mg_str method
Definition mongoose6.h:2071
double mg_set_timer(struct mg_connection *c, double timestamp)
int mg_conn_addr_to_str(struct mg_connection *c, char *buf, size_t len, int flags)
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
size_t 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_printf_html_escape(struct mg_connection *nc, const char *fmt,...)
cs_base64_putc_t b64_putc
Definition mongoose6.h:981
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)
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
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)
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
void mg_if_connect_cb(struct mg_connection *nc, int err)
unsigned int flags
Definition mongoose6.h:1437
void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path, const char *host, const char *protocol, const char *extra_headers)
void cs_base64_finish(struct cs_base64_ctx *ctx)
sock_t ctl[2]
Definition mongoose6.h:1234
double mg_time(void)
double ev_timer_time
Definition mongoose6.h:1260
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)
uint16_t flags
Definition mongoose6.h:3192
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,...)
struct mg_dns_resource_record questions[MG_MAX_DNS_QUESTIONS]
Definition mongoose6.h:3196
struct sockaddr sin6
Definition mongoose6.h:1200
const char * enable_directory_listing
Definition mongoose6.h:2552
size_t c_strnlen(const char *s, size_t maxlen)
size_t 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
uint16_t message_id
Definition mongoose6.h:2881
int mg_base64_decode(const unsigned char *s, int len, char *dst)
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
size_t recv_mbuf_limit
Definition mongoose6.h:1254
double cs_time(void)
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)
void mg_mqtt_suback(struct mg_connection *nc, uint8_t *qoss, size_t qoss_len, uint16_t message_id)
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,...) PRINTF_LIKE(3
char * buf
Definition mongoose6.h:834
mg_dns_resource_record_kind
Definition mongoose6.h:3173
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
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)
unsigned int flags
Definition mongoose6.h:1367
int 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
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)
const char * index_files
Definition mongoose6.h:2525
void cs_sha1_final(unsigned char digest[20], cs_sha1_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)
struct mg_str mg_mk_str(const char *s)
const char ** error_string
Definition mongoose6.h:1438
void cs_base64_encode(const unsigned char *src, int src_len, char *dst)
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,...)
const char * mg_next_comma_list_entry(const char *list, struct mg_str *val, struct mg_str *eq_val)
size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name, char *dst, int dst_len)
void mbuf_trim(struct mbuf *)
FILE * mg_fopen(const char *path, const char *mode)
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)
unsigned char chunk[3]
Definition mongoose6.h:982
int mg_vcmp(const struct mg_str *str2, const char *str1)
int mg_parse_uri(const 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
mg_event_handler_t proto_handler
Definition mongoose6.h:1261
const char * dav_document_root
Definition mongoose6.h:2585
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)
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)
void mg_mqtt_pubrel(struct mg_connection *nc, uint16_t message_id)
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
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
char response[10000]
Definition melog.cxx:90
#define sleep(ms)
#define name(x)
Definition midas_macro.h:24
static FILE * fp
const char * mime_type
int SOCKET
void sl_restart_cb(struct mg_mgr *mgr)
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)
void mg_set_nameserver(struct mg_mgr *mgr, const char *nameserver)
const struct mg_iface_vtable * mg_ifaces[]
double cs_timegm(const struct tm *tm)
const char * mg_strstr(const struct mg_str haystack, const struct mg_str needle)
void mg_strfree(struct mg_str *s)
void mg_http_send_error(struct mg_connection *nc, int code, const char *reason)
void mg_mbuf_append_base64_putc(char ch, void *user_data)
void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass, struct mbuf *buf)
int mg_get_http_basic_auth(struct http_message *hm, char *user, size_t user_len, char *pass, size_t pass_len)
double mg_mgr_min_timer(const struct mg_mgr *mgr)
int mg_parse_http_basic_auth(struct mg_str *hdr, char *user, size_t user_len, char *pass, size_t pass_len)
#define MG_UD_ARG(ud)
void cs_md5_update(cs_md5_ctx *c, const unsigned char *data, size_t len)
void mg_hash_sha1_v(size_t num_msgs, const uint8_t *msgs[], const size_t *msg_lens, uint8_t *digest)
struct mg_str mg_url_encode(const struct mg_str src)
int mg_str_starts_with(struct mg_str s, struct mg_str prefix)
void mg_send_websocket_handshake3v(struct mg_connection *nc, const struct mg_str path, const struct mg_str host, const struct mg_str protocol, const struct mg_str extra_headers, const struct mg_str user, const struct mg_str pass)
int mg_num_ifaces
mg_resolve_err
@ MG_RESOLVE_TIMEOUT
@ MG_RESOLVE_EXCEEDED_RETRY_COUNT
@ MG_RESOLVE_OK
@ MG_RESOLVE_NO_ANSWERS
struct mg_str mg_strdup_nul(const struct mg_str s)
struct mg_str mg_url_encode_opt(const struct mg_str src, const struct mg_str safe, unsigned int flags)
int mg_if_poll(struct mg_connection *nc, double now)
struct mg_str mg_strdup(const struct mg_str s)
void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path, MG_CB(mg_event_handler_t handler, void *user_data))
void mbuf_move(struct mbuf *from, struct mbuf *to)
int mg_asprintf(char **buf, size_t size, const char *fmt,...) PRINTF_LIKE(3
const char * mg_strchr(const struct mg_str s, int c)
#define MG_CB(cb, ud)
struct mg_connection * mg_bind(struct mg_mgr *mgr, const char *address, MG_CB(mg_event_handler_t handler, void *user_data))
void mg_http_send_digest_auth_request(struct mg_connection *c, const char *domain)
void mg_mgr_init_opt(struct mg_mgr *mgr, void *user_data, struct mg_mgr_init_opts opts)
void mg_if_can_recv_cb(struct mg_connection *nc)
int mg_strcmp(const struct mg_str str1, const struct mg_str str2)
void mg_mbuf_append_base64(struct mbuf *mbuf, const void *data, size_t len)
#define PRINTF_LIKE(f, a)
struct mg_connection * mg_connect_http_opt(struct mg_mgr *mgr, MG_CB(mg_event_handler_t ev_handler, void *user_data), struct mg_connect_opts opts, const char *url, const char *extra_headers, const char *post_data)
int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len)
struct mg_connection * mg_add_sock_opt(struct mg_mgr *mgr, sock_t sock, MG_CB(mg_event_handler_t handler, void *user_data), struct mg_add_sock_opts opts)
int mg_assemble_uri(const struct mg_str *scheme, const struct mg_str *user_info, const struct mg_str *host, unsigned int port, const struct mg_str *path, const struct mg_str *query, const struct mg_str *fragment, int normalize_path, struct mg_str *uri)
void mg_http_send_redirect(struct mg_connection *nc, int status_code, const struct mg_str location, const struct mg_str extra_headers)
int mg_check_digest_auth(struct mg_str method, struct mg_str uri, struct mg_str username, struct mg_str cnonce, struct mg_str response, struct mg_str qop, struct mg_str nc, struct mg_str nonce, struct mg_str auth_domain, FILE *fp)
struct mg_iface * mg_if_create_iface(const struct mg_iface_vtable *vtable, struct mg_mgr *mgr)
struct mg_str mg_mk_str_n(const char *s, size_t len)
struct mg_connection * mg_connect_ws_opt(struct mg_mgr *mgr, MG_CB(mg_event_handler_t ev_handler, void *user_data), struct mg_connect_opts opts, const char *url, const char *protocol, const char *extra_headers)
struct mg_connection * mg_connect_ws(struct mg_mgr *mgr, MG_CB(mg_event_handler_t event_handler, void *user_data), const char *url, const char *protocol, const char *extra_headers)
int mg_mqtt_match_topic_expression(struct mg_str exp, struct mg_str topic)
int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain, FILE *fp)
void(* cs_base64_putc_t)(char, void *)
int mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n)
int mg_http_parse_header2(struct mg_str *hdr, const char *var_name, char **buf, size_t buf_size)
@ MG_DNS_INVALID_RECORD
@ MG_DNS_ANSWER
@ MG_DNS_QUESTION
void mg_hash_md5_v(size_t num_msgs, const uint8_t *msgs[], const size_t *msg_lens, uint8_t *digest)
struct mg_connection * mg_connect_opt(struct mg_mgr *mgr, const char *address, MG_CB(mg_event_handler_t handler, void *user_data), struct mg_connect_opts opts)
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, const char *nonce)
struct mg_iface * mg_find_iface(struct mg_mgr *mgr, const struct mg_iface_vtable *vtable, struct mg_iface *from)
int mg_dns_encode_name(struct mbuf *io, const char *name, size_t len)
void(* mg_resolve_callback_t)(struct mg_dns_message *dns_message, void *user_data, enum mg_resolve_err)
void cs_md5_final(unsigned char *md, cs_md5_ctx *c)
int mg_mqtt_vmatch_topic_expression(const char *exp, struct mg_str topic)
void mg_send_websocket_handshake3(struct mg_connection *nc, const char *path, const char *host, const char *protocol, const char *extra_headers, const char *user, const char *pass)
int mg_dns_copy_questions(struct mbuf *io, struct mg_dns_message *msg)
void mg_if_can_send_cb(struct mg_connection *nc)
struct mg_connection * mg_add_sock(struct mg_mgr *mgr, sock_t sock, MG_CB(mg_event_handler_t handler, void *user_data))
struct mg_connection * mg_connect(struct mg_mgr *mgr, const char *address, MG_CB(mg_event_handler_t handler, void *user_data))
struct mg_connection * mg_connect_http(struct mg_mgr *mgr, MG_CB(mg_event_handler_t event_handler, void *user_data), const char *url, const char *extra_headers, const char *post_data)
void cs_from_hex(char *to, const char *p, size_t len)
void(* mg_event_handler_t)(struct mg_connection *nc, int ev, void *ev_data MG_UD_ARG(void *user_data))
struct mg_str mg_strstrip(struct mg_str s)
#define LIST_HEAD(name, type)
struct mg_connection * mg_bind_opt(struct mg_mgr *mgr, const char *address, MG_CB(mg_event_handler_t handler, void *user_data), struct mg_bind_opts opts)
#define LIST_ENTRY(type)
void mbuf_clear(struct mbuf *)
int mg_http_is_authorized(struct http_message *hm, struct mg_str path, const char *domain, const char *passwords_file, int flags)
struct mg_str mg_next_comma_list_entry_n(struct mg_str list, struct mg_str *val, struct mg_str *eq_val)
size_t mbuf_append_and_free(struct mbuf *, void *data, size_t data_size)
void cs_md5_init(cs_md5_ctx *c)
void mg_register_http_endpoint_opt(struct mg_connection *nc, const char *uri_path, mg_event_handler_t handler, struct mg_http_endpoint_opts opts)
#define MG_MAX_HTTP_HEADERS
#define MG_MAX_DNS_ANSWERS
#define MG_MAX_DNS_QUESTIONS
void(* cs_base64_putc_t)(char, void *)
#define intptr_t
int gettimeofday(struct timeval *tp, void *tzp)
timeval tv
Definition msysmon.cxx:1095
MUTEX_T * tm
Definition odbedit.cxx:39
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
struct mg_iface * iface
struct mg_iface * iface
struct mg_iface * iface
const char * nameserver
struct mg_iface * iface
const char * auth_domain
time_t(* poll)(struct mg_iface *iface, int timeout_ms)
void(* destroy_conn)(struct mg_connection *nc)
int(* listen_tcp)(struct mg_connection *nc, union socket_address *sa)
void(* remove_conn)(struct mg_connection *nc)
void(* connect_tcp)(struct mg_connection *nc, const union socket_address *sa)
void(* free)(struct mg_iface *iface)
void(* init)(struct mg_iface *iface)
void(* get_conn_addr)(struct mg_connection *nc, int remote, union socket_address *sa)
void(* connect_udp)(struct mg_connection *nc)
int(* udp_send)(struct mg_connection *nc, const void *buf, size_t len)
int(* create_conn)(struct mg_connection *nc)
int(* listen_udp)(struct mg_connection *nc, union socket_address *sa)
void(* sock_set)(struct mg_connection *nc, sock_t sock)
int(* udp_recv)(struct mg_connection *nc, void *buf, size_t len, union socket_address *sa, size_t *sa_len)
int(* tcp_send)(struct mg_connection *nc, const void *buf, size_t len)
int(* tcp_recv)(struct mg_connection *nc, void *buf, size_t len)
void(* add_conn)(struct mg_connection *nc)
struct mg_mgr * mgr
const struct mg_iface_vtable * vtable
void * data
const char * nameserver
const struct mg_iface_vtable ** ifaces
const struct mg_iface_vtable * main_iface
int num_ifaces
struct mg_iface ** ifaces
int num_calls
const char * nameserver
uint8_t protocol_version
struct mg_str will_topic
uint8_t connect_flags
uint16_t keep_alive_timer
struct mg_str user_name
struct mg_str password
struct mg_str client_id
struct mg_str will_message
struct mg_str protocol_name
const char * nameserver
struct mg_str arg
struct http_message * req
char c
Definition system.cxx:1310
static te_expr * list(state *s)
Definition tinyexpr.c:567