Statistics
| Branch: | Tag: | Revision:

mongoose / mongoose.h @ 577ad259

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.7"
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 <dirent.h>
478
#include <fcntl.h>
479
#include <inttypes.h>
480
#include <machine/endian.h>
481
#include <stdint.h>
482
#include <string.h>
483
#include <sys/stat.h>
484
#include <sys/time.h>
485

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

    
495
#define MG_LWIP 1
496

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

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

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

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

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

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

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

    
541
#define MG_LWIP 1
542

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

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

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

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

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

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

    
581
#define MG_NET_IF MG_NET_IF_SIMPLELINK
582
#define MG_SSL_IF MG_SSL_IF_SIMPLELINK
583

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

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

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

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

    
602
#define SOMAXCONN 8
603

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

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

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

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

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

    
635
#define MG_NET_IF MG_NET_IF_SIMPLELINK
636
#define MG_SSL_IF MG_SSL_IF_SIMPLELINK
637

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

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

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

    
655
#define fileno(x) -1
656

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

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

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

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

    
670
#endif
671

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

    
675
#include <file.h>
676

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

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

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

    
692
#define __S_IFMT 0170000
693

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

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

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

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

    
709
#endif /* __TI_COMPILER_VERSION__ */
710

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

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

    
719
#define d_name name
720
#define dirent spiffs_dirent
721

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

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

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

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

    
740
#ifdef __cplusplus
741
}
742
#endif
743

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

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

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

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

    
771
#define MG_NET_IF MG_NET_IF_SIMPLELINK
772
#define MG_SSL_IF MG_SSL_IF_SIMPLELINK
773

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

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

    
786
#define fileno(x) -1
787

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

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

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

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

    
803
#include <file.h>
804

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

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

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

    
820
#define __S_IFMT 0170000
821

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

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

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

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

    
837
#endif /* __TI_COMPILER_VERSION__ */
838

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

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

    
847
#ifdef __cplusplus
848
}
849
#endif
850

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

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

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

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

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

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

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

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

    
907
#ifdef __cplusplus
908
}
909
#endif
910

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

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

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

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

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

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

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

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

    
969
#endif
970

    
971
#if MG_NET_IF == MG_NET_IF_SIMPLELINK
972

    
973
#define MG_SIMPLELINK_NO_OSI 1
974

    
975
#include <simplelink.h>
976

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

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

    
985
#define SOMAXCONN 8
986

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1097
#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
1098
#define CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
1099

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

    
1104
#include <stdbool.h>
1105

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

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

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

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

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

    
1135
#define SOCK_STREAM SL_SOCK_STREAM
1136
#define SOCK_DGRAM SL_SOCK_DGRAM
1137

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

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

    
1165
#define SOMAXCONN 8
1166

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

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

    
1175
struct mg_mgr;
1176
struct mg_connection;
1177

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

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

    
1183
int sl_fs_init(void);
1184

    
1185
void sl_restart_cb(struct mg_mgr *mgr);
1186

    
1187
int sl_set_ssl_opts(struct mg_connection *nc);
1188

    
1189
#ifdef __cplusplus
1190
}
1191
#endif
1192

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

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

    
1202
#if CS_PLATFORM == CS_P_WINCE
1203

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

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

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

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

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

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

    
1240
#define strdup _strdup
1241

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

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

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

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

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

    
1269
typedef int socklen_t;
1270

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

    
1284
typedef SOCKET sock_t;
1285
typedef uint32_t in_addr_t;
1286

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

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

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

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

    
1304
#define DIRSEP '\\'
1305

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

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

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

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

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

    
1330
#define abort() DebugBreak();
1331

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

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

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

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

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

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

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

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

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

    
1378
#define _S_IFREG 2
1379
#define _S_IFDIR 4
1380

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

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

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

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

    
1403
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_
1404
#define CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_
1405

    
1406
#if CS_PLATFORM == CS_P_NXP_LPC
1407

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

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

    
1418
#define MG_LWIP 1
1419

    
1420
#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1421

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

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

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

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

    
1438
#define CS_ENABLE_STRDUP 1
1439

    
1440
#else
1441

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

    
1446
#endif
1447

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

    
1458
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_
1459
#define CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_
1460

    
1461
#if CS_PLATFORM == CS_P_NXP_KINETIS
1462

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

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

    
1475
#define MG_LWIP 1
1476

    
1477
#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL
1478

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

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

    
1492
#ifndef CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_
1493
#define CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_
1494

    
1495
#if CS_PLATFORM == CS_P_PIC32
1496

    
1497
#define MG_NET_IF MG_NET_IF_PIC32
1498

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

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

    
1507
#include <sys/types.h>
1508

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

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

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

    
1519
char* inet_ntoa(struct in_addr in);
1520

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

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

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

    
1536
#include <sys/types.h>
1537
#include <sys/stat.h>
1538
#include <stdint.h>
1539
#include <inttypes.h>
1540
#include <stdio.h>
1541
#include <ctype.h>
1542
#include <errno.h>
1543
#include <memory.h>
1544
#include <fcntl.h>
1545

    
1546
#define to64(x) strtoll(x, NULL, 10)
1547
#define INT64_FMT PRId64
1548
#define SIZE_T_FMT "u"
1549
typedef struct stat cs_stat_t;
1550
#define DIRSEP '/'
1551

    
1552
#ifndef CS_ENABLE_STDIO
1553
#define CS_ENABLE_STDIO 1
1554
#endif
1555

    
1556
#ifndef MG_ENABLE_FILESYSTEM
1557
#define MG_ENABLE_FILESYSTEM 1
1558
#endif
1559

    
1560
#endif /* CS_PLATFORM == CS_P_STM32 */
1561
#endif /* CS_COMMON_PLATFORMS_PLATFORM_STM32_H_ */
1562
#ifdef MG_MODULE_LINES
1563
#line 1 "common/platforms/lwip/mg_lwip.h"
1564
#endif
1565
/*
1566
 * Copyright (c) 2014-2016 Cesanta Software Limited
1567
 * All rights reserved
1568
 */
1569

    
1570
#ifndef CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
1571
#define CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
1572

    
1573
#ifndef MG_LWIP
1574
#define MG_LWIP 0
1575
#endif
1576

    
1577
#if MG_LWIP
1578

    
1579
/*
1580
 * When compiling for nRF5x chips with arm-none-eabi-gcc, it has BYTE_ORDER
1581
 * already defined, so in order to avoid warnings in lwip, we have to undefine
1582
 * it.
1583
 *
1584
 * TODO: Check if in the future versions of nRF5 SDK that changes.
1585
 *       Current version of nRF51 SDK: 0.8.0
1586
 *                          nRF5 SDK:  0.9.0
1587
 */
1588
#if CS_PLATFORM == CS_P_NRF51 || CS_PLATFORM == CS_P_NRF52
1589
#undef BYTE_ORDER
1590
#endif
1591

    
1592
#include <lwip/opt.h>
1593
#include <lwip/err.h>
1594
#include <lwip/ip_addr.h>
1595
#include <lwip/inet.h>
1596
#include <lwip/netdb.h>
1597
#include <lwip/dns.h>
1598

    
1599
#ifndef LWIP_PROVIDE_ERRNO
1600
#include <errno.h>
1601
#endif
1602

    
1603
#if LWIP_SOCKET
1604
#include <lwip/sockets.h>
1605
#else
1606
/* We really need the definitions from sockets.h. */
1607
#undef LWIP_SOCKET
1608
#define LWIP_SOCKET 1
1609
#include <lwip/sockets.h>
1610
#undef LWIP_SOCKET
1611
#define LWIP_SOCKET 0
1612
#endif
1613

    
1614
#define INVALID_SOCKET (-1)
1615
#define SOMAXCONN 10
1616
typedef int sock_t;
1617

    
1618
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
1619
struct mg_mgr;
1620
struct mg_connection;
1621
uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr);
1622
void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
1623
                                  int interval, int count);
1624
#endif
1625

    
1626
#endif /* MG_LWIP */
1627

    
1628
#endif /* CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_ */
1629
#ifdef MG_MODULE_LINES
1630
#line 1 "common/cs_time.h"
1631
#endif
1632
/*
1633
 * Copyright (c) 2014-2016 Cesanta Software Limited
1634
 * All rights reserved
1635
 */
1636

    
1637
#ifndef CS_COMMON_CS_TIME_H_
1638
#define CS_COMMON_CS_TIME_H_
1639

    
1640
/* Amalgamated: #include "common/platform.h" */
1641

    
1642
#ifdef __cplusplus
1643
extern "C" {
1644
#endif /* __cplusplus */
1645

    
1646
/* Sub-second granularity time(). */
1647
double cs_time(void);
1648

    
1649
#ifdef __cplusplus
1650
}
1651
#endif /* __cplusplus */
1652

    
1653
#endif /* CS_COMMON_CS_TIME_H_ */
1654
#ifdef MG_MODULE_LINES
1655
#line 1 "common/mg_str.h"
1656
#endif
1657
/*
1658
 * Copyright (c) 2014-2016 Cesanta Software Limited
1659
 * All rights reserved
1660
 */
1661

    
1662
#ifndef CS_COMMON_MG_STR_H_
1663
#define CS_COMMON_MG_STR_H_
1664

    
1665
#include <stddef.h>
1666

    
1667
/* Amalgamated: #include "common/platform.h" */
1668

    
1669
#ifdef __cplusplus
1670
extern "C" {
1671
#endif /* __cplusplus */
1672

    
1673
/* Describes chunk of memory */
1674
struct mg_str {
1675
  const char *p; /* Memory chunk pointer */
1676
  size_t len;    /* Memory chunk length */
1677
};
1678

    
1679
/*
1680
 * Helper functions for creating mg_str struct from plain C string.
1681
 * `NULL` is allowed and becomes `{NULL, 0}`.
1682
 */
1683
struct mg_str mg_mk_str(const char *s);
1684
struct mg_str mg_mk_str_n(const char *s, size_t len);
1685

    
1686
/* Macro for initializing mg_str. */
1687
#define MG_MK_STR(str_literal) \
1688
  { str_literal, sizeof(str_literal) - 1 }
1689

    
1690
/*
1691
 * Cross-platform version of `strcmp()` where where first string is
1692
 * specified by `struct mg_str`.
1693
 */
1694
int mg_vcmp(const struct mg_str *str2, const char *str1);
1695

    
1696
/*
1697
 * Cross-platform version of `strncasecmp()` where first string is
1698
 * specified by `struct mg_str`.
1699
 */
1700
int mg_vcasecmp(const struct mg_str *str2, const char *str1);
1701

    
1702
struct mg_str mg_strdup(const struct mg_str s);
1703
int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
1704
int mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n);
1705

    
1706
#ifdef __cplusplus
1707
}
1708
#endif /* __cplusplus */
1709

    
1710
#endif /* CS_COMMON_MG_STR_H_ */
1711
#ifdef MG_MODULE_LINES
1712
#line 1 "common/mbuf.h"
1713
#endif
1714
/*
1715
 * Copyright (c) 2015 Cesanta Software Limited
1716
 * All rights reserved
1717
 */
1718

    
1719
/*
1720
 * === Memory Buffers
1721
 *
1722
 * Mbufs are mutable/growing memory buffers, like C++ strings.
1723
 * Mbuf can append data to the end of a buffer or insert data into arbitrary
1724
 * position in the middle of a buffer. The buffer grows automatically when
1725
 * needed.
1726
 */
1727

    
1728
#ifndef CS_COMMON_MBUF_H_
1729
#define CS_COMMON_MBUF_H_
1730

    
1731
#include <stdlib.h>
1732
/* Amalgamated: #include "common/platform.h" */
1733

    
1734
#if defined(__cplusplus)
1735
extern "C" {
1736
#endif
1737

    
1738
#ifndef MBUF_SIZE_MULTIPLIER
1739
#define MBUF_SIZE_MULTIPLIER 1.5
1740
#endif
1741

    
1742
/* Memory buffer descriptor */
1743
struct mbuf {
1744
  char *buf;   /* Buffer pointer */
1745
  size_t len;  /* Data length. Data is located between offset 0 and len. */
1746
  size_t size; /* Buffer size allocated by realloc(1). Must be >= len */
1747
};
1748

    
1749
/*
1750
 * Initialises an Mbuf.
1751
 * `initial_capacity` specifies the initial capacity of the mbuf.
1752
 */
1753
void mbuf_init(struct mbuf *, size_t initial_capacity);
1754

    
1755
/* Frees the space allocated for the mbuffer and resets the mbuf structure. */
1756
void mbuf_free(struct mbuf *);
1757

    
1758
/*
1759
 * Appends data to the Mbuf.
1760
 *
1761
 * Returns the number of bytes appended or 0 if out of memory.
1762
 */
1763
size_t mbuf_append(struct mbuf *, const void *data, size_t data_size);
1764

    
1765
/*
1766
 * Inserts data at a specified offset in the Mbuf.
1767
 *
1768
 * Existing data will be shifted forwards and the buffer will
1769
 * be grown if necessary.
1770
 * Returns the number of bytes inserted.
1771
 */
1772
size_t mbuf_insert(struct mbuf *, size_t, const void *, size_t);
1773

    
1774
/* Removes `data_size` bytes from the beginning of the buffer. */
1775
void mbuf_remove(struct mbuf *, size_t data_size);
1776

    
1777
/*
1778
 * Resizes an Mbuf.
1779
 *
1780
 * If `new_size` is smaller than buffer's `len`, the
1781
 * resize is not performed.
1782
 */
1783
void mbuf_resize(struct mbuf *, size_t new_size);
1784

    
1785
/* Shrinks an Mbuf by resizing its `size` to `len`. */
1786
void mbuf_trim(struct mbuf *);
1787

    
1788
#if defined(__cplusplus)
1789
}
1790
#endif /* __cplusplus */
1791

    
1792
#endif /* CS_COMMON_MBUF_H_ */
1793
#ifdef MG_MODULE_LINES
1794
#line 1 "common/sha1.h"
1795
#endif
1796
/*
1797
 * Copyright (c) 2014 Cesanta Software Limited
1798
 * All rights reserved
1799
 */
1800

    
1801
#ifndef CS_COMMON_SHA1_H_
1802
#define CS_COMMON_SHA1_H_
1803

    
1804
#ifndef DISABLE_SHA1
1805
#define DISABLE_SHA1 0
1806
#endif
1807

    
1808
#if !DISABLE_SHA1
1809

    
1810
/* Amalgamated: #include "common/platform.h" */
1811

    
1812
#ifdef __cplusplus
1813
extern "C" {
1814
#endif /* __cplusplus */
1815

    
1816
typedef struct {
1817
  uint32_t state[5];
1818
  uint32_t count[2];
1819
  unsigned char buffer[64];
1820
} cs_sha1_ctx;
1821

    
1822
void cs_sha1_init(cs_sha1_ctx *);
1823
void cs_sha1_update(cs_sha1_ctx *, const unsigned char *data, uint32_t len);
1824
void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *);
1825
void cs_hmac_sha1(const unsigned char *key, size_t key_len,
1826
                  const unsigned char *text, size_t text_len,
1827
                  unsigned char out[20]);
1828
#ifdef __cplusplus
1829
}
1830
#endif /* __cplusplus */
1831

    
1832
#endif /* DISABLE_SHA1 */
1833

    
1834
#endif /* CS_COMMON_SHA1_H_ */
1835
#ifdef MG_MODULE_LINES
1836
#line 1 "common/md5.h"
1837
#endif
1838
/*
1839
 * Copyright (c) 2014 Cesanta Software Limited
1840
 * All rights reserved
1841
 */
1842

    
1843
#ifndef CS_COMMON_MD5_H_
1844
#define CS_COMMON_MD5_H_
1845

    
1846
/* Amalgamated: #include "common/platform.h" */
1847

    
1848
#ifndef DISABLE_MD5
1849
#define DISABLE_MD5 0
1850
#endif
1851

    
1852
#ifdef __cplusplus
1853
extern "C" {
1854
#endif /* __cplusplus */
1855

    
1856
typedef struct MD5Context {
1857
  uint32_t buf[4];
1858
  uint32_t bits[2];
1859
  unsigned char in[64];
1860
} MD5_CTX;
1861

    
1862
void MD5_Init(MD5_CTX *c);
1863
void MD5_Update(MD5_CTX *c, const unsigned char *data, size_t len);
1864
void MD5_Final(unsigned char *md, MD5_CTX *c);
1865

    
1866
/*
1867
 * Return stringified MD5 hash for NULL terminated list of pointer/length pairs.
1868
 * A length should be specified as size_t variable.
1869
 * Example:
1870
 *
1871
 *    char buf[33];
1872
 *    cs_md5(buf, "foo", (size_t) 3, "bar", (size_t) 3, NULL);
1873
 */
1874
char *cs_md5(char buf[33], ...);
1875

    
1876
#ifdef __cplusplus
1877
}
1878
#endif /* __cplusplus */
1879

    
1880
#endif /* CS_COMMON_MD5_H_ */
1881
#ifdef MG_MODULE_LINES
1882
#line 1 "common/base64.h"
1883
#endif
1884
/*
1885
 * Copyright (c) 2014 Cesanta Software Limited
1886
 * All rights reserved
1887
 */
1888

    
1889
#ifndef CS_COMMON_BASE64_H_
1890
#define CS_COMMON_BASE64_H_
1891

    
1892
#ifndef DISABLE_BASE64
1893
#define DISABLE_BASE64 0
1894
#endif
1895

    
1896
#if !DISABLE_BASE64
1897

    
1898
#include <stdio.h>
1899

    
1900
#ifdef __cplusplus
1901
extern "C" {
1902
#endif
1903

    
1904
typedef void (*cs_base64_putc_t)(char, void *);
1905

    
1906
struct cs_base64_ctx {
1907
  /* cannot call it putc because it's a macro on some environments */
1908
  cs_base64_putc_t b64_putc;
1909
  unsigned char chunk[3];
1910
  int chunk_size;
1911
  void *user_data;
1912
};
1913

    
1914
void cs_base64_init(struct cs_base64_ctx *ctx, cs_base64_putc_t putc,
1915
                    void *user_data);
1916
void cs_base64_update(struct cs_base64_ctx *ctx, const char *str, size_t len);
1917
void cs_base64_finish(struct cs_base64_ctx *ctx);
1918

    
1919
void cs_base64_encode(const unsigned char *src, int src_len, char *dst);
1920
void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len);
1921
int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len);
1922

    
1923
#ifdef __cplusplus
1924
}
1925
#endif
1926

    
1927
#endif /* DISABLE_BASE64 */
1928

    
1929
#endif /* CS_COMMON_BASE64_H_ */
1930
#ifdef MG_MODULE_LINES
1931
#line 1 "common/str_util.h"
1932
#endif
1933
/*
1934
 * Copyright (c) 2015 Cesanta Software Limited
1935
 * All rights reserved
1936
 */
1937

    
1938
#ifndef CS_COMMON_STR_UTIL_H_
1939
#define CS_COMMON_STR_UTIL_H_
1940

    
1941
#include <stdarg.h>
1942
#include <stdlib.h>
1943

    
1944
/* Amalgamated: #include "common/platform.h" */
1945

    
1946
#ifndef CS_ENABLE_STRDUP
1947
#define CS_ENABLE_STRDUP 0
1948
#endif
1949

    
1950
#ifndef CS_ENABLE_TO64
1951
#define CS_ENABLE_TO64 0
1952
#endif
1953

    
1954
/*
1955
 * Expands to a string representation of its argument: e.g.
1956
 * `CS_STRINGIFY_LIT(5) expands to "5"`
1957
 */
1958
#define CS_STRINGIFY_LIT(x) #x
1959

    
1960
/*
1961
 * Expands to a string representation of its argument, which is allowed
1962
 * to be a macro: e.g.
1963
 *
1964
 * #define FOO 123
1965
 * CS_STRINGIFY_MACRO(FOO)
1966
 *
1967
 * expands to 123.
1968
 */
1969
#define CS_STRINGIFY_MACRO(x) CS_STRINGIFY_LIT(x)
1970

    
1971
#ifdef __cplusplus
1972
extern "C" {
1973
#endif
1974

    
1975
size_t c_strnlen(const char *s, size_t maxlen);
1976
int c_snprintf(char *buf, size_t buf_size, const char *format, ...);
1977
int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap);
1978
/*
1979
 * Find the first occurrence of find in s, where the search is limited to the
1980
 * first slen characters of s.
1981
 */
1982
const char *c_strnstr(const char *s, const char *find, size_t slen);
1983

    
1984
/*
1985
 * Stringify binary data. Output buffer size must be 2 * size_of_input + 1
1986
 * because each byte of input takes 2 bytes in string representation
1987
 * plus 1 byte for the terminating \0 character.
1988
 */
1989
void cs_to_hex(char *to, const unsigned char *p, size_t len);
1990

    
1991
/*
1992
 * Convert stringified binary data back to binary.
1993
 * Does the reverse of `cs_to_hex()`.
1994
 */
1995
void cs_from_hex(char *to, const char *p, size_t len);
1996

    
1997
#if CS_ENABLE_STRDUP
1998
char *strdup(const char *src);
1999
#endif
2000

    
2001
#if CS_ENABLE_TO64
2002
#include <stdint.h>
2003
/*
2004
 * Simple string -> int64 conversion routine.
2005
 */
2006
int64_t cs_to64(const char *s);
2007
#endif
2008

    
2009
/*
2010
 * Cross-platform version of `strncasecmp()`.
2011
 */
2012
int mg_ncasecmp(const char *s1, const char *s2, size_t len);
2013

    
2014
/*
2015
 * Cross-platform version of `strcasecmp()`.
2016
 */
2017
int mg_casecmp(const char *s1, const char *s2);
2018

    
2019
/*
2020
 * Prints message to the buffer. If the buffer is large enough to hold the
2021
 * message, it returns buffer. If buffer is to small, it allocates a large
2022
 * enough buffer on heap and returns allocated buffer.
2023
 * This is a supposed use case:
2024
 *
2025
 *    char buf[5], *p = buf;
2026
 *    mg_avprintf(&p, sizeof(buf), "%s", "hi there");
2027
 *    use_p_somehow(p);
2028
 *    if (p != buf) {
2029
 *      free(p);
2030
 *    }
2031
 *
2032
 * The purpose of this is to avoid malloc-ing if generated strings are small.
2033
 */
2034
int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
2035

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

    
2039
#ifdef __cplusplus
2040
}
2041
#endif
2042

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

    
2080
#ifndef _SYS_QUEUE_H_
2081
#define        _SYS_QUEUE_H_
2082

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

    
2165
#define        TRACEBUF        struct qm_trace trace;
2166
#define        TRACEBUF_INITIALIZER        { __LINE__, 0, __FILE__, NULL } ,
2167
#define        TRASHIT(x)        do {(x) = (void *)-1;} while (0)
2168
#define        QMD_SAVELINK(name, link)        void **name = (void *)&(link)
2169

    
2170
#define        QMD_TRACE_HEAD(head) do {                                        \
2171
        (head)->trace.prevline = (head)->trace.lastline;                \
2172
        (head)->trace.prevfile = (head)->trace.lastfile;                \
2173
        (head)->trace.lastline = __LINE__;                                \
2174
        (head)->trace.lastfile = __FILE__;                                \
2175
} while (0)
2176

    
2177
#define        QMD_TRACE_ELEM(elem) do {                                        \
2178
        (elem)->trace.prevline = (elem)->trace.lastline;                \
2179
        (elem)->trace.prevfile = (elem)->trace.lastfile;                \
2180
        (elem)->trace.lastline = __LINE__;                                \
2181
        (elem)->trace.lastfile = __FILE__;                                \
2182
} while (0)
2183

    
2184
#else
2185
#define        QMD_TRACE_ELEM(elem)
2186
#define        QMD_TRACE_HEAD(head)
2187
#define        QMD_SAVELINK(name, link)
2188
#define        TRACEBUF
2189
#define        TRACEBUF_INITIALIZER
2190
#define        TRASHIT(x)
2191
#endif        /* QUEUE_MACRO_DEBUG */
2192

    
2193
#ifdef __cplusplus
2194
/*
2195
 * In C++ there can be structure lists and class lists:
2196
 */
2197
#define        QUEUE_TYPEOF(type) type
2198
#else
2199
#define        QUEUE_TYPEOF(type) struct type
2200
#endif
2201

    
2202
/*
2203
 * Singly-linked List declarations.
2204
 */
2205
#define        SLIST_HEAD(name, type)                                                \
2206
struct name {                                                                \
2207
        struct type *slh_first;        /* first element */                        \
2208
}
2209

    
2210
#define        SLIST_CLASS_HEAD(name, type)                                        \
2211
struct name {                                                                \
2212
        class type *slh_first;        /* first element */                        \
2213
}
2214

    
2215
#define        SLIST_HEAD_INITIALIZER(head)                                        \
2216
        { NULL }
2217

    
2218
#define        SLIST_ENTRY(type)                                                \
2219
struct {                                                                \
2220
        struct type *sle_next;        /* next element */                        \
2221
}
2222

    
2223
#define        SLIST_CLASS_ENTRY(type)                                                \
2224
struct {                                                                \
2225
        class type *sle_next;                /* next element */                \
2226
}
2227

    
2228
/*
2229
 * Singly-linked List functions.
2230
 */
2231
#define        SLIST_EMPTY(head)        ((head)->slh_first == NULL)
2232

    
2233
#define        SLIST_FIRST(head)        ((head)->slh_first)
2234

    
2235
#define        SLIST_FOREACH(var, head, field)                                        \
2236
        for ((var) = SLIST_FIRST((head));                                \
2237
            (var);                                                        \
2238
            (var) = SLIST_NEXT((var), field))
2239

    
2240
#define        SLIST_FOREACH_FROM(var, head, field)                                \
2241
        for ((var) = ((var) ? (var) : SLIST_FIRST((head)));                \
2242
            (var);                                                        \
2243
            (var) = SLIST_NEXT((var), field))
2244

    
2245
#define        SLIST_FOREACH_SAFE(var, head, field, tvar)                        \
2246
        for ((var) = SLIST_FIRST((head));                                \
2247
            (var) && ((tvar) = SLIST_NEXT((var), field), 1);                \
2248
            (var) = (tvar))
2249

    
2250
#define        SLIST_FOREACH_FROM_SAFE(var, head, field, tvar)                        \
2251
        for ((var) = ((var) ? (var) : SLIST_FIRST((head)));                \
2252
            (var) && ((tvar) = SLIST_NEXT((var), field), 1);                \
2253
            (var) = (tvar))
2254

    
2255
#define        SLIST_FOREACH_PREVPTR(var, varp, head, field)                        \
2256
        for ((varp) = &SLIST_FIRST((head));                                \
2257
            ((var) = *(varp)) != NULL;                                        \
2258
            (varp) = &SLIST_NEXT((var), field))
2259

    
2260
#define        SLIST_INIT(head) do {                                                \
2261
        SLIST_FIRST((head)) = NULL;                                        \
2262
} while (0)
2263

    
2264
#define        SLIST_INSERT_AFTER(slistelm, elm, field) do {                        \
2265
        SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);        \
2266
        SLIST_NEXT((slistelm), field) = (elm);                                \
2267
} while (0)
2268

    
2269
#define        SLIST_INSERT_HEAD(head, elm, field) do {                        \
2270
        SLIST_NEXT((elm), field) = SLIST_FIRST((head));                        \
2271
        SLIST_FIRST((head)) = (elm);                                        \
2272
} while (0)
2273

    
2274
#define        SLIST_NEXT(elm, field)        ((elm)->field.sle_next)
2275

    
2276
#define        SLIST_REMOVE(head, elm, type, field) do {                        \
2277
        QMD_SAVELINK(oldnext, (elm)->field.sle_next);                        \
2278
        if (SLIST_FIRST((head)) == (elm)) {                                \
2279
                SLIST_REMOVE_HEAD((head), field);                        \
2280
        }                                                                \
2281
        else {                                                                \
2282
                QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head);                \
2283
                while (SLIST_NEXT(curelm, field) != (elm))                \
2284
                        curelm = SLIST_NEXT(curelm, field);                \
2285
                SLIST_REMOVE_AFTER(curelm, field);                        \
2286
        }                                                                \
2287
        TRASHIT(*oldnext);                                                \
2288
} while (0)
2289

    
2290
#define SLIST_REMOVE_AFTER(elm, field) do {                                \
2291
        SLIST_NEXT(elm, field) =                                        \
2292
            SLIST_NEXT(SLIST_NEXT(elm, field), field);                        \
2293
} while (0)
2294

    
2295
#define        SLIST_REMOVE_HEAD(head, field) do {                                \
2296
        SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);        \
2297
} while (0)
2298

    
2299
#define SLIST_SWAP(head1, head2, type) do {                                \
2300
        QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1);                \
2301
        SLIST_FIRST(head1) = SLIST_FIRST(head2);                        \
2302
        SLIST_FIRST(head2) = swap_first;                                \
2303
} while (0)
2304

    
2305
/*
2306
 * Singly-linked Tail queue declarations.
2307
 */
2308
#define        STAILQ_HEAD(name, type)                                                \
2309
struct name {                                                                \
2310
        struct type *stqh_first;/* first element */                        \
2311
        struct type **stqh_last;/* addr of last next element */                \
2312
}
2313

    
2314
#define        STAILQ_CLASS_HEAD(name, type)                                        \
2315
struct name {                                                                \
2316
        class type *stqh_first;        /* first element */                        \
2317
        class type **stqh_last;        /* addr of last next element */                \
2318
}
2319

    
2320
#define        STAILQ_HEAD_INITIALIZER(head)                                        \
2321
        { NULL, &(head).stqh_first }
2322

    
2323
#define        STAILQ_ENTRY(type)                                                \
2324
struct {                                                                \
2325
        struct type *stqe_next;        /* next element */                        \
2326
}
2327

    
2328
#define        STAILQ_CLASS_ENTRY(type)                                        \
2329
struct {                                                                \
2330
        class type *stqe_next;        /* next element */                        \
2331
}
2332

    
2333
/*
2334
 * Singly-linked Tail queue functions.
2335
 */
2336
#define        STAILQ_CONCAT(head1, head2) do {                                \
2337
        if (!STAILQ_EMPTY((head2))) {                                        \
2338
                *(head1)->stqh_last = (head2)->stqh_first;                \
2339
                (head1)->stqh_last = (head2)->stqh_last;                \
2340
                STAILQ_INIT((head2));                                        \
2341
        }                                                                \
2342
} while (0)
2343

    
2344
#define        STAILQ_EMPTY(head)        ((head)->stqh_first == NULL)
2345

    
2346
#define        STAILQ_FIRST(head)        ((head)->stqh_first)
2347

    
2348
#define        STAILQ_FOREACH(var, head, field)                                \
2349
        for((var) = STAILQ_FIRST((head));                                \
2350
           (var);                                                        \
2351
           (var) = STAILQ_NEXT((var), field))
2352

    
2353
#define        STAILQ_FOREACH_FROM(var, head, field)                                \
2354
        for ((var) = ((var) ? (var) : STAILQ_FIRST((head)));                \
2355
           (var);                                                        \
2356
           (var) = STAILQ_NEXT((var), field))
2357

    
2358
#define        STAILQ_FOREACH_SAFE(var, head, field, tvar)                        \
2359
        for ((var) = STAILQ_FIRST((head));                                \
2360
            (var) && ((tvar) = STAILQ_NEXT((var), field), 1);                \
2361
            (var) = (tvar))
2362

    
2363
#define        STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)                \
2364
        for ((var) = ((var) ? (var) : STAILQ_FIRST((head)));                \
2365
            (var) && ((tvar) = STAILQ_NEXT((var), field), 1);                \
2366
            (var) = (tvar))
2367

    
2368
#define        STAILQ_INIT(head) do {                                                \
2369
        STAILQ_FIRST((head)) = NULL;                                        \
2370
        (head)->stqh_last = &STAILQ_FIRST((head));                        \
2371
} while (0)
2372

    
2373
#define        STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {                \
2374
        if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
2375
                (head)->stqh_last = &STAILQ_NEXT((elm), field);                \
2376
        STAILQ_NEXT((tqelm), field) = (elm);                                \
2377
} while (0)
2378

    
2379
#define        STAILQ_INSERT_HEAD(head, elm, field) do {                        \
2380
        if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)        \
2381
                (head)->stqh_last = &STAILQ_NEXT((elm), field);                \
2382
        STAILQ_FIRST((head)) = (elm);                                        \
2383
} while (0)
2384

    
2385
#define        STAILQ_INSERT_TAIL(head, elm, field) do {                        \
2386
        STAILQ_NEXT((elm), field) = NULL;                                \
2387
        *(head)->stqh_last = (elm);                                        \
2388
        (head)->stqh_last = &STAILQ_NEXT((elm), field);                        \
2389
} while (0)
2390

    
2391
#define        STAILQ_LAST(head, type, field)                                \
2392
        (STAILQ_EMPTY((head)) ? NULL :                                \
2393
            __containerof((head)->stqh_last,                        \
2394
            QUEUE_TYPEOF(type), field.stqe_next))
2395

    
2396
#define        STAILQ_NEXT(elm, field)        ((elm)->field.stqe_next)
2397

    
2398
#define        STAILQ_REMOVE(head, elm, type, field) do {                        \
2399
        QMD_SAVELINK(oldnext, (elm)->field.stqe_next);                        \
2400
        if (STAILQ_FIRST((head)) == (elm)) {                                \
2401
                STAILQ_REMOVE_HEAD((head), field);                        \
2402
        }                                                                \
2403
        else {                                                                \
2404
                QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head);        \
2405
                while (STAILQ_NEXT(curelm, field) != (elm))                \
2406
                        curelm = STAILQ_NEXT(curelm, field);                \
2407
                STAILQ_REMOVE_AFTER(head, curelm, field);                \
2408
        }                                                                \
2409
        TRASHIT(*oldnext);                                                \
2410
} while (0)
2411

    
2412
#define STAILQ_REMOVE_AFTER(head, elm, field) do {                        \
2413
        if ((STAILQ_NEXT(elm, field) =                                        \
2414
             STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)        \
2415
                (head)->stqh_last = &STAILQ_NEXT((elm), field);                \
2416
} while (0)
2417

    
2418
#define        STAILQ_REMOVE_HEAD(head, field) do {                                \
2419
        if ((STAILQ_FIRST((head)) =                                        \
2420
             STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)                \
2421
                (head)->stqh_last = &STAILQ_FIRST((head));                \
2422
} while (0)
2423

    
2424
#define STAILQ_SWAP(head1, head2, type) do {                                \
2425
        QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1);                \
2426
        QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last;                \
2427
        STAILQ_FIRST(head1) = STAILQ_FIRST(head2);                        \
2428
        (head1)->stqh_last = (head2)->stqh_last;                        \
2429
        STAILQ_FIRST(head2) = swap_first;                                \
2430
        (head2)->stqh_last = swap_last;                                        \
2431
        if (STAILQ_EMPTY(head1))                                        \
2432
                (head1)->stqh_last = &STAILQ_FIRST(head1);                \
2433
        if (STAILQ_EMPTY(head2))                                        \
2434
                (head2)->stqh_last = &STAILQ_FIRST(head2);                \
2435
} while (0)
2436

    
2437

    
2438
/*
2439
 * List declarations.
2440
 */
2441
#define        LIST_HEAD(name, type)                                                \
2442
struct name {                                                                \
2443
        struct type *lh_first;        /* first element */                        \
2444
}
2445

    
2446
#define        LIST_CLASS_HEAD(name, type)                                        \
2447
struct name {                                                                \
2448
        class type *lh_first;        /* first element */                        \
2449
}
2450

    
2451
#define        LIST_HEAD_INITIALIZER(head)                                        \
2452
        { NULL }
2453

    
2454
#define        LIST_ENTRY(type)                                                \
2455
struct {                                                                \
2456
        struct type *le_next;        /* next element */                        \
2457
        struct type **le_prev;        /* address of previous next element */        \
2458
}
2459

    
2460
#define        LIST_CLASS_ENTRY(type)                                                \
2461
struct {                                                                \
2462
        class type *le_next;        /* next element */                        \
2463
        class type **le_prev;        /* address of previous next element */        \
2464
}
2465

    
2466
/*
2467
 * List functions.
2468
 */
2469

    
2470
#if (defined(_KERNEL) && defined(INVARIANTS))
2471
#define        QMD_LIST_CHECK_HEAD(head, field) do {                                \
2472
        if (LIST_FIRST((head)) != NULL &&                                \
2473
            LIST_FIRST((head))->field.le_prev !=                        \
2474
             &LIST_FIRST((head)))                                        \
2475
                panic("Bad list head %p first->prev != head", (head));        \
2476
} while (0)
2477

    
2478
#define        QMD_LIST_CHECK_NEXT(elm, field) do {                                \
2479
        if (LIST_NEXT((elm), field) != NULL &&                                \
2480
            LIST_NEXT((elm), field)->field.le_prev !=                        \
2481
             &((elm)->field.le_next))                                        \
2482
                     panic("Bad link elm %p next->prev != elm", (elm));        \
2483
} while (0)
2484

    
2485
#define        QMD_LIST_CHECK_PREV(elm, field) do {                                \
2486
        if (*(elm)->field.le_prev != (elm))                                \
2487
                panic("Bad link elm %p prev->next != elm", (elm));        \
2488
} while (0)
2489
#else
2490
#define        QMD_LIST_CHECK_HEAD(head, field)
2491
#define        QMD_LIST_CHECK_NEXT(elm, field)
2492
#define        QMD_LIST_CHECK_PREV(elm, field)
2493
#endif /* (_KERNEL && INVARIANTS) */
2494

    
2495
#define        LIST_EMPTY(head)        ((head)->lh_first == NULL)
2496

    
2497
#define        LIST_FIRST(head)        ((head)->lh_first)
2498

    
2499
#define        LIST_FOREACH(var, head, field)                                        \
2500
        for ((var) = LIST_FIRST((head));                                \
2501
            (var);                                                        \
2502
            (var) = LIST_NEXT((var), field))
2503

    
2504
#define        LIST_FOREACH_FROM(var, head, field)                                \
2505
        for ((var) = ((var) ? (var) : LIST_FIRST((head)));                \
2506
            (var);                                                        \
2507
            (var) = LIST_NEXT((var), field))
2508

    
2509
#define        LIST_FOREACH_SAFE(var, head, field, tvar)                        \
2510
        for ((var) = LIST_FIRST((head));                                \
2511
            (var) && ((tvar) = LIST_NEXT((var), field), 1);                \
2512
            (var) = (tvar))
2513

    
2514
#define        LIST_FOREACH_FROM_SAFE(var, head, field, tvar)                        \
2515
        for ((var) = ((var) ? (var) : LIST_FIRST((head)));                \
2516
            (var) && ((tvar) = LIST_NEXT((var), field), 1);                \
2517
            (var) = (tvar))
2518

    
2519
#define        LIST_INIT(head) do {                                                \
2520
        LIST_FIRST((head)) = NULL;                                        \
2521
} while (0)
2522

    
2523
#define        LIST_INSERT_AFTER(listelm, elm, field) do {                        \
2524
        QMD_LIST_CHECK_NEXT(listelm, field);                                \
2525
        if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
2526
                LIST_NEXT((listelm), field)->field.le_prev =                \
2527
                    &LIST_NEXT((elm), field);                                \
2528
        LIST_NEXT((listelm), field) = (elm);                                \
2529
        (elm)->field.le_prev = &LIST_NEXT((listelm), field);                \
2530
} while (0)
2531

    
2532
#define        LIST_INSERT_BEFORE(listelm, elm, field) do {                        \
2533
        QMD_LIST_CHECK_PREV(listelm, field);                                \
2534
        (elm)->field.le_prev = (listelm)->field.le_prev;                \
2535
        LIST_NEXT((elm), field) = (listelm);                                \
2536
        *(listelm)->field.le_prev = (elm);                                \
2537
        (listelm)->field.le_prev = &LIST_NEXT((elm), field);                \
2538
} while (0)
2539

    
2540
#define        LIST_INSERT_HEAD(head, elm, field) do {                                \
2541
        QMD_LIST_CHECK_HEAD((head), field);                                \
2542
        if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)        \
2543
                LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
2544
        LIST_FIRST((head)) = (elm);                                        \
2545
        (elm)->field.le_prev = &LIST_FIRST((head));                        \
2546
} while (0)
2547

    
2548
#define        LIST_NEXT(elm, field)        ((elm)->field.le_next)
2549

    
2550
#define        LIST_PREV(elm, head, type, field)                        \
2551
        ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL :        \
2552
            __containerof((elm)->field.le_prev,                        \
2553
            QUEUE_TYPEOF(type), field.le_next))
2554

    
2555
#define        LIST_REMOVE(elm, field) do {                                        \
2556
        QMD_SAVELINK(oldnext, (elm)->field.le_next);                        \
2557
        QMD_SAVELINK(oldprev, (elm)->field.le_prev);                        \
2558
        QMD_LIST_CHECK_NEXT(elm, field);                                \
2559
        QMD_LIST_CHECK_PREV(elm, field);                                \
2560
        if (LIST_NEXT((elm), field) != NULL)                                \
2561
                LIST_NEXT((elm), field)->field.le_prev =                 \
2562
                    (elm)->field.le_prev;                                \
2563
        *(elm)->field.le_prev = LIST_NEXT((elm), field);                \
2564
        TRASHIT(*oldnext);                                                \
2565
        TRASHIT(*oldprev);                                                \
2566
} while (0)
2567

    
2568
#define LIST_SWAP(head1, head2, type, field) do {                        \
2569
        QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1);                \
2570
        LIST_FIRST((head1)) = LIST_FIRST((head2));                        \
2571
        LIST_FIRST((head2)) = swap_tmp;                                        \
2572
        if ((swap_tmp = LIST_FIRST((head1))) != NULL)                        \
2573
                swap_tmp->field.le_prev = &LIST_FIRST((head1));                \
2574
        if ((swap_tmp = LIST_FIRST((head2))) != NULL)                        \
2575
                swap_tmp->field.le_prev = &LIST_FIRST((head2));                \
2576
} while (0)
2577

    
2578
/*
2579
 * Tail queue declarations.
2580
 */
2581
#define        TAILQ_HEAD(name, type)                                                \
2582
struct name {                                                                \
2583
        struct type *tqh_first;        /* first element */                        \
2584
        struct type **tqh_last;        /* addr of last next element */                \
2585
        TRACEBUF                                                        \
2586
}
2587

    
2588
#define        TAILQ_CLASS_HEAD(name, type)                                        \
2589
struct name {                                                                \
2590
        class type *tqh_first;        /* first element */                        \
2591
        class type **tqh_last;        /* addr of last next element */                \
2592
        TRACEBUF                                                        \
2593
}
2594

    
2595
#define        TAILQ_HEAD_INITIALIZER(head)                                        \
2596
        { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
2597

    
2598
#define        TAILQ_ENTRY(type)                                                \
2599
struct {                                                                \
2600
        struct type *tqe_next;        /* next element */                        \
2601
        struct type **tqe_prev;        /* address of previous next element */        \
2602
        TRACEBUF                                                        \
2603
}
2604

    
2605
#define        TAILQ_CLASS_ENTRY(type)                                                \
2606
struct {                                                                \
2607
        class type *tqe_next;        /* next element */                        \
2608
        class type **tqe_prev;        /* address of previous next element */        \
2609
        TRACEBUF                                                        \
2610
}
2611

    
2612
/*
2613
 * Tail queue functions.
2614
 */
2615
#if (defined(_KERNEL) && defined(INVARIANTS))
2616
#define        QMD_TAILQ_CHECK_HEAD(head, field) do {                                \
2617
        if (!TAILQ_EMPTY(head) &&                                        \
2618
            TAILQ_FIRST((head))->field.tqe_prev !=                        \
2619
             &TAILQ_FIRST((head)))                                        \
2620
                panic("Bad tailq head %p first->prev != head", (head));        \
2621
} while (0)
2622

    
2623
#define        QMD_TAILQ_CHECK_TAIL(head, field) do {                                \
2624
        if (*(head)->tqh_last != NULL)                                        \
2625
                    panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head));         \
2626
} while (0)
2627

    
2628
#define        QMD_TAILQ_CHECK_NEXT(elm, field) do {                                \
2629
        if (TAILQ_NEXT((elm), field) != NULL &&                                \
2630
            TAILQ_NEXT((elm), field)->field.tqe_prev !=                        \
2631
             &((elm)->field.tqe_next))                                        \
2632
                panic("Bad link elm %p next->prev != elm", (elm));        \
2633
} while (0)
2634

    
2635
#define        QMD_TAILQ_CHECK_PREV(elm, field) do {                                \
2636
        if (*(elm)->field.tqe_prev != (elm))                                \
2637
                panic("Bad link elm %p prev->next != elm", (elm));        \
2638
} while (0)
2639
#else
2640
#define        QMD_TAILQ_CHECK_HEAD(head, field)
2641
#define        QMD_TAILQ_CHECK_TAIL(head, headname)
2642
#define        QMD_TAILQ_CHECK_NEXT(elm, field)
2643
#define        QMD_TAILQ_CHECK_PREV(elm, field)
2644
#endif /* (_KERNEL && INVARIANTS) */
2645

    
2646
#define        TAILQ_CONCAT(head1, head2, field) do {                                \
2647
        if (!TAILQ_EMPTY(head2)) {                                        \
2648
                *(head1)->tqh_last = (head2)->tqh_first;                \
2649
                (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;        \
2650
                (head1)->tqh_last = (head2)->tqh_last;                        \
2651
                TAILQ_INIT((head2));                                        \
2652
                QMD_TRACE_HEAD(head1);                                        \
2653
                QMD_TRACE_HEAD(head2);                                        \
2654
        }                                                                \
2655
} while (0)
2656

    
2657
#define        TAILQ_EMPTY(head)        ((head)->tqh_first == NULL)
2658

    
2659
#define        TAILQ_FIRST(head)        ((head)->tqh_first)
2660

    
2661
#define        TAILQ_FOREACH(var, head, field)                                        \
2662
        for ((var) = TAILQ_FIRST((head));                                \
2663
            (var);                                                        \
2664
            (var) = TAILQ_NEXT((var), field))
2665

    
2666
#define        TAILQ_FOREACH_FROM(var, head, field)                                \
2667
        for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));                \
2668
            (var);                                                        \
2669
            (var) = TAILQ_NEXT((var), field))
2670

    
2671
#define        TAILQ_FOREACH_SAFE(var, head, field, tvar)                        \
2672
        for ((var) = TAILQ_FIRST((head));                                \
2673
            (var) && ((tvar) = TAILQ_NEXT((var), field), 1);                \
2674
            (var) = (tvar))
2675

    
2676
#define        TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)                        \
2677
        for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));                \
2678
            (var) && ((tvar) = TAILQ_NEXT((var), field), 1);                \
2679
            (var) = (tvar))
2680

    
2681
#define        TAILQ_FOREACH_REVERSE(var, head, headname, field)                \
2682
        for ((var) = TAILQ_LAST((head), headname);                        \
2683
            (var);                                                        \
2684
            (var) = TAILQ_PREV((var), headname, field))
2685

    
2686
#define        TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field)                \
2687
        for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));        \
2688
            (var);                                                        \
2689
            (var) = TAILQ_PREV((var), headname, field))
2690

    
2691
#define        TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)        \
2692
        for ((var) = TAILQ_LAST((head), headname);                        \
2693
            (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);        \
2694
            (var) = (tvar))
2695

    
2696
#define        TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
2697
        for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));        \
2698
            (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);        \
2699
            (var) = (tvar))
2700

    
2701
#define        TAILQ_INIT(head) do {                                                \
2702
        TAILQ_FIRST((head)) = NULL;                                        \
2703
        (head)->tqh_last = &TAILQ_FIRST((head));                        \
2704
        QMD_TRACE_HEAD(head);                                                \
2705
} while (0)
2706

    
2707
#define        TAILQ_INSERT_AFTER(head, listelm, elm, field) do {                \
2708
        QMD_TAILQ_CHECK_NEXT(listelm, field);                                \
2709
        if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
2710
                TAILQ_NEXT((elm), field)->field.tqe_prev =                 \
2711
                    &TAILQ_NEXT((elm), field);                                \
2712
        else {                                                                \
2713
                (head)->tqh_last = &TAILQ_NEXT((elm), field);                \
2714
                QMD_TRACE_HEAD(head);                                        \
2715
        }                                                                \
2716
        TAILQ_NEXT((listelm), field) = (elm);                                \
2717
        (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);                \
2718
        QMD_TRACE_ELEM(&(elm)->field);                                        \
2719
        QMD_TRACE_ELEM(&(listelm)->field);                                \
2720
} while (0)
2721

    
2722
#define        TAILQ_INSERT_BEFORE(listelm, elm, field) do {                        \
2723
        QMD_TAILQ_CHECK_PREV(listelm, field);                                \
2724
        (elm)->field.tqe_prev = (listelm)->field.tqe_prev;                \
2725
        TAILQ_NEXT((elm), field) = (listelm);                                \
2726
        *(listelm)->field.tqe_prev = (elm);                                \
2727
        (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);                \
2728
        QMD_TRACE_ELEM(&(elm)->field);                                        \
2729
        QMD_TRACE_ELEM(&(listelm)->field);                                \
2730
} while (0)
2731

    
2732
#define        TAILQ_INSERT_HEAD(head, elm, field) do {                        \
2733
        QMD_TAILQ_CHECK_HEAD(head, field);                                \
2734
        if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)        \
2735
                TAILQ_FIRST((head))->field.tqe_prev =                        \
2736
                    &TAILQ_NEXT((elm), field);                                \
2737
        else                                                                \
2738
                (head)->tqh_last = &TAILQ_NEXT((elm), field);                \
2739
        TAILQ_FIRST((head)) = (elm);                                        \
2740
        (elm)->field.tqe_prev = &TAILQ_FIRST((head));                        \
2741
        QMD_TRACE_HEAD(head);                                                \
2742
        QMD_TRACE_ELEM(&(elm)->field);                                        \
2743
} while (0)
2744

    
2745
#define        TAILQ_INSERT_TAIL(head, elm, field) do {                        \
2746
        QMD_TAILQ_CHECK_TAIL(head, field);                                \
2747
        TAILQ_NEXT((elm), field) = NULL;                                \
2748
        (elm)->field.tqe_prev = (head)->tqh_last;                        \
2749
        *(head)->tqh_last = (elm);                                        \
2750
        (head)->tqh_last = &TAILQ_NEXT((elm), field);                        \
2751
        QMD_TRACE_HEAD(head);                                                \
2752
        QMD_TRACE_ELEM(&(elm)->field);                                        \
2753
} while (0)
2754

    
2755
#define        TAILQ_LAST(head, headname)                                        \
2756
        (*(((struct headname *)((head)->tqh_last))->tqh_last))
2757

    
2758
#define        TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
2759

    
2760
#define        TAILQ_PREV(elm, headname, field)                                \
2761
        (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
2762

    
2763
#define        TAILQ_REMOVE(head, elm, field) do {                                \
2764
        QMD_SAVELINK(oldnext, (elm)->field.tqe_next);                        \
2765
        QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);                        \
2766
        QMD_TAILQ_CHECK_NEXT(elm, field);                                \
2767
        QMD_TAILQ_CHECK_PREV(elm, field);                                \
2768
        if ((TAILQ_NEXT((elm), field)) != NULL)                                \
2769
                TAILQ_NEXT((elm), field)->field.tqe_prev =                 \
2770
                    (elm)->field.tqe_prev;                                \
2771
        else {                                                                \
2772
                (head)->tqh_last = (elm)->field.tqe_prev;                \
2773
                QMD_TRACE_HEAD(head);                                        \
2774
        }                                                                \
2775
        *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);                \
2776
        TRASHIT(*oldnext);                                                \
2777
        TRASHIT(*oldprev);                                                \
2778
        QMD_TRACE_ELEM(&(elm)->field);                                        \
2779
} while (0)
2780

    
2781
#define TAILQ_SWAP(head1, head2, type, field) do {                        \
2782
        QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first;                \
2783
        QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last;                \
2784
        (head1)->tqh_first = (head2)->tqh_first;                        \
2785
        (head1)->tqh_last = (head2)->tqh_last;                                \
2786
        (head2)->tqh_first = swap_first;                                \
2787
        (head2)->tqh_last = swap_last;                                        \
2788
        if ((swap_first = (head1)->tqh_first) != NULL)                        \
2789
                swap_first->field.tqe_prev = &(head1)->tqh_first;        \
2790
        else                                                                \
2791
                (head1)->tqh_last = &(head1)->tqh_first;                \
2792
        if ((swap_first = (head2)->tqh_first) != NULL)                        \
2793
                swap_first->field.tqe_prev = &(head2)->tqh_first;        \
2794
        else                                                                \
2795
                (head2)->tqh_last = &(head2)->tqh_first;                \
2796
} while (0)
2797

    
2798
#endif /* !_SYS_QUEUE_H_ */
2799
#ifdef MG_MODULE_LINES
2800
#line 1 "mongoose/src/features.h"
2801
#endif
2802
/*
2803
 * Copyright (c) 2014-2016 Cesanta Software Limited
2804
 * All rights reserved
2805
 */
2806

    
2807
#ifndef CS_MONGOOSE_SRC_FEATURES_H_
2808
#define CS_MONGOOSE_SRC_FEATURES_H_
2809

    
2810
#ifndef MG_DISABLE_HTTP_DIGEST_AUTH
2811
#define MG_DISABLE_HTTP_DIGEST_AUTH 0
2812
#endif
2813

    
2814
#ifndef MG_DISABLE_HTTP_KEEP_ALIVE
2815
#define MG_DISABLE_HTTP_KEEP_ALIVE 0
2816
#endif
2817

    
2818
#ifndef MG_DISABLE_PFS
2819
#define MG_DISABLE_PFS 0
2820
#endif
2821

    
2822
#ifndef MG_DISABLE_WS_RANDOM_MASK
2823
#define MG_DISABLE_WS_RANDOM_MASK 0
2824
#endif
2825

    
2826
#ifndef MG_ENABLE_ASYNC_RESOLVER
2827
#define MG_ENABLE_ASYNC_RESOLVER 1
2828
#endif
2829

    
2830
#ifndef MG_ENABLE_BROADCAST
2831
#define MG_ENABLE_BROADCAST 0
2832
#endif
2833

    
2834
#ifndef MG_ENABLE_COAP
2835
#define MG_ENABLE_COAP 0
2836
#endif
2837

    
2838
#ifndef MG_ENABLE_DEBUG
2839
#define MG_ENABLE_DEBUG 0
2840
#endif
2841

    
2842
#ifndef MG_ENABLE_DIRECTORY_LISTING
2843
#define MG_ENABLE_DIRECTORY_LISTING 0
2844
#endif
2845

    
2846
#ifndef MG_ENABLE_DNS
2847
#define MG_ENABLE_DNS 1
2848
#endif
2849

    
2850
#ifndef MG_ENABLE_DNS_SERVER
2851
#define MG_ENABLE_DNS_SERVER 0
2852
#endif
2853

    
2854
#ifndef MG_ENABLE_FAKE_DAVLOCK
2855
#define MG_ENABLE_FAKE_DAVLOCK 0
2856
#endif
2857

    
2858
#ifndef MG_ENABLE_FILESYSTEM
2859
#define MG_ENABLE_FILESYSTEM 0
2860
#endif
2861

    
2862
#ifndef MG_ENABLE_GETADDRINFO
2863
#define MG_ENABLE_GETADDRINFO 0
2864
#endif
2865

    
2866
#ifndef MG_ENABLE_HEXDUMP
2867
#define MG_ENABLE_HEXDUMP CS_ENABLE_STDIO
2868
#endif
2869

    
2870
#ifndef MG_ENABLE_HTTP
2871
#define MG_ENABLE_HTTP 1
2872
#endif
2873

    
2874
#ifndef MG_ENABLE_HTTP_CGI
2875
#define MG_ENABLE_HTTP_CGI 0
2876
#endif
2877

    
2878
#ifndef MG_ENABLE_HTTP_SSI
2879
#define MG_ENABLE_HTTP_SSI MG_ENABLE_FILESYSTEM
2880
#endif
2881

    
2882
#ifndef MG_ENABLE_HTTP_SSI_EXEC
2883
#define MG_ENABLE_HTTP_SSI_EXEC 0
2884
#endif
2885

    
2886
#ifndef MG_ENABLE_HTTP_STREAMING_MULTIPART
2887
#define MG_ENABLE_HTTP_STREAMING_MULTIPART 0
2888
#endif
2889

    
2890
#ifndef MG_ENABLE_HTTP_WEBDAV
2891
#define MG_ENABLE_HTTP_WEBDAV 0
2892
#endif
2893

    
2894
#ifndef MG_ENABLE_HTTP_WEBSOCKET
2895
#define MG_ENABLE_HTTP_WEBSOCKET MG_ENABLE_HTTP
2896
#endif
2897

    
2898
#ifndef MG_ENABLE_IPV6
2899
#define MG_ENABLE_IPV6 0
2900
#endif
2901

    
2902
#ifndef MG_ENABLE_JAVASCRIPT
2903
#define MG_ENABLE_JAVASCRIPT 0
2904
#endif
2905

    
2906
#ifndef MG_ENABLE_MQTT
2907
#define MG_ENABLE_MQTT 1
2908
#endif
2909

    
2910
#ifndef MG_ENABLE_MQTT_BROKER
2911
#define MG_ENABLE_MQTT_BROKER 0
2912
#endif
2913

    
2914
#ifndef MG_ENABLE_SSL
2915
#define MG_ENABLE_SSL 0
2916
#endif
2917

    
2918
#ifndef MG_ENABLE_SYNC_RESOLVER
2919
#define MG_ENABLE_SYNC_RESOLVER 0
2920
#endif
2921

    
2922
#ifndef MG_ENABLE_STDIO
2923
#define MG_ENABLE_STDIO CS_ENABLE_STDIO
2924
#endif
2925

    
2926
#ifndef MG_NET_IF
2927
#define MG_NET_IF MG_NET_IF_SOCKET
2928
#endif
2929

    
2930
#ifndef MG_SSL_IF
2931
#define MG_SSL_IF MG_SSL_IF_OPENSSL
2932
#endif
2933

    
2934
#ifndef MG_ENABLE_THREADS /* ifdef-ok */
2935
#ifdef _WIN32
2936
#define MG_ENABLE_THREADS 1
2937
#else
2938
#define MG_ENABLE_THREADS 0
2939
#endif
2940
#endif
2941

    
2942
#if MG_ENABLE_DEBUG && !defined(CS_ENABLE_DEBUG)
2943
#define CS_ENABLE_DEBUG 1
2944
#endif
2945

    
2946
/* MQTT broker requires MQTT */
2947
#if MG_ENABLE_MQTT_BROKER && !MG_ENABLE_MQTT
2948
#undef MG_ENABLE_MQTT
2949
#define MG_ENABLE_MQTT 1
2950
#endif
2951

    
2952
#ifndef MG_ENABLE_HTTP_URL_REWRITES
2953
#define MG_ENABLE_HTTP_URL_REWRITES \
2954
  (CS_PLATFORM == CS_P_WINDOWS || CS_PLATFORM == CS_P_UNIX)
2955
#endif
2956

    
2957
#ifndef MG_ENABLE_TUN
2958
#define MG_ENABLE_TUN MG_ENABLE_HTTP_WEBSOCKET
2959
#endif
2960

    
2961
#ifndef MG_ENABLE_SNTP
2962
#define MG_ENABLE_SNTP 0
2963
#endif
2964

    
2965
#ifndef MG_ENABLE_EXTRA_ERRORS_DESC
2966
#define MG_ENABLE_EXTRA_ERRORS_DESC 0
2967
#endif
2968

    
2969
#endif /* CS_MONGOOSE_SRC_FEATURES_H_ */
2970
#ifdef MG_MODULE_LINES
2971
#line 1 "mongoose/src/net_if.h"
2972
#endif
2973
/*
2974
 * Copyright (c) 2014-2016 Cesanta Software Limited
2975
 * All rights reserved
2976
 */
2977

    
2978
#ifndef CS_MONGOOSE_SRC_NET_IF_H_
2979
#define CS_MONGOOSE_SRC_NET_IF_H_
2980

    
2981
/* Amalgamated: #include "common/platform.h" */
2982

    
2983
/*
2984
 * Internal async networking core interface.
2985
 * Consists of calls made by the core, which should not block,
2986
 * and callbacks back into the core ("..._cb").
2987
 * Callbacks may (will) cause methods to be invoked from within,
2988
 * but methods are not allowed to invoke callbacks inline.
2989
 *
2990
 * Implementation must ensure that only one callback is invoked at any time.
2991
 */
2992

    
2993
#ifdef __cplusplus
2994
extern "C" {
2995
#endif /* __cplusplus */
2996

    
2997
#define MG_MAIN_IFACE 0
2998

    
2999
struct mg_mgr;
3000
struct mg_connection;
3001
union socket_address;
3002

    
3003
struct mg_iface_vtable;
3004

    
3005
struct mg_iface {
3006
  struct mg_mgr *mgr;
3007
  void *data; /* Implementation-specific data */
3008
  struct mg_iface_vtable *vtable;
3009
};
3010

    
3011
struct mg_iface_vtable {
3012
  void (*init)(struct mg_iface *iface);
3013
  void (*free)(struct mg_iface *iface);
3014
  void (*add_conn)(struct mg_connection *nc);
3015
  void (*remove_conn)(struct mg_connection *nc);
3016
  time_t (*poll)(struct mg_iface *iface, int timeout_ms);
3017

    
3018
  /* Set up a listening TCP socket on a given address. rv = 0 -> ok. */
3019
  int (*listen_tcp)(struct mg_connection *nc, union socket_address *sa);
3020
  /* Request that a "listening" UDP socket be created. */
3021
  int (*listen_udp)(struct mg_connection *nc, union socket_address *sa);
3022

    
3023
  /* Request that a TCP connection is made to the specified address. */
3024
  void (*connect_tcp)(struct mg_connection *nc, const union socket_address *sa);
3025
  /* Open a UDP socket. Doesn't actually connect anything. */
3026
  void (*connect_udp)(struct mg_connection *nc);
3027

    
3028
  /* Send functions for TCP and UDP. Sent data is copied before return. */
3029
  void (*tcp_send)(struct mg_connection *nc, const void *buf, size_t len);
3030
  void (*udp_send)(struct mg_connection *nc, const void *buf, size_t len);
3031

    
3032
  void (*recved)(struct mg_connection *nc, size_t len);
3033

    
3034
  /* Perform interface-related connection initialization. Return 1 on ok. */
3035
  int (*create_conn)(struct mg_connection *nc);
3036
  /* Perform interface-related cleanup on connection before destruction. */
3037
  void (*destroy_conn)(struct mg_connection *nc);
3038

    
3039
  /* Associate a socket to a connection. */
3040
  void (*sock_set)(struct mg_connection *nc, sock_t sock);
3041

    
3042
  /* Put connection's address into *sa, local (remote = 0) or remote. */
3043
  void (*get_conn_addr)(struct mg_connection *nc, int remote,
3044
                        union socket_address *sa);
3045
};
3046

    
3047
extern struct mg_iface_vtable *mg_ifaces[];
3048
extern int mg_num_ifaces;
3049

    
3050
/* Creates a new interface instance. */
3051
struct mg_iface *mg_if_create_iface(struct mg_iface_vtable *vtable,
3052
                                    struct mg_mgr *mgr);
3053

    
3054
/*
3055
 * Find an interface with a given implementation. The search is started from
3056
 * interface `from`, exclusive. Returns NULL if none is found.
3057
 */
3058
struct mg_iface *mg_find_iface(struct mg_mgr *mgr,
3059
                               struct mg_iface_vtable *vtable,
3060
                               struct mg_iface *from);
3061
/*
3062
 * Deliver a new TCP connection. Returns NULL in case on error (unable to
3063
 * create connection, in which case interface state should be discarded.
3064
 * This is phase 1 of the two-phase process - MG_EV_ACCEPT will be delivered
3065
 * when mg_if_accept_tcp_cb is invoked.
3066
 */
3067
struct mg_connection *mg_if_accept_new_conn(struct mg_connection *lc);
3068
void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,
3069
                         size_t sa_len);
3070

    
3071
/* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */
3072
void mg_if_connect_cb(struct mg_connection *nc, int err);
3073
/* Callback that reports that data has been put on the wire. */
3074
void mg_if_sent_cb(struct mg_connection *nc, int num_sent);
3075
/*
3076
 * Receive callback.
3077
 * if `own` is true, buf must be heap-allocated and ownership is transferred
3078
 * to the core.
3079
 * Core will acknowledge consumption by calling iface::recved.
3080
 */
3081
void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len, int own);
3082
/*
3083
 * Receive callback.
3084
 * buf must be heap-allocated and ownership is transferred to the core.
3085
 * Core will acknowledge consumption by calling iface::recved.
3086
 */
3087
void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
3088
                       union socket_address *sa, size_t sa_len);
3089

    
3090
/* void mg_if_close_conn(struct mg_connection *nc); */
3091

    
3092
/* Deliver a POLL event to the connection. */
3093
void mg_if_poll(struct mg_connection *nc, time_t now);
3094

    
3095
/* Deliver a TIMER event to the connection. */
3096
void mg_if_timer(struct mg_connection *c, double now);
3097

    
3098
#ifdef __cplusplus
3099
}
3100
#endif /* __cplusplus */
3101

    
3102
#endif /* CS_MONGOOSE_SRC_NET_IF_H_ */
3103
#ifdef MG_MODULE_LINES
3104
#line 1 "mongoose/src/ssl_if.h"
3105
#endif
3106
/*
3107
 * Copyright (c) 2014-2016 Cesanta Software Limited
3108
 * All rights reserved
3109
 */
3110

    
3111
#ifndef CS_MONGOOSE_SRC_SSL_IF_H_
3112
#define CS_MONGOOSE_SRC_SSL_IF_H_
3113

    
3114
#if MG_ENABLE_SSL
3115

    
3116
#ifdef __cplusplus
3117
extern "C" {
3118
#endif /* __cplusplus */
3119

    
3120
struct mg_ssl_if_ctx;
3121
struct mg_connection;
3122

    
3123
void mg_ssl_if_init();
3124

    
3125
enum mg_ssl_if_result {
3126
  MG_SSL_OK = 0,
3127
  MG_SSL_WANT_READ = -1,
3128
  MG_SSL_WANT_WRITE = -2,
3129
  MG_SSL_ERROR = -3,
3130
};
3131

    
3132
struct mg_ssl_if_conn_params {
3133
  const char *cert;
3134
  const char *key;
3135
  const char *ca_cert;
3136
  const char *server_name;
3137
  const char *cipher_suites;
3138
};
3139

    
3140
enum mg_ssl_if_result mg_ssl_if_conn_init(
3141
    struct mg_connection *nc, const struct mg_ssl_if_conn_params *params,
3142
    const char **err_msg);
3143
enum mg_ssl_if_result mg_ssl_if_conn_accept(struct mg_connection *nc,
3144
                                            struct mg_connection *lc);
3145
void mg_ssl_if_conn_free(struct mg_connection *nc);
3146

    
3147
enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc);
3148
int mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t buf_size);
3149
int mg_ssl_if_write(struct mg_connection *nc, const void *data, size_t len);
3150

    
3151
#ifdef __cplusplus
3152
}
3153
#endif /* __cplusplus */
3154

    
3155
#endif /* MG_ENABLE_SSL */
3156

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

    
3178
/*
3179
 * === Core API: TCP/UDP/SSL
3180
 *
3181
 * NOTE: Mongoose manager is single threaded. It does not protect
3182
 * its data structures by mutexes, therefore all functions that are dealing
3183
 * with a particular event manager should be called from the same thread,
3184
 * with exception of the `mg_broadcast()` function. It is fine to have different
3185
 * event managers handled by different threads.
3186
 */
3187

    
3188
#ifndef CS_MONGOOSE_SRC_NET_H_
3189
#define CS_MONGOOSE_SRC_NET_H_
3190

    
3191
#if MG_ENABLE_JAVASCRIPT
3192
#define EXCLUDE_COMMON
3193
#include <v7.h>
3194
#endif
3195

    
3196
/* Amalgamated: #include "mongoose/src/common.h" */
3197
/* Amalgamated: #include "mongoose/src/net_if.h" */
3198
/* Amalgamated: #include "common/mbuf.h" */
3199

    
3200
#ifndef MG_VPRINTF_BUFFER_SIZE
3201
#define MG_VPRINTF_BUFFER_SIZE 100
3202
#endif
3203

    
3204
#ifdef MG_USE_READ_WRITE
3205
#define MG_RECV_FUNC(s, b, l, f) read(s, b, l)
3206
#define MG_SEND_FUNC(s, b, l, f) write(s, b, l)
3207
#else
3208
#define MG_RECV_FUNC(s, b, l, f) recv(s, b, l, f)
3209
#define MG_SEND_FUNC(s, b, l, f) send(s, b, l, f)
3210
#endif
3211

    
3212
#ifdef __cplusplus
3213
extern "C" {
3214
#endif /* __cplusplus */
3215

    
3216
union socket_address {
3217
  struct sockaddr sa;
3218
  struct sockaddr_in sin;
3219
#if MG_ENABLE_IPV6
3220
  struct sockaddr_in6 sin6;
3221
#else
3222
  struct sockaddr sin6;
3223
#endif
3224
};
3225

    
3226
struct mg_connection;
3227

    
3228
/*
3229
 * Callback function (event handler) prototype. Must be defined by the user.
3230
 * Mongoose calls the event handler, passing the events defined below.
3231
 */
3232
typedef void (*mg_event_handler_t)(struct mg_connection *nc, int ev,
3233
                                   void *ev_data);
3234

    
3235
/* Events. Meaning of event parameter (evp) is given in the comment. */
3236
#define MG_EV_POLL 0    /* Sent to each connection on each mg_mgr_poll() call */
3237
#define MG_EV_ACCEPT 1  /* New connection accepted. union socket_address * */
3238
#define MG_EV_CONNECT 2 /* connect() succeeded or failed. int *  */
3239
#define MG_EV_RECV 3    /* Data has benn received. int *num_bytes */
3240
#define MG_EV_SEND 4    /* Data has been written to a socket. int *num_bytes */
3241
#define MG_EV_CLOSE 5   /* Connection is closed. NULL */
3242
#define MG_EV_TIMER 6   /* now >= conn->ev_timer_time. double * */
3243

    
3244
/*
3245
 * Mongoose event manager.
3246
 */
3247
struct mg_mgr {
3248
  struct mg_connection *active_connections;
3249
#if MG_ENABLE_HEXDUMP
3250
  const char *hexdump_file; /* Debug hexdump file path */
3251
#endif
3252
#if MG_ENABLE_BROADCAST
3253
  sock_t ctl[2]; /* Socketpair for mg_broadcast() */
3254
#endif
3255
  void *user_data; /* User data */
3256
  int num_ifaces;
3257
  struct mg_iface **ifaces; /* network interfaces */
3258
#if MG_ENABLE_JAVASCRIPT
3259
  struct v7 *v7;
3260
#endif
3261
};
3262

    
3263
/*
3264
 * Mongoose connection.
3265
 */
3266
struct mg_connection {
3267
  struct mg_connection *next, *prev; /* mg_mgr::active_connections linkage */
3268
  struct mg_connection *listener;    /* Set only for accept()-ed connections */
3269
  struct mg_mgr *mgr;                /* Pointer to containing manager */
3270

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

    
3310
/* Flags that are settable by user */
3311
#define MG_F_SEND_AND_CLOSE (1 << 10)       /* Push remaining data and close  */
3312
#define MG_F_CLOSE_IMMEDIATELY (1 << 11)    /* Disconnect */
3313
#define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12)  /* Websocket specific */
3314
#define MG_F_DELETE_CHUNK (1 << 13)         /* HTTP specific */
3315
#define MG_F_ENABLE_BROADCAST (1 << 14)     /* Allow broadcast address usage */
3316
#define MG_F_TUN_DO_NOT_RECONNECT (1 << 15) /* Don't reconnect tunnel */
3317

    
3318
#define MG_F_USER_1 (1 << 20) /* Flags left for application */
3319
#define MG_F_USER_2 (1 << 21)
3320
#define MG_F_USER_3 (1 << 22)
3321
#define MG_F_USER_4 (1 << 23)
3322
#define MG_F_USER_5 (1 << 24)
3323
#define MG_F_USER_6 (1 << 25)
3324
};
3325

    
3326
/*
3327
 * Initialise Mongoose manager. Side effect: ignores SIGPIPE signal.
3328
 * `mgr->user_data` field will be initialised with a `user_data` parameter.
3329
 * That is an arbitrary pointer, where the user code can associate some data
3330
 * with the particular Mongoose manager. For example, a C++ wrapper class
3331
 * could be written in which case `user_data` can hold a pointer to the
3332
 * class instance.
3333
 */
3334
void mg_mgr_init(struct mg_mgr *mgr, void *user_data);
3335

    
3336
/*
3337
 * Optional parameters to `mg_mgr_init_opt()`.
3338
 *
3339
 * If `main_iface` is not NULL, it will be used as the main interface in the
3340
 * default interface set. The pointer will be free'd by `mg_mgr_free`.
3341
 * Otherwise, the main interface will be autodetected based on the current
3342
 * platform.
3343
 *
3344
 * If `num_ifaces` is 0 and `ifaces` is NULL, the default interface set will be
3345
 * used.
3346
 * This is an advanced option, as it requires you to construct a full interface
3347
 * set, including special networking interfaces required by some optional
3348
 * features such as TCP tunneling. Memory backing `ifaces` and each of the
3349
 * `num_ifaces` pointers it contains will be reclaimed by `mg_mgr_free`.
3350
 */
3351
struct mg_mgr_init_opts {
3352
  struct mg_iface_vtable *main_iface;
3353
  int num_ifaces;
3354
  struct mg_iface_vtable **ifaces;
3355
};
3356

    
3357
/*
3358
 * Like `mg_mgr_init` but with more options.
3359
 *
3360
 * Notably, this allows you to create a manger and choose
3361
 * dynamically which networking interface implementation to use.
3362
 */
3363
void mg_mgr_init_opt(struct mg_mgr *mgr, void *user_data,
3364
                     struct mg_mgr_init_opts opts);
3365

    
3366
/*
3367
 * De-initialises Mongoose manager.
3368
 *
3369
 * Closes and deallocates all active connections.
3370
 */
3371
void mg_mgr_free(struct mg_mgr *);
3372

    
3373
/*
3374
 * This function performs the actual IO and must be called in a loop
3375
 * (an event loop). It returns the current timestamp.
3376
 * `milli` is the maximum number of milliseconds to sleep.
3377
 * `mg_mgr_poll()` checks all connections for IO readiness. If at least one
3378
 * of the connections is IO-ready, `mg_mgr_poll()` triggers the respective
3379
 * event handlers and returns.
3380
 */
3381
time_t mg_mgr_poll(struct mg_mgr *, int milli);
3382

    
3383
#if MG_ENABLE_BROADCAST
3384
/*
3385
 * Passes a message of a given length to all connections.
3386
 *
3387
 * Must be called from a thread that does NOT call `mg_mgr_poll()`.
3388
 * Note that `mg_broadcast()` is the only function
3389
 * that can be, and must be, called from a different (non-IO) thread.
3390
 *
3391
 * `func` callback function will be called by the IO thread for each
3392
 * connection. When called, the event will be `MG_EV_POLL`, and a message will
3393
 * be passed as the `ev_data` pointer. Maximum message size is capped
3394
 * by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes.
3395
 */
3396
void mg_broadcast(struct mg_mgr *, mg_event_handler_t func, void *, size_t);
3397
#endif
3398

    
3399
/*
3400
 * Iterates over all active connections.
3401
 *
3402
 * Returns the next connection from the list
3403
 * of active connections or `NULL` if there are no more connections. Below
3404
 * is the iteration idiom:
3405
 *
3406
 * ```c
3407
 * for (c = mg_next(srv, NULL); c != NULL; c = mg_next(srv, c)) {
3408
 *   // Do something with connection `c`
3409
 * }
3410
 * ```
3411
 */
3412
struct mg_connection *mg_next(struct mg_mgr *, struct mg_connection *);
3413

    
3414
/*
3415
 * Optional parameters to `mg_add_sock_opt()`.
3416
 *
3417
 * `flags` is an initial `struct mg_connection::flags` bitmask to set,
3418
 * see `MG_F_*` flags definitions.
3419
 */
3420
struct mg_add_sock_opts {
3421
  void *user_data;           /* Initial value for connection's user_data */
3422
  unsigned int flags;        /* Initial connection flags */
3423
  const char **error_string; /* Placeholder for the error string */
3424
  struct mg_iface *iface;    /* Interface instance */
3425
};
3426

    
3427
/*
3428
 * Creates a connection, associates it with the given socket and event handler
3429
 * and adds it to the manager.
3430
 *
3431
 * For more options see the `mg_add_sock_opt` variant.
3432
 */
3433
struct mg_connection *mg_add_sock(struct mg_mgr *, sock_t, mg_event_handler_t);
3434

    
3435
/*
3436
 * Creates a connection, associates it with the given socket and event handler
3437
 * and adds to the manager.
3438
 *
3439
 * See the `mg_add_sock_opts` structure for a description of the options.
3440
 */
3441
struct mg_connection *mg_add_sock_opt(struct mg_mgr *, sock_t,
3442
                                      mg_event_handler_t,
3443
                                      struct mg_add_sock_opts);
3444

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

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

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

    
3558
/*
3559
 * Connects to a remote host.
3560
 *
3561
 * See `mg_connect_opt()` for full documentation.
3562
 */
3563
struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,
3564
                                 mg_event_handler_t handler);
3565

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

    
3618
#if MG_ENABLE_SSL && MG_NET_IF != MG_NET_IF_SIMPLELINK
3619
/*
3620
 * Note: This function is deprecated. Please, use SSL options in
3621
 * mg_connect_opt.
3622
 *
3623
 * Enables SSL for a given connection.
3624
 * `cert` is a server certificate file name for a listening connection
3625
 * or a client certificate file name for an outgoing connection.
3626
 * The certificate files must be in PEM format. The server certificate file
3627
 * must contain a certificate, concatenated with a private key, optionally
3628
 * concatenated with DH parameters.
3629
 * `ca_cert` is a CA certificate or NULL if peer verification is not
3630
 * required.
3631
 * Return: NULL on success or error message on error.
3632
 */
3633
const char *mg_set_ssl(struct mg_connection *nc, const char *cert,
3634
                       const char *ca_cert);
3635
#endif
3636

    
3637
/*
3638
 * Sends data to the connection.
3639
 *
3640
 * Note that sending functions do not actually push data to the socket.
3641
 * They just append data to the output buffer. MG_EV_SEND will be delivered when
3642
 * the data has actually been pushed out.
3643
 */
3644
void mg_send(struct mg_connection *, const void *buf, int len);
3645

    
3646
/* Enables format string warnings for mg_printf */
3647
#if defined(__GNUC__)
3648
__attribute__((format(printf, 2, 3)))
3649
#endif
3650
/* don't separate from mg_printf declaration */
3651

    
3652
/*
3653
 * Sends `printf`-style formatted data to the connection.
3654
 *
3655
 * See `mg_send` for more details on send semantics.
3656
 */
3657
int mg_printf(struct mg_connection *, const char *fmt, ...);
3658

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

    
3662
/*
3663
 * Creates a socket pair.
3664
 * `sock_type` can be either `SOCK_STREAM` or `SOCK_DGRAM`.
3665
 * Returns 0 on failure and 1 on success.
3666
 */
3667
int mg_socketpair(sock_t[2], int sock_type);
3668

    
3669
#if MG_ENABLE_SYNC_RESOLVER
3670
/*
3671
 * Convert domain name into IP address.
3672
 *
3673
 * This is a utility function. If compilation flags have
3674
 * `-DMG_ENABLE_GETADDRINFO`, then `getaddrinfo()` call is used for name
3675
 * resolution. Otherwise, `gethostbyname()` is used.
3676
 *
3677
 * CAUTION: this function can block.
3678
 * Return 1 on success, 0 on failure.
3679
 */
3680
int mg_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
3681
#endif
3682

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

    
3705
/*
3706
 * Optional parameters for mg_enable_multithreading_opt()
3707
 */
3708
struct mg_multithreading_opts {
3709
  int poll_timeout; /* Polling interval */
3710
};
3711

    
3712
/*
3713
 * Enables multi-threaded handling for the given listening connection `nc`.
3714
 * For each accepted connection, Mongoose will create a separate thread
3715
 * and run an event handler in that thread. Thus, if an event handler is doing
3716
 * a blocking call or some long computation, it will not slow down
3717
 * other connections.
3718
 */
3719
void mg_enable_multithreading(struct mg_connection *nc);
3720
void mg_enable_multithreading_opt(struct mg_connection *nc,
3721
                                  struct mg_multithreading_opts opts);
3722

    
3723
#if MG_ENABLE_JAVASCRIPT
3724
/*
3725
 * Enables server-side JavaScript scripting.
3726
 * Requires a `-DMG_ENABLE_JAVASCRIPT` compilation flag and V7 engine sources.
3727
 * V7 instance must not be destroyed during manager's lifetime.
3728
 * Returns a V7 error.
3729
 */
3730
enum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,
3731
                                 const char *init_js_file_name);
3732
#endif
3733

    
3734
/*
3735
 * Schedules an MG_EV_TIMER event to be delivered at `timestamp` time.
3736
 * `timestamp` is UNIX time (the number of seconds since Epoch). It is
3737
 * `double` instead of `time_t` to allow for sub-second precision.
3738
 * Returns the old timer value.
3739
 *
3740
 * Example: set the connect timeout to 1.5 seconds:
3741
 *
3742
 * ```
3743
 *  c = mg_connect(&mgr, "cesanta.com", ev_handler);
3744
 *  mg_set_timer(c, mg_time() + 1.5);
3745
 *  ...
3746
 *
3747
 *  void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
3748
 *  switch (ev) {
3749
 *    case MG_EV_CONNECT:
3750
 *      mg_set_timer(c, 0);  // Clear connect timer
3751
 *      break;
3752
 *    case MG_EV_TIMER:
3753
 *      log("Connect timeout");
3754
 *      c->flags |= MG_F_CLOSE_IMMEDIATELY;
3755
 *      break;
3756
 * ```
3757
 */
3758
double mg_set_timer(struct mg_connection *c, double timestamp);
3759

    
3760
/*
3761
 * A sub-second precision version of time().
3762
 */
3763
double mg_time(void);
3764

    
3765
#ifdef __cplusplus
3766
}
3767
#endif /* __cplusplus */
3768

    
3769
#endif /* CS_MONGOOSE_SRC_NET_H_ */
3770
#ifdef MG_MODULE_LINES
3771
#line 1 "mongoose/src/uri.h"
3772
#endif
3773
/*
3774
 * Copyright (c) 2014 Cesanta Software Limited
3775
 * All rights reserved
3776
 */
3777

    
3778
/*
3779
 * === URI
3780
 */
3781

    
3782
#ifndef CS_MONGOOSE_SRC_URI_H_
3783
#define CS_MONGOOSE_SRC_URI_H_
3784

    
3785
/* Amalgamated: #include "mongoose/src/net.h" */
3786

    
3787
#ifdef __cplusplus
3788
extern "C" {
3789
#endif /* __cplusplus */
3790

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

    
3819
int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out);
3820

    
3821
#ifdef __cplusplus
3822
}
3823
#endif /* __cplusplus */
3824
#endif /* CS_MONGOOSE_SRC_URI_H_ */
3825
#ifdef MG_MODULE_LINES
3826
#line 1 "mongoose/src/util.h"
3827
#endif
3828
/*
3829
 * Copyright (c) 2014 Cesanta Software Limited
3830
 * All rights reserved
3831
 */
3832

    
3833
/*
3834
 * === Utility API
3835
 */
3836

    
3837
#ifndef CS_MONGOOSE_SRC_UTIL_H_
3838
#define CS_MONGOOSE_SRC_UTIL_H_
3839

    
3840
#include <stdio.h>
3841

    
3842
/* Amalgamated: #include "mongoose/src/common.h" */
3843
/* Amalgamated: #include "mongoose/src/net_if.h" */
3844

    
3845
#ifdef __cplusplus
3846
extern "C" {
3847
#endif /* __cplusplus */
3848

    
3849
#ifndef MAX_PATH_SIZE
3850
#define MAX_PATH_SIZE 500
3851
#endif
3852

    
3853
/*
3854
 * Fetches substring from input string `s`, `end` into `v`.
3855
 * Skips initial delimiter characters. Records first non-delimiter character
3856
 * at the beginning of substring `v`. Then scans the rest of the string
3857
 * until a delimiter character or end-of-string is found.
3858
 * `delimiters` is a 0-terminated string containing delimiter characters.
3859
 * Either one of `delimiters` or `end_string` terminates the search.
3860
 * Returns an `s` pointer, advanced forward where parsing has stopped.
3861
 */
3862
const char *mg_skip(const char *s, const char *end_string,
3863
                    const char *delimiters, struct mg_str *v);
3864

    
3865
/*
3866
 * Decodes base64-encoded string `s`, `len` into the destination `dst`.
3867
 * The destination has to have enough space to hold the decoded buffer.
3868
 * Decoding stops either when all strings have been decoded or invalid an
3869
 * character appeared.
3870
 * Destination is '\0'-terminated.
3871
 * Returns the number of decoded characters. On success, that should be equal
3872
 * to `len`. On error (invalid character) the return value is smaller then
3873
 * `len`.
3874
 */
3875
int mg_base64_decode(const unsigned char *s, int len, char *dst);
3876

    
3877
/*
3878
 * Base64-encode chunk of memory `src`, `src_len` into the destination `dst`.
3879
 * Destination has to have enough space to hold encoded buffer.
3880
 * Destination is '\0'-terminated.
3881
 */
3882
void mg_base64_encode(const unsigned char *src, int src_len, char *dst);
3883

    
3884
#if MG_ENABLE_FILESYSTEM
3885
/*
3886
 * Performs a 64-bit `stat()` call against a given file.
3887
 *
3888
 * `path` should be UTF8 encoded.
3889
 *
3890
 * Return value is the same as for `stat()` syscall.
3891
 */
3892
int mg_stat(const char *path, cs_stat_t *st);
3893

    
3894
/*
3895
 * Opens the given file and returns a file stream.
3896
 *
3897
 * `path` and `mode` should be UTF8 encoded.
3898
 *
3899
 * Return value is the same as for the `fopen()` call.
3900
 */
3901
FILE *mg_fopen(const char *path, const char *mode);
3902

    
3903
/*
3904
 * Opens the given file and returns a file stream.
3905
 *
3906
 * `path` should be UTF8 encoded.
3907
 *
3908
 * Return value is the same as for the `open()` syscall.
3909
 */
3910
int mg_open(const char *path, int flag, int mode);
3911
#endif /* MG_ENABLE_FILESYSTEM */
3912

    
3913
#if MG_ENABLE_THREADS
3914
/*
3915
 * Starts a new detached thread.
3916
 * Arguments and semantics are the same as pthead's `pthread_create()`.
3917
 * `thread_func` is a thread function, `thread_func_param` is a parameter
3918
 * that is passed to the thread function.
3919
 */
3920
void *mg_start_thread(void *(*thread_func)(void *), void *thread_func_param);
3921
#endif
3922

    
3923
void mg_set_close_on_exec(sock_t);
3924

    
3925
#define MG_SOCK_STRINGIFY_IP 1
3926
#define MG_SOCK_STRINGIFY_PORT 2
3927
#define MG_SOCK_STRINGIFY_REMOTE 4
3928
/*
3929
 * Converts a connection's local or remote address into string.
3930
 *
3931
 * The `flags` parameter is a bit mask that controls the behaviour,
3932
 * see `MG_SOCK_STRINGIFY_*` definitions.
3933
 *
3934
 * - MG_SOCK_STRINGIFY_IP - print IP address
3935
 * - MG_SOCK_STRINGIFY_PORT - print port number
3936
 * - MG_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address
3937
 *
3938
 * If both port number and IP address are printed, they are separated by `:`.
3939
 * If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported.
3940
 */
3941
void mg_conn_addr_to_str(struct mg_connection *nc, char *buf, size_t len,
3942
                         int flags);
3943
#if MG_NET_IF == MG_NET_IF_SOCKET
3944
/* Legacy interface. */
3945
void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
3946
#endif
3947

    
3948
/*
3949
 * Convert the socket's address into string.
3950
 *
3951
 * `flags` is MG_SOCK_STRINGIFY_IP and/or MG_SOCK_STRINGIFY_PORT.
3952
 */
3953
void mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
3954
                         int flags);
3955

    
3956
#if MG_ENABLE_HEXDUMP
3957
/*
3958
 * Generates a human-readable hexdump of memory chunk.
3959
 *
3960
 * Takes a memory buffer `buf` of length `len` and creates a hex dump of that
3961
 * buffer in `dst`. The generated output is a-la hexdump(1).
3962
 * Returns the length of generated string, excluding terminating `\0`. If
3963
 * returned length is bigger than `dst_len`, the overflow bytes are discarded.
3964
 */
3965
int mg_hexdump(const void *buf, int len, char *dst, int dst_len);
3966

    
3967
/*
3968
 * Generates human-readable hexdump of the data sent or received by the
3969
 * connection. `path` is a file name where hexdump should be written.
3970
 * `num_bytes` is a number of bytes sent/received. `ev` is one of the `MG_*`
3971
 * events sent to an event handler. This function is supposed to be called from
3972
 * the event handler.
3973
 */
3974
void mg_hexdump_connection(struct mg_connection *nc, const char *path,
3975
                           const void *buf, int num_bytes, int ev);
3976
#endif
3977

    
3978
/*
3979
 * Returns true if target platform is big endian.
3980
 */
3981
int mg_is_big_endian(void);
3982

    
3983
/*
3984
 * A helper function for traversing a comma separated list of values.
3985
 * It returns a list pointer shifted to the next value or NULL if the end
3986
 * of the list found.
3987
 * The value is stored in a val vector. If the value has a form "x=y", then
3988
 * eq_val vector is initialised to point to the "y" part, and val vector length
3989
 * is adjusted to point only to "x".
3990
 * If the list is just a comma separated list of entries, like "aa,bb,cc" then
3991
 * `eq_val` will contain zero-length string.
3992
 *
3993
 * The purpose of this function is to parse comma separated string without
3994
 * any copying/memory allocation.
3995
 */
3996
const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
3997
                                     struct mg_str *eq_val);
3998

    
3999
/*
4000
 * Matches 0-terminated string (mg_match_prefix) or string with given length
4001
 * mg_match_prefix_n against a glob pattern.
4002
 *
4003
 * Match is case-insensitive. Returns number of bytes matched, or -1 if no
4004
 * match.
4005
 */
4006
int mg_match_prefix(const char *pattern, int pattern_len, const char *str);
4007
int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str);
4008

    
4009
/*
4010
 * Use with cs_base64_init/update/finish in order to write out base64 in chunks.
4011
 */
4012
void mg_mbuf_append_base64_putc(char ch, void *user_data);
4013

    
4014
/*
4015
 * Encode `len` bytes starting at `data` as base64 and append them to an mbuf.
4016
 */
4017
void mg_mbuf_append_base64(struct mbuf *mbuf, const void *data, size_t len);
4018

    
4019
/*
4020
 * Generate a Basic Auth header and appends it to buf.
4021
 * If pass is NULL, then user is expected to contain the credentials pair
4022
 * already encoded as `user:pass`.
4023
 */
4024
void mg_basic_auth_header(const char *user, const char *pass, struct mbuf *buf);
4025

    
4026
#ifdef __cplusplus
4027
}
4028
#endif /* __cplusplus */
4029
#endif /* CS_MONGOOSE_SRC_UTIL_H_ */
4030
#ifdef MG_MODULE_LINES
4031
#line 1 "mongoose/src/http.h"
4032
#endif
4033
/*
4034
 * Copyright (c) 2014 Cesanta Software Limited
4035
 * All rights reserved
4036
 */
4037

    
4038
/*
4039
 * === Common API reference
4040
 */
4041

    
4042
#ifndef CS_MONGOOSE_SRC_HTTP_H_
4043
#define CS_MONGOOSE_SRC_HTTP_H_
4044

    
4045
#if MG_ENABLE_HTTP
4046

    
4047
/* Amalgamated: #include "mongoose/src/net.h" */
4048
/* Amalgamated: #include "common/mg_str.h" */
4049

    
4050
#ifdef __cplusplus
4051
extern "C" {
4052
#endif /* __cplusplus */
4053

    
4054
#ifndef MG_MAX_HTTP_HEADERS
4055
#define MG_MAX_HTTP_HEADERS 20
4056
#endif
4057

    
4058
#ifndef MG_MAX_HTTP_REQUEST_SIZE
4059
#define MG_MAX_HTTP_REQUEST_SIZE 1024
4060
#endif
4061

    
4062
#ifndef MG_MAX_PATH
4063
#ifdef PATH_MAX
4064
#define MG_MAX_PATH PATH_MAX
4065
#else
4066
#define MG_MAX_PATH 256
4067
#endif
4068
#endif
4069

    
4070
#ifndef MG_MAX_HTTP_SEND_MBUF
4071
#define MG_MAX_HTTP_SEND_MBUF 1024
4072
#endif
4073

    
4074
#ifndef MG_CGI_ENVIRONMENT_SIZE
4075
#define MG_CGI_ENVIRONMENT_SIZE 8192
4076
#endif
4077

    
4078
/* HTTP message */
4079
struct http_message {
4080
  struct mg_str message; /* Whole message: request line + headers + body */
4081

    
4082
  /* HTTP Request line (or HTTP response line) */
4083
  struct mg_str method; /* "GET" */
4084
  struct mg_str uri;    /* "/my_file.html" */
4085
  struct mg_str proto;  /* "HTTP/1.1" -- for both request and response */
4086

    
4087
  /* For responses, code and response status message are set */
4088
  int resp_code;
4089
  struct mg_str resp_status_msg;
4090

    
4091
  /*
4092
   * Query-string part of the URI. For example, for HTTP request
4093
   *    GET /foo/bar?param1=val1&param2=val2
4094
   *    |    uri    |     query_string     |
4095
   *
4096
   * Note that question mark character doesn't belong neither to the uri,
4097
   * nor to the query_string
4098
   */
4099
  struct mg_str query_string;
4100

    
4101
  /* Headers */
4102
  struct mg_str header_names[MG_MAX_HTTP_HEADERS];
4103
  struct mg_str header_values[MG_MAX_HTTP_HEADERS];
4104

    
4105
  /* Message body */
4106
  struct mg_str body; /* Zero-length for requests with no body */
4107
};
4108

    
4109
#if MG_ENABLE_HTTP_WEBSOCKET
4110
/* WebSocket message */
4111
struct websocket_message {
4112
  unsigned char *data;
4113
  size_t size;
4114
  unsigned char flags;
4115
};
4116
#endif
4117

    
4118
/* HTTP multipart part */
4119
struct mg_http_multipart_part {
4120
  const char *file_name;
4121
  const char *var_name;
4122
  struct mg_str data;
4123
  int status; /* <0 on error */
4124
  void *user_data;
4125
};
4126

    
4127
/* SSI call context */
4128
struct mg_ssi_call_ctx {
4129
  struct http_message *req; /* The request being processed. */
4130
  struct mg_str file;       /* Filesystem path of the file being processed. */
4131
  struct mg_str arg; /* The argument passed to the tag: <!-- call arg -->. */
4132
};
4133

    
4134
/* HTTP and websocket events. void *ev_data is described in a comment. */
4135
#define MG_EV_HTTP_REQUEST 100 /* struct http_message * */
4136
#define MG_EV_HTTP_REPLY 101   /* struct http_message * */
4137
#define MG_EV_HTTP_CHUNK 102   /* struct http_message * */
4138
#define MG_EV_SSI_CALL 105     /* char * */
4139
#define MG_EV_SSI_CALL_CTX 106 /* struct mg_ssi_call_ctx * */
4140

    
4141
#if MG_ENABLE_HTTP_WEBSOCKET
4142
#define MG_EV_WEBSOCKET_HANDSHAKE_REQUEST 111 /* struct http_message * */
4143
#define MG_EV_WEBSOCKET_HANDSHAKE_DONE 112    /* NULL */
4144
#define MG_EV_WEBSOCKET_FRAME 113             /* struct websocket_message * */
4145
#define MG_EV_WEBSOCKET_CONTROL_FRAME 114     /* struct websocket_message * */
4146
#endif
4147

    
4148
#if MG_ENABLE_HTTP_STREAMING_MULTIPART
4149
#define MG_EV_HTTP_MULTIPART_REQUEST 121 /* struct http_message */
4150
#define MG_EV_HTTP_PART_BEGIN 122        /* struct mg_http_multipart_part */
4151
#define MG_EV_HTTP_PART_DATA 123         /* struct mg_http_multipart_part */
4152
#define MG_EV_HTTP_PART_END 124          /* struct mg_http_multipart_part */
4153
/* struct mg_http_multipart_part */
4154
#define MG_EV_HTTP_MULTIPART_REQUEST_END 125
4155
#endif
4156

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

    
4211
#if MG_ENABLE_HTTP_WEBSOCKET
4212
/*
4213
 * Send websocket handshake to the server.
4214
 *
4215
 * `nc` must be a valid connection, connected to a server. `uri` is an URI
4216
 * to fetch, extra_headers` is extra HTTP headers to send or `NULL`.
4217
 *
4218
 * This function is intended to be used by websocket client.
4219
 *
4220
 * Note that the Host header is mandatory in HTTP/1.1 and must be
4221
 * included in `extra_headers`. `mg_send_websocket_handshake2` offers
4222
 * a better API for that.
4223
 *
4224
 * Deprecated in favour of `mg_send_websocket_handshake2`
4225
 */
4226
void mg_send_websocket_handshake(struct mg_connection *nc, const char *uri,
4227
                                 const char *extra_headers);
4228

    
4229
/*
4230
 * Send websocket handshake to the server.
4231
 *
4232
 * `nc` must be a valid connection, connected to a server. `uri` is an URI
4233
 * to fetch, `host` goes into the `Host` header, `protocol` goes into the
4234
 * `Sec-WebSocket-Proto` header (NULL to omit), extra_headers` is extra HTTP
4235
 * headers to send or `NULL`.
4236
 *
4237
 * This function is intended to be used by websocket client.
4238
 */
4239
void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path,
4240
                                  const char *host, const char *protocol,
4241
                                  const char *extra_headers);
4242

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

    
4273
/*
4274
 * Helper function that creates an outbound WebSocket connection
4275
 *
4276
 * Mostly identical to `mg_connect_ws`, but allows to provide extra parameters
4277
 * (for example, SSL parameters)
4278
 */
4279
struct mg_connection *mg_connect_ws_opt(struct mg_mgr *mgr,
4280
                                        mg_event_handler_t ev_handler,
4281
                                        struct mg_connect_opts opts,
4282
                                        const char *url, const char *protocol,
4283
                                        const char *extra_headers);
4284

    
4285
/*
4286
 * Send WebSocket frame to the remote end.
4287
 *
4288
 * `op_and_flags` specifies the frame's type. It's one of:
4289
 *
4290
 * - WEBSOCKET_OP_CONTINUE
4291
 * - WEBSOCKET_OP_TEXT
4292
 * - WEBSOCKET_OP_BINARY
4293
 * - WEBSOCKET_OP_CLOSE
4294
 * - WEBSOCKET_OP_PING
4295
 * - WEBSOCKET_OP_PONG
4296
 *
4297
 * Orred with one of the flags:
4298
 *
4299
 * - WEBSOCKET_DONT_FIN: Don't set the FIN flag on the frame to be sent.
4300
 *
4301
 * `data` and `data_len` contain frame data.
4302
 */
4303
void mg_send_websocket_frame(struct mg_connection *nc, int op_and_flags,
4304
                             const void *data, size_t data_len);
4305

    
4306
/*
4307
 * Sends multiple websocket frames.
4308
 *
4309
 * Like `mg_send_websocket_frame()`, but composes a frame from multiple buffers.
4310
 */
4311
void mg_send_websocket_framev(struct mg_connection *nc, int op_and_flags,
4312
                              const struct mg_str *strings, int num_strings);
4313

    
4314
/*
4315
 * Sends WebSocket frame to the remote end.
4316
 *
4317
 * Like `mg_send_websocket_frame()`, but allows to create formatted messages
4318
 * with `printf()`-like semantics.
4319
 */
4320
void mg_printf_websocket_frame(struct mg_connection *nc, int op_and_flags,
4321
                               const char *fmt, ...);
4322

    
4323
/* Websocket opcodes, from http://tools.ietf.org/html/rfc6455 */
4324
#define WEBSOCKET_OP_CONTINUE 0
4325
#define WEBSOCKET_OP_TEXT 1
4326
#define WEBSOCKET_OP_BINARY 2
4327
#define WEBSOCKET_OP_CLOSE 8
4328
#define WEBSOCKET_OP_PING 9
4329
#define WEBSOCKET_OP_PONG 10
4330

    
4331
/*
4332
 * If set causes the FIN flag to not be set on outbound
4333
 * frames. This enables sending multiple fragments of a single
4334
 * logical message.
4335
 *
4336
 * The WebSocket protocol mandates that if the FIN flag of a data
4337
 * frame is not set, the next frame must be a WEBSOCKET_OP_CONTINUE.
4338
 * The last frame must have the FIN bit set.
4339
 *
4340
 * Note that mongoose will automatically defragment incoming messages,
4341
 * so this flag is used only on outbound messages.
4342
 */
4343
#define WEBSOCKET_DONT_FIN 0x100
4344

    
4345
#endif /* MG_ENABLE_HTTP_WEBSOCKET */
4346

    
4347
/*
4348
 * Decodes a URL-encoded string.
4349
 *
4350
 * Source string is specified by (`src`, `src_len`), and destination is
4351
 * (`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then
4352
 * `+` character is decoded as a blank space character. This function
4353
 * guarantees to NUL-terminate the destination. If destination is too small,
4354
 * then the source string is partially decoded and `-1` is returned. Otherwise,
4355
 * a length of the decoded string is returned, not counting final NUL.
4356
 */
4357
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len,
4358
                  int is_form_url_encoded);
4359

    
4360
#ifdef __cplusplus
4361
}
4362
#endif /* __cplusplus */
4363

    
4364
#endif /* MG_ENABLE_HTTP */
4365

    
4366
#endif /* CS_MONGOOSE_SRC_HTTP_H_ */
4367
#ifdef MG_MODULE_LINES
4368
#line 1 "mongoose/src/http_server.h"
4369
#endif
4370
/*
4371
 * === Server API reference
4372
 */
4373

    
4374
#ifndef CS_MONGOOSE_SRC_HTTP_SERVER_H_
4375
#define CS_MONGOOSE_SRC_HTTP_SERVER_H_
4376

    
4377
#if MG_ENABLE_HTTP
4378

    
4379
#ifdef __cplusplus
4380
extern "C" {
4381
#endif /* __cplusplus */
4382

    
4383
/*
4384
 * Parses a HTTP message.
4385
 *
4386
 * `is_req` should be set to 1 if parsing a request, 0 if reply.
4387
 *
4388
 * Returns the number of bytes parsed. If HTTP message is
4389
 * incomplete `0` is returned. On parse error, a negative number is returned.
4390
 */
4391
int mg_parse_http(const char *s, int n, struct http_message *hm, int is_req);
4392

    
4393
/*
4394
 * Searches and returns the header `name` in parsed HTTP message `hm`.
4395
 * If header is not found, NULL is returned. Example:
4396
 *
4397
 *     struct mg_str *host_hdr = mg_get_http_header(hm, "Host");
4398
 */
4399
struct mg_str *mg_get_http_header(struct http_message *hm, const char *name);
4400

    
4401
/*
4402
 * Parses the HTTP header `hdr`. Finds variable `var_name` and stores its value
4403
 * in the buffer `buf`, `buf_size`. Returns 0 if variable not found, non-zero
4404
 * otherwise.
4405
 *
4406
 * This function is supposed to parse cookies, authentication headers, etc.
4407
 * Example (error handling omitted):
4408
 *
4409
 *     char user[20];
4410
 *     struct mg_str *hdr = mg_get_http_header(hm, "Authorization");
4411
 *     mg_http_parse_header(hdr, "username", user, sizeof(user));
4412
 *
4413
 * Returns the length of the variable's value. If buffer is not large enough,
4414
 * or variable not found, 0 is returned.
4415
 */
4416
int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,
4417
                         size_t buf_size);
4418

    
4419
/*
4420
 * Gets and parses the Authorization: Basic header
4421
 * Returns -1 if no Authorization header is found, or if
4422
 * mg_parse_http_basic_auth
4423
 * fails parsing the resulting header.
4424
 */
4425
int mg_get_http_basic_auth(struct http_message *hm, char *user, size_t user_len,
4426
                           char *pass, size_t pass_len);
4427

    
4428
/*
4429
 * Parses the Authorization: Basic header
4430
 * Returns -1 iif the authorization type is not "Basic" or any other error such
4431
 * as incorrectly encoded base64 user password pair.
4432
 */
4433
int mg_parse_http_basic_auth(struct mg_str *hdr, char *user, size_t user_len,
4434
                             char *pass, size_t pass_len);
4435

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

    
4477
/*
4478
 * Fetches a HTTP form variable.
4479
 *
4480
 * Fetches a variable `name` from a `buf` into a buffer specified by `dst`,
4481
 * `dst_len`. The destination is always zero-terminated. Returns the length of
4482
 * a fetched variable. If not found, 0 is returned. `buf` must be valid
4483
 * url-encoded buffer. If destination is too small, `-1` is returned.
4484
 */
4485
int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst,
4486
                    size_t dst_len);
4487

    
4488
#if MG_ENABLE_FILESYSTEM
4489
/*
4490
 * This structure defines how `mg_serve_http()` works.
4491
 * Best practice is to set only required settings, and leave the rest as NULL.
4492
 */
4493
struct mg_serve_http_opts {
4494
  /* Path to web root directory */
4495
  const char *document_root;
4496

    
4497
  /* List of index files. Default is "" */
4498
  const char *index_files;
4499

    
4500
  /*
4501
   * Leave as NULL to disable authentication.
4502
   * To enable directory protection with authentication, set this to ".htpasswd"
4503
   * Then, creating ".htpasswd" file in any directory automatically protects
4504
   * it with digest authentication.
4505
   * Use `mongoose` web server binary, or `htdigest` Apache utility to
4506
   * create/manipulate passwords file.
4507
   * Make sure `auth_domain` is set to a valid domain name.
4508
   */
4509
  const char *per_directory_auth_file;
4510

    
4511
  /* Authorization domain (domain name of this web server) */
4512
  const char *auth_domain;
4513

    
4514
  /*
4515
   * Leave as NULL to disable authentication.
4516
   * Normally, only selected directories in the document root are protected.
4517
   * If absolutely every access to the web server needs to be authenticated,
4518
   * regardless of the URI, set this option to the path to the passwords file.
4519
   * Format of that file is the same as ".htpasswd" file. Make sure that file
4520
   * is located outside document root to prevent people fetching it.
4521
   */
4522
  const char *global_auth_file;
4523

    
4524
  /* Set to "no" to disable directory listing. Enabled by default. */
4525
  const char *enable_directory_listing;
4526

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

    
4587
  /* IP ACL. By default, NULL, meaning all IPs are allowed to connect */
4588
  const char *ip_acl;
4589

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

    
4618
  /* DAV document root. If NULL, DAV requests are going to fail. */
4619
  const char *dav_document_root;
4620

    
4621
  /*
4622
   * DAV passwords file. If NULL, DAV requests are going to fail.
4623
   * If passwords file is set to "-", then DAV auth is disabled.
4624
   */
4625
  const char *dav_auth_file;
4626

    
4627
  /* Glob pattern for the files to hide. */
4628
  const char *hidden_file_pattern;
4629

    
4630
  /* Set to non-NULL to enable CGI, e.g. **.cgi$|**.php$" */
4631
  const char *cgi_file_pattern;
4632

    
4633
  /* If not NULL, ignore CGI script hashbang and use this interpreter */
4634
  const char *cgi_interpreter;
4635

    
4636
  /*
4637
   * Comma-separated list of Content-Type overrides for path suffixes, e.g.
4638
   * ".txt=text/plain; charset=utf-8,.c=text/plain"
4639
   */
4640
  const char *custom_mime_types;
4641

    
4642
  /*
4643
   * Extra HTTP headers to add to each server response.
4644
   * Example: to enable CORS, set this to "Access-Control-Allow-Origin: *".
4645
   */
4646
  const char *extra_headers;
4647
};
4648

    
4649
/*
4650
 * Serves given HTTP request according to the `options`.
4651
 *
4652
 * Example code snippet:
4653
 *
4654
 * ```c
4655
 * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
4656
 *   struct http_message *hm = (struct http_message *) ev_data;
4657
 *   struct mg_serve_http_opts opts = { .document_root = "/var/www" };  // C99
4658
 *
4659
 *   switch (ev) {
4660
 *     case MG_EV_HTTP_REQUEST:
4661
 *       mg_serve_http(nc, hm, opts);
4662
 *       break;
4663
 *     default:
4664
 *       break;
4665
 *   }
4666
 * }
4667
 * ```
4668
 */
4669
void mg_serve_http(struct mg_connection *nc, struct http_message *hm,
4670
                   struct mg_serve_http_opts opts);
4671

    
4672
/*
4673
 * Serves a specific file with a given MIME type and optional extra headers.
4674
 *
4675
 * Example code snippet:
4676
 *
4677
 * ```c
4678
 * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
4679
 *   switch (ev) {
4680
 *     case MG_EV_HTTP_REQUEST: {
4681
 *       struct http_message *hm = (struct http_message *) ev_data;
4682
 *       mg_http_serve_file(nc, hm, "file.txt",
4683
 *                          mg_mk_str("text/plain"), mg_mk_str(""));
4684
 *       break;
4685
 *     }
4686
 *     ...
4687
 *   }
4688
 * }
4689
 * ```
4690
 */
4691
void mg_http_serve_file(struct mg_connection *nc, struct http_message *hm,
4692
                        const char *path, const struct mg_str mime_type,
4693
                        const struct mg_str extra_headers);
4694

    
4695
#if MG_ENABLE_HTTP_STREAMING_MULTIPART
4696

    
4697
/* Callback prototype for `mg_file_upload_handler()`. */
4698
typedef struct mg_str (*mg_fu_fname_fn)(struct mg_connection *nc,
4699
                                        struct mg_str fname);
4700

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

    
4738
/*
4739
 * Registers a callback for a specified http endpoint
4740
 * Note: if callback is registered it is called instead of the
4741
 * callback provided in mg_bind
4742
 *
4743
 * Example code snippet:
4744
 *
4745
 * ```c
4746
 * static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
4747
 *   (void) ev; (void) ev_data;
4748
 *   mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello1]");
4749
 *  nc->flags |= MG_F_SEND_AND_CLOSE;
4750
 * }
4751
 *
4752
 * static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
4753
 *  (void) ev; (void) ev_data;
4754
 *   mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello2]");
4755
 *  nc->flags |= MG_F_SEND_AND_CLOSE;
4756
 * }
4757
 *
4758
 * void init() {
4759
 *   nc = mg_bind(&mgr, local_addr, cb1);
4760
 *   mg_register_http_endpoint(nc, "/hello1", handle_hello1);
4761
 *   mg_register_http_endpoint(nc, "/hello1/hello2", handle_hello2);
4762
 * }
4763
 * ```
4764
 */
4765
void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,
4766
                               mg_event_handler_t handler);
4767

    
4768
/*
4769
 * Authenticates a HTTP request against an opened password file.
4770
 * Returns 1 if authenticated, 0 otherwise.
4771
 */
4772
int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain,
4773
                              FILE *fp);
4774

    
4775
/*
4776
 * Sends buffer `buf` of size `len` to the client using chunked HTTP encoding.
4777
 * This function sends the buffer size as hex number + newline first, then
4778
 * the buffer itself, then the newline. For example,
4779
 * `mg_send_http_chunk(nc, "foo", 3)` whill append the `3\r\nfoo\r\n` string
4780
 * to the `nc->send_mbuf` output IO buffer.
4781
 *
4782
 * NOTE: The HTTP header "Transfer-Encoding: chunked" should be sent prior to
4783
 * using this function.
4784
 *
4785
 * NOTE: do not forget to send an empty chunk at the end of the response,
4786
 * to tell the client that everything was sent. Example:
4787
 *
4788
 * ```
4789
 *   mg_printf_http_chunk(nc, "%s", "my response!");