Statistics
| Branch: | Tag: | Revision:

mongoose / mongoose.h @ 58b9ee41

History | View | Annotate | Download (168 KB)

1
#ifdef MG_MODULE_LINES
2
#line 1 "mongoose/src/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.6"
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_CC3200 4
50
#define CS_P_MSP432 5
51
#define CS_P_CC3100 6
52
#define CS_P_TM4C129 14
53
#define CS_P_MBED 7
54
#define CS_P_WINCE 8
55
#define CS_P_NXP_LPC 13
56
#define CS_P_NXP_KINETIS 9
57
#define CS_P_NRF51 12
58
#define CS_P_NRF52 10
59
#define CS_P_PIC32 11
60
#define CS_P_STM32 16
61
/* Next id: 17 */
62

    
63
/* If not specified explicitly, we guess platform by defines. */
64
#ifndef CS_PLATFORM
65

    
66
#if defined(TARGET_IS_MSP432P4XX) || defined(__MSP432P401R__)
67
#define CS_PLATFORM CS_P_MSP432
68
#elif defined(cc3200)
69
#define CS_PLATFORM CS_P_CC3200
70
#elif defined(__unix__) || defined(__APPLE__)
71
#define CS_PLATFORM CS_P_UNIX
72
#elif defined(WINCE)
73
#define CS_PLATFORM CS_P_WINCE
74
#elif defined(_WIN32)
75
#define CS_PLATFORM CS_P_WINDOWS
76
#elif defined(__MBED__)
77
#define CS_PLATFORM CS_P_MBED
78
#elif defined(__USE_LPCOPEN)
79
#define CS_PLATFORM CS_P_NXP_LPC
80
#elif defined(FRDM_K64F) || defined(FREEDOM)
81
#define CS_PLATFORM CS_P_NXP_KINETIS
82
#elif defined(PIC32)
83
#define CS_PLATFORM CS_P_PIC32
84
#elif defined(ESP_PLATFORM)
85
#define CS_PLATFORM CS_P_ESP32
86
#elif defined(ICACHE_FLASH)
87
#define CS_PLATFORM CS_P_ESP8266
88
#elif defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || \
89
    defined(TARGET_IS_TM4C129_RA2)
90
#define CS_PLATFORM CS_P_TM4C129
91
#elif defined(STM32)
92
#define CS_PLATFORM CS_P_STM32
93
#endif
94

    
95
#ifndef CS_PLATFORM
96
#error "CS_PLATFORM is not specified and we couldn't guess it."
97
#endif
98

    
99
#endif /* !defined(CS_PLATFORM) */
100

    
101
#define MG_NET_IF_SOCKET 1
102
#define MG_NET_IF_SIMPLELINK 2
103
#define MG_NET_IF_LWIP_LOW_LEVEL 3
104
#define MG_NET_IF_PIC32 4
105

    
106
#define MG_SSL_IF_OPENSSL 1
107
#define MG_SSL_IF_MBEDTLS 2
108
#define MG_SSL_IF_SIMPLELINK 3
109

    
110
/* Amalgamated: #include "common/platforms/platform_unix.h" */
111
/* Amalgamated: #include "common/platforms/platform_windows.h" */
112
/* Amalgamated: #include "common/platforms/platform_esp32.h" */
113
/* Amalgamated: #include "common/platforms/platform_esp8266.h" */
114
/* Amalgamated: #include "common/platforms/platform_cc3200.h" */
115
/* Amalgamated: #include "common/platforms/platform_cc3100.h" */
116
/* Amalgamated: #include "common/platforms/platform_mbed.h" */
117
/* Amalgamated: #include "common/platforms/platform_nrf51.h" */
118
/* Amalgamated: #include "common/platforms/platform_nrf52.h" */
119
/* Amalgamated: #include "common/platforms/platform_wince.h" */
120
/* Amalgamated: #include "common/platforms/platform_nxp_lpc.h" */
121
/* Amalgamated: #include "common/platforms/platform_nxp_kinetis.h" */
122
/* Amalgamated: #include "common/platforms/platform_pic32.h" */
123
/* Amalgamated: #include "common/platforms/platform_stm32.h" */
124

    
125
/* Common stuff */
126

    
127
#if !defined(WEAK)
128
#if (defined(__GNUC__) || defined(__TI_COMPILER_VERSION__)) && !defined(_WIN32)
129
#define WEAK __attribute__((weak))
130
#else
131
#define WEAK
132
#endif
133
#endif
134

    
135
#ifdef __GNUC__
136
#define NORETURN __attribute__((noreturn))
137
#define NOINLINE __attribute__((noinline))
138
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
139
#define NOINSTR __attribute__((no_instrument_function))
140
#define DO_NOT_WARN_UNUSED __attribute__((unused))
141
#else
142
#define NORETURN
143
#define NOINLINE
144
#define WARN_UNUSED_RESULT
145
#define NOINSTR
146
#define DO_NOT_WARN_UNUSED
147
#endif /* __GNUC__ */
148

    
149
#ifndef ARRAY_SIZE
150
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
151
#endif
152

    
153
#endif /* CS_COMMON_PLATFORM_H_ */
154
#ifdef MG_MODULE_LINES
155
#line 1 "common/platforms/platform_windows.h"
156
#endif
157
#ifndef CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_
158
#define CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_
159
#if CS_PLATFORM == CS_P_WINDOWS
160

    
161
/*
162
 * MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
163
 * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
164
 * MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
165
 * MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
166
 * MSVC++ 9.0  _MSC_VER == 1500 (Visual Studio 2008)
167
 * MSVC++ 8.0  _MSC_VER == 1400 (Visual Studio 2005)
168
 * MSVC++ 7.1  _MSC_VER == 1310 (Visual Studio 2003)
169
 * MSVC++ 7.0  _MSC_VER == 1300
170
 * MSVC++ 6.0  _MSC_VER == 1200
171
 * MSVC++ 5.0  _MSC_VER == 1100
172
 */
173
#ifdef _MSC_VER
174
#pragma warning(disable : 4127) /* FD_SET() emits warning, disable it */
175
#pragma warning(disable : 4204) /* missing c99 support */
176
#endif
177

    
178
#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
179
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
180
#endif
181

    
182
#ifndef _CRT_SECURE_NO_WARNINGS
183
#define _CRT_SECURE_NO_WARNINGS
184
#endif
185

    
186
#include <assert.h>
187
#include <direct.h>
188
#include <errno.h>
189
#include <fcntl.h>
190
#include <io.h>
191
#include <limits.h>
192
#include <signal.h>
193
#include <stddef.h>
194
#include <stdio.h>
195
#include <stdlib.h>
196
#include <sys/stat.h>
197
#include <time.h>
198

    
199
#ifdef _MSC_VER
200
#pragma comment(lib, "ws2_32.lib") /* Linking with winsock library */
201
#endif
202

    
203
#include <winsock2.h>
204
#include <ws2tcpip.h>
205
#include <windows.h>
206
#include <process.h>
207

    
208
#if defined(_MSC_VER) && _MSC_VER >= 1800
209
#define strdup _strdup
210
#endif
211

    
212
#ifndef EINPROGRESS
213
#define EINPROGRESS WSAEINPROGRESS
214
#endif
215
#ifndef EWOULDBLOCK
216
#define EWOULDBLOCK WSAEWOULDBLOCK
217
#endif
218
#ifndef __func__
219
#define STRX(x) #x
220
#define STR(x) STRX(x)
221
#define __func__ __FILE__ ":" STR(__LINE__)
222
#endif
223
#define snprintf _snprintf
224
#define fileno _fileno
225
#define vsnprintf _vsnprintf
226
#define sleep(x) Sleep((x) *1000)
227
#define to64(x) _atoi64(x)
228
#if !defined(__MINGW32__) && !defined(__MINGW64__)
229
#define popen(x, y) _popen((x), (y))
230
#define pclose(x) _pclose(x)
231
#endif
232
#define rmdir _rmdir
233
#if defined(_MSC_VER) && _MSC_VER >= 1400
234
#define fseeko(x, y, z) _fseeki64((x), (y), (z))
235
#else
236
#define fseeko(x, y, z) fseek((x), (y), (z))
237
#endif
238
#if defined(_MSC_VER) && _MSC_VER <= 1200
239
typedef unsigned long uintptr_t;
240
typedef long intptr_t;
241
#endif
242
typedef int socklen_t;
243
#if _MSC_VER >= 1700
244
#include <stdint.h>
245
#else
246
typedef signed char int8_t;
247
typedef unsigned char uint8_t;
248
typedef int int32_t;
249
typedef unsigned int uint32_t;
250
typedef short int16_t;
251
typedef unsigned short uint16_t;
252
typedef __int64 int64_t;
253
typedef unsigned __int64 uint64_t;
254
#endif
255
typedef SOCKET sock_t;
256
typedef uint32_t in_addr_t;
257
#ifndef UINT16_MAX
258
#define UINT16_MAX 65535
259
#endif
260
#ifndef UINT32_MAX
261
#define UINT32_MAX 4294967295
262
#endif
263
#ifndef pid_t
264
#define pid_t HANDLE
265
#endif
266
#define INT64_FMT "I64d"
267
#define INT64_X_FMT "I64x"
268
#define SIZE_T_FMT "Iu"
269
typedef struct _stati64 cs_stat_t;
270
#ifndef S_ISDIR
271
#define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
272
#endif
273
#ifndef S_ISREG
274
#define S_ISREG(x) (((x) &_S_IFMT) == _S_IFREG)
275
#endif
276
#define DIRSEP '\\'
277

    
278
#ifndef va_copy
279
#ifdef __va_copy
280
#define va_copy __va_copy
281
#else
282
#define va_copy(x, y) (x) = (y)
283
#endif
284
#endif
285

    
286
#ifndef MG_MAX_HTTP_REQUEST_SIZE
287
#define MG_MAX_HTTP_REQUEST_SIZE 8192
288
#endif
289

    
290
#ifndef MG_MAX_HTTP_SEND_MBUF
291
#define MG_MAX_HTTP_SEND_MBUF 4096
292
#endif
293

    
294
#ifndef MG_MAX_HTTP_HEADERS
295
#define MG_MAX_HTTP_HEADERS 40
296
#endif
297

    
298
#ifndef CS_ENABLE_STDIO
299
#define CS_ENABLE_STDIO 1
300
#endif
301

    
302
#ifndef MG_ENABLE_BROADCAST
303
#define MG_ENABLE_BROADCAST 1
304
#endif
305

    
306
#ifndef MG_ENABLE_DIRECTORY_LISTING
307
#define MG_ENABLE_DIRECTORY_LISTING 1
308
#endif
309

    
310
#ifndef MG_ENABLE_FILESYSTEM
311
#define MG_ENABLE_FILESYSTEM 1
312
#endif
313

    
314
#ifndef MG_ENABLE_HTTP_CGI
315
#define MG_ENABLE_HTTP_CGI MG_ENABLE_FILESYSTEM
316
#endif
317

    
318
#ifndef MG_NET_IF
319
#define MG_NET_IF MG_NET_IF_SOCKET
320
#endif
321

    
322
#endif /* CS_PLATFORM == CS_P_WINDOWS */
323
#endif /* CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_ */
324
#ifdef MG_MODULE_LINES
325
#line 1 "common/platforms/platform_unix.h"
326
#endif
327
#ifndef CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_
328
#define CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_
329
#if CS_PLATFORM == CS_P_UNIX
330

    
331
#ifndef _XOPEN_SOURCE
332
#define _XOPEN_SOURCE 600
333
#endif
334

    
335
/* <inttypes.h> wants this for C++ */
336
#ifndef __STDC_FORMAT_MACROS
337
#define __STDC_FORMAT_MACROS
338
#endif
339

    
340
/* C++ wants that for INT64_MAX */
341
#ifndef __STDC_LIMIT_MACROS
342
#define __STDC_LIMIT_MACROS
343
#endif
344

    
345
/* Enable fseeko() and ftello() functions */
346
#ifndef _LARGEFILE_SOURCE
347
#define _LARGEFILE_SOURCE
348
#endif
349

    
350
/* Enable 64-bit file offsets */
351
#ifndef _FILE_OFFSET_BITS
352
#define _FILE_OFFSET_BITS 64
353
#endif
354

    
355
#include <arpa/inet.h>
356
#include <assert.h>
357
#include <ctype.h>
358
#include <dirent.h>
359
#include <errno.h>
360
#include <fcntl.h>
361
#include <inttypes.h>
362
#include <stdint.h>
363
#include <limits.h>
364
#include <math.h>
365
#include <netdb.h>
366
#include <netinet/in.h>
367
#include <pthread.h>
368
#include <signal.h>
369
#include <stdarg.h>
370
#include <stdio.h>
371
#include <stdlib.h>
372
#include <string.h>
373
#include <sys/param.h>
374
#include <sys/socket.h>
375
#include <sys/select.h>
376
#include <sys/stat.h>
377
#include <sys/time.h>
378
#include <sys/types.h>
379
#include <unistd.h>
380

    
381
#ifdef __APPLE__
382
#include <machine/endian.h>
383
#ifndef BYTE_ORDER
384
#define LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN
385
#define BIG_ENDIAN __DARWIN_BIG_ENDIAN
386
#define PDP_ENDIAN __DARWIN_PDP_ENDIAN
387
#define BYTE_ORDER __DARWIN_BYTE_ORDER
388
#endif
389
#endif
390

    
391
/*
392
 * osx correctly avoids defining strtoll when compiling in strict ansi mode.
393
 * c++ 11 standard defines strtoll as well.
394
 * We require strtoll, and if your embedded pre-c99 compiler lacks one, please
395
 * implement a shim.
396
 */
397
#if !(defined(__cplusplus) && __cplusplus >= 201103L) && \
398
    !(defined(__DARWIN_C_LEVEL) && __DARWIN_C_LEVEL >= 200809L)
399
long long strtoll(const char *, char **, int);
400
#endif
401

    
402
typedef int sock_t;
403
#define INVALID_SOCKET (-1)
404
#define SIZE_T_FMT "zu"
405
typedef struct stat cs_stat_t;
406
#define DIRSEP '/'
407
#define to64(x) strtoll(x, NULL, 10)
408
#define INT64_FMT PRId64
409
#define INT64_X_FMT PRIx64
410

    
411
#ifndef __cdecl
412
#define __cdecl
413
#endif
414

    
415
#ifndef va_copy
416
#ifdef __va_copy
417
#define va_copy __va_copy
418
#else
419
#define va_copy(x, y) (x) = (y)
420
#endif
421
#endif
422

    
423
#define closesocket(x) close(x)
424

    
425
#ifndef MG_MAX_HTTP_REQUEST_SIZE
426
#define MG_MAX_HTTP_REQUEST_SIZE 8192
427
#endif
428

    
429
#ifndef MG_MAX_HTTP_SEND_MBUF
430
#define MG_MAX_HTTP_SEND_MBUF 4096
431
#endif
432

    
433
#ifndef MG_MAX_HTTP_HEADERS
434
#define MG_MAX_HTTP_HEADERS 40
435
#endif
436

    
437
#ifndef CS_ENABLE_STDIO
438
#define CS_ENABLE_STDIO 1
439
#endif
440

    
441
#ifndef MG_ENABLE_BROADCAST
442
#define MG_ENABLE_BROADCAST 1
443
#endif
444

    
445
#ifndef MG_ENABLE_DIRECTORY_LISTING
446
#define MG_ENABLE_DIRECTORY_LISTING 1
447
#endif
448

    
449
#ifndef MG_ENABLE_FILESYSTEM
450
#define MG_ENABLE_FILESYSTEM 1
451
#endif
452

    
453
#ifndef MG_ENABLE_HTTP_CGI
454
#define MG_ENABLE_HTTP_CGI MG_ENABLE_FILESYSTEM
455
#endif
456

    
457
#ifndef MG_NET_IF
458
#define MG_NET_IF MG_NET_IF_SOCKET
459
#endif
460

    
461
#endif /* CS_PLATFORM == CS_P_UNIX */
462
#endif /* CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_ */
463
#ifdef MG_MODULE_LINES
464
#line 1 "common/platforms/platform_esp32.h"
465
#endif
466
/*
467
 * Copyright (c) 2014-2016 Cesanta Software Limited
468
 * All rights reserved
469
 */
470

    
471
#ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_
472
#define CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_
473
#if CS_PLATFORM == CS_P_ESP32
474

    
475
#include <assert.h>
476
#include <ctype.h>
477
#include <fcntl.h>
478
#include <inttypes.h>
479
#include <machine/endian.h>
480
#include <stdint.h>
481
#include <string.h>
482
#include <sys/stat.h>
483
#include <sys/time.h>
484

    
485
#define SIZE_T_FMT "u"
486
typedef struct stat cs_stat_t;
487
#define DIRSEP '/'
488
#define to64(x) strtoll(x, NULL, 10)
489
#define INT64_FMT PRId64
490
#define INT64_X_FMT PRIx64
491
#define __cdecl
492
#define _FILE_OFFSET_BITS 32
493

    
494
#define MG_LWIP 1
495

    
496
#ifndef MG_NET_IF
497
#define MG_NET_IF MG_NET_IF_SOCKET
498
#endif
499

    
500
#ifndef CS_ENABLE_STDIO
501
#define CS_ENABLE_STDIO 1
502
#endif
503

    
504
#endif /* CS_PLATFORM == CS_P_ESP32 */
505
#endif /* CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_ */
506
#ifdef MG_MODULE_LINES
507
#line 1 "common/platforms/platform_esp8266.h"
508
#endif
509
/*
510
 * Copyright (c) 2014-2016 Cesanta Software Limited
511
 * All rights reserved
512
 */
513

    
514
#ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_
515
#define CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_
516
#if CS_PLATFORM == CS_P_ESP8266
517

    
518
#include <assert.h>
519
#include <ctype.h>
520
#include <fcntl.h>
521
#include <inttypes.h>
522
#include <machine/endian.h>
523
#include <string.h>
524
#include <sys/stat.h>
525
#include <sys/time.h>
526

    
527
#define SIZE_T_FMT "u"
528
typedef struct stat cs_stat_t;
529
#define DIRSEP '/'
530
#define to64(x) strtoll(x, NULL, 10)
531
#define INT64_FMT PRId64
532
#define INT64_X_FMT PRIx64
533
#define __cdecl
534
#define _FILE_OFFSET_BITS 32
535

    
536
#ifndef RTOS_SDK
537
#define fileno(x) -1
538
#endif
539

    
540
#define MG_LWIP 1
541

    
542
/* struct timeval is defined in sys/time.h. */
543
#define LWIP_TIMEVAL_PRIVATE 0
544

    
545
#ifndef MG_NET_IF
546
#include <lwip/opt.h>
547
#if LWIP_SOCKET /* RTOS SDK has LWIP sockets */
548
#  define MG_NET_IF MG_NET_IF_SOCKET
549
#else
550
#  define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
551
#endif
552
#endif
553

    
554
#ifndef CS_ENABLE_STDIO
555
#define CS_ENABLE_STDIO 1
556
#endif
557

    
558
#endif /* CS_PLATFORM == CS_P_ESP8266 */
559
#endif /* CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_ */
560
#ifdef MG_MODULE_LINES
561
#line 1 "common/platforms/platform_cc3100.h"
562
#endif
563
/*
564
 * Copyright (c) 2014-2016 Cesanta Software Limited
565
 * All rights reserved
566
 */
567

    
568
#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_
569
#define CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_
570
#if CS_PLATFORM == CS_P_CC3100
571

    
572
#include <assert.h>
573
#include <ctype.h>
574
#include <errno.h>
575
#include <inttypes.h>
576
#include <stdint.h>
577
#include <string.h>
578
#include <time.h>
579

    
580
#define MG_NET_IF MG_NET_IF_SIMPLELINK
581
#define MG_SSL_IF MG_SSL_IF_SIMPLELINK
582

    
583
/*
584
 * CC3100 SDK and STM32 SDK include headers w/out path, just like
585
 * #include "simplelink.h". As result, we have to add all required directories
586
 * into Makefile IPATH and do the same thing (include w/out path)
587
 */
588

    
589
#include <simplelink.h>
590
#include <netapp.h>
591
#undef timeval 
592

    
593
typedef int sock_t;
594
#define INVALID_SOCKET (-1)
595

    
596
#define to64(x) strtoll(x, NULL, 10)
597
#define INT64_FMT PRId64
598
#define INT64_X_FMT PRIx64
599
#define SIZE_T_FMT "u"
600

    
601
#define SOMAXCONN 8
602

    
603
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
604
char *inet_ntoa(struct in_addr in);
605
int inet_pton(int af, const char *src, void *dst);
606

    
607
#endif /* CS_PLATFORM == CS_P_CC3100 */
608
#endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_ */
609
#ifdef MG_MODULE_LINES
610
#line 1 "common/platforms/platform_cc3200.h"
611
#endif
612
/*
613
 * Copyright (c) 2014-2016 Cesanta Software Limited
614
 * All rights reserved
615
 */
616

    
617
#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
618
#define CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
619
#if CS_PLATFORM == CS_P_CC3200
620

    
621
#include <assert.h>
622
#include <ctype.h>
623
#include <errno.h>
624
#include <inttypes.h>
625
#include <stdint.h>
626
#include <string.h>
627
#include <time.h>
628

    
629
#ifndef __TI_COMPILER_VERSION__
630
#include <fcntl.h>
631
#include <sys/time.h>
632
#endif
633

    
634
#define MG_NET_IF MG_NET_IF_SIMPLELINK
635
#define MG_SSL_IF MG_SSL_IF_SIMPLELINK
636

    
637
/* Only SPIFFS supports directories, SLFS does not. */
638
#if defined(CC3200_FS_SPIFFS) && !defined(MG_ENABLE_DIRECTORY_LISTING)
639
#define MG_ENABLE_DIRECTORY_LISTING 1
640
#endif
641

    
642
/* Amalgamated: #include "common/platforms/simplelink/cs_simplelink.h" */
643

    
644
typedef int sock_t;
645
#define INVALID_SOCKET (-1)
646
#define SIZE_T_FMT "u"
647
typedef struct stat cs_stat_t;
648
#define DIRSEP '/'
649
#define to64(x) strtoll(x, NULL, 10)
650
#define INT64_FMT PRId64
651
#define INT64_X_FMT PRIx64
652
#define __cdecl
653

    
654
#define fileno(x) -1
655

    
656
/* Some functions we implement for Mongoose. */
657

    
658
#ifdef __cplusplus
659
extern "C" {
660
#endif
661

    
662
#ifdef __TI_COMPILER_VERSION__
663
struct SlTimeval_t;
664
#define timeval SlTimeval_t
665
int gettimeofday(struct timeval *t, void *tz);
666

    
667
int asprintf(char **strp, const char *fmt, ...);
668

    
669
#endif
670

    
671
/* TI's libc does not have stat & friends, add them. */
672
#ifdef __TI_COMPILER_VERSION__
673

    
674
#include <file.h>
675

    
676
typedef unsigned int mode_t;
677
typedef size_t _off_t;
678
typedef long ssize_t;
679

    
680
struct stat {
681
  int st_ino;
682
  mode_t st_mode;
683
  int st_nlink;
684
  time_t st_mtime;
685
  off_t st_size;
686
};
687

    
688
int _stat(const char *pathname, struct stat *st);
689
#define stat(a, b) _stat(a, b)
690

    
691
#define __S_IFMT 0170000
692

    
693
#define __S_IFDIR 0040000
694
#define __S_IFCHR 0020000
695
#define __S_IFREG 0100000
696

    
697
#define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
698

    
699
#define S_IFDIR __S_IFDIR
700
#define S_IFCHR __S_IFCHR
701
#define S_IFREG __S_IFREG
702
#define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
703
#define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
704

    
705
/* As of 5.2.7, TI compiler does not support va_copy() yet. */
706
#define va_copy(apc, ap) ((apc) = (ap))
707

    
708
#endif /* __TI_COMPILER_VERSION__ */
709

    
710
#ifdef CC3200_FS_SPIFFS
711
#include <common/spiffs/spiffs.h>
712

    
713
typedef struct {
714
  spiffs_DIR dh;
715
  struct spiffs_dirent de;
716
} DIR;
717

    
718
#define d_name name
719
#define dirent spiffs_dirent
720

    
721
DIR *opendir(const char *dir_name);
722
int closedir(DIR *dir);
723
struct dirent *readdir(DIR *dir);
724
#endif /* CC3200_FS_SPIFFS */
725

    
726
#ifdef CC3200_FS_SLFS
727
#define MG_FS_SLFS
728
#endif
729

    
730
#if (defined(CC3200_FS_SPIFFS) || defined(CC3200_FS_SLFS)) && \
731
    !defined(MG_ENABLE_FILESYSTEM)
732
#define MG_ENABLE_FILESYSTEM 1
733
#endif
734

    
735
#ifndef CS_ENABLE_STDIO
736
#define CS_ENABLE_STDIO 1
737
#endif
738

    
739
#ifdef __cplusplus
740
}
741
#endif
742

    
743
#endif /* CS_PLATFORM == CS_P_CC3200 */
744
#endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ */
745
#ifdef MG_MODULE_LINES
746
#line 1 "common/platforms/platform_msp432.h"
747
#endif
748
/*
749
 * Copyright (c) 2014-2016 Cesanta Software Limited
750
 * All rights reserved
751
 */
752

    
753
#ifndef CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
754
#define CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
755
#if CS_PLATFORM == CS_P_MSP432
756

    
757
#include <assert.h>
758
#include <ctype.h>
759
#include <errno.h>
760
#include <inttypes.h>
761
#include <stdint.h>
762
#include <string.h>
763
#include <time.h>
764

    
765
#ifndef __TI_COMPILER_VERSION__
766
#include <fcntl.h>
767
#include <sys/time.h>
768
#endif
769

    
770
#define MG_NET_IF MG_NET_IF_SIMPLELINK
771
#define MG_SSL_IF MG_SSL_IF_SIMPLELINK
772

    
773
/* Amalgamated: #include "common/platforms/simplelink/cs_simplelink.h" */
774

    
775
typedef int sock_t;
776
#define INVALID_SOCKET (-1)
777
#define SIZE_T_FMT "u"
778
typedef struct stat cs_stat_t;
779
#define DIRSEP '/'
780
#define to64(x) strtoll(x, NULL, 10)
781
#define INT64_FMT PRId64
782
#define INT64_X_FMT PRIx64
783
#define __cdecl
784

    
785
#define fileno(x) -1
786

    
787
/* Some functions we implement for Mongoose. */
788

    
789
#ifdef __cplusplus
790
extern "C" {
791
#endif
792

    
793
#ifdef __TI_COMPILER_VERSION__
794
struct SlTimeval_t;
795
#define timeval SlTimeval_t
796
int gettimeofday(struct timeval *t, void *tz);
797
#endif
798

    
799
/* TI's libc does not have stat & friends, add them. */
800
#ifdef __TI_COMPILER_VERSION__
801

    
802
#include <file.h>
803

    
804
typedef unsigned int mode_t;
805
typedef size_t _off_t;
806
typedef long ssize_t;
807

    
808
struct stat {
809
  int st_ino;
810
  mode_t st_mode;
811
  int st_nlink;
812
  time_t st_mtime;
813
  off_t st_size;
814
};
815

    
816
int _stat(const char *pathname, struct stat *st);
817
#define stat(a, b) _stat(a, b)
818

    
819
#define __S_IFMT 0170000
820

    
821
#define __S_IFDIR 0040000
822
#define __S_IFCHR 0020000
823
#define __S_IFREG 0100000
824

    
825
#define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
826

    
827
#define S_IFDIR __S_IFDIR
828
#define S_IFCHR __S_IFCHR
829
#define S_IFREG __S_IFREG
830
#define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
831
#define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
832

    
833
/* As of 5.2.7, TI compiler does not support va_copy() yet. */
834
#define va_copy(apc, ap) ((apc) = (ap))
835

    
836
#endif /* __TI_COMPILER_VERSION__ */
837

    
838
#ifndef CS_ENABLE_STDIO
839
#define CS_ENABLE_STDIO 1
840
#endif
841

    
842
#if (defined(CC3200_FS_SPIFFS) || defined(CC3200_FS_SLFS)) && !defined(MG_ENABLE_FILESYSTEM)
843
#define MG_ENABLE_FILESYSTEM 1
844
#endif
845

    
846
#ifdef __cplusplus
847
}
848
#endif
849

    
850
#endif /* CS_PLATFORM == CS_P_MSP432 */
851
#endif /* CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_ */
852
#ifdef MG_MODULE_LINES
853
#line 1 "common/platforms/platform_tm4c129.h"
854
#endif
855
/*
856
 * Copyright (c) 2014-2016 Cesanta Software Limited
857
 * All rights reserved
858
 */
859

    
860
#ifndef CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_
861
#define CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_
862
#if CS_PLATFORM == CS_P_TM4C129
863

    
864
#include <assert.h>
865
#include <ctype.h>
866
#include <errno.h>
867
#include <inttypes.h>
868
#include <stdint.h>
869
#include <string.h>
870
#include <time.h>
871

    
872
#ifndef __TI_COMPILER_VERSION__
873
#include <fcntl.h>
874
#include <sys/time.h>
875
#endif
876

    
877
#define SIZE_T_FMT "u"
878
typedef struct stat cs_stat_t;
879
#define DIRSEP '/'
880
#define to64(x) strtoll(x, NULL, 10)
881
#define INT64_FMT PRId64
882
#define INT64_X_FMT PRIx64
883
#define __cdecl
884

    
885
#ifndef MG_NET_IF
886
#  include <lwip/opt.h>
887
#  if LWIP_SOCKET
888
#    define MG_NET_IF MG_NET_IF_SOCKET
889
#  else
890
#    define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
891
#  endif
892
#  define MG_LWIP 1
893
#elif MG_NET_IF == MG_NET_IF_SIMPLELINK
894
#  include "common/platforms/simplelink/cs_simplelink.h"
895
#endif
896

    
897
#ifndef CS_ENABLE_STDIO
898
#define CS_ENABLE_STDIO 1
899
#endif
900

    
901
#ifdef __TI_COMPILER_VERSION__
902
/* As of 5.2.8, TI compiler does not support va_copy() yet. */
903
#define va_copy(apc, ap) ((apc) = (ap))
904
#endif /* __TI_COMPILER_VERSION__ */
905

    
906
#ifdef __cplusplus
907
}
908
#endif
909

    
910
#endif /* CS_PLATFORM == CS_P_TM4C129 */
911
#endif /* CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_ */
912
#ifdef MG_MODULE_LINES
913
#line 1 "common/platforms/platform_mbed.h"
914
#endif
915
/*
916
 * Copyright (c) 2014-2016 Cesanta Software Limited
917
 * All rights reserved
918
 */
919

    
920
#ifndef CS_COMMON_PLATFORMS_PLATFORM_MBED_H_
921
#define CS_COMMON_PLATFORMS_PLATFORM_MBED_H_
922
#if CS_PLATFORM == CS_P_MBED
923

    
924
/*
925
 * mbed.h contains C++ code (e.g. templates), thus, it should be processed
926
 * only if included directly to startup file (ex: main.cpp)
927
 */
928
#ifdef __cplusplus
929
/* Amalgamated: #include "mbed.h" */
930
#endif /* __cplusplus */
931

    
932
#include <assert.h>
933
#include <ctype.h>
934
#include <errno.h>
935
#include <inttypes.h>
936
#include <stdint.h>
937
#include <string.h>
938
#include <time.h>
939
#include <sys/stat.h>
940
#include <sys/types.h>
941
#include <fcntl.h>
942
#include <stdio.h>
943

    
944
typedef struct stat cs_stat_t;
945
#define DIRSEP '/'
946

    
947
#ifndef CS_ENABLE_STDIO
948
#define CS_ENABLE_STDIO 1
949
#endif
950

    
951
/*
952
 * mbed can be compiled with the ARM compiler which
953
 * just doesn't come with a gettimeofday shim
954
 * because it's a BSD API and ARM targets embedded
955
 * non-unix platforms.
956
 */
957
#if defined(__ARMCC_VERSION) || defined(__ICCARM__)
958
#define _TIMEVAL_DEFINED
959
#define gettimeofday _gettimeofday
960

    
961
/* copied from GCC on ARM; for some reason useconds are signed */
962
typedef long suseconds_t; /* microseconds (signed) */
963
struct timeval {
964
  time_t tv_sec;       /* seconds */
965
  suseconds_t tv_usec; /* and microseconds */
966
};
967

    
968
#endif
969

    
970
#if MG_NET_IF == MG_NET_IF_SIMPLELINK
971

    
972
#define MG_SIMPLELINK_NO_OSI 1
973

    
974
#include <simplelink.h>
975

    
976
typedef int sock_t;
977
#define INVALID_SOCKET (-1)
978

    
979
#define to64(x) strtoll(x, NULL, 10)
980
#define INT64_FMT PRId64
981
#define INT64_X_FMT PRIx64
982
#define SIZE_T_FMT "u"
983

    
984
#define SOMAXCONN 8
985

    
986
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
987
char *inet_ntoa(struct in_addr in);
988
int inet_pton(int af, const char *src, void *dst);
989
int inet_aton(const char *cp, struct in_addr *inp);
990
in_addr_t inet_addr(const char *cp);
991

    
992
#endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK */
993

    
994
#endif /* CS_PLATFORM == CS_P_MBED */
995
#endif /* CS_COMMON_PLATFORMS_PLATFORM_MBED_H_ */
996
#ifdef MG_MODULE_LINES
997
#line 1 "common/platforms/platform_nrf51.h"
998
#endif
999
/*
1000
 * Copyright (c) 2014-2016 Cesanta Software Limited
1001
 * All rights reserved
1002
 */
1003
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_
1004
#define CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_
1005
#if CS_PLATFORM == CS_P_NRF51
1006

    
1007
#include <assert.h>
1008
#include <ctype.h>
1009
#include <inttypes.h>
1010
#include <stdint.h>
1011
#include <string.h>
1012
#include <time.h>
1013

    
1014
#define to64(x) strtoll(x, NULL, 10)
1015

    
1016
#define MG_NET_IF             MG_NET_IF_LWIP_LOW_LEVEL
1017
#define MG_LWIP               1
1018
#define MG_ENABLE_IPV6        1
1019

    
1020
/*
1021
 * For ARM C Compiler, make lwip to export `struct timeval`; for other
1022
 * compilers, suppress it.
1023
 */
1024
#if !defined(__ARMCC_VERSION)
1025
# define LWIP_TIMEVAL_PRIVATE  0
1026
#else
1027
struct timeval;
1028
int gettimeofday(struct timeval *tp, void *tzp);
1029
#endif
1030

    
1031
#define INT64_FMT PRId64
1032
#define SIZE_T_FMT "u"
1033

    
1034
/*
1035
 * ARM C Compiler doesn't have strdup, so we provide it
1036
 */
1037
#define CS_ENABLE_STRDUP defined(__ARMCC_VERSION)
1038

    
1039
#endif /* CS_PLATFORM == CS_P_NRF51 */
1040
#endif /* CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_ */
1041
#ifdef MG_MODULE_LINES
1042
#line 1 "common/platforms/platform_nrf52.h"
1043
#endif
1044
/*
1045
 * Copyright (c) 2014-2016 Cesanta Software Limited
1046
 * All rights reserved
1047
 */
1048
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_
1049
#define CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_
1050
#if CS_PLATFORM == CS_P_NRF52
1051

    
1052
#include <assert.h>
1053
#include <ctype.h>
1054
#include <errno.h>
1055
#include <inttypes.h>
1056
#include <stdint.h>
1057
#include <string.h>
1058
#include <time.h>
1059

    
1060
#define to64(x) strtoll(x, NULL, 10)
1061

    
1062
#define MG_NET_IF             MG_NET_IF_LWIP_LOW_LEVEL
1063
#define MG_LWIP               1
1064
#define MG_ENABLE_IPV6        1
1065

    
1066
#if !defined(ENOSPC)
1067
# define ENOSPC 28  /* No space left on device */
1068
#endif
1069

    
1070
/*
1071
 * For ARM C Compiler, make lwip to export `struct timeval`; for other
1072
 * compilers, suppress it.
1073
 */
1074
#if !defined(__ARMCC_VERSION)
1075
# define LWIP_TIMEVAL_PRIVATE  0
1076
#endif
1077

    
1078
#define INT64_FMT PRId64
1079
#define SIZE_T_FMT "u"
1080

    
1081
/*
1082
 * ARM C Compiler doesn't have strdup, so we provide it
1083
 */
1084
#define CS_ENABLE_STRDUP defined(__ARMCC_VERSION)
1085

    
1086
#endif /* CS_PLATFORM == CS_P_NRF52 */
1087
#endif /* CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_ */
1088
#ifdef MG_MODULE_LINES
1089
#line 1 "common/platforms/simplelink/cs_simplelink.h"
1090
#endif
1091
/*
1092
 * Copyright (c) 2014-2016 Cesanta Software Limited
1093
 * All rights reserved
1094
 */
1095

    
1096
#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
1097
#define CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
1098

    
1099
/* If simplelink.h is already included, all bets are off. */
1100
#if defined(MG_NET_IF) && MG_NET_IF == MG_NET_IF_SIMPLELINK && \
1101
    !defined(__SIMPLELINK_H__)
1102

    
1103
#include <stdbool.h>
1104

    
1105
#ifndef __TI_COMPILER_VERSION__
1106
#undef __CONCAT
1107
#undef FD_CLR
1108
#undef FD_ISSET
1109
#undef FD_SET
1110
#undef FD_SETSIZE
1111
#undef FD_ZERO
1112
#undef fd_set
1113
#endif
1114

    
1115
/* We want to disable SL_INC_STD_BSD_API_NAMING, so we include user.h ourselves
1116
 * and undef it. */
1117
#define PROVISIONING_API_H_
1118
#include <simplelink/user.h>
1119
#undef PROVISIONING_API_H_
1120
#undef SL_INC_STD_BSD_API_NAMING
1121

    
1122
#include <simplelink/include/simplelink.h>
1123
#include <simplelink/include/netapp.h>
1124

    
1125
/* Now define only the subset of the BSD API that we use.
1126
 * Notably, close(), read() and write() are not defined. */
1127
#define AF_INET SL_AF_INET
1128

    
1129
#define socklen_t SlSocklen_t
1130
#define sockaddr SlSockAddr_t
1131
#define sockaddr_in SlSockAddrIn_t
1132
#define in_addr SlInAddr_t
1133

    
1134
#define SOCK_STREAM SL_SOCK_STREAM
1135
#define SOCK_DGRAM SL_SOCK_DGRAM
1136

    
1137
#define htonl sl_Htonl
1138
#define ntohl sl_Ntohl
1139
#define htons sl_Htons
1140
#define ntohs sl_Ntohs
1141

    
1142
#ifndef EACCES
1143
#define EACCES SL_EACCES
1144
#endif
1145
#ifndef EAFNOSUPPORT
1146
#define EAFNOSUPPORT SL_EAFNOSUPPORT
1147
#endif
1148
#ifndef EAGAIN
1149
#define EAGAIN SL_EAGAIN
1150
#endif
1151
#ifndef EBADF
1152
#define EBADF SL_EBADF
1153
#endif
1154
#ifndef EINVAL
1155
#define EINVAL SL_EINVAL
1156
#endif
1157
#ifndef ENOMEM
1158
#define ENOMEM SL_ENOMEM
1159
#endif
1160
#ifndef EWOULDBLOCK
1161
#define EWOULDBLOCK SL_EWOULDBLOCK
1162
#endif
1163

    
1164
#define SOMAXCONN 8
1165

    
1166
#ifdef __cplusplus
1167
extern "C" {
1168
#endif
1169

    
1170
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
1171
char *inet_ntoa(struct in_addr in);
1172
int inet_pton(int af, const char *src, void *dst);
1173

    
1174
struct mg_mgr;
1175
struct mg_connection;
1176

    
1177
typedef void (*mg_init_cb)(struct mg_mgr *mgr);
1178
bool mg_start_task(int priority, int stack_size, mg_init_cb mg_init);
1179

    
1180
void mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg);
1181

    
1182
int sl_fs_init(void);
1183

    
1184
void sl_restart_cb(struct mg_mgr *mgr);
1185

    
1186
int sl_set_ssl_opts(struct mg_connection *nc);
1187

    
1188
#ifdef __cplusplus
1189
}
1190
#endif
1191

    
1192
#endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK && !defined(__SIMPLELINK_H__) */
1193

    
1194
#endif /* CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_ */
1195
#ifdef MG_MODULE_LINES
1196
#line 1 "common/platforms/platform_wince.h"
1197
#endif
1198
#ifndef CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_
1199
#define CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_
1200

    
1201
#if CS_PLATFORM == CS_P_WINCE
1202

    
1203
/*
1204
 * MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
1205
 * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
1206
 * MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
1207
 * MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
1208
 * MSVC++ 9.0  _MSC_VER == 1500 (Visual Studio 2008)
1209
 * MSVC++ 8.0  _MSC_VER == 1400 (Visual Studio 2005)
1210
 * MSVC++ 7.1  _MSC_VER == 1310 (Visual Studio 2003)
1211
 * MSVC++ 7.0  _MSC_VER == 1300
1212
 * MSVC++ 6.0  _MSC_VER == 1200
1213
 * MSVC++ 5.0  _MSC_VER == 1100
1214
 */
1215
#pragma warning(disable : 4127) /* FD_SET() emits warning, disable it */
1216
#pragma warning(disable : 4204) /* missing c99 support */
1217

    
1218
#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
1219
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
1220
#endif
1221

    
1222
#ifndef _CRT_SECURE_NO_WARNINGS
1223
#define _CRT_SECURE_NO_WARNINGS
1224
#endif
1225

    
1226
#include <assert.h>
1227
#include <limits.h>
1228
#include <stddef.h>
1229
#include <stdio.h>
1230
#include <stdlib.h>
1231
#include <time.h>
1232

    
1233
#pragma comment(lib, "ws2.lib") /* Linking with WinCE winsock library */
1234

    
1235
#include <winsock2.h>
1236
#include <ws2tcpip.h>
1237
#include <windows.h>
1238

    
1239
#define strdup _strdup
1240

    
1241
#ifndef EINPROGRESS
1242
#define EINPROGRESS WSAEINPROGRESS
1243
#endif
1244

    
1245
#ifndef EWOULDBLOCK
1246
#define EWOULDBLOCK WSAEWOULDBLOCK
1247
#endif
1248

    
1249
#ifndef __func__
1250
#define STRX(x) #x
1251
#define STR(x) STRX(x)
1252
#define __func__ __FILE__ ":" STR(__LINE__)
1253
#endif
1254

    
1255
#define snprintf _snprintf
1256
#define fileno _fileno
1257
#define vsnprintf _vsnprintf
1258
#define sleep(x) Sleep((x) *1000)
1259
#define to64(x) _atoi64(x)
1260
#define rmdir _rmdir
1261

    
1262
#if defined(_MSC_VER) && _MSC_VER >= 1400
1263
#define fseeko(x, y, z) _fseeki64((x), (y), (z))
1264
#else
1265
#define fseeko(x, y, z) fseek((x), (y), (z))
1266
#endif
1267

    
1268
typedef int socklen_t;
1269

    
1270
#if _MSC_VER >= 1700
1271
#include <stdint.h>
1272
#else
1273
typedef signed char int8_t;
1274
typedef unsigned char uint8_t;
1275
typedef int int32_t;
1276
typedef unsigned int uint32_t;
1277
typedef short int16_t;
1278
typedef unsigned short uint16_t;
1279
typedef __int64 int64_t;
1280
typedef unsigned __int64 uint64_t;
1281
#endif
1282

    
1283
typedef SOCKET sock_t;
1284
typedef uint32_t in_addr_t;
1285

    
1286
#ifndef UINT16_MAX
1287
#define UINT16_MAX 65535
1288
#endif
1289

    
1290
#ifndef UINT32_MAX
1291
#define UINT32_MAX 4294967295
1292
#endif
1293

    
1294
#ifndef pid_t
1295
#define pid_t HANDLE
1296
#endif
1297

    
1298
#define INT64_FMT "I64d"
1299
#define INT64_X_FMT "I64x"
1300
/* TODO(alashkin): check if this is correct */
1301
#define SIZE_T_FMT "u"
1302

    
1303
#define DIRSEP '\\'
1304

    
1305
#ifndef va_copy
1306
#ifdef __va_copy
1307
#define va_copy __va_copy
1308
#else
1309
#define va_copy(x, y) (x) = (y)
1310
#endif
1311
#endif
1312

    
1313
#ifndef MG_MAX_HTTP_REQUEST_SIZE
1314
#define MG_MAX_HTTP_REQUEST_SIZE 8192
1315
#endif
1316

    
1317
#ifndef MG_MAX_HTTP_SEND_MBUF
1318
#define MG_MAX_HTTP_SEND_MBUF 4096
1319
#endif
1320

    
1321
#ifndef MG_MAX_HTTP_HEADERS
1322
#define MG_MAX_HTTP_HEADERS 40
1323
#endif
1324

    
1325
#ifndef CS_ENABLE_STDIO
1326
#define CS_ENABLE_STDIO 1
1327
#endif
1328

    
1329
#define abort() DebugBreak();
1330

    
1331
#ifndef BUFSIZ
1332
#define BUFSIZ 4096
1333
#endif
1334
/*
1335
 * Explicitly disabling MG_ENABLE_THREADS for WinCE
1336
 * because they are enabled for _WIN32 by default
1337
 */
1338
#ifndef MG_ENABLE_THREADS
1339
#define MG_ENABLE_THREADS 0
1340
#endif
1341

    
1342
#ifndef MG_ENABLE_FILESYSTEM
1343
#define MG_ENABLE_FILESYSTEM 1
1344
#endif
1345

    
1346
#ifndef MG_NET_IF
1347
#define MG_NET_IF MG_NET_IF_SOCKET
1348
#endif
1349

    
1350
typedef struct _stati64 {
1351
  uint32_t st_mtime;
1352
  uint32_t st_size;
1353
  uint32_t st_mode;
1354
} cs_stat_t;
1355

    
1356
/*
1357
 * WinCE 6.0 has a lot of useful definitions in ATL (not windows.h) headers
1358
 * use #ifdefs to avoid conflicts
1359
 */
1360

    
1361
#ifndef ENOENT
1362
#define ENOENT ERROR_PATH_NOT_FOUND
1363
#endif
1364

    
1365
#ifndef EACCES
1366
#define EACCES ERROR_ACCESS_DENIED
1367
#endif
1368

    
1369
#ifndef ENOMEM
1370
#define ENOMEM ERROR_NOT_ENOUGH_MEMORY
1371
#endif
1372

    
1373
#ifndef _UINTPTR_T_DEFINED
1374
typedef unsigned int* uintptr_t;
1375
#endif
1376

    
1377
#define _S_IFREG 2
1378
#define _S_IFDIR 4
1379

    
1380
#ifndef S_ISDIR
1381
#define S_ISDIR(x) (((x) & _S_IFDIR) != 0)
1382
#endif
1383

    
1384
#ifndef S_ISREG
1385
#define S_ISREG(x) (((x) & _S_IFREG) != 0)
1386
#endif
1387

    
1388
int open(const char *filename, int oflag, int pmode);
1389
int _wstati64(const wchar_t *path, cs_stat_t *st);
1390
const char *strerror();
1391

    
1392
#endif /* CS_PLATFORM == CS_P_WINCE */
1393
#endif /* CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_ */
1394
#ifdef MG_MODULE_LINES
1395
#line 1 "common/platforms/platform_nxp_lpc.h"
1396
#endif
1397
/*
1398
 * Copyright (c) 2014-2016 Cesanta Software Limited
1399
 * All rights reserved
1400
 */
1401

    
1402
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_
1403
#define CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_
1404

    
1405
#if CS_PLATFORM == CS_P_NXP_LPC
1406

    
1407
#include <ctype.h>
1408
#include <stdint.h>
1409
#include <string.h>
1410

    
1411
#define SIZE_T_FMT "u"
1412
typedef struct stat cs_stat_t;
1413
#define INT64_FMT "lld"
1414
#define INT64_X_FMT "llx"
1415
#define __cdecl
1416

    
1417
#define MG_LWIP 1
1418

    
1419
#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1420

    
1421
/*
1422
 * LPCXpress comes with 3 C library implementations: Newlib, NewlibNano and Redlib.
1423
 * See https://community.nxp.com/message/630860 for more details.
1424
 *
1425
 * Redlib is the default and lacks certain things, so we provide them.
1426
 */
1427
#ifdef __REDLIB_INTERFACE_VERSION__
1428

    
1429
/* Let LWIP define timeval for us. */
1430
#define LWIP_TIMEVAL_PRIVATE 1
1431

    
1432
#define va_copy(d, s) __builtin_va_copy(d, s)
1433

    
1434
#define CS_ENABLE_TO64 1
1435
#define to64(x) cs_to64(x)
1436

    
1437
#define CS_ENABLE_STRDUP 1
1438

    
1439
#else
1440

    
1441
#include <sys/time.h>
1442
#define LWIP_TIMEVAL_PRIVATE 0
1443
#define to64(x) strtoll(x, NULL, 10)
1444

    
1445
#endif
1446

    
1447
#endif /* CS_PLATFORM == CS_P_NXP_LPC */
1448
#endif /* CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_ */
1449
#ifdef MG_MODULE_LINES
1450
#line 1 "common/platforms/platform_nxp_kinetis.h"
1451
#endif
1452
/*
1453
 * Copyright (c) 2014-2016 Cesanta Software Limited
1454
 * All rights reserved
1455
 */
1456

    
1457
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_
1458
#define CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_
1459

    
1460
#if CS_PLATFORM == CS_P_NXP_KINETIS
1461

    
1462
#include <ctype.h>
1463
#include <inttypes.h>
1464
#include <string.h>
1465
#include <sys/time.h>
1466

    
1467
#define SIZE_T_FMT "u"
1468
typedef struct stat cs_stat_t;
1469
#define to64(x) strtoll(x, NULL, 10)
1470
#define INT64_FMT "lld"
1471
#define INT64_X_FMT "llx"
1472
#define __cdecl
1473

    
1474
#define MG_LWIP 1
1475

    
1476
#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1477

    
1478
/* struct timeval is defined in sys/time.h. */
1479
#define LWIP_TIMEVAL_PRIVATE 0
1480

    
1481
#endif /* CS_PLATFORM == CS_P_NXP_KINETIS */
1482
#endif /* CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_ */
1483
#ifdef MG_MODULE_LINES
1484
#line 1 "common/platforms/platform_pic32.h"
1485
#endif
1486
/*
1487
 * Copyright (c) 2014-2016 Cesanta Software Limited
1488
 * All rights reserved
1489
 */
1490

    
1491
#ifndef CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_
1492
#define CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_
1493

    
1494
#if CS_PLATFORM == CS_P_PIC32
1495

    
1496
#define MG_NET_IF MG_NET_IF_PIC32
1497

    
1498
#include <stdint.h>
1499
#include <time.h>
1500
#include <ctype.h>
1501
#include <stdlib.h>
1502

    
1503
#include <system_config.h>
1504
#include <system_definitions.h>
1505

    
1506
#include <sys/types.h>
1507

    
1508
typedef TCP_SOCKET sock_t;
1509
#define to64(x) strtoll(x, NULL, 10)
1510

    
1511
#define SIZE_T_FMT "lu"
1512
#define INT64_FMT "lld"
1513

    
1514
#ifndef CS_ENABLE_STDIO
1515
#define CS_ENABLE_STDIO 1
1516
#endif
1517

    
1518
char* inet_ntoa(struct in_addr in);
1519

    
1520
#endif /* CS_PLATFORM == CS_P_PIC32 */
1521

    
1522
#endif /* CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_ */
1523
#ifdef MG_MODULE_LINES
1524
#line 1 "common/platforms/platform_stm32.h"
1525
#endif
1526
/*
1527
 * Copyright (c) 2014-2016 Cesanta Software Limited
1528
 * All rights reserved
1529
 */
1530

    
1531
#ifndef CS_COMMON_PLATFORMS_PLATFORM_STM32_H_
1532
#define CS_COMMON_PLATFORMS_PLATFORM_STM32_H_
1533
#if CS_PLATFORM == CS_P_STM32
1534

    
1535
#include <sys/types.h>
1536
#include <stdint.h>
1537
#include <inttypes.h>
1538
#include <stdio.h>
1539
#include <ctype.h>
1540
#include <errno.h>
1541
#include <memory.h>
1542

    
1543
#define to64(x) strtoll(x, NULL, 10)
1544
#define INT64_FMT PRId64
1545
#define SIZE_T_FMT "u"
1546

    
1547
#endif /* CS_PLATFORM == CS_P_STM32 */
1548
#endif /* CS_COMMON_PLATFORMS_PLATFORM_STM32_H_ */
1549
#ifdef MG_MODULE_LINES
1550
#line 1 "common/platforms/lwip/mg_lwip.h"
1551
#endif
1552
/*
1553
 * Copyright (c) 2014-2016 Cesanta Software Limited
1554
 * All rights reserved
1555
 */
1556

    
1557
#ifndef CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
1558
#define CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
1559

    
1560
#ifndef MG_LWIP
1561
#define MG_LWIP 0
1562
#endif
1563

    
1564
#if MG_LWIP
1565

    
1566
/*
1567
 * When compiling for nRF5x chips with arm-none-eabi-gcc, it has BYTE_ORDER
1568
 * already defined, so in order to avoid warnings in lwip, we have to undefine
1569
 * it.
1570
 *
1571
 * TODO: Check if in the future versions of nRF5 SDK that changes.
1572
 *       Current version of nRF51 SDK: 0.8.0
1573
 *                          nRF5 SDK:  0.9.0
1574
 */
1575
#if CS_PLATFORM == CS_P_NRF51 || CS_PLATFORM == CS_P_NRF52
1576
#undef BYTE_ORDER
1577
#endif
1578

    
1579
#include <lwip/opt.h>
1580
#include <lwip/err.h>
1581
#include <lwip/ip_addr.h>
1582
#include <lwip/inet.h>
1583
#include <lwip/netdb.h>
1584
#include <lwip/dns.h>
1585

    
1586
#ifndef LWIP_PROVIDE_ERRNO
1587
#include <errno.h>
1588
#endif
1589

    
1590
#if LWIP_SOCKET
1591
#include <lwip/sockets.h>
1592
#else
1593
/* We really need the definitions from sockets.h. */
1594
#undef LWIP_SOCKET
1595
#define LWIP_SOCKET 1
1596
#include <lwip/sockets.h>
1597
#undef LWIP_SOCKET
1598
#define LWIP_SOCKET 0
1599
#endif
1600

    
1601
#define INVALID_SOCKET (-1)
1602
#define SOMAXCONN 10
1603
typedef int sock_t;
1604

    
1605
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
1606
struct mg_mgr;
1607
struct mg_connection;
1608
uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr);
1609
void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
1610
                                  int interval, int count);
1611
#endif
1612

    
1613
#endif /* MG_LWIP */
1614

    
1615
#endif /* CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_ */
1616
#ifdef MG_MODULE_LINES
1617
#line 1 "common/cs_time.h"
1618
#endif
1619
/*
1620
 * Copyright (c) 2014-2016 Cesanta Software Limited
1621
 * All rights reserved
1622
 */
1623

    
1624
#ifndef CS_COMMON_CS_TIME_H_
1625
#define CS_COMMON_CS_TIME_H_
1626

    
1627
/* Amalgamated: #include "common/platform.h" */
1628

    
1629
#ifdef __cplusplus
1630
extern "C" {
1631
#endif /* __cplusplus */
1632

    
1633
/* Sub-second granularity time(). */
1634
double cs_time(void);
1635

    
1636
#ifdef __cplusplus
1637
}
1638
#endif /* __cplusplus */
1639

    
1640
#endif /* CS_COMMON_CS_TIME_H_ */
1641
#ifdef MG_MODULE_LINES
1642
#line 1 "common/mg_str.h"
1643
#endif
1644
/*
1645
 * Copyright (c) 2014-2016 Cesanta Software Limited
1646
 * All rights reserved
1647
 */
1648

    
1649
#ifndef CS_COMMON_MG_STR_H_
1650
#define CS_COMMON_MG_STR_H_
1651

    
1652
#include <stddef.h>
1653

    
1654
/* Amalgamated: #include "common/platform.h" */
1655

    
1656
#ifdef __cplusplus
1657
extern "C" {
1658
#endif /* __cplusplus */
1659

    
1660
/* Describes chunk of memory */
1661
struct mg_str {
1662
  const char *p; /* Memory chunk pointer */
1663
  size_t len;    /* Memory chunk length */
1664
};
1665

    
1666
/*
1667
 * Helper functions for creating mg_str struct from plain C string.
1668
 * `NULL` is allowed and becomes `{NULL, 0}`.
1669
 */
1670
struct mg_str mg_mk_str(const char *s);
1671
struct mg_str mg_mk_str_n(const char *s, size_t len);
1672

    
1673
/* Macro for initializing mg_str. */
1674
#define MG_MK_STR(str_literal) \
1675
  { str_literal, sizeof(str_literal) - 1 }
1676

    
1677
/*
1678
 * Cross-platform version of `strcmp()` where where first string is
1679
 * specified by `struct mg_str`.
1680
 */
1681
int mg_vcmp(const struct mg_str *str2, const char *str1);
1682

    
1683
/*
1684
 * Cross-platform version of `strncasecmp()` where first string is
1685
 * specified by `struct mg_str`.
1686
 */
1687
int mg_vcasecmp(const struct mg_str *str2, const char *str1);
1688

    
1689
struct mg_str mg_strdup(const struct mg_str s);
1690
int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
1691
int mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n);
1692

    
1693
#ifdef __cplusplus
1694
}
1695
#endif /* __cplusplus */
1696

    
1697
#endif /* CS_COMMON_MG_STR_H_ */
1698
#ifdef MG_MODULE_LINES
1699
#line 1 "common/mbuf.h"
1700
#endif
1701
/*
1702
 * Copyright (c) 2015 Cesanta Software Limited
1703
 * All rights reserved
1704
 */
1705

    
1706
/*
1707
 * === Memory Buffers
1708
 *
1709
 * Mbufs are mutable/growing memory buffers, like C++ strings.
1710
 * Mbuf can append data to the end of a buffer or insert data into arbitrary
1711
 * position in the middle of a buffer. The buffer grows automatically when
1712
 * needed.
1713
 */
1714

    
1715
#ifndef CS_COMMON_MBUF_H_
1716
#define CS_COMMON_MBUF_H_
1717

    
1718
#include <stdlib.h>
1719
/* Amalgamated: #include "common/platform.h" */
1720

    
1721
#if defined(__cplusplus)
1722
extern "C" {
1723
#endif
1724

    
1725
#ifndef MBUF_SIZE_MULTIPLIER
1726
#define MBUF_SIZE_MULTIPLIER 1.5
1727
#endif
1728

    
1729
/* Memory buffer descriptor */
1730
struct mbuf {
1731
  char *buf;   /* Buffer pointer */
1732
  size_t len;  /* Data length. Data is located between offset 0 and len. */
1733
  size_t size; /* Buffer size allocated by realloc(1). Must be >= len */
1734
};
1735

    
1736
/*
1737
 * Initialises an Mbuf.
1738
 * `initial_capacity` specifies the initial capacity of the mbuf.
1739
 */
1740
void mbuf_init(struct mbuf *, size_t initial_capacity);
1741

    
1742
/* Frees the space allocated for the mbuffer and resets the mbuf structure. */
1743
void mbuf_free(struct mbuf *);
1744

    
1745
/*
1746
 * Appends data to the Mbuf.
1747
 *
1748
 * Returns the number of bytes appended or 0 if out of memory.
1749
 */
1750
size_t mbuf_append(struct mbuf *, const void *data, size_t data_size);
1751

    
1752
/*
1753
 * Inserts data at a specified offset in the Mbuf.
1754
 *
1755
 * Existing data will be shifted forwards and the buffer will
1756
 * be grown if necessary.
1757
 * Returns the number of bytes inserted.
1758
 */
1759
size_t mbuf_insert(struct mbuf *, size_t, const void *, size_t);
1760

    
1761
/* Removes `data_size` bytes from the beginning of the buffer. */
1762
void mbuf_remove(struct mbuf *, size_t data_size);
1763

    
1764
/*
1765
 * Resizes an Mbuf.
1766
 *
1767
 * If `new_size` is smaller than buffer's `len`, the
1768
 * resize is not performed.
1769
 */
1770
void mbuf_resize(struct mbuf *, size_t new_size);
1771

    
1772
/* Shrinks an Mbuf by resizing its `size` to `len`. */
1773
void mbuf_trim(struct mbuf *);
1774

    
1775
#if defined(__cplusplus)
1776
}
1777
#endif /* __cplusplus */
1778

    
1779
#endif /* CS_COMMON_MBUF_H_ */
1780
#ifdef MG_MODULE_LINES
1781
#line 1 "common/sha1.h"
1782
#endif
1783
/*
1784
 * Copyright (c) 2014 Cesanta Software Limited
1785
 * All rights reserved
1786
 */
1787

    
1788
#ifndef CS_COMMON_SHA1_H_
1789
#define CS_COMMON_SHA1_H_
1790

    
1791
#ifndef DISABLE_SHA1
1792
#define DISABLE_SHA1 0
1793
#endif
1794

    
1795
#if !DISABLE_SHA1
1796

    
1797
/* Amalgamated: #include "common/platform.h" */
1798

    
1799
#ifdef __cplusplus
1800
extern "C" {
1801
#endif /* __cplusplus */
1802

    
1803
typedef struct {
1804
  uint32_t state[5];
1805
  uint32_t count[2];
1806
  unsigned char buffer[64];
1807
} cs_sha1_ctx;
1808

    
1809
void cs_sha1_init(cs_sha1_ctx *);
1810
void cs_sha1_update(cs_sha1_ctx *, const unsigned char *data, uint32_t len);
1811
void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *);
1812
void cs_hmac_sha1(const unsigned char *key, size_t key_len,
1813
                  const unsigned char *text, size_t text_len,
1814
                  unsigned char out[20]);
1815
#ifdef __cplusplus
1816
}
1817
#endif /* __cplusplus */
1818

    
1819
#endif /* DISABLE_SHA1 */
1820

    
1821
#endif /* CS_COMMON_SHA1_H_ */
1822
#ifdef MG_MODULE_LINES
1823
#line 1 "common/md5.h"
1824
#endif
1825
/*
1826
 * Copyright (c) 2014 Cesanta Software Limited
1827
 * All rights reserved
1828
 */
1829

    
1830
#ifndef CS_COMMON_MD5_H_
1831
#define CS_COMMON_MD5_H_
1832

    
1833
/* Amalgamated: #include "common/platform.h" */
1834

    
1835
#ifndef DISABLE_MD5
1836
#define DISABLE_MD5 0
1837
#endif
1838

    
1839
#ifdef __cplusplus
1840
extern "C" {
1841
#endif /* __cplusplus */
1842

    
1843
typedef struct MD5Context {
1844
  uint32_t buf[4];
1845
  uint32_t bits[2];
1846
  unsigned char in[64];
1847
} MD5_CTX;
1848

    
1849
void MD5_Init(MD5_CTX *c);
1850
void MD5_Update(MD5_CTX *c, const unsigned char *data, size_t len);
1851
void MD5_Final(unsigned char *md, MD5_CTX *c);
1852

    
1853
/*
1854
 * Return stringified MD5 hash for NULL terminated list of pointer/length pairs.
1855
 * A length should be specified as size_t variable.
1856
 * Example:
1857
 *
1858
 *    char buf[33];
1859
 *    cs_md5(buf, "foo", (size_t) 3, "bar", (size_t) 3, NULL);
1860
 */
1861
char *cs_md5(char buf[33], ...);
1862

    
1863
#ifdef __cplusplus
1864
}
1865
#endif /* __cplusplus */
1866

    
1867
#endif /* CS_COMMON_MD5_H_ */
1868
#ifdef MG_MODULE_LINES
1869
#line 1 "common/base64.h"
1870
#endif
1871
/*
1872
 * Copyright (c) 2014 Cesanta Software Limited
1873
 * All rights reserved
1874
 */
1875

    
1876
#ifndef CS_COMMON_BASE64_H_
1877
#define CS_COMMON_BASE64_H_
1878

    
1879
#ifndef DISABLE_BASE64
1880
#define DISABLE_BASE64 0
1881
#endif
1882

    
1883
#if !DISABLE_BASE64
1884

    
1885
#include <stdio.h>
1886

    
1887
#ifdef __cplusplus
1888
extern "C" {
1889
#endif
1890

    
1891
typedef void (*cs_base64_putc_t)(char, void *);
1892

    
1893
struct cs_base64_ctx {
1894
  /* cannot call it putc because it's a macro on some environments */
1895
  cs_base64_putc_t b64_putc;
1896
  unsigned char chunk[3];
1897
  int chunk_size;
1898
  void *user_data;
1899
};
1900

    
1901
void cs_base64_init(struct cs_base64_ctx *ctx, cs_base64_putc_t putc,
1902
                    void *user_data);
1903
void cs_base64_update(struct cs_base64_ctx *ctx, const char *str, size_t len);
1904
void cs_base64_finish(struct cs_base64_ctx *ctx);
1905

    
1906
void cs_base64_encode(const unsigned char *src, int src_len, char *dst);
1907
void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len);
1908
int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len);
1909

    
1910
#ifdef __cplusplus
1911
}
1912
#endif
1913

    
1914
#endif /* DISABLE_BASE64 */
1915

    
1916
#endif /* CS_COMMON_BASE64_H_ */
1917
#ifdef MG_MODULE_LINES
1918
#line 1 "common/str_util.h"
1919
#endif
1920
/*
1921
 * Copyright (c) 2015 Cesanta Software Limited
1922
 * All rights reserved
1923
 */
1924

    
1925
#ifndef CS_COMMON_STR_UTIL_H_
1926
#define CS_COMMON_STR_UTIL_H_
1927

    
1928
#include <stdarg.h>
1929
#include <stdlib.h>
1930

    
1931
/* Amalgamated: #include "common/platform.h" */
1932

    
1933
#ifndef CS_ENABLE_STRDUP
1934
#define CS_ENABLE_STRDUP 0
1935
#endif
1936

    
1937
#ifndef CS_ENABLE_TO64
1938
#define CS_ENABLE_TO64 0
1939
#endif
1940

    
1941
/*
1942
 * Expands to a string representation of its argument: e.g.
1943
 * `CS_STRINGIFY_LIT(5) expands to "5"`
1944
 */
1945
#define CS_STRINGIFY_LIT(x) #x
1946

    
1947
/*
1948
 * Expands to a string representation of its argument, which is allowed
1949
 * to be a macro: e.g.
1950
 *
1951
 * #define FOO 123
1952
 * CS_STRINGIFY_MACRO(FOO)
1953
 *
1954
 * expands to 123.
1955
 */
1956
#define CS_STRINGIFY_MACRO(x) CS_STRINGIFY_LIT(x)
1957

    
1958
#ifdef __cplusplus
1959
extern "C" {
1960
#endif
1961

    
1962
size_t c_strnlen(const char *s, size_t maxlen);
1963
int c_snprintf(char *buf, size_t buf_size, const char *format, ...);
1964
int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap);
1965
/*
1966
 * Find the first occurrence of find in s, where the search is limited to the
1967
 * first slen characters of s.
1968
 */
1969
const char *c_strnstr(const char *s, const char *find, size_t slen);
1970

    
1971
/*
1972
 * Stringify binary data. Output buffer size must be 2 * size_of_input + 1
1973
 * because each byte of input takes 2 bytes in string representation
1974
 * plus 1 byte for the terminating \0 character.
1975
 */
1976
void cs_to_hex(char *to, const unsigned char *p, size_t len);
1977

    
1978
/*
1979
 * Convert stringified binary data back to binary.
1980
 * Does the reverse of `cs_to_hex()`.
1981
 */
1982
void cs_from_hex(char *to, const char *p, size_t len);
1983

    
1984
#if CS_ENABLE_STRDUP
1985
char *strdup(const char *src);
1986
#endif
1987

    
1988
#if CS_ENABLE_TO64
1989
#include <stdint.h>
1990
/*
1991
 * Simple string -> int64 conversion routine.
1992
 */
1993
int64_t cs_to64(const char *s);
1994
#endif
1995

    
1996
/*
1997
 * Cross-platform version of `strncasecmp()`.
1998
 */
1999
int mg_ncasecmp(const char *s1, const char *s2, size_t len);
2000

    
2001
/*
2002
 * Cross-platform version of `strcasecmp()`.
2003
 */
2004
int mg_casecmp(const char *s1, const char *s2);
2005

    
2006
/*
2007
 * Prints message to the buffer. If the buffer is large enough to hold the
2008
 * message, it returns buffer. If buffer is to small, it allocates a large
2009
 * enough buffer on heap and returns allocated buffer.
2010
 * This is a supposed use case:
2011
 *
2012
 *    char buf[5], *p = buf;
2013
 *    mg_avprintf(&p, sizeof(buf), "%s", "hi there");
2014
 *    use_p_somehow(p);
2015
 *    if (p != buf) {
2016
 *      free(p);
2017
 *    }
2018
 *
2019
 * The purpose of this is to avoid malloc-ing if generated strings are small.
2020
 */
2021
int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
2022

    
2023
/* Same as mg_asprintf, but takes varargs list. */
2024
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
2025

    
2026
#ifdef __cplusplus
2027
}
2028
#endif
2029

    
2030
#endif /* CS_COMMON_STR_UTIL_H_ */
2031
#ifdef MG_MODULE_LINES
2032
#line 1 "common/queue.h"
2033
#endif
2034
/* clang-format off */
2035
/*-
2036
 * Copyright (c) 1991, 1993
2037
 *        The Regents of the University of California.  All rights reserved.
2038
 *
2039
 * Redistribution and use in source and binary forms, with or without
2040
 * modification, are permitted provided that the following conditions
2041
 * are met:
2042
 * 1. Redistributions of source code must retain the above copyright
2043
 *    notice, this list of conditions and the following disclaimer.
2044
 * 2. Redistributions in binary form must reproduce the above copyright
2045
 *    notice, this list of conditions and the following disclaimer in the
2046
 *    documentation and/or other materials provided with the distribution.
2047
 * 4. Neither the name of the University nor the names of its contributors
2048
 *    may be used to endorse or promote products derived from this software
2049
 *    without specific prior written permission.
2050
 *
2051
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2052
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2053
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2054
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2055
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2056
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2057
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2058
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2059
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2060
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2061
 * SUCH DAMAGE.
2062
 *
2063
 *        @(#)queue.h        8.5 (Berkeley) 8/20/94
2064
 * $FreeBSD$
2065
 */
2066

    
2067
#ifndef _SYS_QUEUE_H_
2068
#define        _SYS_QUEUE_H_
2069

    
2070
/*
2071
 * This file defines four types of data structures: singly-linked lists,
2072
 * singly-linked tail queues, lists and tail queues.
2073
 *
2074
 * A singly-linked list is headed by a single forward pointer. The elements
2075
 * are singly linked for minimum space and pointer manipulation overhead at
2076
 * the expense of O(n) removal for arbitrary elements. New elements can be
2077
 * added to the list after an existing element or at the head of the list.
2078
 * Elements being removed from the head of the list should use the explicit
2079
 * macro for this purpose for optimum efficiency. A singly-linked list may
2080
 * only be traversed in the forward direction.  Singly-linked lists are ideal
2081
 * for applications with large datasets and few or no removals or for
2082
 * implementing a LIFO queue.
2083
 *
2084
 * A singly-linked tail queue is headed by a pair of pointers, one to the
2085
 * head of the list and the other to the tail of the list. The elements are
2086
 * singly linked for minimum space and pointer manipulation overhead at the
2087
 * expense of O(n) removal for arbitrary elements. New elements can be added
2088
 * to the list after an existing element, at the head of the list, or at the
2089
 * end of the list. Elements being removed from the head of the tail queue
2090
 * should use the explicit macro for this purpose for optimum efficiency.
2091
 * A singly-linked tail queue may only be traversed in the forward direction.
2092
 * Singly-linked tail queues are ideal for applications with large datasets
2093
 * and few or no removals or for implementing a FIFO queue.
2094
 *
2095
 * A list is headed by a single forward pointer (or an array of forward
2096
 * pointers for a hash table header). The elements are doubly linked
2097
 * so that an arbitrary element can be removed without a need to
2098
 * traverse the list. New elements can be added to the list before
2099
 * or after an existing element or at the head of the list. A list
2100
 * may be traversed in either direction.
2101
 *
2102
 * A tail queue is headed by a pair of pointers, one to the head of the
2103
 * list and the other to the tail of the list. The elements are doubly
2104
 * linked so that an arbitrary element can be removed without a need to
2105
 * traverse the list. New elements can be added to the list before or
2106
 * after an existing element, at the head of the list, or at the end of
2107
 * the list. A tail queue may be traversed in either direction.
2108
 *
2109
 * For details on the use of these macros, see the queue(3) manual page.
2110
 *
2111
 *
2112
 *                                SLIST        LIST        STAILQ        TAILQ
2113
 * _HEAD                        +        +        +        +
2114
 * _CLASS_HEAD                        +        +        +        +
2115
 * _HEAD_INITIALIZER                +        +        +        +
2116
 * _ENTRY                        +        +        +        +
2117
 * _CLASS_ENTRY                        +        +        +        +
2118
 * _INIT                        +        +        +        +
2119
 * _EMPTY                        +        +        +        +
2120
 * _FIRST                        +        +        +        +
2121
 * _NEXT                        +        +        +        +
2122
 * _PREV                        -        +        -        +
2123
 * _LAST                        -        -        +        +
2124
 * _FOREACH                        +        +        +        +
2125
 * _FOREACH_FROM                +        +        +        +
2126
 * _FOREACH_SAFE                +        +        +        +
2127
 * _FOREACH_FROM_SAFE                +        +        +        +
2128
 * _FOREACH_REVERSE                -        -        -        +
2129
 * _FOREACH_REVERSE_FROM        -        -        -        +
2130
 * _FOREACH_REVERSE_SAFE        -        -        -        +
2131
 * _FOREACH_REVERSE_FROM_SAFE        -        -        -        +
2132
 * _INSERT_HEAD                        +        +        +        +
2133
 * _INSERT_BEFORE                -        +        -        +
2134
 * _INSERT_AFTER                +        +        +        +
2135
 * _INSERT_TAIL                        -        -        +        +
2136
 * _CONCAT                        -        -        +        +
2137
 * _REMOVE_AFTER                +        -        +        -
2138
 * _REMOVE_HEAD                        +        -        +        -
2139
 * _REMOVE                        +        +        +        +
2140
 * _SWAP                        +        +        +        +
2141
 *
2142
 */
2143
#ifdef QUEUE_MACRO_DEBUG
2144
/* Store the last 2 places the queue element or head was altered */
2145
struct qm_trace {
2146
        unsigned long         lastline;
2147
        unsigned long         prevline;
2148
        const char        *lastfile;
2149
        const char        *prevfile;
2150
};
2151

    
2152
#define        TRACEBUF        struct qm_trace trace;
2153
#define        TRACEBUF_INITIALIZER        { __LINE__, 0, __FILE__, NULL } ,
2154
#define        TRASHIT(x)        do {(x) = (void *)-1;} while (0)
2155
#define        QMD_SAVELINK(name, link)        void **name = (void *)&(link)
2156

    
2157
#define        QMD_TRACE_HEAD(head) do {                                        \
2158
        (head)->trace.prevline = (head)->trace.lastline;                \
2159
        (head)->trace.prevfile = (head)->trace.lastfile;                \
2160
        (head)->trace.lastline = __LINE__;                                \
2161
        (head)->trace.lastfile = __FILE__;                                \
2162
} while (0)
2163

    
2164
#define        QMD_TRACE_ELEM(elem) do {                                        \
2165
        (elem)->trace.prevline = (elem)->trace.lastline;                \
2166
        (elem)->trace.prevfile = (elem)->trace.lastfile;                \
2167
        (elem)->trace.lastline = __LINE__;                                \
2168
        (elem)->trace.lastfile = __FILE__;                                \
2169
} while (0)
2170

    
2171
#else
2172
#define        QMD_TRACE_ELEM(elem)
2173
#define        QMD_TRACE_HEAD(head)
2174
#define        QMD_SAVELINK(name, link)
2175
#define        TRACEBUF
2176
#define        TRACEBUF_INITIALIZER
2177
#define        TRASHIT(x)
2178
#endif        /* QUEUE_MACRO_DEBUG */
2179

    
2180
#ifdef __cplusplus
2181
/*
2182
 * In C++ there can be structure lists and class lists:
2183
 */
2184
#define        QUEUE_TYPEOF(type) type
2185
#else
2186
#define        QUEUE_TYPEOF(type) struct type
2187
#endif
2188

    
2189
/*
2190
 * Singly-linked List declarations.
2191
 */
2192
#define        SLIST_HEAD(name, type)                                                \
2193
struct name {                                                                \
2194
        struct type *slh_first;        /* first element */                        \
2195
}
2196

    
2197
#define        SLIST_CLASS_HEAD(name, type)                                        \
2198
struct name {                                                                \
2199
        class type *slh_first;        /* first element */                        \
2200
}
2201

    
2202
#define        SLIST_HEAD_INITIALIZER(head)                                        \
2203
        { NULL }
2204

    
2205
#define        SLIST_ENTRY(type)                                                \
2206
struct {                                                                \
2207
        struct type *sle_next;        /* next element */                        \
2208
}
2209

    
2210
#define        SLIST_CLASS_ENTRY(type)                                                \
2211
struct {                                                                \
2212
        class type *sle_next;                /* next element */                \
2213
}
2214

    
2215
/*
2216
 * Singly-linked List functions.
2217
 */
2218
#define        SLIST_EMPTY(head)        ((head)->slh_first == NULL)
2219

    
2220
#define        SLIST_FIRST(head)        ((head)->slh_first)
2221

    
2222
#define        SLIST_FOREACH(var, head, field)                                        \
2223
        for ((var) = SLIST_FIRST((head));                                \
2224
            (var);                                                        \
2225
            (var) = SLIST_NEXT((var), field))
2226

    
2227
#define        SLIST_FOREACH_FROM(var, head, field)                                \
2228
        for ((var) = ((var) ? (var) : SLIST_FIRST((head)));                \
2229
            (var);                                                        \
2230
            (var) = SLIST_NEXT((var), field))
2231

    
2232
#define        SLIST_FOREACH_SAFE(var, head, field, tvar)                        \
2233
        for ((var) = SLIST_FIRST((head));                                \
2234
            (var) && ((tvar) = SLIST_NEXT((var), field), 1);                \
2235
            (var) = (tvar))
2236

    
2237
#define        SLIST_FOREACH_FROM_SAFE(var, head, field, tvar)                        \
2238
        for ((var) = ((var) ? (var) : SLIST_FIRST((head)));                \
2239
            (var) && ((tvar) = SLIST_NEXT((var), field), 1);                \
2240
            (var) = (tvar))
2241

    
2242
#define        SLIST_FOREACH_PREVPTR(var, varp, head, field)                        \
2243
        for ((varp) = &SLIST_FIRST((head));                                \
2244
            ((var) = *(varp)) != NULL;                                        \
2245
            (varp) = &SLIST_NEXT((var), field))
2246

    
2247
#define        SLIST_INIT(head) do {                                                \
2248
        SLIST_FIRST((head)) = NULL;                                        \
2249
} while (0)
2250

    
2251
#define        SLIST_INSERT_AFTER(slistelm, elm, field) do {                        \
2252
        SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);        \
2253
        SLIST_NEXT((slistelm), field) = (elm);                                \
2254
} while (0)
2255

    
2256
#define        SLIST_INSERT_HEAD(head, elm, field) do {                        \
2257
        SLIST_NEXT((elm), field) = SLIST_FIRST((head));                        \
2258
        SLIST_FIRST((head)) = (elm);                                        \
2259
} while (0)
2260

    
2261
#define        SLIST_NEXT(elm, field)        ((elm)->field.sle_next)
2262

    
2263
#define        SLIST_REMOVE(head, elm, type, field) do {                        \
2264
        QMD_SAVELINK(oldnext, (elm)->field.sle_next);                        \
2265
        if (SLIST_FIRST((head)) == (elm)) {                                \
2266
                SLIST_REMOVE_HEAD((head), field);                        \
2267
        }                                                                \
2268
        else {                                                                \
2269
                QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head);                \
2270
                while (SLIST_NEXT(curelm, field) != (elm))                \
2271
                        curelm = SLIST_NEXT(curelm, field);                \
2272
                SLIST_REMOVE_AFTER(curelm, field);                        \
2273
        }                                                                \
2274
        TRASHIT(*oldnext);                                                \
2275
} while (0)
2276

    
2277
#define SLIST_REMOVE_AFTER(elm, field) do {                                \
2278
        SLIST_NEXT(elm, field) =                                        \
2279
            SLIST_NEXT(SLIST_NEXT(elm, field), field);                        \
2280
} while (0)
2281

    
2282
#define        SLIST_REMOVE_HEAD(head, field) do {                                \
2283
        SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);        \
2284
} while (0)
2285

    
2286
#define SLIST_SWAP(head1, head2, type) do {                                \
2287
        QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1);                \
2288
        SLIST_FIRST(head1) = SLIST_FIRST(head2);                        \
2289
        SLIST_FIRST(head2) = swap_first;                                \
2290
} while (0)
2291

    
2292
/*
2293
 * Singly-linked Tail queue declarations.
2294
 */
2295
#define        STAILQ_HEAD(name, type)                                                \
2296
struct name {                                                                \
2297
        struct type *stqh_first;/* first element */                        \
2298
        struct type **stqh_last;/* addr of last next element */                \
2299
}
2300

    
2301
#define        STAILQ_CLASS_HEAD(name, type)                                        \
2302
struct name {                                                                \
2303
        class type *stqh_first;        /* first element */                        \
2304
        class type **stqh_last;        /* addr of last next element */                \
2305
}
2306

    
2307
#define        STAILQ_HEAD_INITIALIZER(head)                                        \
2308
        { NULL, &(head).stqh_first }
2309

    
2310
#define        STAILQ_ENTRY(type)                                                \
2311
struct {                                                                \
2312
        struct type *stqe_next;        /* next element */                        \
2313
}
2314

    
2315
#define        STAILQ_CLASS_ENTRY(type)                                        \
2316
struct {                                                                \
2317
        class type *stqe_next;        /* next element */                        \
2318
}
2319

    
2320
/*
2321
 * Singly-linked Tail queue functions.
2322
 */
2323
#define        STAILQ_CONCAT(head1, head2) do {                                \
2324
        if (!STAILQ_EMPTY((head2))) {                                        \
2325
                *(head1)->stqh_last = (head2)->stqh_first;                \
2326
                (head1)->stqh_last = (head2)->stqh_last;                \
2327
                STAILQ_INIT((head2));                                        \
2328
        }                                                                \
2329
} while (0)
2330

    
2331
#define        STAILQ_EMPTY(head)        ((head)->stqh_first == NULL)
2332

    
2333
#define        STAILQ_FIRST(head)        ((head)->stqh_first)
2334

    
2335
#define        STAILQ_FOREACH(var, head, field)                                \
2336
        for((var) = STAILQ_FIRST((head));                                \
2337
           (var);                                                        \
2338
           (var) = STAILQ_NEXT((var), field))
2339

    
2340
#define        STAILQ_FOREACH_FROM(var, head, field)                                \
2341
        for ((var) = ((var) ? (var) : STAILQ_FIRST((head)));                \
2342
           (var);                                                        \
2343
           (var) = STAILQ_NEXT((var), field))
2344

    
2345
#define        STAILQ_FOREACH_SAFE(var, head, field, tvar)                        \
2346
        for ((var) = STAILQ_FIRST((head));                                \
2347
            (var) && ((tvar) = STAILQ_NEXT((var), field), 1);                \
2348
            (var) = (tvar))
2349

    
2350
#define        STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)                \
2351
        for ((var) = ((var) ? (var) : STAILQ_FIRST((head)));                \
2352
            (var) && ((tvar) = STAILQ_NEXT((var), field), 1);                \
2353
            (var) = (tvar))
2354

    
2355
#define        STAILQ_INIT(head) do {                                                \
2356
        STAILQ_FIRST((head)) = NULL;                                        \
2357
        (head)->stqh_last = &STAILQ_FIRST((head));                        \
2358
} while (0)
2359

    
2360
#define        STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {                \
2361
        if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
2362
                (head)->stqh_last = &STAILQ_NEXT((elm), field);                \
2363
        STAILQ_NEXT((tqelm), field) = (elm);                                \
2364
} while (0)
2365

    
2366
#define        STAILQ_INSERT_HEAD(head, elm, field) do {                        \
2367
        if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)        \
2368
                (head)->stqh_last = &STAILQ_NEXT((elm), field);                \
2369
        STAILQ_FIRST((head)) = (elm);                                        \
2370
} while (0)
2371

    
2372
#define        STAILQ_INSERT_TAIL(head, elm, field) do {                        \
2373
        STAILQ_NEXT((elm), field) = NULL;                                \
2374
        *(head)->stqh_last = (elm);                                        \
2375
        (head)->stqh_last = &STAILQ_NEXT((elm), field);                        \
2376
} while (0)
2377

    
2378
#define        STAILQ_LAST(head, type, field)                                \
2379
        (STAILQ_EMPTY((head)) ? NULL :                                \
2380
            __containerof((head)->stqh_last,                        \
2381
            QUEUE_TYPEOF(type), field.stqe_next))
2382

    
2383
#define        STAILQ_NEXT(elm, field)        ((elm)->field.stqe_next)
2384

    
2385
#define        STAILQ_REMOVE(head, elm, type, field) do {                        \
2386
        QMD_SAVELINK(oldnext, (elm)->field.stqe_next);                        \
2387
        if (STAILQ_FIRST((head)) == (elm)) {                                \
2388
                STAILQ_REMOVE_HEAD((head), field);                        \
2389
        }                                                                \
2390
        else {                                                                \
2391
                QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head);        \
2392
                while (STAILQ_NEXT(curelm, field) != (elm))                \
2393
                        curelm = STAILQ_NEXT(curelm, field);                \
2394
                STAILQ_REMOVE_AFTER(head, curelm, field);                \
2395
        }                                                                \
2396
        TRASHIT(*oldnext);                                                \
2397
} while (0)
2398

    
2399
#define STAILQ_REMOVE_AFTER(head, elm, field) do {                        \
2400
        if ((STAILQ_NEXT(elm, field) =                                        \
2401
             STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)        \
2402
                (head)->stqh_last = &STAILQ_NEXT((elm), field);                \
2403
} while (0)
2404

    
2405
#define        STAILQ_REMOVE_HEAD(head, field) do {                                \
2406
        if ((STAILQ_FIRST((head)) =                                        \
2407
             STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)                \
2408
                (head)->stqh_last = &STAILQ_FIRST((head));                \
2409
} while (0)
2410

    
2411
#define STAILQ_SWAP(head1, head2, type) do {                                \
2412
        QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1);                \
2413
        QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last;                \
2414
        STAILQ_FIRST(head1) = STAILQ_FIRST(head2);                        \
2415
        (head1)->stqh_last = (head2)->stqh_last;                        \
2416
        STAILQ_FIRST(head2) = swap_first;                                \
2417
        (head2)->stqh_last = swap_last;                                        \
2418
        if (STAILQ_EMPTY(head1))                                        \
2419
                (head1)->stqh_last = &STAILQ_FIRST(head1);                \
2420
        if (STAILQ_EMPTY(head2))                                        \
2421
                (head2)->stqh_last = &STAILQ_FIRST(head2);                \
2422
} while (0)
2423

    
2424

    
2425
/*
2426
 * List declarations.
2427
 */
2428
#define        LIST_HEAD(name, type)                                                \
2429
struct name {                                                                \
2430
        struct type *lh_first;        /* first element */                        \
2431
}
2432

    
2433
#define        LIST_CLASS_HEAD(name, type)                                        \
2434
struct name {                                                                \
2435
        class type *lh_first;        /* first element */                        \
2436
}
2437

    
2438
#define        LIST_HEAD_INITIALIZER(head)                                        \
2439
        { NULL }
2440

    
2441
#define        LIST_ENTRY(type)                                                \
2442
struct {                                                                \
2443
        struct type *le_next;        /* next element */                        \
2444
        struct type **le_prev;        /* address of previous next element */        \
2445
}
2446

    
2447
#define        LIST_CLASS_ENTRY(type)                                                \
2448
struct {                                                                \
2449
        class type *le_next;        /* next element */                        \
2450
        class type **le_prev;        /* address of previous next element */        \
2451
}
2452

    
2453
/*
2454
 * List functions.
2455
 */
2456

    
2457
#if (defined(_KERNEL) && defined(INVARIANTS))
2458
#define        QMD_LIST_CHECK_HEAD(head, field) do {                                \
2459
        if (LIST_FIRST((head)) != NULL &&                                \
2460
            LIST_FIRST((head))->field.le_prev !=                        \
2461
             &LIST_FIRST((head)))                                        \
2462
                panic("Bad list head %p first->prev != head", (head));        \
2463
} while (0)
2464

    
2465
#define        QMD_LIST_CHECK_NEXT(elm, field) do {                                \
2466
        if (LIST_NEXT((elm), field) != NULL &&                                \
2467
            LIST_NEXT((elm), field)->field.le_prev !=                        \
2468
             &((elm)->field.le_next))                                        \
2469
                     panic("Bad link elm %p next->prev != elm", (elm));        \
2470
} while (0)
2471

    
2472
#define        QMD_LIST_CHECK_PREV(elm, field) do {                                \
2473
        if (*(elm)->field.le_prev != (elm))                                \
2474
                panic("Bad link elm %p prev->next != elm", (elm));        \
2475
} while (0)
2476
#else
2477
#define        QMD_LIST_CHECK_HEAD(head, field)
2478
#define        QMD_LIST_CHECK_NEXT(elm, field)
2479
#define        QMD_LIST_CHECK_PREV(elm, field)
2480
#endif /* (_KERNEL && INVARIANTS) */
2481

    
2482
#define        LIST_EMPTY(head)        ((head)->lh_first == NULL)
2483

    
2484
#define        LIST_FIRST(head)        ((head)->lh_first)
2485

    
2486
#define        LIST_FOREACH(var, head, field)                                        \
2487
        for ((var) = LIST_FIRST((head));                                \
2488
            (var);                                                        \
2489
            (var) = LIST_NEXT((var), field))
2490

    
2491
#define        LIST_FOREACH_FROM(var, head, field)                                \
2492
        for ((var) = ((var) ? (var) : LIST_FIRST((head)));                \
2493
            (var);                                                        \
2494
            (var) = LIST_NEXT((var), field))
2495

    
2496
#define        LIST_FOREACH_SAFE(var, head, field, tvar)                        \
2497
        for ((var) = LIST_FIRST((head));                                \
2498
            (var) && ((tvar) = LIST_NEXT((var), field), 1);                \
2499
            (var) = (tvar))
2500

    
2501
#define        LIST_FOREACH_FROM_SAFE(var, head, field, tvar)                        \
2502
        for ((var) = ((var) ? (var) : LIST_FIRST((head)));                \
2503
            (var) && ((tvar) = LIST_NEXT((var), field), 1);                \
2504
            (var) = (tvar))
2505

    
2506
#define        LIST_INIT(head) do {                                                \
2507
        LIST_FIRST((head)) = NULL;                                        \
2508
} while (0)
2509

    
2510
#define        LIST_INSERT_AFTER(listelm, elm, field) do {                        \
2511
        QMD_LIST_CHECK_NEXT(listelm, field);                                \
2512
        if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
2513
                LIST_NEXT((listelm), field)->field.le_prev =                \
2514
                    &LIST_NEXT((elm), field);                                \
2515
        LIST_NEXT((listelm), field) = (elm);                                \
2516
        (elm)->field.le_prev = &LIST_NEXT((listelm), field);                \
2517
} while (0)
2518

    
2519
#define        LIST_INSERT_BEFORE(listelm, elm, field) do {                        \
2520
        QMD_LIST_CHECK_PREV(listelm, field);                                \
2521
        (elm)->field.le_prev = (listelm)->field.le_prev;                \
2522
        LIST_NEXT((elm), field) = (listelm);                                \
2523
        *(listelm)->field.le_prev = (elm);                                \
2524
        (listelm)->field.le_prev = &LIST_NEXT((elm), field);                \
2525
} while (0)
2526

    
2527
#define        LIST_INSERT_HEAD(head, elm, field) do {                                \
2528
        QMD_LIST_CHECK_HEAD((head), field);                                \
2529
        if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)        \
2530
                LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
2531
        LIST_FIRST((head)) = (elm);                                        \
2532
        (elm)->field.le_prev = &LIST_FIRST((head));                        \
2533
} while (0)
2534

    
2535
#define        LIST_NEXT(elm, field)        ((elm)->field.le_next)
2536

    
2537
#define        LIST_PREV(elm, head, type, field)                        \
2538
        ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL :        \
2539
            __containerof((elm)->field.le_prev,                        \
2540
            QUEUE_TYPEOF(type), field.le_next))
2541

    
2542
#define        LIST_REMOVE(elm, field) do {                                        \
2543
        QMD_SAVELINK(oldnext, (elm)->field.le_next);                        \
2544
        QMD_SAVELINK(oldprev, (elm)->field.le_prev);                        \
2545
        QMD_LIST_CHECK_NEXT(elm, field);                                \
2546
        QMD_LIST_CHECK_PREV(elm, field);                                \
2547
        if (LIST_NEXT((elm), field) != NULL)                                \
2548
                LIST_NEXT((elm), field)->field.le_prev =                 \
2549
                    (elm)->field.le_prev;                                \
2550
        *(elm)->field.le_prev = LIST_NEXT((elm), field);                \
2551
        TRASHIT(*oldnext);                                                \
2552
        TRASHIT(*oldprev);                                                \
2553
} while (0)
2554

    
2555
#define LIST_SWAP(head1, head2, type, field) do {                        \
2556
        QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1);                \
2557
        LIST_FIRST((head1)) = LIST_FIRST((head2));                        \
2558
        LIST_FIRST((head2)) = swap_tmp;                                        \
2559
        if ((swap_tmp = LIST_FIRST((head1))) != NULL)                        \
2560
                swap_tmp->field.le_prev = &LIST_FIRST((head1));                \
2561
        if ((swap_tmp = LIST_FIRST((head2))) != NULL)                        \
2562
                swap_tmp->field.le_prev = &LIST_FIRST((head2));                \
2563
} while (0)
2564

    
2565
/*
2566
 * Tail queue declarations.
2567
 */
2568
#define        TAILQ_HEAD(name, type)                                                \
2569
struct name {                                                                \
2570
        struct type *tqh_first;        /* first element */                        \
2571
        struct type **tqh_last;        /* addr of last next element */                \
2572
        TRACEBUF                                                        \
2573
}
2574

    
2575
#define        TAILQ_CLASS_HEAD(name, type)                                        \
2576
struct name {                                                                \
2577
        class type *tqh_first;        /* first element */                        \
2578
        class type **tqh_last;        /* addr of last next element */                \
2579
        TRACEBUF                                                        \
2580
}
2581

    
2582
#define        TAILQ_HEAD_INITIALIZER(head)                                        \
2583
        { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
2584

    
2585
#define        TAILQ_ENTRY(type)                                                \
2586
struct {                                                                \
2587
        struct type *tqe_next;        /* next element */                        \
2588
        struct type **tqe_prev;        /* address of previous next element */        \
2589
        TRACEBUF                                                        \
2590
}
2591

    
2592
#define        TAILQ_CLASS_ENTRY(type)                                                \
2593
struct {                                                                \
2594
        class type *tqe_next;        /* next element */                        \
2595
        class type **tqe_prev;        /* address of previous next element */        \
2596
        TRACEBUF                                                        \
2597
}
2598

    
2599
/*
2600
 * Tail queue functions.
2601
 */
2602
#if (defined(_KERNEL) && defined(INVARIANTS))
2603
#define        QMD_TAILQ_CHECK_HEAD(head, field) do {                                \
2604
        if (!TAILQ_EMPTY(head) &&                                        \
2605
            TAILQ_FIRST((head))->field.tqe_prev !=                        \
2606
             &TAILQ_FIRST((head)))                                        \
2607
                panic("Bad tailq head %p first->prev != head", (head));        \
2608
} while (0)
2609

    
2610
#define        QMD_TAILQ_CHECK_TAIL(head, field) do {                                \
2611
        if (*(head)->tqh_last != NULL)                                        \
2612
                    panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head));         \
2613
} while (0)
2614

    
2615
#define        QMD_TAILQ_CHECK_NEXT(elm, field) do {                                \
2616
        if (TAILQ_NEXT((elm), field) != NULL &&                                \
2617
            TAILQ_NEXT((elm), field)->field.tqe_prev !=                        \
2618
             &((elm)->field.tqe_next))                                        \
2619
                panic("Bad link elm %p next->prev != elm", (elm));        \
2620
} while (0)
2621

    
2622
#define        QMD_TAILQ_CHECK_PREV(elm, field) do {                                \
2623
        if (*(elm)->field.tqe_prev != (elm))                                \
2624
                panic("Bad link elm %p prev->next != elm", (elm));        \
2625
} while (0)
2626
#else
2627
#define        QMD_TAILQ_CHECK_HEAD(head, field)
2628
#define        QMD_TAILQ_CHECK_TAIL(head, headname)
2629
#define        QMD_TAILQ_CHECK_NEXT(elm, field)
2630
#define        QMD_TAILQ_CHECK_PREV(elm, field)
2631
#endif /* (_KERNEL && INVARIANTS) */
2632

    
2633
#define        TAILQ_CONCAT(head1, head2, field) do {                                \
2634
        if (!TAILQ_EMPTY(head2)) {                                        \
2635
                *(head1)->tqh_last = (head2)->tqh_first;                \
2636
                (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;        \
2637
                (head1)->tqh_last = (head2)->tqh_last;                        \
2638
                TAILQ_INIT((head2));                                        \
2639
                QMD_TRACE_HEAD(head1);                                        \
2640
                QMD_TRACE_HEAD(head2);                                        \
2641
        }                                                                \
2642
} while (0)
2643

    
2644
#define        TAILQ_EMPTY(head)        ((head)->tqh_first == NULL)
2645

    
2646
#define        TAILQ_FIRST(head)        ((head)->tqh_first)
2647

    
2648
#define        TAILQ_FOREACH(var, head, field)                                        \
2649
        for ((var) = TAILQ_FIRST((head));                                \
2650
            (var);                                                        \
2651
            (var) = TAILQ_NEXT((var), field))
2652

    
2653
#define        TAILQ_FOREACH_FROM(var, head, field)                                \
2654
        for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));                \
2655
            (var);                                                        \
2656
            (var) = TAILQ_NEXT((var), field))
2657

    
2658
#define        TAILQ_FOREACH_SAFE(var, head, field, tvar)                        \
2659
        for ((var) = TAILQ_FIRST((head));                                \
2660
            (var) && ((tvar) = TAILQ_NEXT((var), field), 1);                \
2661
            (var) = (tvar))
2662

    
2663
#define        TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)                        \
2664
        for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));                \
2665
            (var) && ((tvar) = TAILQ_NEXT((var), field), 1);                \
2666
            (var) = (tvar))
2667

    
2668
#define        TAILQ_FOREACH_REVERSE(var, head, headname, field)                \
2669
        for ((var) = TAILQ_LAST((head), headname);                        \
2670
            (var);                                                        \
2671
            (var) = TAILQ_PREV((var), headname, field))
2672

    
2673
#define        TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field)                \
2674
        for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));        \
2675
            (var);                                                        \
2676
            (var) = TAILQ_PREV((var), headname, field))
2677

    
2678
#define        TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)        \
2679
        for ((var) = TAILQ_LAST((head), headname);                        \
2680
            (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);        \
2681
            (var) = (tvar))
2682

    
2683
#define        TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
2684
        for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));        \
2685
            (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);        \
2686
            (var) = (tvar))
2687

    
2688
#define        TAILQ_INIT(head) do {                                                \
2689
        TAILQ_FIRST((head)) = NULL;                                        \
2690
        (head)->tqh_last = &TAILQ_FIRST((head));                        \
2691
        QMD_TRACE_HEAD(head);                                                \
2692
} while (0)
2693

    
2694
#define        TAILQ_INSERT_AFTER(head, listelm, elm, field) do {                \
2695
        QMD_TAILQ_CHECK_NEXT(listelm, field);                                \
2696
        if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
2697
                TAILQ_NEXT((elm), field)->field.tqe_prev =                 \
2698
                    &TAILQ_NEXT((elm), field);                                \
2699
        else {                                                                \
2700
                (head)->tqh_last = &TAILQ_NEXT((elm), field);                \
2701
                QMD_TRACE_HEAD(head);                                        \
2702
        }                                                                \
2703
        TAILQ_NEXT((listelm), field) = (elm);                                \
2704
        (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);                \
2705
        QMD_TRACE_ELEM(&(elm)->field);                                        \
2706
        QMD_TRACE_ELEM(&(listelm)->field);                                \
2707
} while (0)
2708

    
2709
#define        TAILQ_INSERT_BEFORE(listelm, elm, field) do {                        \
2710
        QMD_TAILQ_CHECK_PREV(listelm, field);                                \
2711
        (elm)->field.tqe_prev = (listelm)->field.tqe_prev;                \
2712
        TAILQ_NEXT((elm), field) = (listelm);                                \
2713
        *(listelm)->field.tqe_prev = (elm);                                \
2714
        (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);                \
2715
        QMD_TRACE_ELEM(&(elm)->field);                                        \
2716
        QMD_TRACE_ELEM(&(listelm)->field);                                \
2717
} while (0)
2718

    
2719
#define        TAILQ_INSERT_HEAD(head, elm, field) do {                        \
2720
        QMD_TAILQ_CHECK_HEAD(head, field);                                \
2721
        if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)        \
2722
                TAILQ_FIRST((head))->field.tqe_prev =                        \
2723
                    &TAILQ_NEXT((elm), field);                                \
2724
        else                                                                \
2725
                (head)->tqh_last = &TAILQ_NEXT((elm), field);                \
2726
        TAILQ_FIRST((head)) = (elm);                                        \
2727
        (elm)->field.tqe_prev = &TAILQ_FIRST((head));                        \
2728
        QMD_TRACE_HEAD(head);                                                \
2729
        QMD_TRACE_ELEM(&(elm)->field);                                        \
2730
} while (0)
2731

    
2732
#define        TAILQ_INSERT_TAIL(head, elm, field) do {                        \
2733
        QMD_TAILQ_CHECK_TAIL(head, field);                                \
2734
        TAILQ_NEXT((elm), field) = NULL;                                \
2735
        (elm)->field.tqe_prev = (head)->tqh_last;                        \
2736
        *(head)->tqh_last = (elm);                                        \
2737
        (head)->tqh_last = &TAILQ_NEXT((elm), field);                        \
2738
        QMD_TRACE_HEAD(head);                                                \
2739
        QMD_TRACE_ELEM(&(elm)->field);                                        \
2740
} while (0)
2741

    
2742
#define        TAILQ_LAST(head, headname)                                        \
2743
        (*(((struct headname *)((head)->tqh_last))->tqh_last))
2744

    
2745
#define        TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
2746

    
2747
#define        TAILQ_PREV(elm, headname, field)                                \
2748
        (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
2749

    
2750
#define        TAILQ_REMOVE(head, elm, field) do {                                \
2751
        QMD_SAVELINK(oldnext, (elm)->field.tqe_next);                        \
2752
        QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);                        \
2753
        QMD_TAILQ_CHECK_NEXT(elm, field);                                \
2754
        QMD_TAILQ_CHECK_PREV(elm, field);                                \
2755
        if ((TAILQ_NEXT((elm), field)) != NULL)                                \
2756
                TAILQ_NEXT((elm), field)->field.tqe_prev =                 \
2757
                    (elm)->field.tqe_prev;                                \
2758
        else {                                                                \
2759
                (head)->tqh_last = (elm)->field.tqe_prev;                \
2760
                QMD_TRACE_HEAD(head);                                        \
2761
        }                                                                \
2762
        *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);                \
2763
        TRASHIT(*oldnext);                                                \
2764
        TRASHIT(*oldprev);                                                \
2765
        QMD_TRACE_ELEM(&(elm)->field);                                        \
2766
} while (0)
2767

    
2768
#define TAILQ_SWAP(head1, head2, type, field) do {                        \
2769
        QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first;                \
2770
        QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last;                \
2771
        (head1)->tqh_first = (head2)->tqh_first;                        \
2772
        (head1)->tqh_last = (head2)->tqh_last;                                \
2773
        (head2)->tqh_first = swap_first;                                \
2774
        (head2)->tqh_last = swap_last;                                        \
2775
        if ((swap_first = (head1)->tqh_first) != NULL)                        \
2776
                swap_first->field.tqe_prev = &(head1)->tqh_first;        \
2777
        else                                                                \
2778
                (head1)->tqh_last = &(head1)->tqh_first;                \
2779
        if ((swap_first = (head2)->tqh_first) != NULL)                        \
2780
                swap_first->field.tqe_prev = &(head2)->tqh_first;        \
2781
        else                                                                \
2782
                (head2)->tqh_last = &(head2)->tqh_first;                \
2783
} while (0)
2784

    
2785
#endif /* !_SYS_QUEUE_H_ */
2786
#ifdef MG_MODULE_LINES
2787
#line 1 "mongoose/src/features.h"
2788
#endif
2789
/*
2790
 * Copyright (c) 2014-2016 Cesanta Software Limited
2791
 * All rights reserved
2792
 */
2793

    
2794
#ifndef CS_MONGOOSE_SRC_FEATURES_H_
2795
#define CS_MONGOOSE_SRC_FEATURES_H_
2796

    
2797
#ifndef MG_DISABLE_HTTP_DIGEST_AUTH
2798
#define MG_DISABLE_HTTP_DIGEST_AUTH 0
2799
#endif
2800

    
2801
#ifndef MG_DISABLE_HTTP_KEEP_ALIVE
2802
#define MG_DISABLE_HTTP_KEEP_ALIVE 0
2803
#endif
2804

    
2805
#ifndef MG_DISABLE_PFS
2806
#define MG_DISABLE_PFS 0
2807
#endif
2808

    
2809
#ifndef MG_DISABLE_WS_RANDOM_MASK
2810
#define MG_DISABLE_WS_RANDOM_MASK 0
2811
#endif
2812

    
2813
#ifndef MG_ENABLE_ASYNC_RESOLVER
2814
#define MG_ENABLE_ASYNC_RESOLVER 1
2815
#endif
2816

    
2817
#ifndef MG_ENABLE_BROADCAST
2818
#define MG_ENABLE_BROADCAST 0
2819
#endif
2820

    
2821
#ifndef MG_ENABLE_COAP
2822
#define MG_ENABLE_COAP 0
2823
#endif
2824

    
2825
#ifndef MG_ENABLE_DEBUG
2826
#define MG_ENABLE_DEBUG 0
2827
#endif
2828

    
2829
#ifndef MG_ENABLE_DIRECTORY_LISTING
2830
#define MG_ENABLE_DIRECTORY_LISTING 0
2831
#endif
2832

    
2833
#ifndef MG_ENABLE_DNS
2834
#define MG_ENABLE_DNS 1
2835
#endif
2836

    
2837
#ifndef MG_ENABLE_DNS_SERVER
2838
#define MG_ENABLE_DNS_SERVER 0
2839
#endif
2840

    
2841
#ifndef MG_ENABLE_FAKE_DAVLOCK
2842
#define MG_ENABLE_FAKE_DAVLOCK 0
2843
#endif
2844

    
2845
#ifndef MG_ENABLE_FILESYSTEM
2846
#define MG_ENABLE_FILESYSTEM 0
2847
#endif
2848

    
2849
#ifndef MG_ENABLE_GETADDRINFO
2850
#define MG_ENABLE_GETADDRINFO 0
2851
#endif
2852

    
2853
#ifndef MG_ENABLE_HEXDUMP
2854
#define MG_ENABLE_HEXDUMP CS_ENABLE_STDIO
2855
#endif
2856

    
2857
#ifndef MG_ENABLE_HTTP
2858
#define MG_ENABLE_HTTP 1
2859
#endif
2860

    
2861
#ifndef MG_ENABLE_HTTP_CGI
2862
#define MG_ENABLE_HTTP_CGI 0
2863
#endif
2864

    
2865
#ifndef MG_ENABLE_HTTP_SSI
2866
#define MG_ENABLE_HTTP_SSI MG_ENABLE_FILESYSTEM
2867
#endif
2868

    
2869
#ifndef MG_ENABLE_HTTP_SSI_EXEC
2870
#define MG_ENABLE_HTTP_SSI_EXEC 0
2871
#endif
2872

    
2873
#ifndef MG_ENABLE_HTTP_STREAMING_MULTIPART
2874
#define MG_ENABLE_HTTP_STREAMING_MULTIPART 0
2875
#endif
2876

    
2877
#ifndef MG_ENABLE_HTTP_WEBDAV
2878
#define MG_ENABLE_HTTP_WEBDAV 0
2879
#endif
2880

    
2881
#ifndef MG_ENABLE_HTTP_WEBSOCKET
2882
#define MG_ENABLE_HTTP_WEBSOCKET MG_ENABLE_HTTP
2883
#endif
2884

    
2885
#ifndef MG_ENABLE_IPV6
2886
#define MG_ENABLE_IPV6 0
2887
#endif
2888

    
2889
#ifndef MG_ENABLE_JAVASCRIPT
2890
#define MG_ENABLE_JAVASCRIPT 0
2891
#endif
2892

    
2893
#ifndef MG_ENABLE_MQTT
2894
#define MG_ENABLE_MQTT 1
2895
#endif
2896

    
2897
#ifndef MG_ENABLE_MQTT_BROKER
2898
#define MG_ENABLE_MQTT_BROKER 0
2899
#endif
2900

    
2901
#ifndef MG_ENABLE_SSL
2902
#define MG_ENABLE_SSL 0
2903
#endif
2904

    
2905
#ifndef MG_ENABLE_SYNC_RESOLVER
2906
#define MG_ENABLE_SYNC_RESOLVER 0
2907
#endif
2908

    
2909
#ifndef MG_ENABLE_STDIO
2910
#define MG_ENABLE_STDIO CS_ENABLE_STDIO
2911
#endif
2912

    
2913
#ifndef MG_NET_IF
2914
#define MG_NET_IF MG_NET_IF_SOCKET
2915
#endif
2916

    
2917
#ifndef MG_SSL_IF
2918
#define MG_SSL_IF MG_SSL_IF_OPENSSL
2919
#endif
2920

    
2921
#ifndef MG_ENABLE_THREADS /* ifdef-ok */
2922
#ifdef _WIN32
2923
#define MG_ENABLE_THREADS 1
2924
#else
2925
#define MG_ENABLE_THREADS 0
2926
#endif
2927
#endif
2928

    
2929
#if MG_ENABLE_DEBUG && !defined(CS_ENABLE_DEBUG)
2930
#define CS_ENABLE_DEBUG 1
2931
#endif
2932

    
2933
/* MQTT broker requires MQTT */
2934
#if MG_ENABLE_MQTT_BROKER && !MG_ENABLE_MQTT
2935
#undef MG_ENABLE_MQTT
2936
#define MG_ENABLE_MQTT 1
2937
#endif
2938

    
2939
#ifndef MG_ENABLE_HTTP_URL_REWRITES
2940
#define MG_ENABLE_HTTP_URL_REWRITES \
2941
  (CS_PLATFORM == CS_P_WINDOWS || CS_PLATFORM == CS_P_UNIX)
2942
#endif
2943

    
2944
#ifndef MG_ENABLE_TUN
2945
#define MG_ENABLE_TUN MG_ENABLE_HTTP_WEBSOCKET
2946
#endif
2947

    
2948
#ifndef MG_ENABLE_SNTP
2949
#define MG_ENABLE_SNTP 0
2950
#endif
2951

    
2952
#ifndef MG_ENABLE_EXTRA_ERRORS_DESC
2953
#define MG_ENABLE_EXTRA_ERRORS_DESC 0
2954
#endif
2955

    
2956
#endif /* CS_MONGOOSE_SRC_FEATURES_H_ */
2957
#ifdef MG_MODULE_LINES
2958
#line 1 "mongoose/src/net_if.h"
2959
#endif
2960
/*
2961
 * Copyright (c) 2014-2016 Cesanta Software Limited
2962
 * All rights reserved
2963
 */
2964

    
2965
#ifndef CS_MONGOOSE_SRC_NET_IF_H_
2966
#define CS_MONGOOSE_SRC_NET_IF_H_
2967

    
2968
/* Amalgamated: #include "common/platform.h" */
2969

    
2970
/*
2971
 * Internal async networking core interface.
2972
 * Consists of calls made by the core, which should not block,
2973
 * and callbacks back into the core ("..._cb").
2974
 * Callbacks may (will) cause methods to be invoked from within,
2975
 * but methods are not allowed to invoke callbacks inline.
2976
 *
2977
 * Implementation must ensure that only one callback is invoked at any time.
2978
 */
2979

    
2980
#ifdef __cplusplus
2981
extern "C" {
2982
#endif /* __cplusplus */
2983

    
2984
#define MG_MAIN_IFACE 0
2985

    
2986
struct mg_mgr;
2987
struct mg_connection;
2988
union socket_address;
2989

    
2990
struct mg_iface_vtable;
2991

    
2992
struct mg_iface {
2993
  struct mg_mgr *mgr;
2994
  void *data; /* Implementation-specific data */
2995
  struct mg_iface_vtable *vtable;
2996
};
2997

    
2998
struct mg_iface_vtable {
2999
  void (*init)(struct mg_iface *iface);
3000
  void (*free)(struct mg_iface *iface);
3001
  void (*add_conn)(struct mg_connection *nc);
3002
  void (*remove_conn)(struct mg_connection *nc);
3003
  time_t (*poll)(struct mg_iface *iface, int timeout_ms);
3004

    
3005
  /* Set up a listening TCP socket on a given address. rv = 0 -> ok. */
3006
  int (*listen_tcp)(struct mg_connection *nc, union socket_address *sa);
3007
  /* Request that a "listening" UDP socket be created. */
3008
  int (*listen_udp)(struct mg_connection *nc, union socket_address *sa);
3009

    
3010
  /* Request that a TCP connection is made to the specified address. */
3011
  void (*connect_tcp)(struct mg_connection *nc, const union socket_address *sa);
3012
  /* Open a UDP socket. Doesn't actually connect anything. */
3013
  void (*connect_udp)(struct mg_connection *nc);
3014

    
3015
  /* Send functions for TCP and UDP. Sent data is copied before return. */
3016
  void (*tcp_send)(struct mg_connection *nc, const void *buf, size_t len);
3017
  void (*udp_send)(struct mg_connection *nc, const void *buf, size_t len);
3018

    
3019
  void (*recved)(struct mg_connection *nc, size_t len);
3020

    
3021
  /* Perform interface-related connection initialization. Return 1 on ok. */
3022
  int (*create_conn)(struct mg_connection *nc);
3023
  /* Perform interface-related cleanup on connection before destruction. */
3024
  void (*destroy_conn)(struct mg_connection *nc);
3025

    
3026
  /* Associate a socket to a connection. */
3027
  void (*sock_set)(struct mg_connection *nc, sock_t sock);
3028

    
3029
  /* Put connection's address into *sa, local (remote = 0) or remote. */
3030
  void (*get_conn_addr)(struct mg_connection *nc, int remote,
3031
                        union socket_address *sa);
3032
};
3033

    
3034
extern struct mg_iface_vtable *mg_ifaces[];
3035
extern int mg_num_ifaces;
3036

    
3037
/* Creates a new interface instance. */
3038
struct mg_iface *mg_if_create_iface(struct mg_iface_vtable *vtable,
3039
                                    struct mg_mgr *mgr);
3040

    
3041
/*
3042
 * Find an interface with a given implementation. The search is started from
3043
 * interface `from`, exclusive. Returns NULL if none is found.
3044
 */
3045
struct mg_iface *mg_find_iface(struct mg_mgr *mgr,
3046
                               struct mg_iface_vtable *vtable,
3047
                               struct mg_iface *from);
3048
/*
3049
 * Deliver a new TCP connection. Returns NULL in case on error (unable to
3050
 * create connection, in which case interface state should be discarded.
3051
 * This is phase 1 of the two-phase process - MG_EV_ACCEPT will be delivered
3052
 * when mg_if_accept_tcp_cb is invoked.
3053
 */
3054
struct mg_connection *mg_if_accept_new_conn(struct mg_connection *lc);
3055
void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,
3056
                         size_t sa_len);
3057

    
3058
/* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */
3059
void mg_if_connect_cb(struct mg_connection *nc, int err);
3060
/* Callback that reports that data has been put on the wire. */
3061
void mg_if_sent_cb(struct mg_connection *nc, int num_sent);
3062
/*
3063
 * Receive callback.
3064
 * if `own` is true, buf must be heap-allocated and ownership is transferred
3065
 * to the core.
3066
 * Core will acknowledge consumption by calling iface::recved.
3067
 */
3068
void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len, int own);
3069
/*
3070
 * Receive callback.
3071
 * buf must be heap-allocated and ownership is transferred to the core.
3072
 * Core will acknowledge consumption by calling iface::recved.
3073
 */
3074
void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
3075
                       union socket_address *sa, size_t sa_len);
3076

    
3077
/* void mg_if_close_conn(struct mg_connection *nc); */
3078

    
3079
/* Deliver a POLL event to the connection. */
3080
void mg_if_poll(struct mg_connection *nc, time_t now);
3081

    
3082
/* Deliver a TIMER event to the connection. */
3083
void mg_if_timer(struct mg_connection *c, double now);
3084

    
3085
#ifdef __cplusplus
3086
}
3087
#endif /* __cplusplus */
3088

    
3089
#endif /* CS_MONGOOSE_SRC_NET_IF_H_ */
3090
#ifdef MG_MODULE_LINES
3091
#line 1 "mongoose/src/ssl_if.h"
3092
#endif
3093
/*
3094
 * Copyright (c) 2014-2016 Cesanta Software Limited
3095
 * All rights reserved
3096
 */
3097

    
3098
#ifndef CS_MONGOOSE_SRC_SSL_IF_H_
3099
#define CS_MONGOOSE_SRC_SSL_IF_H_
3100

    
3101
#if MG_ENABLE_SSL
3102

    
3103
#ifdef __cplusplus
3104
extern "C" {
3105
#endif /* __cplusplus */
3106

    
3107
struct mg_ssl_if_ctx;
3108
struct mg_connection;
3109

    
3110
void mg_ssl_if_init();
3111

    
3112
enum mg_ssl_if_result {
3113
  MG_SSL_OK = 0,
3114
  MG_SSL_WANT_READ = -1,
3115
  MG_SSL_WANT_WRITE = -2,
3116
  MG_SSL_ERROR = -3,
3117
};
3118

    
3119
struct mg_ssl_if_conn_params {
3120
  const char *cert;
3121
  const char *key;
3122
  const char *ca_cert;
3123
  const char *server_name;
3124
  const char *cipher_suites;
3125
};
3126

    
3127
enum mg_ssl_if_result mg_ssl_if_conn_init(
3128
    struct mg_connection *nc, const struct mg_ssl_if_conn_params *params,
3129
    const char **err_msg);
3130
enum mg_ssl_if_result mg_ssl_if_conn_accept(struct mg_connection *nc,
3131
                                            struct mg_connection *lc);
3132
void mg_ssl_if_conn_free(struct mg_connection *nc);
3133

    
3134
enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc);
3135
int mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t buf_size);
3136
int mg_ssl_if_write(struct mg_connection *nc, const void *data, size_t len);
3137

    
3138
#ifdef __cplusplus
3139
}
3140
#endif /* __cplusplus */
3141

    
3142
#endif /* MG_ENABLE_SSL */
3143

    
3144
#endif /* CS_MONGOOSE_SRC_SSL_IF_H_ */
3145
#ifdef MG_MODULE_LINES
3146
#line 1 "mongoose/src/net.h"
3147
#endif
3148
/*
3149
 * Copyright (c) 2014 Cesanta Software Limited
3150
 * All rights reserved
3151
 * This software is dual-licensed: you can redistribute it and/or modify
3152
 * it under the terms of the GNU General Public License version 2 as
3153
 * published by the Free Software Foundation. For the terms of this
3154
 * license, see <http://www.gnu.org/licenses/>.
3155
 *
3156
 * You are free to use this software under the terms of the GNU General
3157
 * Public License, but WITHOUT ANY WARRANTY; without even the implied
3158
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
3159
 * See the GNU General Public License for more details.
3160
 *
3161
 * Alternatively, you can license this software under a commercial
3162
 * license, as set out in <https://www.cesanta.com/license>.
3163
 */
3164

    
3165
/*
3166
 * === Core API: TCP/UDP/SSL
3167
 *
3168
 * NOTE: Mongoose manager is single threaded. It does not protect
3169
 * its data structures by mutexes, therefore all functions that are dealing
3170
 * with a particular event manager should be called from the same thread,
3171
 * with exception of the `mg_broadcast()` function. It is fine to have different
3172
 * event managers handled by different threads.
3173
 */
3174

    
3175
#ifndef CS_MONGOOSE_SRC_NET_H_
3176
#define CS_MONGOOSE_SRC_NET_H_
3177

    
3178
#if MG_ENABLE_JAVASCRIPT
3179
#define EXCLUDE_COMMON
3180
#include <v7.h>
3181
#endif
3182

    
3183
/* Amalgamated: #include "mongoose/src/common.h" */
3184
/* Amalgamated: #include "mongoose/src/net_if.h" */
3185
/* Amalgamated: #include "common/mbuf.h" */
3186

    
3187
#ifndef MG_VPRINTF_BUFFER_SIZE
3188
#define MG_VPRINTF_BUFFER_SIZE 100
3189
#endif
3190

    
3191
#ifdef MG_USE_READ_WRITE
3192
#define MG_RECV_FUNC(s, b, l, f) read(s, b, l)
3193
#define MG_SEND_FUNC(s, b, l, f) write(s, b, l)
3194
#else
3195
#define MG_RECV_FUNC(s, b, l, f) recv(s, b, l, f)
3196
#define MG_SEND_FUNC(s, b, l, f) send(s, b, l, f)
3197
#endif
3198

    
3199
#ifdef __cplusplus
3200
extern "C" {
3201
#endif /* __cplusplus */
3202

    
3203
union socket_address {
3204
  struct sockaddr sa;
3205
  struct sockaddr_in sin;
3206
#if MG_ENABLE_IPV6
3207
  struct sockaddr_in6 sin6;
3208
#else
3209
  struct sockaddr sin6;
3210
#endif
3211
};
3212

    
3213
struct mg_connection;
3214

    
3215
/*
3216
 * Callback function (event handler) prototype. Must be defined by the user.
3217
 * Mongoose calls the event handler, passing the events defined below.
3218
 */
3219
typedef void (*mg_event_handler_t)(struct mg_connection *nc, int ev,
3220
                                   void *ev_data);
3221

    
3222
/* Events. Meaning of event parameter (evp) is given in the comment. */
3223
#define MG_EV_POLL 0    /* Sent to each connection on each mg_mgr_poll() call */
3224
#define MG_EV_ACCEPT 1  /* New connection accepted. union socket_address * */
3225
#define MG_EV_CONNECT 2 /* connect() succeeded or failed. int *  */
3226
#define MG_EV_RECV 3    /* Data has benn received. int *num_bytes */
3227
#define MG_EV_SEND 4    /* Data has been written to a socket. int *num_bytes */
3228
#define MG_EV_CLOSE 5   /* Connection is closed. NULL */
3229
#define MG_EV_TIMER 6   /* now >= conn->ev_timer_time. double * */
3230

    
3231
/*
3232
 * Mongoose event manager.
3233
 */
3234
struct mg_mgr {
3235
  struct mg_connection *active_connections;
3236
#if MG_ENABLE_HEXDUMP
3237
  const char *hexdump_file; /* Debug hexdump file path */
3238
#endif
3239
#if MG_ENABLE_BROADCAST
3240
  sock_t ctl[2]; /* Socketpair for mg_broadcast() */
3241
#endif
3242
  void *user_data; /* User data */
3243
  int num_ifaces;
3244
  struct mg_iface **ifaces; /* network interfaces */
3245
#if MG_ENABLE_JAVASCRIPT
3246
  struct v7 *v7;
3247
#endif
3248
};
3249

    
3250
/*
3251
 * Mongoose connection.
3252
 */
3253
struct mg_connection {
3254
  struct mg_connection *next, *prev; /* mg_mgr::active_connections linkage */
3255
  struct mg_connection *listener;    /* Set only for accept()-ed connections */
3256
  struct mg_mgr *mgr;                /* Pointer to containing manager */
3257

    
3258
  sock_t sock; /* Socket to the remote peer */
3259
  int err;
3260
  union socket_address sa; /* Remote peer address */
3261
  size_t recv_mbuf_limit;  /* Max size of recv buffer */
3262
  struct mbuf recv_mbuf;   /* Received data */
3263
  struct mbuf send_mbuf;   /* Data scheduled for sending */
3264
  time_t last_io_time;     /* Timestamp of the last socket IO */
3265
  double ev_timer_time;    /* Timestamp of the future MG_EV_TIMER */
3266
#if MG_ENABLE_SSL
3267
  void *ssl_if_data; /* SSL library data. */
3268
#endif
3269
  mg_event_handler_t proto_handler; /* Protocol-specific event handler */
3270
  void *proto_data;                 /* Protocol-specific data */
3271
  void (*proto_data_destructor)(void *proto_data);
3272
  mg_event_handler_t handler; /* Event handler function */
3273
  void *user_data;            /* User-specific data */
3274
  union {
3275
    void *v;
3276
    /*
3277
     * the C standard is fussy about fitting function pointers into
3278
     * void pointers, since some archs might have fat pointers for functions.
3279
     */
3280
    mg_event_handler_t f;
3281
  } priv_1;       /* Used by mg_enable_multithreading() */
3282
  void *priv_2;   /* Used by mg_enable_multithreading() */
3283
  void *mgr_data; /* Implementation-specific event manager's data. */
3284
  struct mg_iface *iface;
3285
  unsigned long flags;
3286
/* Flags set by Mongoose */
3287
#define MG_F_LISTENING (1 << 0)          /* This connection is listening */
3288
#define MG_F_UDP (1 << 1)                /* This connection is UDP */
3289
#define MG_F_RESOLVING (1 << 2)          /* Waiting for async resolver */
3290
#define MG_F_CONNECTING (1 << 3)         /* connect() call in progress */
3291
#define MG_F_SSL (1 << 4)                /* SSL is enabled on the connection */
3292
#define MG_F_SSL_HANDSHAKE_DONE (1 << 5) /* SSL hanshake has completed */
3293
#define MG_F_WANT_READ (1 << 6)          /* SSL specific */
3294
#define MG_F_WANT_WRITE (1 << 7)         /* SSL specific */
3295
#define MG_F_IS_WEBSOCKET (1 << 8)       /* Websocket specific */
3296

    
3297
/* Flags that are settable by user */
3298
#define MG_F_SEND_AND_CLOSE (1 << 10)       /* Push remaining data and close  */
3299
#define MG_F_CLOSE_IMMEDIATELY (1 << 11)    /* Disconnect */
3300
#define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12)  /* Websocket specific */
3301
#define MG_F_DELETE_CHUNK (1 << 13)         /* HTTP specific */
3302
#define MG_F_ENABLE_BROADCAST (1 << 14)     /* Allow broadcast address usage */
3303
#define MG_F_TUN_DO_NOT_RECONNECT (1 << 15) /* Don't reconnect tunnel */
3304

    
3305
#define MG_F_USER_1 (1 << 20) /* Flags left for application */
3306
#define MG_F_USER_2 (1 << 21)
3307
#define MG_F_USER_3 (1 << 22)
3308
#define MG_F_USER_4 (1 << 23)
3309
#define MG_F_USER_5 (1 << 24)
3310
#define MG_F_USER_6 (1 << 25)
3311
};
3312

    
3313
/*
3314
 * Initialise Mongoose manager. Side effect: ignores SIGPIPE signal.
3315
 * `mgr->user_data` field will be initialised with a `user_data` parameter.
3316
 * That is an arbitrary pointer, where the user code can associate some data
3317
 * with the particular Mongoose manager. For example, a C++ wrapper class
3318
 * could be written in which case `user_data` can hold a pointer to the
3319
 * class instance.
3320
 */
3321
void mg_mgr_init(struct mg_mgr *mgr, void *user_data);
3322

    
3323
/*
3324
 * Optional parameters to `mg_mgr_init_opt()`.
3325
 *
3326
 * If `main_iface` is not NULL, it will be used as the main interface in the
3327
 * default interface set. The pointer will be free'd by `mg_mgr_free`.
3328
 * Otherwise, the main interface will be autodetected based on the current
3329
 * platform.
3330
 *
3331
 * If `num_ifaces` is 0 and `ifaces` is NULL, the default interface set will be
3332
 * used.
3333
 * This is an advanced option, as it requires you to construct a full interface
3334
 * set, including special networking interfaces required by some optional
3335
 * features such as TCP tunneling. Memory backing `ifaces` and each of the
3336
 * `num_ifaces` pointers it contains will be reclaimed by `mg_mgr_free`.
3337
 */
3338
struct mg_mgr_init_opts {
3339
  struct mg_iface_vtable *main_iface;
3340
  int num_ifaces;
3341
  struct mg_iface_vtable **ifaces;
3342
};
3343

    
3344
/*
3345
 * Like `mg_mgr_init` but with more options.
3346
 *
3347
 * Notably, this allows you to create a manger and choose
3348
 * dynamically which networking interface implementation to use.
3349
 */
3350
void mg_mgr_init_opt(struct mg_mgr *mgr, void *user_data,
3351
                     struct mg_mgr_init_opts opts);
3352

    
3353
/*
3354
 * De-initialises Mongoose manager.
3355
 *
3356
 * Closes and deallocates all active connections.
3357
 */
3358
void mg_mgr_free(struct mg_mgr *);
3359

    
3360
/*
3361
 * This function performs the actual IO and must be called in a loop
3362
 * (an event loop). It returns the current timestamp.
3363
 * `milli` is the maximum number of milliseconds to sleep.
3364
 * `mg_mgr_poll()` checks all connections for IO readiness. If at least one
3365
 * of the connections is IO-ready, `mg_mgr_poll()` triggers the respective
3366
 * event handlers and returns.
3367
 */
3368
time_t mg_mgr_poll(struct mg_mgr *, int milli);
3369

    
3370
#if MG_ENABLE_BROADCAST
3371
/*
3372
 * Passes a message of a given length to all connections.
3373
 *
3374
 * Must be called from a thread that does NOT call `mg_mgr_poll()`.
3375
 * Note that `mg_broadcast()` is the only function
3376
 * that can be, and must be, called from a different (non-IO) thread.
3377
 *
3378
 * `func` callback function will be called by the IO thread for each
3379
 * connection. When called, the event will be `MG_EV_POLL`, and a message will
3380
 * be passed as the `ev_data` pointer. Maximum message size is capped
3381
 * by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes.
3382
 */
3383
void mg_broadcast(struct mg_mgr *, mg_event_handler_t func, void *, size_t);
3384
#endif
3385

    
3386
/*
3387
 * Iterates over all active connections.
3388
 *
3389
 * Returns the next connection from the list
3390
 * of active connections or `NULL` if there are no more connections. Below
3391
 * is the iteration idiom:
3392
 *
3393
 * ```c
3394
 * for (c = mg_next(srv, NULL); c != NULL; c = mg_next(srv, c)) {
3395
 *   // Do something with connection `c`
3396
 * }
3397
 * ```
3398
 */
3399
struct mg_connection *mg_next(struct mg_mgr *, struct mg_connection *);
3400

    
3401
/*
3402
 * Optional parameters to `mg_add_sock_opt()`.
3403
 *
3404
 * `flags` is an initial `struct mg_connection::flags` bitmask to set,
3405
 * see `MG_F_*` flags definitions.
3406
 */
3407
struct mg_add_sock_opts {
3408
  void *user_data;           /* Initial value for connection's user_data */
3409
  unsigned int flags;        /* Initial connection flags */
3410
  const char **error_string; /* Placeholder for the error string */
3411
  struct mg_iface *iface;    /* Interface instance */
3412
};
3413

    
3414
/*
3415
 * Creates a connection, associates it with the given socket and event handler
3416
 * and adds it to the manager.
3417
 *
3418
 * For more options see the `mg_add_sock_opt` variant.
3419
 */
3420
struct mg_connection *mg_add_sock(struct mg_mgr *, sock_t, mg_event_handler_t);
3421

    
3422
/*
3423
 * Creates a connection, associates it with the given socket and event handler
3424
 * and adds to the manager.
3425
 *
3426
 * See the `mg_add_sock_opts` structure for a description of the options.
3427
 */
3428
struct mg_connection *mg_add_sock_opt(struct mg_mgr *, sock_t,
3429
                                      mg_event_handler_t,
3430
                                      struct mg_add_sock_opts);
3431

    
3432
/*
3433
 * Optional parameters to `mg_bind_opt()`.
3434
 *
3435
 * `flags` is an initial `struct mg_connection::flags` bitmask to set,
3436
 * see `MG_F_*` flags definitions.
3437
 */
3438
struct mg_bind_opts {
3439
  void *user_data;           /* Initial value for connection's user_data */
3440
  unsigned int flags;        /* Extra connection flags */
3441
  const char **error_string; /* Placeholder for the error string */
3442
  struct mg_iface *iface;    /* Interface instance */
3443
#if MG_ENABLE_SSL
3444
  /*
3445
   * SSL settings.
3446
   *
3447
   * Server certificate to present to clients or client certificate to
3448
   * present to tunnel dispatcher (for tunneled connections).
3449
   */
3450
  const char *ssl_cert;
3451
  /* Private key corresponding to the certificate. If ssl_cert is set but
3452
   * ssl_key is not, ssl_cert is used. */
3453
  const char *ssl_key;
3454
  /* CA bundle used to verify client certificates or tunnel dispatchers. */
3455
  const char *ssl_ca_cert;
3456
  /* Colon-delimited list of acceptable cipher suites.
3457
   * Names depend on the library used, for example:
3458
   *
3459
   * ECDH-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256 (OpenSSL)
3460
   * TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256
3461
   *   (mbedTLS)
3462
   *
3463
   * For OpenSSL the list can be obtained by running "openssl ciphers".
3464
   * For mbedTLS, names can be found in library/ssl_ciphersuites.c
3465
   * If NULL, a reasonable default is used.
3466
   */
3467
  const char *ssl_cipher_suites;
3468
#endif
3469
};
3470

    
3471
/*
3472
 * Creates a listening connection.
3473
 *
3474
 * See `mg_bind_opt` for full documentation.
3475
 */
3476
struct mg_connection *mg_bind(struct mg_mgr *, const char *,
3477
                              mg_event_handler_t);
3478
/*
3479
 * Creates a listening connection.
3480
 *
3481
 * The `address` parameter specifies which address to bind to. It's format is
3482
 * the same as for the `mg_connect()` call, where `HOST` part is optional.
3483
 * `address` can be just a port number, e.g. `:8000`. To bind to a specific
3484
 * interface, an IP address can be specified, e.g. `1.2.3.4:8000`. By default,
3485
 * a TCP connection is created. To create UDP connection, prepend `udp://`
3486
 * prefix, e.g. `udp://:8000`. To summarize, `address` paramer has following
3487
 * format: `[PROTO://][IP_ADDRESS]:PORT`, where `PROTO` could be `tcp` or
3488
 * `udp`.
3489
 *
3490
 * See the `mg_bind_opts` structure for a description of the optional
3491
 * parameters.
3492
 *
3493
 * Returns a new listening connection or `NULL` on error.
3494
 * NOTE: The connection remains owned by the manager, do not free().
3495
 */
3496
struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,
3497
                                  mg_event_handler_t handler,
3498
                                  struct mg_bind_opts opts);
3499

    
3500
/* Optional parameters to `mg_connect_opt()` */
3501
struct mg_connect_opts {
3502
  void *user_data;           /* Initial value for connection's user_data */
3503
  unsigned int flags;        /* Extra connection flags */
3504
  const char **error_string; /* Placeholder for the error string */
3505
  struct mg_iface *iface;    /* Interface instance */
3506
#if MG_ENABLE_SSL
3507
  /*
3508
   * SSL settings.
3509
   * Client certificate to present to the server.
3510
   */
3511
  const char *ssl_cert;
3512
  /*
3513
   * Private key corresponding to the certificate.
3514
   * If ssl_cert is set but ssl_key is not, ssl_cert is used.
3515
   */
3516
  const char *ssl_key;
3517
  /*
3518
   * Verify server certificate using this CA bundle. If set to "*", then SSL
3519
   * is enabled but no cert verification is performed.
3520
   */
3521
  const char *ssl_ca_cert;
3522
  /* Colon-delimited list of acceptable cipher suites.
3523
   * Names depend on the library used, for example:
3524
   *
3525
   * ECDH-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256 (OpenSSL)
3526
   * TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256
3527
   *   (mbedTLS)
3528
   *
3529
   * For OpenSSL the list can be obtained by running "openssl ciphers".
3530
   * For mbedTLS, names can be found in library/ssl_ciphersuites.c
3531
   * If NULL, a reasonable default is used.
3532
   */
3533
  const char *ssl_cipher_suites;
3534
  /*
3535
   * Server name verification. If ssl_ca_cert is set and the certificate has
3536
   * passed verification, its subject will be verified against this string.
3537
   * By default (if ssl_server_name is NULL) hostname part of the address will
3538
   * be used. Wildcard matching is supported. A special value of "*" disables
3539
   * name verification.
3540
   */
3541
  const char *ssl_server_name;
3542
#endif
3543
};
3544

    
3545
/*
3546
 * Connects to a remote host.
3547
 *
3548
 * See `mg_connect_opt()` for full documentation.
3549
 */
3550
struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,
3551
                                 mg_event_handler_t handler);
3552

    
3553
/*
3554
 * Connects to a remote host.
3555
 *
3556
 * The `address` format is `[PROTO://]HOST:PORT`. `PROTO` could be `tcp` or
3557
 * `udp`. `HOST` could be an IP address,
3558
 * IPv6 address (if Mongoose is compiled with `-DMG_ENABLE_IPV6`) or a host
3559
 * name. If `HOST` is a name, Mongoose will resolve it asynchronously. Examples
3560
 * of valid addresses: `google.com:80`, `udp://1.2.3.4:53`, `10.0.0.1:443`,
3561
 * `[::1]:80`
3562
 *
3563
 * See the `mg_connect_opts` structure for a description of the optional
3564
 * parameters.
3565
 *
3566
 * Returns a new outbound connection or `NULL` on error.
3567
 *
3568
 * NOTE: The connection remains owned by the manager, do not free().
3569
 *
3570
 * NOTE: To enable IPv6 addresses `-DMG_ENABLE_IPV6` should be specified
3571
 * in the compilation flags.
3572
 *
3573
 * NOTE: The new connection will receive `MG_EV_CONNECT` as its first event
3574
 * which will report the connect success status.
3575
 * If the asynchronous resolution fails or the `connect()` syscall fails for
3576
 * whatever reason (e.g. with `ECONNREFUSED` or `ENETUNREACH`), then
3577
 * `MG_EV_CONNECT` event will report failure. Code example below:
3578
 *
3579
 * ```c
3580
 * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
3581
 *   int connect_status;
3582
 *
3583
 *   switch (ev) {
3584
 *     case MG_EV_CONNECT:
3585
 *       connect_status = * (int *) ev_data;
3586
 *       if (connect_status == 0) {
3587
 *         // Success
3588
 *       } else  {
3589
 *         // Error
3590
 *         printf("connect() error: %s\n", strerror(connect_status));
3591
 *       }
3592
 *       break;
3593
 *     ...
3594
 *   }
3595
 * }
3596
 *
3597
 *   ...
3598
 *   mg_connect(mgr, "my_site.com:80", ev_handler);
3599
 * ```
3600
 */
3601
struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
3602
                                     mg_event_handler_t handler,
3603
                                     struct mg_connect_opts opts);
3604

    
3605
#if MG_ENABLE_SSL && MG_NET_IF != MG_NET_IF_SIMPLELINK
3606
/*
3607
 * Note: This function is deprecated. Please, use SSL options in
3608
 * mg_connect_opt.
3609
 *
3610
 * Enables SSL for a given connection.
3611
 * `cert` is a server certificate file name for a listening connection
3612
 * or a client certificate file name for an outgoing connection.
3613
 * The certificate files must be in PEM format. The server certificate file
3614
 * must contain a certificate, concatenated with a private key, optionally
3615
 * concatenated with DH parameters.
3616
 * `ca_cert` is a CA certificate or NULL if peer verification is not
3617
 * required.
3618
 * Return: NULL on success or error message on error.
3619
 */
3620
const char *mg_set_ssl(struct mg_connection *nc, const char *cert,
3621
                       const char *ca_cert);
3622
#endif
3623

    
3624
/*
3625
 * Sends data to the connection.
3626
 *
3627
 * Note that sending functions do not actually push data to the socket.
3628
 * They just append data to the output buffer. MG_EV_SEND will be delivered when
3629
 * the data has actually been pushed out.
3630
 */
3631
void mg_send(struct mg_connection *, const void *buf, int len);
3632

    
3633
/* Enables format string warnings for mg_printf */
3634
#if defined(__GNUC__)
3635
__attribute__((format(printf, 2, 3)))
3636
#endif
3637
/* don't separate from mg_printf declaration */
3638

    
3639
/*
3640
 * Sends `printf`-style formatted data to the connection.
3641
 *
3642
 * See `mg_send` for more details on send semantics.
3643
 */
3644
int mg_printf(struct mg_connection *, const char *fmt, ...);
3645

    
3646
/* Same as `mg_printf()`, but takes `va_list ap` as an argument. */
3647
int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
3648

    
3649
/*
3650
 * Creates a socket pair.
3651
 * `sock_type` can be either `SOCK_STREAM` or `SOCK_DGRAM`.
3652
 * Returns 0 on failure and 1 on success.
3653
 */
3654
int mg_socketpair(sock_t[2], int sock_type);
3655

    
3656
#if MG_ENABLE_SYNC_RESOLVER
3657
/*
3658
 * Convert domain name into IP address.
3659
 *
3660
 * This is a utility function. If compilation flags have
3661
 * `-DMG_ENABLE_GETADDRINFO`, then `getaddrinfo()` call is used for name
3662
 * resolution. Otherwise, `gethostbyname()` is used.
3663
 *
3664
 * CAUTION: this function can block.
3665
 * Return 1 on success, 0 on failure.
3666
 */
3667
int mg_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
3668
#endif
3669

    
3670
/*
3671
 * Verify given IP address against the ACL.
3672
 *
3673
 * `remote_ip` - an IPv4 address to check, in host byte order
3674
 * `acl` - a comma separated list of IP subnets: `x.x.x.x/x` or `x.x.x.x`.
3675
 * Each subnet is
3676
 * prepended by either a - or a + sign. A plus sign means allow, where a
3677
 * minus sign means deny. If a subnet mask is omitted, such as `-1.2.3.4`,
3678
 * it means that only that single IP address is denied.
3679
 * Subnet masks may vary from 0 to 32, inclusive. The default setting
3680
 * is to allow all access. On each request the full list is traversed,
3681
 * and the last match wins. Example:
3682
 *
3683
 * `-0.0.0.0/0,+192.168/16` - deny all acccesses, only allow 192.168/16 subnet
3684
 *
3685
 * To learn more about subnet masks, see this
3686
 * link:https://en.wikipedia.org/wiki/Subnetwork[Wikipedia page on Subnetwork].
3687
 *
3688
 * Returns -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed.
3689
 */
3690
int mg_check_ip_acl(const char *acl, uint32_t remote_ip);
3691

    
3692
/*
3693
 * Optional parameters for mg_enable_multithreading_opt()
3694
 */
3695
struct mg_multithreading_opts {
3696
  int poll_timeout; /* Polling interval */
3697
};
3698

    
3699
/*
3700
 * Enables multi-threaded handling for the given listening connection `nc`.
3701
 * For each accepted connection, Mongoose will create a separate thread
3702
 * and run an event handler in that thread. Thus, if an event handler is doing
3703
 * a blocking call or some long computation, it will not slow down
3704
 * other connections.
3705
 */
3706
void mg_enable_multithreading(struct mg_connection *nc);
3707
void mg_enable_multithreading_opt(struct mg_connection *nc,
3708
                                  struct mg_multithreading_opts opts);
3709

    
3710
#if MG_ENABLE_JAVASCRIPT
3711
/*
3712
 * Enables server-side JavaScript scripting.
3713
 * Requires a `-DMG_ENABLE_JAVASCRIPT` compilation flag and V7 engine sources.
3714
 * V7 instance must not be destroyed during manager's lifetime.
3715
 * Returns a V7 error.
3716
 */
3717
enum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,
3718
                                 const char *init_js_file_name);
3719
#endif
3720

    
3721
/*
3722
 * Schedules an MG_EV_TIMER event to be delivered at `timestamp` time.
3723
 * `timestamp` is UNIX time (the number of seconds since Epoch). It is
3724
 * `double` instead of `time_t` to allow for sub-second precision.
3725
 * Returns the old timer value.
3726
 *
3727
 * Example: set the connect timeout to 1.5 seconds:
3728
 *
3729
 * ```
3730
 *  c = mg_connect(&mgr, "cesanta.com", ev_handler);
3731
 *  mg_set_timer(c, mg_time() + 1.5);
3732
 *  ...
3733
 *
3734
 *  void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
3735
 *  switch (ev) {
3736
 *    case MG_EV_CONNECT:
3737
 *      mg_set_timer(c, 0);  // Clear connect timer
3738
 *      break;
3739
 *    case MG_EV_TIMER:
3740
 *      log("Connect timeout");
3741
 *      c->flags |= MG_F_CLOSE_IMMEDIATELY;
3742
 *      break;
3743
 * ```
3744
 */
3745
double mg_set_timer(struct mg_connection *c, double timestamp);
3746

    
3747
/*
3748
 * A sub-second precision version of time().
3749
 */
3750
double mg_time(void);
3751

    
3752
#ifdef __cplusplus
3753
}
3754
#endif /* __cplusplus */
3755

    
3756
#endif /* CS_MONGOOSE_SRC_NET_H_ */
3757
#ifdef MG_MODULE_LINES
3758
#line 1 "mongoose/src/uri.h"
3759
#endif
3760
/*
3761
 * Copyright (c) 2014 Cesanta Software Limited
3762
 * All rights reserved
3763
 */
3764

    
3765
/*
3766
 * === URI
3767
 */
3768

    
3769
#ifndef CS_MONGOOSE_SRC_URI_H_
3770
#define CS_MONGOOSE_SRC_URI_H_
3771

    
3772
/* Amalgamated: #include "mongoose/src/net.h" */
3773

    
3774
#ifdef __cplusplus
3775
extern "C" {
3776
#endif /* __cplusplus */
3777

    
3778
/*
3779
 * Parses an URI and fills string chunks with locations of the respective
3780
 * uri components within the input uri string. NULL pointers will be
3781
 * ignored.
3782
 *
3783
 * General syntax:
3784
 *
3785
 *     [scheme://[user_info@]]host[:port][/path][?query][#fragment]
3786
 *
3787
 * Example:
3788
 *
3789
 *     foo.com:80
3790
 *     tcp://foo.com:1234
3791
 *     http://foo.com:80/bar?baz=1
3792
 *     https://user:pw@foo.com:443/blah
3793
 *
3794
 * `path` will include the leading slash. `query` won't include the leading `?`.
3795
 * `host` can contain embedded colons if surrounded by square brackets in order
3796
 * to support IPv6 literal addresses.
3797
 *
3798
 *
3799
 * Returns 0 on success, -1 on error.
3800
 */
3801
int mg_parse_uri(struct mg_str uri, struct mg_str *scheme,
3802
                 struct mg_str *user_info, struct mg_str *host,
3803
                 unsigned int *port, struct mg_str *path, struct mg_str *query,
3804
                 struct mg_str *fragment);
3805

    
3806
int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out);
3807

    
3808
#ifdef __cplusplus
3809
}
3810
#endif /* __cplusplus */
3811
#endif /* CS_MONGOOSE_SRC_URI_H_ */
3812
#ifdef MG_MODULE_LINES
3813
#line 1 "mongoose/src/util.h"
3814
#endif
3815
/*
3816
 * Copyright (c) 2014 Cesanta Software Limited
3817
 * All rights reserved
3818
 */
3819

    
3820
/*
3821
 * === Utility API
3822
 */
3823

    
3824
#ifndef CS_MONGOOSE_SRC_UTIL_H_
3825
#define CS_MONGOOSE_SRC_UTIL_H_
3826

    
3827
#include <stdio.h>
3828

    
3829
/* Amalgamated: #include "mongoose/src/common.h" */
3830
/* Amalgamated: #include "mongoose/src/net_if.h" */
3831

    
3832
#ifdef __cplusplus
3833
extern "C" {
3834
#endif /* __cplusplus */
3835

    
3836
#ifndef MAX_PATH_SIZE
3837
#define MAX_PATH_SIZE 500
3838
#endif
3839

    
3840
/*
3841
 * Fetches substring from input string `s`, `end` into `v`.
3842
 * Skips initial delimiter characters. Records first non-delimiter character
3843
 * at the beginning of substring `v`. Then scans the rest of the string
3844
 * until a delimiter character or end-of-string is found.
3845
 * `delimiters` is a 0-terminated string containing delimiter characters.
3846
 * Either one of `delimiters` or `end_string` terminates the search.
3847
 * Returns an `s` pointer, advanced forward where parsing has stopped.
3848
 */
3849
const char *mg_skip(const char *s, const char *end_string,
3850
                    const char *delimiters, struct mg_str *v);
3851

    
3852
/*
3853
 * Decodes base64-encoded string `s`, `len` into the destination `dst`.
3854
 * The destination has to have enough space to hold the decoded buffer.
3855
 * Decoding stops either when all strings have been decoded or invalid an
3856
 * character appeared.
3857
 * Destination is '\0'-terminated.
3858
 * Returns the number of decoded characters. On success, that should be equal
3859
 * to `len`. On error (invalid character) the return value is smaller then
3860
 * `len`.
3861
 */
3862
int mg_base64_decode(const unsigned char *s, int len, char *dst);
3863

    
3864
/*
3865
 * Base64-encode chunk of memory `src`, `src_len` into the destination `dst`.
3866
 * Destination has to have enough space to hold encoded buffer.
3867
 * Destination is '\0'-terminated.
3868
 */
3869
void mg_base64_encode(const unsigned char *src, int src_len, char *dst);
3870

    
3871
#if MG_ENABLE_FILESYSTEM
3872
/*
3873
 * Performs a 64-bit `stat()` call against a given file.
3874
 *
3875
 * `path` should be UTF8 encoded.
3876
 *
3877
 * Return value is the same as for `stat()` syscall.
3878
 */
3879
int mg_stat(const char *path, cs_stat_t *st);
3880

    
3881
/*
3882
 * Opens the given file and returns a file stream.
3883
 *
3884
 * `path` and `mode` should be UTF8 encoded.
3885
 *
3886
 * Return value is the same as for the `fopen()` call.
3887
 */
3888
FILE *mg_fopen(const char *path, const char *mode);
3889

    
3890
/*
3891
 * Opens the given file and returns a file stream.
3892
 *
3893
 * `path` should be UTF8 encoded.
3894
 *
3895
 * Return value is the same as for the `open()` syscall.
3896
 */
3897
int mg_open(const char *path, int flag, int mode);
3898
#endif /* MG_ENABLE_FILESYSTEM */
3899

    
3900
#if MG_ENABLE_THREADS
3901
/*
3902
 * Starts a new detached thread.
3903
 * Arguments and semantics are the same as pthead's `pthread_create()`.
3904
 * `thread_func` is a thread function, `thread_func_param` is a parameter
3905
 * that is passed to the thread function.
3906
 */
3907
void *mg_start_thread(void *(*thread_func)(void *), void *thread_func_param);
3908
#endif
3909

    
3910
void mg_set_close_on_exec(sock_t);
3911

    
3912
#define MG_SOCK_STRINGIFY_IP 1
3913
#define MG_SOCK_STRINGIFY_PORT 2
3914
#define MG_SOCK_STRINGIFY_REMOTE 4
3915
/*
3916
 * Converts a connection's local or remote address into string.
3917
 *
3918
 * The `flags` parameter is a bit mask that controls the behaviour,
3919
 * see `MG_SOCK_STRINGIFY_*` definitions.
3920
 *
3921
 * - MG_SOCK_STRINGIFY_IP - print IP address
3922
 * - MG_SOCK_STRINGIFY_PORT - print port number
3923
 * - MG_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address
3924
 *
3925
 * If both port number and IP address are printed, they are separated by `:`.
3926
 * If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported.
3927
 */
3928
void mg_conn_addr_to_str(struct mg_connection *nc, char *buf, size_t len,
3929
                         int flags);
3930
#if MG_NET_IF == MG_NET_IF_SOCKET
3931
/* Legacy interface. */
3932
void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
3933
#endif
3934

    
3935
/*
3936
 * Convert the socket's address into string.
3937
 *
3938
 * `flags` is MG_SOCK_STRINGIFY_IP and/or MG_SOCK_STRINGIFY_PORT.
3939
 */
3940
void mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
3941
                         int flags);
3942

    
3943
#if MG_ENABLE_HEXDUMP
3944
/*
3945
 * Generates a human-readable hexdump of memory chunk.
3946
 *
3947
 * Takes a memory buffer `buf` of length `len` and creates a hex dump of that
3948
 * buffer in `dst`. The generated output is a-la hexdump(1).
3949
 * Returns the length of generated string, excluding terminating `\0`. If
3950
 * returned length is bigger than `dst_len`, the overflow bytes are discarded.
3951
 */
3952
int mg_hexdump(const void *buf, int len, char *dst, int dst_len);
3953

    
3954
/*
3955
 * Generates human-readable hexdump of the data sent or received by the
3956
 * connection. `path` is a file name where hexdump should be written.
3957
 * `num_bytes` is a number of bytes sent/received. `ev` is one of the `MG_*`
3958
 * events sent to an event handler. This function is supposed to be called from
3959
 * the event handler.
3960
 */
3961
void mg_hexdump_connection(struct mg_connection *nc, const char *path,
3962
                           const void *buf, int num_bytes, int ev);
3963
#endif
3964

    
3965
/*
3966
 * Returns true if target platform is big endian.
3967
 */
3968
int mg_is_big_endian(void);
3969

    
3970
/*
3971
 * A helper function for traversing a comma separated list of values.
3972
 * It returns a list pointer shifted to the next value or NULL if the end
3973
 * of the list found.
3974
 * The value is stored in a val vector. If the value has a form "x=y", then
3975
 * eq_val vector is initialised to point to the "y" part, and val vector length
3976
 * is adjusted to point only to "x".
3977
 * If the list is just a comma separated list of entries, like "aa,bb,cc" then
3978
 * `eq_val` will contain zero-length string.
3979
 *
3980
 * The purpose of this function is to parse comma separated string without
3981
 * any copying/memory allocation.
3982
 */
3983
const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
3984
                                     struct mg_str *eq_val);
3985

    
3986
/*
3987
 * Matches 0-terminated string (mg_match_prefix) or string with given length
3988
 * mg_match_prefix_n against a glob pattern.
3989
 *
3990
 * Match is case-insensitive. Returns number of bytes matched, or -1 if no
3991
 * match.
3992
 */
3993
int mg_match_prefix(const char *pattern, int pattern_len, const char *str);
3994
int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str);
3995

    
3996
/*
3997
 * Use with cs_base64_init/update/finish in order to write out base64 in chunks.
3998
 */
3999
void mg_mbuf_append_base64_putc(char ch, void *user_data);
4000

    
4001
/*
4002
 * Encode `len` bytes starting at `data` as base64 and append them to an mbuf.
4003
 */
4004
void mg_mbuf_append_base64(struct mbuf *mbuf, const void *data, size_t len);
4005

    
4006
/*
4007
 * Generate a Basic Auth header and appends it to buf.
4008
 * If pass is NULL, then user is expected to contain the credentials pair
4009
 * already encoded as `user:pass`.
4010
 */
4011
void mg_basic_auth_header(const char *user, const char *pass, struct mbuf *buf);
4012

    
4013
#ifdef __cplusplus
4014
}
4015
#endif /* __cplusplus */
4016
#endif /* CS_MONGOOSE_SRC_UTIL_H_ */
4017
#ifdef MG_MODULE_LINES
4018
#line 1 "mongoose/src/http.h"
4019
#endif
4020
/*
4021
 * Copyright (c) 2014 Cesanta Software Limited
4022
 * All rights reserved
4023
 */
4024

    
4025
/*
4026
 * === Common API reference
4027
 */
4028

    
4029
#ifndef CS_MONGOOSE_SRC_HTTP_H_
4030
#define CS_MONGOOSE_SRC_HTTP_H_
4031

    
4032
#if MG_ENABLE_HTTP
4033

    
4034
/* Amalgamated: #include "mongoose/src/net.h" */
4035
/* Amalgamated: #include "common/mg_str.h" */
4036

    
4037
#ifdef __cplusplus
4038
extern "C" {
4039
#endif /* __cplusplus */
4040

    
4041
#ifndef MG_MAX_HTTP_HEADERS
4042
#define MG_MAX_HTTP_HEADERS 20
4043
#endif
4044

    
4045
#ifndef MG_MAX_HTTP_REQUEST_SIZE
4046
#define MG_MAX_HTTP_REQUEST_SIZE 1024
4047
#endif
4048

    
4049
#ifndef MG_MAX_PATH
4050
#ifdef PATH_MAX
4051
#define MG_MAX_PATH PATH_MAX
4052
#else
4053
#define MG_MAX_PATH 256
4054
#endif
4055
#endif
4056

    
4057
#ifndef MG_MAX_HTTP_SEND_MBUF
4058
#define MG_MAX_HTTP_SEND_MBUF 1024
4059
#endif
4060

    
4061
#ifndef MG_CGI_ENVIRONMENT_SIZE
4062
#define MG_CGI_ENVIRONMENT_SIZE 8192
4063
#endif
4064

    
4065
/* HTTP message */
4066
struct http_message {
4067
  struct mg_str message; /* Whole message: request line + headers + body */
4068

    
4069
  /* HTTP Request line (or HTTP response line) */
4070
  struct mg_str method; /* "GET" */
4071
  struct mg_str uri;    /* "/my_file.html" */
4072
  struct mg_str proto;  /* "HTTP/1.1" -- for both request and response */
4073

    
4074
  /* For responses, code and response status message are set */
4075
  int resp_code;
4076
  struct mg_str resp_status_msg;
4077

    
4078
  /*
4079
   * Query-string part of the URI. For example, for HTTP request
4080
   *    GET /foo/bar?param1=val1&param2=val2
4081
   *    |    uri    |     query_string     |
4082
   *
4083
   * Note that question mark character doesn't belong neither to the uri,
4084
   * nor to the query_string
4085
   */
4086
  struct mg_str query_string;
4087

    
4088
  /* Headers */
4089
  struct mg_str header_names[MG_MAX_HTTP_HEADERS];
4090
  struct mg_str header_values[MG_MAX_HTTP_HEADERS];
4091

    
4092
  /* Message body */
4093
  struct mg_str body; /* Zero-length for requests with no body */
4094
};
4095

    
4096
#if MG_ENABLE_HTTP_WEBSOCKET
4097
/* WebSocket message */
4098
struct websocket_message {
4099
  unsigned char *data;
4100
  size_t size;
4101
  unsigned char flags;
4102
};
4103
#endif
4104

    
4105
/* HTTP multipart part */
4106
struct mg_http_multipart_part {
4107
  const char *file_name;
4108
  const char *var_name;
4109
  struct mg_str data;
4110
  int status; /* <0 on error */
4111
  void *user_data;
4112
};
4113

    
4114
/* SSI call context */
4115
struct mg_ssi_call_ctx {
4116
  struct http_message *req; /* The request being processed. */
4117
  struct mg_str file;       /* Filesystem path of the file being processed. */
4118
  struct mg_str arg; /* The argument passed to the tag: <!-- call arg -->. */
4119
};
4120

    
4121
/* HTTP and websocket events. void *ev_data is described in a comment. */
4122
#define MG_EV_HTTP_REQUEST 100 /* struct http_message * */
4123
#define MG_EV_HTTP_REPLY 101   /* struct http_message * */
4124
#define MG_EV_HTTP_CHUNK 102   /* struct http_message * */
4125
#define MG_EV_SSI_CALL 105     /* char * */
4126
#define MG_EV_SSI_CALL_CTX 106 /* struct mg_ssi_call_ctx * */
4127

    
4128
#if MG_ENABLE_HTTP_WEBSOCKET
4129
#define MG_EV_WEBSOCKET_HANDSHAKE_REQUEST 111 /* struct http_message * */
4130
#define MG_EV_WEBSOCKET_HANDSHAKE_DONE 112    /* NULL */
4131
#define MG_EV_WEBSOCKET_FRAME 113             /* struct websocket_message * */
4132
#define MG_EV_WEBSOCKET_CONTROL_FRAME 114     /* struct websocket_message * */
4133
#endif
4134

    
4135
#if MG_ENABLE_HTTP_STREAMING_MULTIPART
4136
#define MG_EV_HTTP_MULTIPART_REQUEST 121 /* struct http_message */
4137
#define MG_EV_HTTP_PART_BEGIN 122        /* struct mg_http_multipart_part */
4138
#define MG_EV_HTTP_PART_DATA 123         /* struct mg_http_multipart_part */
4139
#define MG_EV_HTTP_PART_END 124          /* struct mg_http_multipart_part */
4140
/* struct mg_http_multipart_part */
4141
#define MG_EV_HTTP_MULTIPART_REQUEST_END 125
4142
#endif
4143

    
4144
/*
4145
 * Attaches a built-in HTTP event handler to the given connection.
4146
 * The user-defined event handler will receive following extra events:
4147
 *
4148
 * - MG_EV_HTTP_REQUEST: HTTP request has arrived. Parsed HTTP request
4149
 *  is passed as
4150
 *   `struct http_message` through the handler's `void *ev_data` pointer.
4151
 * - MG_EV_HTTP_REPLY: The HTTP reply has arrived. The parsed HTTP reply is
4152
 *   passed as `struct http_message` through the handler's `void *ev_data`
4153
 *   pointer.
4154
 * - MG_EV_HTTP_CHUNK: The HTTP chunked-encoding chunk has arrived.
4155
 *   The parsed HTTP reply is passed as `struct http_message` through the
4156
 *   handler's `void *ev_data` pointer. `http_message::body` would contain
4157
 *   incomplete, reassembled HTTP body.
4158
 *   It will grow with every new chunk that arrives, and it can
4159
 *   potentially consume a lot of memory. An event handler may process
4160
 *   the body as chunks are coming, and signal Mongoose to delete processed
4161
 *   body by setting `MG_F_DELETE_CHUNK` in `mg_connection::flags`. When
4162
 *   the last zero chunk is received,
4163
 *   Mongoose sends `MG_EV_HTTP_REPLY` event with
4164
 *   full reassembled body (if handler did not signal to delete chunks) or
4165
 *   with empty body (if handler did signal to delete chunks).
4166
 * - MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: server has received the WebSocket
4167
 *   handshake request. `ev_data` contains parsed HTTP request.
4168
 * - MG_EV_WEBSOCKET_HANDSHAKE_DONE: server has completed the WebSocket
4169
 *   handshake. `ev_data` is `NULL`.
4170
 * - MG_EV_WEBSOCKET_FRAME: new WebSocket frame has arrived. `ev_data` is
4171
 *   `struct websocket_message *`
4172
 *
4173
 * When compiled with MG_ENABLE_HTTP_STREAMING_MULTIPART, Mongoose parses
4174
 * multipart requests and splits them into separate events:
4175
 * - MG_EV_HTTP_MULTIPART_REQUEST: Start of the request.
4176
 *   This event is sent before body is parsed. After this, the user
4177
 *   should expect a sequence of PART_BEGIN/DATA/END requests.
4178
 *   This is also the last time when headers and other request fields are
4179
 *   accessible.
4180
 * - MG_EV_HTTP_PART_BEGIN: Start of a part of a multipart message.
4181
 *   Argument: mg_http_multipart_part with var_name and file_name set
4182
 *   (if present). No data is passed in this message.
4183
 * - MG_EV_HTTP_PART_DATA: new portion of data from the multipart message.
4184
 *   Argument: mg_http_multipart_part. var_name and file_name are preserved,
4185
 *   data is available in mg_http_multipart_part.data.
4186
 * - MG_EV_HTTP_PART_END: End of the current part. var_name, file_name are
4187
 *   the same, no data in the message. If status is 0, then the part is
4188
 *   properly terminated with a boundary, status < 0 means that connection
4189
 *   was terminated.
4190
 * - MG_EV_HTTP_MULTIPART_REQUEST_END: End of the multipart request.
4191
 *   Argument: mg_http_multipart_part, var_name and file_name are NULL,
4192
 *   status = 0 means request was properly closed, < 0 means connection
4193
 *   was terminated (note: in this case both PART_END and REQUEST_END are
4194
 *   delivered).
4195
 */
4196
void mg_set_protocol_http_websocket(struct mg_connection *nc);
4197

    
4198
#if MG_ENABLE_HTTP_WEBSOCKET
4199
/*
4200
 * Send websocket handshake to the server.
4201
 *
4202
 * `nc` must be a valid connection, connected to a server. `uri` is an URI
4203
 * to fetch, extra_headers` is extra HTTP headers to send or `NULL`.
4204
 *
4205
 * This function is intended to be used by websocket client.
4206
 *
4207
 * Note that the Host header is mandatory in HTTP/1.1 and must be
4208
 * included in `extra_headers`. `mg_send_websocket_handshake2` offers
4209
 * a better API for that.
4210
 *
4211
 * Deprecated in favour of `mg_send_websocket_handshake2`
4212
 */
4213
void mg_send_websocket_handshake(struct mg_connection *nc, const char *uri,
4214
                                 const char *extra_headers);
4215

    
4216
/*
4217
 * Send websocket handshake to the server.
4218
 *
4219
 * `nc` must be a valid connection, connected to a server. `uri` is an URI
4220
 * to fetch, `host` goes into the `Host` header, `protocol` goes into the
4221
 * `Sec-WebSocket-Proto` header (NULL to omit), extra_headers` is extra HTTP
4222
 * headers to send or `NULL`.
4223
 *
4224
 * This function is intended to be used by websocket client.
4225
 */
4226
void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path,
4227
                                  const char *host, const char *protocol,
4228
                                  const char *extra_headers);
4229

    
4230
/* Like mg_send_websocket_handshake2 but also passes basic auth header */
4231
void mg_send_websocket_handshake3(struct mg_connection *nc, const char *path,
4232
                                  const char *host, const char *protocol,
4233
                                  const char *extra_headers, const char *user,
4234
                                  const char *pass);
4235
/*
4236
 * Helper function that creates an outbound WebSocket connection.
4237
 *
4238
 * `url` is a URL to connect to. It must be properly URL-encoded, e.g. have
4239
 * no spaces, etc. By default, `mg_connect_ws()` sends Connection and
4240
 * Host headers. `extra_headers` is an extra HTTP header to send, e.g.
4241
 * `"User-Agent: my-app\r\n"`.
4242
 * If `protocol` is not NULL, then a `Sec-WebSocket-Protocol` header is sent.
4243
 *
4244
 * Examples:
4245
 *
4246
 * ```c
4247
 *   nc1 = mg_connect_ws(mgr, ev_handler_1, "ws://echo.websocket.org", NULL,
4248
 *                       NULL);
4249
 *   nc2 = mg_connect_ws(mgr, ev_handler_1, "wss://echo.websocket.org", NULL,
4250
 *                       NULL);
4251
 *   nc3 = mg_connect_ws(mgr, ev_handler_1, "ws://api.cesanta.com",
4252
 *                       "clubby.cesanta.com", NULL);
4253
 * ```
4254
 */
4255
struct mg_connection *mg_connect_ws(struct mg_mgr *mgr,
4256
                                    mg_event_handler_t event_handler,
4257
                                    const char *url, const char *protocol,
4258
                                    const char *extra_headers);
4259

    
4260
/*
4261
 * Helper function that creates an outbound WebSocket connection
4262
 *
4263
 * Mostly identical to `mg_connect_ws`, but allows to provide extra parameters
4264
 * (for example, SSL parameters)
4265
 */
4266
struct mg_connection *mg_connect_ws_opt(struct mg_mgr *mgr,
4267
                                        mg_event_handler_t ev_handler,
4268
                                        struct mg_connect_opts opts,
4269
                                        const char *url, const char *protocol,
4270
                                        const char *extra_headers);
4271

    
4272
/*
4273
 * Send WebSocket frame to the remote end.
4274
 *
4275
 * `op_and_flags` specifies the frame's type. It's one of:
4276
 *
4277
 * - WEBSOCKET_OP_CONTINUE
4278
 * - WEBSOCKET_OP_TEXT
4279
 * - WEBSOCKET_OP_BINARY
4280
 * - WEBSOCKET_OP_CLOSE
4281
 * - WEBSOCKET_OP_PING
4282
 * - WEBSOCKET_OP_PONG
4283
 *
4284
 * Orred with one of the flags:
4285
 *
4286
 * - WEBSOCKET_DONT_FIN: Don't set the FIN flag on the frame to be sent.
4287
 *
4288
 * `data` and `data_len` contain frame data.
4289
 */
4290
void mg_send_websocket_frame(struct mg_connection *nc, int op_and_flags,
4291
                             const void *data, size_t data_len);
4292

    
4293
/*
4294
 * Sends multiple websocket frames.
4295
 *
4296
 * Like `mg_send_websocket_frame()`, but composes a frame from multiple buffers.
4297
 */
4298
void mg_send_websocket_framev(struct mg_connection *nc, int op_and_flags,
4299
                              const struct mg_str *strings, int num_strings);
4300

    
4301
/*
4302
 * Sends WebSocket frame to the remote end.
4303
 *
4304
 * Like `mg_send_websocket_frame()`, but allows to create formatted messages
4305
 * with `printf()`-like semantics.
4306
 */
4307
void mg_printf_websocket_frame(struct mg_connection *nc, int op_and_flags,
4308
                               const char *fmt, ...);
4309

    
4310
/* Websocket opcodes, from http://tools.ietf.org/html/rfc6455 */
4311
#define WEBSOCKET_OP_CONTINUE 0
4312
#define WEBSOCKET_OP_TEXT 1
4313
#define WEBSOCKET_OP_BINARY 2
4314
#define WEBSOCKET_OP_CLOSE 8
4315
#define WEBSOCKET_OP_PING 9
4316
#define WEBSOCKET_OP_PONG 10
4317

    
4318
/*
4319
 * If set causes the FIN flag to not be set on outbound
4320
 * frames. This enables sending multiple fragments of a single
4321
 * logical message.
4322
 *
4323
 * The WebSocket protocol mandates that if the FIN flag of a data
4324
 * frame is not set, the next frame must be a WEBSOCKET_OP_CONTINUE.
4325
 * The last frame must have the FIN bit set.
4326
 *
4327
 * Note that mongoose will automatically defragment incoming messages,
4328
 * so this flag is used only on outbound messages.
4329
 */
4330
#define WEBSOCKET_DONT_FIN 0x100
4331

    
4332
#endif /* MG_ENABLE_HTTP_WEBSOCKET */
4333

    
4334
/*
4335
 * Decodes a URL-encoded string.
4336
 *
4337
 * Source string is specified by (`src`, `src_len`), and destination is
4338
 * (`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then
4339
 * `+` character is decoded as a blank space character. This function
4340
 * guarantees to NUL-terminate the destination. If destination is too small,
4341
 * then the source string is partially decoded and `-1` is returned. Otherwise,
4342
 * a length of the decoded string is returned, not counting final NUL.
4343
 */
4344
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len,
4345
                  int is_form_url_encoded);
4346

    
4347
#ifdef __cplusplus
4348
}
4349
#endif /* __cplusplus */
4350

    
4351
#endif /* MG_ENABLE_HTTP */
4352

    
4353
#endif /* CS_MONGOOSE_SRC_HTTP_H_ */
4354
#ifdef MG_MODULE_LINES
4355
#line 1 "mongoose/src/http_server.h"
4356
#endif
4357
/*
4358
 * === Server API reference
4359
 */
4360

    
4361
#ifndef CS_MONGOOSE_SRC_HTTP_SERVER_H_
4362
#define CS_MONGOOSE_SRC_HTTP_SERVER_H_
4363

    
4364
#if MG_ENABLE_HTTP
4365

    
4366
#ifdef __cplusplus
4367
extern "C" {
4368
#endif /* __cplusplus */
4369

    
4370
/*
4371
 * Parses a HTTP message.
4372
 *
4373
 * `is_req` should be set to 1 if parsing a request, 0 if reply.
4374
 *
4375
 * Returns the number of bytes parsed. If HTTP message is
4376
 * incomplete `0` is returned. On parse error, a negative number is returned.
4377
 */
4378
int mg_parse_http(const char *s, int n, struct http_message *hm, int is_req);
4379

    
4380
/*
4381
 * Searches and returns the header `name` in parsed HTTP message `hm`.
4382
 * If header is not found, NULL is returned. Example:
4383
 *
4384
 *     struct mg_str *host_hdr = mg_get_http_header(hm, "Host");
4385
 */
4386
struct mg_str *mg_get_http_header(struct http_message *hm, const char *name);
4387

    
4388
/*
4389
 * Parses the HTTP header `hdr`. Finds variable `var_name` and stores its value
4390
 * in the buffer `buf`, `buf_size`. Returns 0 if variable not found, non-zero
4391
 * otherwise.
4392
 *
4393
 * This function is supposed to parse cookies, authentication headers, etc.
4394
 * Example (error handling omitted):
4395
 *
4396
 *     char user[20];
4397
 *     struct mg_str *hdr = mg_get_http_header(hm, "Authorization");
4398
 *     mg_http_parse_header(hdr, "username", user, sizeof(user));
4399
 *
4400
 * Returns the length of the variable's value. If buffer is not large enough,
4401
 * or variable not found, 0 is returned.
4402
 */
4403
int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,
4404
                         size_t buf_size);
4405

    
4406
/*
4407
 * Gets and parses the Authorization: Basic header
4408
 * Returns -1 if no Authorization header is found, or if
4409
 * mg_parse_http_basic_auth
4410
 * fails parsing the resulting header.
4411
 */
4412
int mg_get_http_basic_auth(struct http_message *hm, char *user, size_t user_len,
4413
                           char *pass, size_t pass_len);
4414

    
4415
/*
4416
 * Parses the Authorization: Basic header
4417
 * Returns -1 iif the authorization type is not "Basic" or any other error such
4418
 * as incorrectly encoded base64 user password pair.
4419
 */
4420
int mg_parse_http_basic_auth(struct mg_str *hdr, char *user, size_t user_len,
4421
                             char *pass, size_t pass_len);
4422

    
4423
/*
4424
 * Parses the buffer `buf`, `buf_len` that contains multipart form data chunks.
4425
 * Stores the chunk name in a `var_name`, `var_name_len` buffer.
4426
 * If a chunk is an uploaded file, then `file_name`, `file_name_len` is
4427
 * filled with an uploaded file name. `chunk`, `chunk_len`
4428
 * points to the chunk data.
4429
 *
4430
 * Return: number of bytes to skip to the next chunk or 0 if there are
4431
 *         no more chunks.
4432
 *
4433
 * Usage example:
4434
 *
4435
 * ```c
4436
 *    static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
4437
 *      switch(ev) {
4438
 *        case MG_EV_HTTP_REQUEST: {
4439
 *          struct http_message *hm = (struct http_message *) ev_data;
4440
 *          char var_name[100], file_name[100];
4441
 *          const char *chunk;
4442
 *          size_t chunk_len, n1, n2;
4443
 *
4444
 *          n1 = n2 = 0;
4445
 *          while ((n2 = mg_parse_multipart(hm->body.p + n1,
4446
 *                                          hm->body.len - n1,
4447
 *                                          var_name, sizeof(var_name),
4448
 *                                          file_name, sizeof(file_name),
4449
 *                                          &chunk, &chunk_len)) > 0) {
4450
 *            printf("var: %s, file_name: %s, size: %d, chunk: [%.*s]\n",
4451
 *                   var_name, file_name, (int) chunk_len,
4452
 *                   (int) chunk_len, chunk);
4453
 *            n1 += n2;
4454
 *          }
4455
 *        }
4456
 *        break;
4457
 * ```
4458
 */
4459
size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
4460
                          size_t var_name_len, char *file_name,
4461
                          size_t file_name_len, const char **chunk,
4462
                          size_t *chunk_len);
4463

    
4464
/*
4465
 * Fetches a HTTP form variable.
4466
 *
4467
 * Fetches a variable `name` from a `buf` into a buffer specified by `dst`,
4468
 * `dst_len`. The destination is always zero-terminated. Returns the length of
4469
 * a fetched variable. If not found, 0 is returned. `buf` must be valid
4470
 * url-encoded buffer. If destination is too small, `-1` is returned.
4471
 */
4472
int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst,
4473
                    size_t dst_len);
4474

    
4475
#if MG_ENABLE_FILESYSTEM
4476
/*
4477
 * This structure defines how `mg_serve_http()` works.
4478
 * Best practice is to set only required settings, and leave the rest as NULL.
4479
 */
4480
struct mg_serve_http_opts {
4481
  /* Path to web root directory */
4482
  const char *document_root;
4483

    
4484
  /* List of index files. Default is "" */
4485
  const char *index_files;
4486

    
4487
  /*
4488
   * Leave as NULL to disable authentication.
4489
   * To enable directory protection with authentication, set this to ".htpasswd"
4490
   * Then, creating ".htpasswd" file in any directory automatically protects
4491
   * it with digest authentication.
4492
   * Use `mongoose` web server binary, or `htdigest` Apache utility to
4493
   * create/manipulate passwords file.
4494
   * Make sure `auth_domain` is set to a valid domain name.
4495
   */
4496
  const char *per_directory_auth_file;
4497

    
4498
  /* Authorization domain (domain name of this web server) */
4499
  const char *auth_domain;
4500

    
4501
  /*
4502
   * Leave as NULL to disable authentication.
4503
   * Normally, only selected directories in the document root are protected.
4504
   * If absolutely every access to the web server needs to be authenticated,
4505
   * regardless of the URI, set this option to the path to the passwords file.
4506
   * Format of that file is the same as ".htpasswd" file. Make sure that file
4507
   * is located outside document root to prevent people fetching it.
4508
   */
4509
  const char *global_auth_file;
4510

    
4511
  /* Set to "no" to disable directory listing. Enabled by default. */
4512
  const char *enable_directory_listing;
4513

    
4514
  /*
4515
   * SSI files pattern. If not set, "**.shtml$|**.shtm$" is used.
4516
   *
4517
   * All files that match ssi_pattern are treated as SSI.
4518
   *
4519
   * Server Side Includes (SSI) is a simple interpreted server-side scripting
4520
   * language which is most commonly used to include the contents of a file
4521
   * into a web page. It can be useful when it is desirable to include a common
4522
   * piece of code throughout a website, for example, headers and footers.
4523
   *
4524
   * In order for a webpage to recognize an SSI-enabled HTML file, the
4525
   * filename should end with a special extension, by default the extension
4526
   * should be either .shtml or .shtm
4527
   *
4528
   * Unknown SSI directives are silently ignored by Mongoose. Currently,
4529
   * the following SSI directives are supported:
4530
   *    &lt;!--#include FILE_TO_INCLUDE --&gt;
4531
   *    &lt;!--#exec "COMMAND_TO_EXECUTE" --&gt;
4532
   *    &lt;!--#call COMMAND --&gt;
4533
   *
4534
   * Note that &lt;!--#include ...> directive supports three path
4535
   *specifications:
4536
   *
4537
   * &lt;!--#include virtual="path" --&gt;  Path is relative to web server root
4538
   * &lt;!--#include abspath="path" --&gt;  Path is absolute or relative to the
4539
   *                                  web server working dir
4540
   * &lt;!--#include file="path" --&gt;,    Path is relative to current document
4541
   * &lt;!--#include "path" --&gt;
4542
   *
4543
   * The include directive may be used to include the contents of a file or
4544
   * the result of running a CGI script.
4545
   *
4546
   * The exec directive is used to execute
4547
   * a command on a server, and show command's output. Example:
4548
   *
4549
   * &lt;!--#exec "ls -l" --&gt;
4550
   *
4551
   * The call directive is a way to invoke a C handler from the HTML page.
4552
   * On each occurence of &lt;!--#call COMMAND OPTIONAL_PARAMS> directive,
4553
   * Mongoose calls a registered event handler with MG_EV_SSI_CALL event,
4554
   * and event parameter will point to the COMMAND OPTIONAL_PARAMS string.
4555
   * An event handler can output any text, for example by calling
4556
   * `mg_printf()`. This is a flexible way of generating a web page on
4557
   * server side by calling a C event handler. Example:
4558
   *
4559
   * &lt;!--#call foo --&gt; ... &lt;!--#call bar --&gt;
4560
   *
4561
   * In the event handler:
4562
   *    case MG_EV_SSI_CALL: {
4563
   *      const char *param = (const char *) ev_data;
4564
   *      if (strcmp(param, "foo") == 0) {
4565
   *        mg_printf(c, "hello from foo");
4566
   *      } else if (strcmp(param, "bar") == 0) {
4567
   *        mg_printf(c, "hello from bar");
4568
   *      }
4569
   *      break;
4570
   *    }
4571
   */
4572
  const char *ssi_pattern;
4573

    
4574
  /* IP ACL. By default, NULL, meaning all IPs are allowed to connect */
4575
  const char *ip_acl;
4576

    
4577
#if MG_ENABLE_HTTP_URL_REWRITES
4578
  /* URL rewrites.
4579
   *
4580
   * Comma-separated list of `uri_pattern=url_file_or_directory_path` rewrites.
4581
   * When HTTP request is received, Mongoose constructs a file name from the
4582
   * requested URI by combining `document_root` and the URI. However, if the
4583
   * rewrite option is used and `uri_pattern` matches requested URI, then
4584
   * `document_root` is ignored. Instead, `url_file_or_directory_path` is used,
4585
   * which should be a full path name or a path relative to the web server's
4586
   * current working directory. It can also be an URI (http:// or https://)
4587
   * in which case mongoose will behave as a reverse proxy for that destination.
4588
   *
4589
   * Note that `uri_pattern`, as all Mongoose patterns, is a prefix pattern.
4590
   *
4591
   * If uri_pattern starts with `@` symbol, then Mongoose compares it with the
4592
   * HOST header of the request. If they are equal, Mongoose sets document root
4593
   * to `file_or_directory_path`, implementing virtual hosts support.
4594
   * Example: `@foo.com=/document/root/for/foo.com`
4595
   *
4596
   * If `uri_pattern` starts with `%` symbol, then Mongoose compares it with
4597
   * the listening port. If they match, then Mongoose issues a 301 redirect.
4598
   * For example, to redirect all HTTP requests to the
4599
   * HTTPS port, do `%80=https://my.site.com`. Note that the request URI is
4600
   * automatically appended to the redirect location.
4601
   */
4602
  const char *url_rewrites;
4603
#endif
4604

    
4605
  /* DAV document root. If NULL, DAV requests are going to fail. */
4606
  const char *dav_document_root;
4607

    
4608
  /*
4609
   * DAV passwords file. If NULL, DAV requests are going to fail.
4610
   * If passwords file is set to "-", then DAV auth is disabled.
4611
   */
4612
  const char *dav_auth_file;
4613

    
4614
  /* Glob pattern for the files to hide. */
4615
  const char *hidden_file_pattern;
4616

    
4617
  /* Set to non-NULL to enable CGI, e.g. **.cgi$|**.php$" */
4618
  const char *cgi_file_pattern;
4619

    
4620
  /* If not NULL, ignore CGI script hashbang and use this interpreter */
4621
  const char *cgi_interpreter;
4622

    
4623
  /*
4624
   * Comma-separated list of Content-Type overrides for path suffixes, e.g.
4625
   * ".txt=text/plain; charset=utf-8,.c=text/plain"
4626
   */
4627
  const char *custom_mime_types;
4628

    
4629
  /*
4630
   * Extra HTTP headers to add to each server response.
4631
   * Example: to enable CORS, set this to "Access-Control-Allow-Origin: *".
4632
   */
4633
  const char *extra_headers;
4634
};
4635

    
4636
/*
4637
 * Serves given HTTP request according to the `options`.
4638
 *
4639
 * Example code snippet:
4640
 *
4641
 * ```c
4642
 * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
4643
 *   struct http_message *hm = (struct http_message *) ev_data;
4644
 *   struct mg_serve_http_opts opts = { .document_root = "/var/www" };  // C99
4645
 *
4646
 *   switch (ev) {
4647
 *     case MG_EV_HTTP_REQUEST:
4648
 *       mg_serve_http(nc, hm, opts);
4649
 *       break;
4650
 *     default:
4651
 *       break;
4652
 *   }
4653
 * }
4654
 * ```
4655
 */
4656
void mg_serve_http(struct mg_connection *nc, struct http_message *hm,
4657
                   struct mg_serve_http_opts opts);
4658

    
4659
/*
4660
 * Serves a specific file with a given MIME type and optional extra headers.
4661
 *
4662
 * Example code snippet:
4663
 *
4664
 * ```c
4665
 * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
4666
 *   switch (ev) {
4667
 *     case MG_EV_HTTP_REQUEST: {
4668
 *       struct http_message *hm = (struct http_message *) ev_data;
4669
 *       mg_http_serve_file(nc, hm, "file.txt",
4670
 *                          mg_mk_str("text/plain"), mg_mk_str(""));
4671
 *       break;
4672
 *     }
4673
 *     ...
4674
 *   }
4675
 * }
4676
 * ```
4677
 */
4678
void mg_http_serve_file(struct mg_connection *nc, struct http_message *hm,
4679
                        const char *path, const struct mg_str mime_type,
4680
                        const struct mg_str extra_headers);
4681

    
4682
#if MG_ENABLE_HTTP_STREAMING_MULTIPART
4683

    
4684
/* Callback prototype for `mg_file_upload_handler()`. */
4685
typedef struct mg_str (*mg_fu_fname_fn)(struct mg_connection *nc,
4686
                                        struct mg_str fname);
4687

    
4688
/*
4689
 * File upload handler.
4690
 * This handler can be used to implement file uploads with minimum code.
4691
 * This handler will process MG_EV_HTTP_PART_* events and store file data into
4692
 * a local file.
4693
 * `local_name_fn` will be invoked with whatever name was provided by the client
4694
 * and will expect the name of the local file to open. A return value of NULL
4695
 * will abort file upload (client will get a "403 Forbidden" response). If
4696
 * non-null, the returned string must be heap-allocated and will be freed by
4697
 * the caller.
4698
 * Exception: it is ok to return the same string verbatim.
4699
 *
4700
 * Example:
4701
 *
4702
 * ```c
4703
 * struct mg_str upload_fname(struct mg_connection *nc, struct mg_str fname) {
4704
 *   // Just return the same filename. Do not actually do this except in test!
4705
 *   // fname is user-controlled and needs to be sanitized.
4706
 *   return fname;
4707
 * }
4708
 * void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
4709
 *   switch (ev) {
4710
 *     ...
4711
 *     case MG_EV_HTTP_PART_BEGIN:
4712
 *     case MG_EV_HTTP_PART_DATA:
4713
 *     case MG_EV_HTTP_PART_END:
4714
 *       mg_file_upload_handler(nc, ev, ev_data, upload_fname);
4715
 *       break;
4716
 *   }
4717
 * }
4718
 * ```
4719
 */
4720
void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
4721
                            mg_fu_fname_fn local_name_fn);
4722
#endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */
4723
#endif /* MG_ENABLE_FILESYSTEM */
4724

    
4725
/*
4726
 * Registers a callback for a specified http endpoint
4727
 * Note: if callback is registered it is called instead of the
4728
 * callback provided in mg_bind
4729
 *
4730
 * Example code snippet:
4731
 *
4732
 * ```c
4733
 * static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
4734
 *   (void) ev; (void) ev_data;
4735
 *   mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello1]");
4736
 *  nc->flags |= MG_F_SEND_AND_CLOSE;
4737
 * }
4738
 *
4739
 * static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
4740
 *  (void) ev; (void) ev_data;
4741
 *   mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello2]");
4742
 *  nc->flags |= MG_F_SEND_AND_CLOSE;
4743
 * }
4744
 *
4745
 * void init() {
4746
 *   nc = mg_bind(&mgr, local_addr, cb1);
4747
 *   mg_register_http_endpoint(nc, "/hello1", handle_hello1);
4748
 *   mg_register_http_endpoint(nc, "/hello1/hello2", handle_hello2);
4749
 * }
4750
 * ```
4751
 */
4752
void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,
4753
                               mg_event_handler_t handler);
4754

    
4755
/*
4756
 * Authenticates a HTTP request against an opened password file.
4757
 * Returns 1 if authenticated, 0 otherwise.
4758
 */
4759
int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain,
4760
                              FILE *fp);
4761

    
4762
/*
4763
 * Sends buffer `buf` of size `len` to the client using chunked HTTP encoding.
4764
 * This function sends the buffer size as hex number + newline first, then
4765
 * the buffer itself, then the newline. For example,
4766
 * `mg_send_http_chunk(nc, "foo", 3)` whill append the `3\r\nfoo\r\n` string
4767
 * to the `nc->send_mbuf` output IO buffer.
4768
 *
4769
 * NOTE: The HTTP header "Transfer-Encoding: chunked" should be sent prior to
4770
 * using this function.
4771
 *
4772
 * NOTE: do not forget to send an empty chunk at the end of the response,
4773
 * to tell the client that everything was sent. Example:
4774
 *
4775
 * ```
4776
 *   mg_printf_http_chunk(nc, "%s", "my response!");
4777
 *   mg_send_http_chunk(nc, "", 0); // Tell the client we're finished
4778
 * ```
4779
 */
4780
void mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len);
4781

    
4782
/*
4783
 * Sends a printf-formatted HTTP chunk.
4784
 * Functionality is similar to `mg_send_http_chunk()`.
4785
 */
4786
void mg_printf_http_chunk(struct mg_connection *nc, const char *fmt, ...);
4787

    
4788
/*
4789
 * Sends th