2020-12-05 11:26:32 +00:00
|
|
|
// Copyright (c) 2004-2013 Sergey Lyubka
|
2022-02-22 18:13:06 +00:00
|
|
|
// Copyright (c) 2013-2022 Cesanta Software Limited
|
2020-12-05 11:26:32 +00:00
|
|
|
// All rights reserved
|
|
|
|
//
|
|
|
|
// This software is dual-licensed: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License version 2 as
|
|
|
|
// published by the Free Software Foundation. For the terms of this
|
2021-10-20 10:04:49 +01:00
|
|
|
// license, see http://www.gnu.org/licenses/
|
2020-12-05 11:26:32 +00:00
|
|
|
//
|
|
|
|
// You are free to use this software under the terms of the GNU General
|
|
|
|
// Public License, but WITHOUT ANY WARRANTY; without even the implied
|
|
|
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
// See the GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// Alternatively, you can license this software under a commercial
|
2021-10-20 10:04:49 +01:00
|
|
|
// license, as set out in https://www.mongoose.ws/licensing/
|
2022-02-22 18:13:06 +00:00
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: GPL-2.0 or commercial
|
2021-07-20 11:33:38 +01:00
|
|
|
|
2021-07-19 09:04:18 +01:00
|
|
|
#ifndef MONGOOSE_H
|
|
|
|
#define MONGOOSE_H
|
|
|
|
|
2022-05-19 11:44:32 +01:00
|
|
|
#define MG_VERSION "7.7"
|
2020-12-05 11:26:32 +00:00
|
|
|
|
2021-07-13 06:58:34 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
|
|
|
|
#define MG_ARCH_CUSTOM 0
|
|
|
|
#define MG_ARCH_UNIX 1
|
|
|
|
#define MG_ARCH_WIN32 2
|
|
|
|
#define MG_ARCH_ESP32 3
|
|
|
|
#define MG_ARCH_ESP8266 4
|
2021-05-11 09:12:06 +01:00
|
|
|
#define MG_ARCH_FREERTOS_TCP 5
|
2021-05-28 23:49:26 +01:00
|
|
|
#define MG_ARCH_FREERTOS_LWIP 6
|
2021-09-14 09:28:28 +03:00
|
|
|
#define MG_ARCH_AZURERTOS 7
|
2022-02-18 10:07:10 +02:00
|
|
|
#define MG_ARCH_RTX_LWIP 8
|
2022-03-30 07:56:44 +01:00
|
|
|
#define MG_ARCH_ZEPHYR 9
|
2022-05-01 13:47:33 +01:00
|
|
|
#define MG_ARCH_NEWLIB 10
|
2022-05-12 08:07:51 +01:00
|
|
|
#define MG_ARCH_RTX 11
|
2022-05-15 19:18:18 +03:00
|
|
|
#define MG_ARCH_TIRTOS 12
|
2020-12-05 11:26:32 +00:00
|
|
|
|
|
|
|
#if !defined(MG_ARCH)
|
2021-05-11 09:12:06 +01:00
|
|
|
#if defined(__unix__) || defined(__APPLE__)
|
2020-12-05 11:26:32 +00:00
|
|
|
#define MG_ARCH MG_ARCH_UNIX
|
2016-03-29 17:27:55 +01:00
|
|
|
#elif defined(_WIN32)
|
2020-12-05 11:26:32 +00:00
|
|
|
#define MG_ARCH MG_ARCH_WIN32
|
|
|
|
#elif defined(ICACHE_FLASH) || defined(ICACHE_RAM_ATTR)
|
|
|
|
#define MG_ARCH MG_ARCH_ESP8266
|
2020-12-27 01:29:42 +00:00
|
|
|
#elif defined(ESP_PLATFORM)
|
|
|
|
#define MG_ARCH MG_ARCH_ESP32
|
2021-05-17 17:36:57 +01:00
|
|
|
#elif defined(FREERTOS_IP_H)
|
|
|
|
#define MG_ARCH MG_ARCH_FREERTOS_TCP
|
2021-09-14 09:28:28 +03:00
|
|
|
#elif defined(AZURE_RTOS_THREADX)
|
|
|
|
#define MG_ARCH MG_ARCH_AZURERTOS
|
2022-03-30 07:56:44 +01:00
|
|
|
#elif defined(__ZEPHYR__)
|
|
|
|
#define MG_ARCH MG_ARCH_ZEPHYR
|
2016-03-29 17:27:55 +01:00
|
|
|
#endif
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#if !defined(MG_ARCH)
|
2022-05-12 08:07:51 +01:00
|
|
|
#error "MG_ARCH is not specified and we couldn't guess it. Set -D MG_ARCH=..."
|
2016-10-17 12:03:59 +03:00
|
|
|
#endif
|
2020-12-05 11:26:32 +00:00
|
|
|
#endif // !defined(MG_ARCH)
|
2016-10-17 12:03:59 +03:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#if MG_ARCH == MG_ARCH_CUSTOM
|
2022-05-12 08:07:51 +01:00
|
|
|
#include <mongoose_custom.h>
|
2017-10-16 20:00:16 +01:00
|
|
|
#endif
|
|
|
|
|
Change from using #ifdef to #if for features tests
"#if FOO" still works with simple -DFOO, but gives more flexibility.
Specifically, if user expressed no preference (FOO is not defined),
we can apply reasonable defaults (this is the legitimate use of ifdef).
In short, from now on, please use
#if MG_ENABLE_FOO
instead of
#ifdef MG_ENABLE_FOO
Since we are all used to #ifdef, this change also adds a precommit check
to police this. Specifically, in *.h and *.c files that are Copyright Cesanta,
"ifdef" and "if defined()" are not allowed to be used with macros that contain
ENABLE or DISABLE, unless the like also contains "ifdef-ok".
Hence, if you are sure you want to use ifdef, use this:
#ifdef MG_ENABLE_FOO /* ifdef-ok */
PUBLISHED_FROM=9be829448f53cff575d6cae8b9945fb12531c15a
2016-10-13 20:55:08 +03:00
|
|
|
|
|
|
|
|
2016-10-17 22:08:11 +03:00
|
|
|
|
2016-10-14 13:15:11 +03:00
|
|
|
|
2016-10-17 21:13:21 +03:00
|
|
|
|
2016-11-13 21:20:15 +00:00
|
|
|
|
2016-10-14 13:15:11 +03:00
|
|
|
|
2021-05-28 23:49:26 +01:00
|
|
|
|
2022-03-30 07:56:44 +01:00
|
|
|
|
2022-05-01 13:47:33 +01:00
|
|
|
|
2022-05-12 08:07:51 +01:00
|
|
|
|
|
|
|
|
2021-09-14 09:28:28 +03:00
|
|
|
#if MG_ARCH == MG_ARCH_AZURERTOS
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdbool.h>
|
2022-01-11 19:15:38 +00:00
|
|
|
#include <stdint.h>
|
2021-09-14 09:28:28 +03:00
|
|
|
#include <stdio.h>
|
2022-01-11 19:15:38 +00:00
|
|
|
#include <time.h>
|
|
|
|
|
2021-09-14 09:28:28 +03:00
|
|
|
#include <fx_api.h>
|
2022-01-11 19:15:38 +00:00
|
|
|
#include <tx_api.h>
|
2021-09-14 09:28:28 +03:00
|
|
|
|
|
|
|
#include <nx_api.h>
|
|
|
|
#include <nx_bsd.h>
|
2022-01-11 19:15:38 +00:00
|
|
|
#include <nx_port.h>
|
|
|
|
#include <tx_port.h>
|
2021-09-14 09:28:28 +03:00
|
|
|
|
|
|
|
#ifdef __REDLIB__
|
2022-01-11 19:15:38 +00:00
|
|
|
#define va_copy(d, s) __builtin_va_copy(d, s)
|
2021-09-14 09:28:28 +03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#define PATH_MAX FX_MAXIMUM_PATH
|
|
|
|
#define MG_DIRSEP '\\'
|
|
|
|
|
|
|
|
#define socklen_t int
|
|
|
|
#define closesocket(x) soc_close(x)
|
|
|
|
|
|
|
|
#undef FOPEN_MAX
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#if MG_ARCH == MG_ARCH_ESP32
|
2016-10-13 21:48:45 +01:00
|
|
|
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <ctype.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <dirent.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <limits.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <netdb.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2021-02-03 02:13:05 +00:00
|
|
|
#include <sys/stat.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
2022-05-16 11:54:26 +01:00
|
|
|
#include <esp_timer.h>
|
|
|
|
|
2021-02-03 02:13:05 +00:00
|
|
|
#define MG_PATH_MAX 128
|
2016-10-26 17:41:54 +03:00
|
|
|
|
2016-11-24 09:46:40 +00:00
|
|
|
#endif
|
|
|
|
|
2016-11-29 11:17:57 +00:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#if MG_ARCH == MG_ARCH_ESP8266
|
|
|
|
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <ctype.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <dirent.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <limits.h>
|
2020-12-27 01:29:42 +00:00
|
|
|
#include <netdb.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <stdarg.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <stdbool.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <sys/time.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#include <esp_system.h>
|
|
|
|
|
2021-10-30 19:34:53 +01:00
|
|
|
#define MG_PATH_MAX 128
|
2017-03-15 02:37:45 +02:00
|
|
|
|
2016-11-08 23:29:07 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2021-05-28 23:49:26 +01:00
|
|
|
#if MG_ARCH == MG_ARCH_FREERTOS_LWIP
|
|
|
|
|
2022-02-08 13:36:04 +00:00
|
|
|
#include <ctype.h>
|
2021-05-28 23:49:26 +01:00
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
2021-09-29 12:13:02 +03:00
|
|
|
#include <stdio.h>
|
2022-01-14 12:33:06 +00:00
|
|
|
#include <string.h>
|
2021-05-29 09:44:07 +01:00
|
|
|
|
|
|
|
#if defined(__GNUC__)
|
2021-07-24 03:44:00 +01:00
|
|
|
#include <sys/stat.h>
|
2021-05-28 23:49:26 +01:00
|
|
|
#include <sys/time.h>
|
2021-05-29 09:44:07 +01:00
|
|
|
#else
|
|
|
|
struct timeval {
|
|
|
|
time_t tv_sec;
|
2022-01-14 12:33:06 +00:00
|
|
|
long tv_usec;
|
2021-05-29 09:44:07 +01:00
|
|
|
};
|
|
|
|
#endif
|
2021-05-28 23:49:26 +01:00
|
|
|
|
|
|
|
#include <FreeRTOS.h>
|
|
|
|
#include <task.h>
|
|
|
|
|
|
|
|
#include <lwip/sockets.h>
|
|
|
|
|
2021-08-11 09:56:46 +03:00
|
|
|
#if LWIP_SOCKET != 1
|
2021-09-15 07:43:48 +01:00
|
|
|
// Sockets support disabled in LWIP by default
|
2021-08-11 09:56:46 +03:00
|
|
|
#error Set LWIP_SOCKET variable to 1 (in lwipopts.h)
|
|
|
|
#endif
|
|
|
|
|
2021-05-28 23:49:26 +01:00
|
|
|
// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
|
|
|
|
static inline void *mg_calloc(int cnt, size_t size) {
|
|
|
|
void *p = pvPortMalloc(cnt * size);
|
|
|
|
if (p != NULL) memset(p, 0, size);
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
#define calloc(a, b) mg_calloc((a), (b))
|
|
|
|
#define free(a) vPortFree(a)
|
|
|
|
#define malloc(a) pvPortMalloc(a)
|
2022-02-19 13:46:07 +00:00
|
|
|
|
2022-01-18 19:31:10 +00:00
|
|
|
#define mkdir(a, b) (-1)
|
2021-05-28 23:49:26 +01:00
|
|
|
|
2022-02-11 11:02:06 +00:00
|
|
|
#ifndef MG_IO_SIZE
|
|
|
|
#define MG_IO_SIZE 512
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_PATH_MAX
|
|
|
|
#define MG_PATH_MAX 128
|
|
|
|
#endif
|
|
|
|
|
2021-05-28 23:49:26 +01:00
|
|
|
#endif // MG_ARCH == MG_ARCH_FREERTOS_LWIP
|
|
|
|
|
|
|
|
|
2021-05-11 09:12:06 +01:00
|
|
|
#if MG_ARCH == MG_ARCH_FREERTOS_TCP
|
2021-03-13 12:34:26 +00:00
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <stdarg.h>
|
2021-05-11 09:12:06 +01:00
|
|
|
#include <stdbool.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2021-05-19 08:10:38 +01:00
|
|
|
#include <sys/stat.h>
|
2021-07-24 03:44:00 +01:00
|
|
|
#include <time.h>
|
2021-05-19 08:10:38 +01:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <FreeRTOS.h>
|
|
|
|
#include <FreeRTOS_IP.h>
|
|
|
|
#include <FreeRTOS_Sockets.h>
|
2021-05-11 09:12:06 +01:00
|
|
|
#include <task.h>
|
2016-11-08 23:29:07 +01:00
|
|
|
|
2021-05-17 17:36:57 +01:00
|
|
|
// Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing
|
|
|
|
// with FreeRTOS_ prefix, is beyond me
|
2020-12-05 11:26:32 +00:00
|
|
|
#define IPPROTO_TCP FREERTOS_IPPROTO_TCP
|
|
|
|
#define IPPROTO_UDP FREERTOS_IPPROTO_UDP
|
|
|
|
#define AF_INET FREERTOS_AF_INET
|
|
|
|
#define SOCK_STREAM FREERTOS_SOCK_STREAM
|
|
|
|
#define SOCK_DGRAM FREERTOS_SOCK_DGRAM
|
|
|
|
#define SO_BROADCAST 0
|
|
|
|
#define SO_ERROR 0
|
|
|
|
#define SOL_SOCKET 0
|
|
|
|
#define SO_REUSEADDR 0
|
|
|
|
#define sockaddr_in freertos_sockaddr
|
2021-05-12 08:43:34 +01:00
|
|
|
#define sockaddr freertos_sockaddr
|
2020-12-05 11:26:32 +00:00
|
|
|
#define accept(a, b, c) FreeRTOS_accept((a), (b), (c))
|
|
|
|
#define connect(a, b, c) FreeRTOS_connect((a), (b), (c))
|
|
|
|
#define bind(a, b, c) FreeRTOS_bind((a), (b), (c))
|
|
|
|
#define listen(a, b) FreeRTOS_listen((a), (b))
|
|
|
|
#define socket(a, b, c) FreeRTOS_socket((a), (b), (c))
|
|
|
|
#define send(a, b, c, d) FreeRTOS_send((a), (b), (c), (d))
|
|
|
|
#define recv(a, b, c, d) FreeRTOS_recv((a), (b), (c), (d))
|
|
|
|
#define setsockopt(a, b, c, d, e) FreeRTOS_setsockopt((a), (b), (c), (d), (e))
|
|
|
|
#define sendto(a, b, c, d, e, f) FreeRTOS_sendto((a), (b), (c), (d), (e), (f))
|
|
|
|
#define recvfrom(a, b, c, d, e, f) \
|
|
|
|
FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f))
|
|
|
|
#define closesocket(x) FreeRTOS_closesocket(x)
|
|
|
|
#define gethostbyname(x) FreeRTOS_gethostbyname(x)
|
2021-07-24 03:44:00 +01:00
|
|
|
#define getsockname(a, b, c) (-1)
|
2020-12-05 11:26:32 +00:00
|
|
|
|
2021-05-17 17:36:57 +01:00
|
|
|
// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
|
|
|
|
static inline void *mg_calloc(int cnt, size_t size) {
|
|
|
|
void *p = pvPortMalloc(cnt * size);
|
|
|
|
if (p != NULL) memset(p, 0, size);
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
#define calloc(a, b) mg_calloc((a), (b))
|
|
|
|
#define free(a) vPortFree(a)
|
|
|
|
#define malloc(a) pvPortMalloc(a)
|
2022-01-18 19:31:10 +00:00
|
|
|
#define mkdir(a, b) (-1)
|
2021-05-17 17:36:57 +01:00
|
|
|
|
2021-05-19 00:00:32 +01:00
|
|
|
#if !defined(__GNUC__)
|
|
|
|
// copied from GCC on ARM; for some reason useconds are signed
|
|
|
|
struct timeval {
|
|
|
|
time_t tv_sec;
|
2022-01-14 12:33:06 +00:00
|
|
|
long tv_usec;
|
2021-05-19 00:00:32 +01:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef EINPROGRESS
|
|
|
|
#define EINPROGRESS pdFREERTOS_ERRNO_EINPROGRESS
|
|
|
|
#endif
|
|
|
|
#ifndef EWOULDBLOCK
|
|
|
|
#define EWOULDBLOCK pdFREERTOS_ERRNO_EWOULDBLOCK
|
|
|
|
#endif
|
|
|
|
#ifndef EAGAIN
|
|
|
|
#define EAGAIN pdFREERTOS_ERRNO_EAGAIN
|
|
|
|
#endif
|
|
|
|
#ifndef EINTR
|
|
|
|
#define EINTR pdFREERTOS_ERRNO_EINTR
|
|
|
|
#endif
|
2020-12-05 11:26:32 +00:00
|
|
|
|
2021-05-11 09:12:06 +01:00
|
|
|
#endif // MG_ARCH == MG_ARCH_FREERTOS_TCP
|
2020-12-05 11:26:32 +00:00
|
|
|
|
|
|
|
|
2022-05-01 13:47:33 +01:00
|
|
|
#if MG_ARCH == MG_ARCH_NEWLIB
|
|
|
|
#define _POSIX_TIMERS
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#define MG_PATH_MAX 100
|
|
|
|
#define MG_ENABLE_SOCKET 0
|
|
|
|
#define MG_ENABLE_DIRLIST 0
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2022-05-12 08:07:51 +01:00
|
|
|
#if MG_ARCH == MG_ARCH_RTX
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#include <rl_net.h>
|
|
|
|
|
|
|
|
#define MG_ENABLE_CUSTOM_MILLIS 1
|
|
|
|
typedef int socklen_t;
|
|
|
|
#define closesocket(x) closesocket(x)
|
|
|
|
#define mkdir(a, b) (-1)
|
|
|
|
#define EWOULDBLOCK BSD_EWOULDBLOCK
|
|
|
|
#define EAGAIN BSD_EWOULDBLOCK
|
|
|
|
#define EINPROGRESS BSD_EWOULDBLOCK
|
|
|
|
#define EINTR BSD_EWOULDBLOCK
|
|
|
|
#define ECONNRESET BSD_ECONNRESET
|
|
|
|
#define EPIPE BSD_ECONNRESET
|
|
|
|
#define TCP_NODELAY SO_KEEPALIVE
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2022-02-18 10:07:10 +02:00
|
|
|
#if MG_ARCH == MG_ARCH_RTX_LWIP
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#if defined(__GNUC__)
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#else
|
|
|
|
struct timeval {
|
|
|
|
time_t tv_sec;
|
|
|
|
long tv_usec;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <lwip/sockets.h>
|
|
|
|
|
|
|
|
#if LWIP_SOCKET != 1
|
|
|
|
// Sockets support disabled in LWIP by default
|
|
|
|
#error Set LWIP_SOCKET variable to 1 (in lwipopts.h)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define mkdir(a, b) (-1)
|
|
|
|
|
|
|
|
#ifndef MG_IO_SIZE
|
|
|
|
#define MG_IO_SIZE 512
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_PATH_MAX
|
|
|
|
#define MG_PATH_MAX 128
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
|
2022-05-15 19:18:18 +03:00
|
|
|
#if MG_ARCH == MG_ARCH_TIRTOS
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
|
|
|
extern int SockStatus(SOCKET hSock, int request, int *results );
|
|
|
|
extern int SockSet(SOCKET hSock, int Type, int Prop, void *pbuf, int size);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#if MG_ARCH == MG_ARCH_UNIX
|
|
|
|
|
2021-07-24 10:35:48 +01:00
|
|
|
#define _DARWIN_UNLIMITED_SELECT 1 // No limit on file descriptors
|
2016-11-08 23:29:07 +01:00
|
|
|
|
2022-05-27 22:26:17 +01:00
|
|
|
#if !defined(MG_ENABLE_POLL) && (defined(__linux__) || defined(__APPLE__))
|
2022-05-26 08:55:28 +01:00
|
|
|
#define MG_ENABLE_POLL 1
|
|
|
|
#endif
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <arpa/inet.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <ctype.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <dirent.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
2021-01-26 17:43:31 +00:00
|
|
|
#include <inttypes.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <limits.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <netdb.h>
|
2022-01-24 02:20:45 +00:00
|
|
|
#include <netinet/in.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <netinet/tcp.h>
|
|
|
|
#include <signal.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <stdarg.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <stdbool.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <stddef.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <stdint.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2022-05-26 11:18:36 +01:00
|
|
|
#if defined(MG_ENABLE_POLL) && MG_ENABLE_POLL
|
2022-05-25 00:43:22 +03:00
|
|
|
#include <poll.h>
|
|
|
|
#else
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <sys/select.h>
|
2022-05-25 00:43:22 +03:00
|
|
|
#endif
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <sys/socket.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <sys/stat.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <sys/time.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <time.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <unistd.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
|
2022-02-14 11:32:01 +00:00
|
|
|
#ifndef MG_ENABLE_DIRLIST
|
|
|
|
#define MG_ENABLE_DIRLIST 1
|
|
|
|
#endif
|
|
|
|
|
2016-11-11 20:34:00 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#if MG_ARCH == MG_ARCH_WIN32
|
2016-11-11 20:34:00 +00:00
|
|
|
|
2021-07-13 07:13:06 +01:00
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
|
|
|
#define _CRT_SECURE_NO_WARNINGS
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
|
|
|
|
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
|
|
|
#endif
|
|
|
|
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <ctype.h>
|
2022-01-21 12:35:28 +00:00
|
|
|
#include <direct.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <limits.h>
|
2022-02-12 16:43:08 +00:00
|
|
|
#include <signal.h>
|
2021-03-13 12:34:26 +00:00
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#if defined(_MSC_VER) && _MSC_VER < 1700
|
|
|
|
#define __func__ ""
|
|
|
|
typedef __int64 int64_t;
|
|
|
|
typedef unsigned __int64 uint64_t;
|
|
|
|
typedef unsigned char uint8_t;
|
2021-01-25 10:08:15 +00:00
|
|
|
typedef char int8_t;
|
2020-12-05 11:26:32 +00:00
|
|
|
typedef unsigned short uint16_t;
|
2021-01-25 10:08:15 +00:00
|
|
|
typedef short int16_t;
|
2020-12-05 11:26:32 +00:00
|
|
|
typedef unsigned int uint32_t;
|
2021-01-25 10:08:15 +00:00
|
|
|
typedef int int32_t;
|
2021-01-26 12:16:58 +00:00
|
|
|
typedef enum { false = 0, true = 1 } bool;
|
2020-12-05 11:26:32 +00:00
|
|
|
#else
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
2020-12-22 09:44:59 +00:00
|
|
|
#include <ws2tcpip.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#endif
|
2016-11-11 20:34:00 +00:00
|
|
|
|
2022-02-12 16:43:08 +00:00
|
|
|
#include <process.h>
|
2022-03-15 10:10:08 +00:00
|
|
|
#include <winerror.h>
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <winsock2.h>
|
2020-12-23 21:05:46 +00:00
|
|
|
|
2020-12-23 21:20:48 +00:00
|
|
|
// Protect from calls like std::snprintf in app code
|
2020-12-23 21:05:46 +00:00
|
|
|
// See https://github.com/cesanta/mongoose/issues/1047
|
|
|
|
#ifndef __cplusplus
|
2020-12-05 11:26:32 +00:00
|
|
|
#define snprintf _snprintf
|
|
|
|
#define vsnprintf _vsnprintf
|
2021-09-27 13:52:39 +01:00
|
|
|
#ifndef strdup // For MSVC with _DEBUG, see #1359
|
2020-12-05 11:26:32 +00:00
|
|
|
#define strdup(x) _strdup(x)
|
2020-12-23 21:05:46 +00:00
|
|
|
#endif
|
2021-09-27 13:52:39 +01:00
|
|
|
#endif
|
2020-12-23 21:05:46 +00:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
typedef int socklen_t;
|
|
|
|
#define MG_DIRSEP '\\'
|
2020-12-24 07:26:50 +00:00
|
|
|
#ifndef PATH_MAX
|
|
|
|
#define PATH_MAX MAX_PATH
|
|
|
|
#endif
|
2020-12-05 11:26:32 +00:00
|
|
|
#ifndef EINPROGRESS
|
|
|
|
#define EINPROGRESS WSAEINPROGRESS
|
2016-09-27 06:59:51 +02:00
|
|
|
#endif
|
2020-12-05 11:26:32 +00:00
|
|
|
#ifndef EWOULDBLOCK
|
|
|
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
2015-12-05 18:46:53 +02:00
|
|
|
#endif
|
2021-07-24 10:35:48 +01:00
|
|
|
|
2021-12-22 18:04:36 +00:00
|
|
|
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
|
|
|
|
#define sleep(x) Sleep(x)
|
2022-01-21 12:35:28 +00:00
|
|
|
#define mkdir(a, b) _mkdir(a)
|
2021-12-22 18:04:36 +00:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#ifndef va_copy
|
|
|
|
#ifdef __va_copy
|
|
|
|
#define va_copy __va_copy
|
2015-09-08 13:49:03 +02:00
|
|
|
#else
|
2020-12-05 11:26:32 +00:00
|
|
|
#define va_copy(x, y) (x) = (y)
|
|
|
|
#endif
|
2015-09-08 13:49:03 +02:00
|
|
|
#endif
|
2020-12-05 11:26:32 +00:00
|
|
|
#ifndef S_ISDIR
|
|
|
|
#define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
|
|
|
|
#endif
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2022-02-14 11:32:01 +00:00
|
|
|
#ifndef MG_ENABLE_DIRLIST
|
|
|
|
#define MG_ENABLE_DIRLIST 1
|
|
|
|
#endif
|
|
|
|
|
2015-09-08 13:49:03 +02:00
|
|
|
#endif
|
|
|
|
|
2016-03-19 11:48:50 +02:00
|
|
|
|
2022-03-30 07:56:44 +01:00
|
|
|
#if MG_ARCH == MG_ARCH_ZEPHYR
|
|
|
|
|
|
|
|
#include <zephyr.h>
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <net/socket.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
2022-05-20 09:45:17 +01:00
|
|
|
#define MG_PUTCHAR(x) printk("%c", x)
|
2022-03-30 07:56:44 +01:00
|
|
|
#define strerror(x) zsock_gai_strerror(x)
|
|
|
|
#define FD_CLOEXEC 0
|
|
|
|
#define F_SETFD 0
|
2022-04-01 16:42:41 +01:00
|
|
|
#define MG_ENABLE_SSI 0
|
2022-03-30 07:56:44 +01:00
|
|
|
|
|
|
|
int rand(void);
|
|
|
|
int sscanf(const char *, const char *, ...);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2022-05-18 21:19:21 +01:00
|
|
|
#ifndef MG_ENABLE_MIP
|
|
|
|
#define MG_ENABLE_MIP 0
|
|
|
|
#endif
|
|
|
|
|
2022-05-25 00:43:22 +03:00
|
|
|
#ifndef MG_ENABLE_POLL
|
|
|
|
#define MG_ENABLE_POLL 0
|
|
|
|
#endif
|
|
|
|
|
2022-01-18 07:44:30 +00:00
|
|
|
#ifndef MG_ENABLE_FATFS
|
|
|
|
#define MG_ENABLE_FATFS 0
|
|
|
|
#endif
|
|
|
|
|
2021-12-21 17:39:55 +00:00
|
|
|
#ifndef MG_ENABLE_SOCKET
|
|
|
|
#define MG_ENABLE_SOCKET 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_ENABLE_MBEDTLS
|
|
|
|
#define MG_ENABLE_MBEDTLS 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_ENABLE_OPENSSL
|
|
|
|
#define MG_ENABLE_OPENSSL 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_ENABLE_CUSTOM_TLS
|
|
|
|
#define MG_ENABLE_CUSTOM_TLS 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_ENABLE_SSI
|
2022-05-08 21:54:15 +01:00
|
|
|
#define MG_ENABLE_SSI 0
|
2021-12-21 17:39:55 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_ENABLE_IPV6
|
|
|
|
#define MG_ENABLE_IPV6 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_ENABLE_MD5
|
|
|
|
#define MG_ENABLE_MD5 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Set MG_ENABLE_WINSOCK=0 for Win32 builds with external IP stack (like LWIP)
|
|
|
|
#ifndef MG_ENABLE_WINSOCK
|
|
|
|
#define MG_ENABLE_WINSOCK 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_ENABLE_DIRLIST
|
2022-02-14 11:32:01 +00:00
|
|
|
#define MG_ENABLE_DIRLIST 0
|
2021-12-21 17:39:55 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_ENABLE_CUSTOM_RANDOM
|
|
|
|
#define MG_ENABLE_CUSTOM_RANDOM 0
|
|
|
|
#endif
|
|
|
|
|
2022-04-04 18:14:59 +01:00
|
|
|
#ifndef MG_ENABLE_CUSTOM_MILLIS
|
|
|
|
#define MG_ENABLE_CUSTOM_MILLIS 0
|
|
|
|
#endif
|
|
|
|
|
2021-12-21 17:39:55 +00:00
|
|
|
#ifndef MG_ENABLE_PACKED_FS
|
|
|
|
#define MG_ENABLE_PACKED_FS 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Granularity of the send/recv IO buffer growth
|
|
|
|
#ifndef MG_IO_SIZE
|
|
|
|
#define MG_IO_SIZE 2048
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Maximum size of the recv IO buffer
|
2022-06-02 13:50:44 +01:00
|
|
|
#ifndef MG_MAX_RECV_SIZE
|
|
|
|
#define MG_MAX_RECV_SIZE (3 * 1024 * 1024)
|
2021-12-21 17:39:55 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_MAX_HTTP_HEADERS
|
|
|
|
#define MG_MAX_HTTP_HEADERS 40
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_HTTP_INDEX
|
|
|
|
#define MG_HTTP_INDEX "index.html"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_PATH_MAX
|
|
|
|
#ifdef PATH_MAX
|
|
|
|
#define MG_PATH_MAX PATH_MAX
|
|
|
|
#else
|
|
|
|
#define MG_PATH_MAX 128
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_SOCK_LISTEN_BACKLOG_SIZE
|
2022-05-12 15:07:02 +01:00
|
|
|
#define MG_SOCK_LISTEN_BACKLOG_SIZE 3
|
2021-12-21 17:39:55 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_DIRSEP
|
|
|
|
#define MG_DIRSEP '/'
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MG_ENABLE_FILE
|
|
|
|
#if defined(FOPEN_MAX)
|
|
|
|
#define MG_ENABLE_FILE 1
|
|
|
|
#else
|
|
|
|
#define MG_ENABLE_FILE 0
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2022-05-20 09:45:17 +01:00
|
|
|
#ifndef MG_PUTCHAR
|
|
|
|
#define MG_PUTCHAR(x) putchar(x)
|
|
|
|
#endif
|
|
|
|
|
2021-12-21 17:39:55 +00:00
|
|
|
|
2022-01-10 17:30:51 +00:00
|
|
|
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_str {
|
2021-09-15 07:43:48 +01:00
|
|
|
const char *ptr; // Pointer to string data
|
|
|
|
size_t len; // String len
|
2015-09-08 13:49:03 +02:00
|
|
|
};
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#define MG_NULL_STR \
|
|
|
|
{ NULL, 0 }
|
2020-05-24 17:32:33 +01:00
|
|
|
|
2022-01-23 06:10:14 +00:00
|
|
|
#define MG_C_STR(a) \
|
|
|
|
{ (a), sizeof(a) - 1 }
|
|
|
|
|
2021-07-15 02:18:32 +01:00
|
|
|
// Using macro to avoid shadowing C++ struct constructor, see #1298
|
|
|
|
#define mg_str(s) mg_str_s(s)
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_str mg_str(const char *s);
|
2020-12-07 03:47:37 +00:00
|
|
|
struct mg_str mg_str_n(const char *s, size_t n);
|
2020-12-05 11:26:32 +00:00
|
|
|
int mg_lower(const char *s);
|
|
|
|
int mg_ncasecmp(const char *s1, const char *s2, size_t len);
|
|
|
|
int mg_casecmp(const char *s1, const char *s2);
|
|
|
|
int mg_vcmp(const struct mg_str *s1, const char *s2);
|
|
|
|
int mg_vcasecmp(const struct mg_str *str1, const char *str2);
|
|
|
|
int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
|
|
|
|
struct mg_str mg_strstrip(struct mg_str s);
|
|
|
|
struct mg_str mg_strdup(const struct mg_str s);
|
|
|
|
const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle);
|
2022-01-29 11:03:54 +00:00
|
|
|
bool mg_match(struct mg_str str, struct mg_str pattern, struct mg_str *caps);
|
|
|
|
bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
|
|
|
|
bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v);
|
2022-05-31 14:11:14 +04:30
|
|
|
bool mg_split(struct mg_str *s, struct mg_str *k, struct mg_str *v, char delim);
|
2022-06-10 09:38:36 +01:00
|
|
|
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap);
|
2022-06-08 22:09:11 +01:00
|
|
|
size_t mg_snprintf(char *, size_t, const char *fmt, ...);
|
2022-02-10 11:56:55 +00:00
|
|
|
char *mg_hex(const void *buf, size_t len, char *dst);
|
|
|
|
void mg_unhex(const char *buf, size_t len, unsigned char *to);
|
|
|
|
unsigned long mg_unhexn(const char *s, size_t len);
|
2022-06-08 22:09:11 +01:00
|
|
|
size_t mg_asprintf(char **, size_t, const char *fmt, ...);
|
2022-02-10 17:11:03 +00:00
|
|
|
size_t mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap);
|
2022-06-10 09:38:36 +01:00
|
|
|
char *mg_mprintf(const char *fmt, ...);
|
|
|
|
char *mg_vmprintf(const char *fmt, va_list ap);
|
2022-02-10 11:56:55 +00:00
|
|
|
int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip);
|
|
|
|
int64_t mg_to64(struct mg_str str);
|
2022-04-12 10:20:43 +01:00
|
|
|
uint64_t mg_tou64(struct mg_str str);
|
2022-03-06 14:31:42 +00:00
|
|
|
size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex);
|
2022-06-09 12:39:48 +01:00
|
|
|
double mg_atod(const char *buf, int len, int *numlen);
|
2022-06-10 09:38:36 +01:00
|
|
|
size_t mg_dtoa(char *buf, size_t len, double d, int width);
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2016-02-26 00:12:32 +00:00
|
|
|
|
2016-10-05 00:38:27 +01:00
|
|
|
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
|
2022-02-12 18:17:25 +00:00
|
|
|
enum { MG_LL_NONE, MG_LL_ERROR, MG_LL_INFO, MG_LL_DEBUG, MG_LL_VERBOSE };
|
2022-06-08 22:09:11 +01:00
|
|
|
void mg_log(const char *fmt, ...);
|
2022-01-23 06:10:14 +00:00
|
|
|
bool mg_log_prefix(int ll, const char *file, int line, const char *fname);
|
|
|
|
void mg_log_set(const char *spec);
|
2022-05-06 21:09:13 +01:00
|
|
|
void mg_hexdump(const void *buf, size_t len);
|
2022-01-24 02:20:45 +00:00
|
|
|
|
2022-02-12 18:17:25 +00:00
|
|
|
#define MG_LOG(level, args) \
|
2020-12-05 11:26:32 +00:00
|
|
|
do { \
|
|
|
|
if (mg_log_prefix((level), __FILE__, __LINE__, __func__)) mg_log args; \
|
|
|
|
} while (0)
|
2022-01-24 02:20:45 +00:00
|
|
|
|
2022-02-12 18:17:25 +00:00
|
|
|
#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
|
|
|
|
#define MG_INFO(args) MG_LOG(MG_LL_INFO, args)
|
|
|
|
#define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
|
|
|
|
#define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
|
|
|
|
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2021-12-21 21:50:18 +00:00
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_timer {
|
2022-04-07 13:50:25 +01:00
|
|
|
uint64_t period_ms; // Timer period in milliseconds
|
2022-04-12 14:14:55 +01:00
|
|
|
uint64_t prev_ms; // Timestamp of a previous poll
|
2022-04-07 13:50:25 +01:00
|
|
|
uint64_t expire; // Expiration timestamp in milliseconds
|
2021-05-28 18:30:42 +01:00
|
|
|
unsigned flags; // Possible flags values below
|
2022-05-15 14:29:34 +01:00
|
|
|
#define MG_TIMER_ONCE 0 // Call function once
|
|
|
|
#define MG_TIMER_REPEAT 1 // Call function periodically
|
2021-11-06 11:29:56 +00:00
|
|
|
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
2020-12-05 11:26:32 +00:00
|
|
|
void (*fn)(void *); // Function to call
|
2021-03-11 13:15:53 +00:00
|
|
|
void *arg; // Function argument
|
2022-05-15 14:29:34 +01:00
|
|
|
struct mg_timer *next; // Linkage
|
2020-12-05 11:26:32 +00:00
|
|
|
};
|
2016-10-14 19:58:14 +03:00
|
|
|
|
2022-04-12 14:14:55 +01:00
|
|
|
void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
|
|
|
|
uint64_t milliseconds, unsigned flags, void (*fn)(void *),
|
|
|
|
void *arg);
|
|
|
|
void mg_timer_free(struct mg_timer **head, struct mg_timer *);
|
|
|
|
void mg_timer_poll(struct mg_timer **head, uint64_t new_ms);
|
2015-09-08 13:49:03 +02:00
|
|
|
|
|
|
|
|
2015-10-20 12:31:23 +03:00
|
|
|
|
2015-09-08 13:49:03 +02:00
|
|
|
|
|
|
|
|
2022-01-18 17:11:02 +00:00
|
|
|
enum { MG_FS_READ = 1, MG_FS_WRITE = 2, MG_FS_DIR = 4 };
|
|
|
|
|
|
|
|
// Filesystem API functions
|
2022-02-08 13:36:04 +00:00
|
|
|
// st() returns MG_FS_* flags and populates file size and modification time
|
|
|
|
// ls() calls fn() for every directory entry, allowing to list a directory
|
|
|
|
//
|
|
|
|
// NOTE: UNIX-style shorthand names for the API functions are deliberately
|
|
|
|
// chosen to avoid conflicts with some libraries that make macros for e.g.
|
|
|
|
// stat(), write(), read() calls.
|
2022-01-18 17:11:02 +00:00
|
|
|
struct mg_fs {
|
2022-02-08 13:36:04 +00:00
|
|
|
int (*st)(const char *path, size_t *size, time_t *mtime); // stat file
|
|
|
|
void (*ls)(const char *path, void (*fn)(const char *, void *), void *);
|
|
|
|
void *(*op)(const char *path, int flags); // Open file
|
|
|
|
void (*cl)(void *fd); // Close file
|
|
|
|
size_t (*rd)(void *fd, void *buf, size_t len); // Read file
|
|
|
|
size_t (*wr)(void *fd, const void *buf, size_t len); // Write file
|
|
|
|
size_t (*sk)(void *fd, size_t offset); // Set file position
|
|
|
|
bool (*mv)(const char *from, const char *to); // Rename file
|
|
|
|
bool (*rm)(const char *path); // Delete file
|
|
|
|
bool (*mkd)(const char *path); // Create directory
|
2022-01-18 17:11:02 +00:00
|
|
|
};
|
|
|
|
|
2022-01-19 09:25:01 +00:00
|
|
|
extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
|
2022-05-25 13:28:25 +01:00
|
|
|
extern struct mg_fs mg_fs_packed; // Packed FS, see examples/device-dashboard
|
2022-01-19 09:25:01 +00:00
|
|
|
extern struct mg_fs mg_fs_fat; // FAT FS
|
|
|
|
|
2022-01-18 17:11:02 +00:00
|
|
|
// File descriptor
|
|
|
|
struct mg_fd {
|
|
|
|
void *fd;
|
|
|
|
struct mg_fs *fs;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags);
|
|
|
|
void mg_fs_close(struct mg_fd *fd);
|
|
|
|
char *mg_file_read(struct mg_fs *fs, const char *path, size_t *size);
|
|
|
|
bool mg_file_write(struct mg_fs *fs, const char *path, const void *, size_t);
|
|
|
|
bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-12-21 18:16:12 +00:00
|
|
|
|
2021-07-30 13:19:20 +01:00
|
|
|
void mg_random(void *buf, size_t len);
|
2020-12-05 11:26:32 +00:00
|
|
|
uint16_t mg_ntohs(uint16_t net);
|
|
|
|
uint32_t mg_ntohl(uint32_t net);
|
2021-03-08 15:41:16 +00:00
|
|
|
uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
|
2022-04-07 13:50:25 +01:00
|
|
|
uint64_t mg_millis(void);
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#define mg_htons(x) mg_ntohs(x)
|
|
|
|
#define mg_htonl(x) mg_ntohl(x)
|
2015-11-18 07:39:51 +00:00
|
|
|
|
2021-04-09 16:55:12 +01:00
|
|
|
// Linked list management macros
|
2020-12-05 11:26:32 +00:00
|
|
|
#define LIST_ADD_HEAD(type_, head_, elem_) \
|
|
|
|
do { \
|
|
|
|
(elem_)->next = (*head_); \
|
|
|
|
*(head_) = (elem_); \
|
|
|
|
} while (0)
|
2016-10-14 19:58:14 +03:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#define LIST_ADD_TAIL(type_, head_, elem_) \
|
|
|
|
do { \
|
|
|
|
type_ **h = head_; \
|
|
|
|
while (*h != NULL) h = &(*h)->next; \
|
|
|
|
*h = (elem_); \
|
|
|
|
} while (0)
|
2016-10-14 19:58:14 +03:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#define LIST_DELETE(type_, head_, elem_) \
|
|
|
|
do { \
|
|
|
|
type_ **h = head_; \
|
|
|
|
while (*h != (elem_)) h = &(*h)->next; \
|
|
|
|
*h = (elem_)->next; \
|
|
|
|
} while (0)
|
2015-09-08 13:49:03 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
unsigned short mg_url_port(const char *url);
|
|
|
|
int mg_url_is_ssl(const char *url);
|
|
|
|
struct mg_str mg_url_host(const char *url);
|
|
|
|
struct mg_str mg_url_user(const char *url);
|
|
|
|
struct mg_str mg_url_pass(const char *url);
|
|
|
|
const char *mg_url_uri(const char *url);
|
2016-10-27 20:43:56 +03:00
|
|
|
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#include <stddef.h>
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_iobuf {
|
2021-08-30 13:06:45 +01:00
|
|
|
unsigned char *buf; // Pointer to stored data
|
2021-08-28 08:08:54 +01:00
|
|
|
size_t size; // Total size available
|
|
|
|
size_t len; // Current number of bytes
|
2015-09-08 13:49:03 +02:00
|
|
|
};
|
|
|
|
|
2021-01-29 12:32:34 +00:00
|
|
|
int mg_iobuf_init(struct mg_iobuf *, size_t);
|
|
|
|
int mg_iobuf_resize(struct mg_iobuf *, size_t);
|
2020-12-05 11:26:32 +00:00
|
|
|
void mg_iobuf_free(struct mg_iobuf *);
|
2021-08-28 08:08:54 +01:00
|
|
|
size_t mg_iobuf_add(struct mg_iobuf *, size_t, const void *, size_t, size_t);
|
2021-08-27 10:25:24 +01:00
|
|
|
size_t mg_iobuf_del(struct mg_iobuf *, size_t ofs, size_t len);
|
2016-11-09 09:52:59 +00:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
int mg_base64_update(unsigned char p, char *to, int len);
|
|
|
|
int mg_base64_final(char *to, int len);
|
|
|
|
int mg_base64_encode(const unsigned char *p, int n, char *to);
|
|
|
|
int mg_base64_decode(const char *src, int n, char *dst);
|
2015-09-08 13:49:03 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
typedef struct {
|
|
|
|
uint32_t buf[4];
|
|
|
|
uint32_t bits[2];
|
|
|
|
unsigned char in[64];
|
|
|
|
} mg_md5_ctx;
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
void mg_md5_init(mg_md5_ctx *c);
|
|
|
|
void mg_md5_update(mg_md5_ctx *c, const unsigned char *data, size_t len);
|
|
|
|
void mg_md5_final(mg_md5_ctx *c, unsigned char[16]);
|
2015-09-08 13:49:03 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
typedef struct {
|
|
|
|
uint32_t state[5];
|
|
|
|
uint32_t count[2];
|
|
|
|
unsigned char buffer[64];
|
|
|
|
} mg_sha1_ctx;
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
void mg_sha1_init(mg_sha1_ctx *);
|
|
|
|
void mg_sha1_update(mg_sha1_ctx *, const unsigned char *data, size_t len);
|
|
|
|
void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *);
|
2015-09-08 13:49:03 +02:00
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_connection;
|
|
|
|
typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
|
|
|
|
void *ev_data, void *fn_data);
|
|
|
|
void mg_call(struct mg_connection *c, int ev, void *ev_data);
|
|
|
|
void mg_error(struct mg_connection *c, const char *fmt, ...);
|
|
|
|
|
|
|
|
enum {
|
2021-03-08 15:41:16 +00:00
|
|
|
MG_EV_ERROR, // Error char *error_message
|
2021-11-01 16:20:00 +00:00
|
|
|
MG_EV_OPEN, // Connection created NULL
|
2022-04-07 13:50:25 +01:00
|
|
|
MG_EV_POLL, // mg_mgr_poll iteration uint64_t *milliseconds
|
2021-03-08 15:41:16 +00:00
|
|
|
MG_EV_RESOLVE, // Host name is resolved NULL
|
|
|
|
MG_EV_CONNECT, // Connection established NULL
|
|
|
|
MG_EV_ACCEPT, // Connection accepted NULL
|
|
|
|
MG_EV_READ, // Data received from socket struct mg_str *
|
2021-05-28 18:30:42 +01:00
|
|
|
MG_EV_WRITE, // Data written to socket long *bytes_written
|
2021-03-08 15:41:16 +00:00
|
|
|
MG_EV_CLOSE, // Connection closed NULL
|
|
|
|
MG_EV_HTTP_MSG, // HTTP request/response struct mg_http_message *
|
|
|
|
MG_EV_HTTP_CHUNK, // HTTP chunk (partial msg) struct mg_http_message *
|
|
|
|
MG_EV_WS_OPEN, // Websocket handshake done struct mg_http_message *
|
|
|
|
MG_EV_WS_MSG, // Websocket msg, text or bin struct mg_ws_message *
|
|
|
|
MG_EV_WS_CTL, // Websocket control msg struct mg_ws_message *
|
|
|
|
MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message *
|
|
|
|
MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message *
|
|
|
|
MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code
|
2022-04-07 13:50:25 +01:00
|
|
|
MG_EV_SNTP_TIME, // SNTP time received uint64_t *milliseconds
|
2021-03-08 15:41:16 +00:00
|
|
|
MG_EV_USER, // Starting ID for user events
|
2015-09-08 13:49:03 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-12-23 10:15:09 +00:00
|
|
|
|
2022-04-12 14:14:55 +01:00
|
|
|
|
2020-12-22 09:44:59 +00:00
|
|
|
struct mg_dns {
|
|
|
|
const char *url; // DNS server URL
|
|
|
|
struct mg_connection *c; // DNS server connection
|
2015-09-08 13:49:03 +02:00
|
|
|
};
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_addr {
|
2020-12-20 16:55:33 +00:00
|
|
|
uint16_t port; // TCP or UDP port in network byte order
|
|
|
|
uint32_t ip; // IP address in network byte order
|
|
|
|
uint8_t ip6[16]; // IPv6 address
|
|
|
|
bool is_ip6; // True when address is IPv6 address
|
2020-12-05 11:26:32 +00:00
|
|
|
};
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2020-12-22 09:44:59 +00:00
|
|
|
struct mg_mgr {
|
|
|
|
struct mg_connection *conns; // List of active connections
|
|
|
|
struct mg_dns dns4; // DNS for IPv4
|
|
|
|
struct mg_dns dns6; // DNS for IPv6
|
|
|
|
int dnstimeout; // DNS resolve timeout in milliseconds
|
2022-04-22 20:44:53 +01:00
|
|
|
bool use_dns6; // Use DNS6 server by default, see #1532
|
2020-12-22 09:44:59 +00:00
|
|
|
unsigned long nextid; // Next connection ID
|
2021-02-28 16:40:27 +00:00
|
|
|
void *userdata; // Arbitrary user data pointer
|
2022-04-12 14:14:55 +01:00
|
|
|
uint16_t mqtt_id; // MQTT IDs for pub/sub
|
|
|
|
void *active_dns_requests; // DNS requests in progress
|
|
|
|
struct mg_timer *timers; // Active timers
|
2022-05-01 13:47:33 +01:00
|
|
|
void *priv; // Used by the experimental stack
|
2022-05-04 17:18:35 +01:00
|
|
|
size_t extraconnsize; // Used by the experimental stack
|
2021-05-11 09:12:06 +01:00
|
|
|
#if MG_ARCH == MG_ARCH_FREERTOS_TCP
|
2020-12-22 09:44:59 +00:00
|
|
|
SocketSet_t ss; // NOTE(lsm): referenced from socket struct
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_connection {
|
|
|
|
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
|
|
|
struct mg_mgr *mgr; // Our container
|
2022-02-22 22:00:55 +00:00
|
|
|
struct mg_addr loc; // Local address
|
|
|
|
struct mg_addr rem; // Remote address
|
2020-12-05 11:26:32 +00:00
|
|
|
void *fd; // Connected socket, or LWIP data
|
2020-12-21 12:26:44 +00:00
|
|
|
unsigned long id; // Auto-incrementing unique connection ID
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_iobuf recv; // Incoming data
|
|
|
|
struct mg_iobuf send; // Outgoing data
|
|
|
|
mg_event_handler_t fn; // User-specified event handler function
|
2021-03-11 13:15:53 +00:00
|
|
|
void *fn_data; // User-specified function parameter
|
2020-12-05 11:26:32 +00:00
|
|
|
mg_event_handler_t pfn; // Protocol-specific handler function
|
|
|
|
void *pfn_data; // Protocol-specific function parameter
|
2021-02-10 11:09:13 +00:00
|
|
|
char label[50]; // Arbitrary label
|
2020-12-05 11:26:32 +00:00
|
|
|
void *tls; // TLS specific data
|
|
|
|
unsigned is_listening : 1; // Listening connection
|
|
|
|
unsigned is_client : 1; // Outbound (client) connection
|
|
|
|
unsigned is_accepted : 1; // Accepted (server) connection
|
2021-03-11 13:15:53 +00:00
|
|
|
unsigned is_resolving : 1; // Non-blocking DNS resolution is in progress
|
2020-12-05 11:26:32 +00:00
|
|
|
unsigned is_connecting : 1; // Non-blocking connect is in progress
|
|
|
|
unsigned is_tls : 1; // TLS-enabled connection
|
|
|
|
unsigned is_tls_hs : 1; // TLS handshake is in progress
|
|
|
|
unsigned is_udp : 1; // UDP connection
|
|
|
|
unsigned is_websocket : 1; // WebSocket connection
|
|
|
|
unsigned is_hexdumping : 1; // Hexdump in/out traffic
|
2020-12-06 21:12:05 +00:00
|
|
|
unsigned is_draining : 1; // Send remaining data, then close and free
|
|
|
|
unsigned is_closing : 1; // Close and free the connection immediately
|
2022-06-03 11:37:35 +01:00
|
|
|
unsigned is_full : 1; // Stop reads, until cleared
|
2020-12-05 11:26:32 +00:00
|
|
|
unsigned is_readable : 1; // Connection is ready to read
|
|
|
|
unsigned is_writable : 1; // Connection is ready to write
|
|
|
|
};
|
|
|
|
|
|
|
|
void mg_mgr_poll(struct mg_mgr *, int ms);
|
|
|
|
void mg_mgr_init(struct mg_mgr *);
|
|
|
|
void mg_mgr_free(struct mg_mgr *);
|
|
|
|
|
|
|
|
struct mg_connection *mg_listen(struct mg_mgr *, const char *url,
|
|
|
|
mg_event_handler_t fn, void *fn_data);
|
|
|
|
struct mg_connection *mg_connect(struct mg_mgr *, const char *url,
|
|
|
|
mg_event_handler_t fn, void *fn_data);
|
2022-04-22 14:42:07 +01:00
|
|
|
struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd,
|
|
|
|
mg_event_handler_t fn, void *fn_data);
|
2021-10-22 14:00:31 +01:00
|
|
|
void mg_connect_resolved(struct mg_connection *);
|
2021-05-28 18:30:42 +01:00
|
|
|
bool mg_send(struct mg_connection *, const void *, size_t);
|
2022-02-10 17:11:03 +00:00
|
|
|
size_t mg_printf(struct mg_connection *, const char *fmt, ...);
|
|
|
|
size_t mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
|
2022-01-05 19:09:11 +00:00
|
|
|
char *mg_straddr(struct mg_addr *, char *, size_t);
|
2020-12-20 16:55:33 +00:00
|
|
|
bool mg_aton(struct mg_str str, struct mg_addr *addr);
|
|
|
|
char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len);
|
2022-05-31 18:23:32 +01:00
|
|
|
int mg_mkpipe(struct mg_mgr *, mg_event_handler_t, void *, bool udp);
|
2021-08-07 17:22:47 +01:00
|
|
|
|
2022-02-22 21:14:29 +00:00
|
|
|
// These functions are used to integrate with custom network stacks
|
2022-02-23 10:51:01 +00:00
|
|
|
struct mg_connection *mg_alloc_conn(struct mg_mgr *);
|
2022-02-23 03:06:02 +00:00
|
|
|
void mg_close_conn(struct mg_connection *c);
|
|
|
|
bool mg_open_listener(struct mg_connection *c, const char *url);
|
2022-04-12 14:14:55 +01:00
|
|
|
struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
|
|
|
|
unsigned flags, void (*fn)(void *), void *arg);
|
2022-02-22 21:14:29 +00:00
|
|
|
|
2015-09-08 13:49:03 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2015-12-08 12:25:44 +00:00
|
|
|
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2021-07-28 21:11:07 +01:00
|
|
|
|
2021-12-21 18:16:12 +00:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_http_header {
|
2021-09-15 07:43:48 +01:00
|
|
|
struct mg_str name; // Header name
|
|
|
|
struct mg_str value; // Header value
|
2015-09-08 13:49:03 +02:00
|
|
|
};
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_http_message {
|
2020-12-25 15:04:43 +00:00
|
|
|
struct mg_str method, uri, query, proto; // Request/response line
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers
|
2020-12-25 15:04:43 +00:00
|
|
|
struct mg_str body; // Body
|
2021-02-09 13:27:17 +00:00
|
|
|
struct mg_str head; // Request + headers
|
2021-03-07 11:56:20 +00:00
|
|
|
struct mg_str chunk; // Chunk for chunked encoding, or partial body
|
2021-02-09 13:27:17 +00:00
|
|
|
struct mg_str message; // Request + headers + body
|
2020-12-05 11:26:32 +00:00
|
|
|
};
|
|
|
|
|
2021-01-02 12:30:09 +00:00
|
|
|
// Parameter for mg_http_serve_dir()
|
|
|
|
struct mg_http_serve_opts {
|
2021-07-24 02:44:25 +01:00
|
|
|
const char *root_dir; // Web root directory, must be non-NULL
|
|
|
|
const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml
|
|
|
|
const char *extra_headers; // Extra HTTP headers to add in responses
|
2021-07-28 21:11:07 +01:00
|
|
|
const char *mime_types; // Extra mime types, ext1=type1,ext2=type2,..
|
2022-05-31 23:44:03 +01:00
|
|
|
const char *page404; // Path to the 404 page, or NULL by default
|
2021-07-28 21:11:07 +01:00
|
|
|
struct mg_fs *fs; // Filesystem implementation. Use NULL for POSIX
|
2021-01-02 12:30:09 +00:00
|
|
|
};
|
|
|
|
|
2021-03-15 13:20:53 +00:00
|
|
|
// Parameter for mg_http_next_multipart
|
|
|
|
struct mg_http_part {
|
|
|
|
struct mg_str name; // Form field name
|
|
|
|
struct mg_str filename; // Filename for file uploads
|
2021-03-17 07:43:29 +00:00
|
|
|
struct mg_str body; // Part contents
|
2021-03-15 13:20:53 +00:00
|
|
|
};
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
int mg_http_parse(const char *s, size_t len, struct mg_http_message *);
|
|
|
|
int mg_http_get_request_len(const unsigned char *buf, size_t buf_len);
|
|
|
|
void mg_http_printf_chunk(struct mg_connection *cnn, const char *fmt, ...);
|
|
|
|
void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len);
|
2021-03-08 15:41:16 +00:00
|
|
|
void mg_http_delete_chunk(struct mg_connection *c, struct mg_http_message *hm);
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
|
|
|
|
mg_event_handler_t fn, void *fn_data);
|
|
|
|
struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
|
|
|
|
mg_event_handler_t fn, void *fn_data);
|
|
|
|
void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
|
2022-04-12 10:04:55 +01:00
|
|
|
const struct mg_http_serve_opts *);
|
2021-07-28 21:11:07 +01:00
|
|
|
void mg_http_serve_file(struct mg_connection *, struct mg_http_message *hm,
|
2022-04-12 10:04:55 +01:00
|
|
|
const char *path, const struct mg_http_serve_opts *);
|
2020-12-17 22:45:22 +00:00
|
|
|
void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
|
|
|
|
const char *body_fmt, ...);
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
|
2021-05-28 18:30:42 +01:00
|
|
|
int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
|
2020-12-05 11:26:32 +00:00
|
|
|
int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
|
2021-05-28 18:30:42 +01:00
|
|
|
size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);
|
|
|
|
void mg_http_creds(struct mg_http_message *, char *, size_t, char *, size_t);
|
2020-12-05 11:26:32 +00:00
|
|
|
bool mg_http_match_uri(const struct mg_http_message *, const char *glob);
|
|
|
|
int mg_http_upload(struct mg_connection *, struct mg_http_message *hm,
|
2022-01-18 17:11:02 +00:00
|
|
|
struct mg_fs *fs, const char *dir);
|
2020-12-05 11:26:32 +00:00
|
|
|
void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
|
2021-03-17 07:43:29 +00:00
|
|
|
struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v);
|
|
|
|
size_t mg_http_next_multipart(struct mg_str, size_t, struct mg_http_part *);
|
2022-02-12 16:51:37 +00:00
|
|
|
int mg_http_status(const struct mg_http_message *hm);
|
2020-12-05 11:26:32 +00:00
|
|
|
|
|
|
|
|
2021-01-02 17:57:51 +00:00
|
|
|
void mg_http_serve_ssi(struct mg_connection *c, const char *root,
|
|
|
|
const char *fullpath);
|
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
|
2021-12-14 12:42:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_tls_opts {
|
2021-01-30 13:03:11 +00:00
|
|
|
const char *ca; // CA certificate file. For both listeners and clients
|
2021-10-14 17:32:48 +02:00
|
|
|
const char *crl; // Certificate Revocation List. For clients
|
2021-01-30 13:03:11 +00:00
|
|
|
const char *cert; // Certificate
|
|
|
|
const char *certkey; // Certificate key
|
|
|
|
const char *ciphers; // Cipher list
|
|
|
|
struct mg_str srvname; // If not empty, enables server name verification
|
2022-01-18 17:11:02 +00:00
|
|
|
struct mg_fs *fs; // FS API for reading certificate files
|
2020-12-05 11:26:32 +00:00
|
|
|
};
|
|
|
|
|
2022-04-12 10:04:55 +01:00
|
|
|
void mg_tls_init(struct mg_connection *, const struct mg_tls_opts *);
|
2021-05-28 18:30:42 +01:00
|
|
|
void mg_tls_free(struct mg_connection *);
|
|
|
|
long mg_tls_send(struct mg_connection *, const void *buf, size_t len);
|
|
|
|
long mg_tls_recv(struct mg_connection *, void *buf, size_t len);
|
2022-04-12 09:38:25 +01:00
|
|
|
size_t mg_tls_pending(struct mg_connection *);
|
2021-05-28 18:30:42 +01:00
|
|
|
void mg_tls_handshake(struct mg_connection *);
|
2015-09-08 13:49:03 +02:00
|
|
|
|
|
|
|
|
2021-12-14 12:42:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-01-24 02:20:45 +00:00
|
|
|
|
|
|
|
#if MG_ENABLE_MBEDTLS
|
2021-12-14 12:42:41 +00:00
|
|
|
#include <mbedtls/debug.h>
|
2022-01-18 17:11:02 +00:00
|
|
|
#include <mbedtls/net_sockets.h>
|
2021-12-14 12:42:41 +00:00
|
|
|
#include <mbedtls/ssl.h>
|
|
|
|
|
|
|
|
struct mg_tls {
|
|
|
|
char *cafile; // CA certificate path
|
|
|
|
mbedtls_x509_crt ca; // Parsed CA certificate
|
|
|
|
mbedtls_x509_crt cert; // Parsed certificate
|
|
|
|
mbedtls_ssl_context ssl; // SSL/TLS context
|
|
|
|
mbedtls_ssl_config conf; // SSL-TLS config
|
|
|
|
mbedtls_pk_context pk; // Private key context
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if MG_ENABLE_OPENSSL
|
|
|
|
|
|
|
|
#include <openssl/err.h>
|
|
|
|
#include <openssl/ssl.h>
|
|
|
|
|
|
|
|
struct mg_tls {
|
|
|
|
SSL_CTX *ctx;
|
|
|
|
SSL *ssl;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
#define WEBSOCKET_OP_CONTINUE 0
|
|
|
|
#define WEBSOCKET_OP_TEXT 1
|
|
|
|
#define WEBSOCKET_OP_BINARY 2
|
|
|
|
#define WEBSOCKET_OP_CLOSE 8
|
|
|
|
#define WEBSOCKET_OP_PING 9
|
|
|
|
#define WEBSOCKET_OP_PONG 10
|
2015-09-08 13:49:03 +02:00
|
|
|
|
2016-11-24 09:46:40 +00:00
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_ws_message {
|
2021-09-15 07:43:48 +01:00
|
|
|
struct mg_str data; // Websocket message data
|
|
|
|
uint8_t flags; // Websocket message flags
|
2020-12-05 11:26:32 +00:00
|
|
|
};
|
2016-11-24 09:46:40 +00:00
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
|
|
|
|
mg_event_handler_t fn, void *fn_data,
|
|
|
|
const char *fmt, ...);
|
2021-01-16 22:48:43 +00:00
|
|
|
void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
|
|
|
|
const char *fmt, ...);
|
2020-12-05 11:26:32 +00:00
|
|
|
size_t mg_ws_send(struct mg_connection *, const char *buf, size_t len, int op);
|
2021-08-01 14:10:21 +01:00
|
|
|
size_t mg_ws_wrap(struct mg_connection *, size_t len, int op);
|
2022-06-05 14:59:50 +01:00
|
|
|
size_t mg_ws_printf(struct mg_connection *c, int op, const char *fmt, ...);
|
|
|
|
size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt, va_list);
|
2016-11-24 09:46:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
|
|
|
|
mg_event_handler_t fn, void *fn_data);
|
2022-05-15 18:41:01 +01:00
|
|
|
void mg_sntp_request(struct mg_connection *c);
|
2021-12-21 21:50:18 +00:00
|
|
|
int64_t mg_sntp_parse(const unsigned char *buf, size_t len);
|
2016-11-24 09:46:40 +00:00
|
|
|
|
2017-10-16 20:00:16 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
2017-10-19 08:38:33 +01:00
|
|
|
|
2020-12-15 20:29:47 +00:00
|
|
|
#define MQTT_CMD_CONNECT 1
|
|
|
|
#define MQTT_CMD_CONNACK 2
|
|
|
|
#define MQTT_CMD_PUBLISH 3
|
|
|
|
#define MQTT_CMD_PUBACK 4
|
|
|
|
#define MQTT_CMD_PUBREC 5
|
|
|
|
#define MQTT_CMD_PUBREL 6
|
|
|
|
#define MQTT_CMD_PUBCOMP 7
|
|
|
|
#define MQTT_CMD_SUBSCRIBE 8
|
|
|
|
#define MQTT_CMD_SUBACK 9
|
|
|
|
#define MQTT_CMD_UNSUBSCRIBE 10
|
|
|
|
#define MQTT_CMD_UNSUBACK 11
|
|
|
|
#define MQTT_CMD_PINGREQ 12
|
|
|
|
#define MQTT_CMD_PINGRESP 13
|
|
|
|
#define MQTT_CMD_DISCONNECT 14
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_mqtt_opts {
|
2021-10-31 12:48:32 +00:00
|
|
|
struct mg_str user; // Username, can be empty
|
|
|
|
struct mg_str pass; // Password, can be empty
|
2021-09-15 07:43:48 +01:00
|
|
|
struct mg_str client_id; // Client ID
|
|
|
|
struct mg_str will_topic; // Will topic
|
|
|
|
struct mg_str will_message; // Will message
|
2021-12-23 11:00:18 +00:00
|
|
|
uint8_t will_qos; // Will message quality of service
|
2021-09-15 07:43:48 +01:00
|
|
|
bool will_retain; // Retain last will
|
|
|
|
bool clean; // Use clean session, 0 or 1
|
|
|
|
uint16_t keepalive; // Keep-alive timer in seconds
|
2017-10-16 20:00:16 +01:00
|
|
|
};
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_mqtt_message {
|
2021-06-10 19:15:50 +01:00
|
|
|
struct mg_str topic; // Parsed topic
|
|
|
|
struct mg_str data; // Parsed message
|
|
|
|
struct mg_str dgram; // Whole MQTT datagram, including headers
|
2020-12-15 20:29:47 +00:00
|
|
|
uint16_t id; // Set for PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, PUBLISH
|
|
|
|
uint8_t cmd; // MQTT command, one of MQTT_CMD_*
|
|
|
|
uint8_t qos; // Quality of service
|
|
|
|
uint8_t ack; // Connack return code. 0 - success
|
2017-10-16 20:00:16 +01:00
|
|
|
};
|
|
|
|
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url,
|
2022-04-12 10:04:55 +01:00
|
|
|
const struct mg_mqtt_opts *opts,
|
2020-12-05 11:26:32 +00:00
|
|
|
mg_event_handler_t fn, void *fn_data);
|
2020-12-15 20:29:47 +00:00
|
|
|
struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
|
|
|
|
mg_event_handler_t fn, void *fn_data);
|
2022-04-12 10:04:55 +01:00
|
|
|
void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts);
|
2022-01-19 09:57:27 +00:00
|
|
|
void mg_mqtt_pub(struct mg_connection *c, struct mg_str topic,
|
|
|
|
struct mg_str data, int qos, bool retain);
|
|
|
|
void mg_mqtt_sub(struct mg_connection *, struct mg_str topic, int qos);
|
2020-12-16 10:14:00 +00:00
|
|
|
int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m);
|
2020-12-15 20:29:47 +00:00
|
|
|
void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags,
|
|
|
|
uint32_t len);
|
2021-05-28 18:30:42 +01:00
|
|
|
size_t mg_mqtt_next_sub(struct mg_mqtt_message *msg, struct mg_str *topic,
|
|
|
|
uint8_t *qos, size_t pos);
|
|
|
|
size_t mg_mqtt_next_unsub(struct mg_mqtt_message *msg, struct mg_str *topic,
|
|
|
|
size_t pos);
|
2021-03-07 12:21:59 +00:00
|
|
|
void mg_mqtt_ping(struct mg_connection *);
|
|
|
|
void mg_mqtt_pong(struct mg_connection *);
|
|
|
|
void mg_mqtt_disconnect(struct mg_connection *);
|
2017-10-16 20:00:16 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-12-22 09:44:59 +00:00
|
|
|
// Mongoose sends DNS queries that contain only one question:
|
|
|
|
// either A (IPv4) or AAAA (IPv6) address lookup.
|
|
|
|
// Therefore, we expect zero or one answer.
|
|
|
|
// If `resolved` is true, then `addr` contains resolved IPv4 or IPV6 address.
|
2020-12-05 11:26:32 +00:00
|
|
|
struct mg_dns_message {
|
2020-12-22 09:44:59 +00:00
|
|
|
uint16_t txnid; // Transaction ID
|
|
|
|
bool resolved; // Resolve successful, addr is set
|
|
|
|
struct mg_addr addr; // Resolved address
|
|
|
|
char name[256]; // Host name
|
2020-12-05 11:26:32 +00:00
|
|
|
};
|
2017-10-16 20:00:16 +01:00
|
|
|
|
2020-12-28 05:25:29 +00:00
|
|
|
struct mg_dns_header {
|
|
|
|
uint16_t txnid; // Transaction ID
|
|
|
|
uint16_t flags;
|
|
|
|
uint16_t num_questions;
|
|
|
|
uint16_t num_answers;
|
|
|
|
uint16_t num_authority_prs;
|
|
|
|
uint16_t num_other_prs;
|
|
|
|
};
|
|
|
|
|
|
|
|
// DNS resource record
|
|
|
|
struct mg_dns_rr {
|
|
|
|
uint16_t nlen; // Name or pointer length
|
|
|
|
uint16_t atype; // Address type
|
|
|
|
uint16_t aclass; // Address class
|
|
|
|
uint16_t alen; // Address length
|
|
|
|
};
|
|
|
|
|
2022-01-07 15:00:10 +00:00
|
|
|
void mg_resolve(struct mg_connection *, const char *url);
|
2020-12-22 09:44:59 +00:00
|
|
|
void mg_resolve_cancel(struct mg_connection *);
|
2020-12-20 16:55:33 +00:00
|
|
|
bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *);
|
2020-12-28 05:25:29 +00:00
|
|
|
size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
|
|
|
|
bool is_question, struct mg_dns_rr *);
|
2021-07-13 06:58:34 +01:00
|
|
|
|
2022-05-18 21:19:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-06-11 17:29:45 +01:00
|
|
|
#ifndef MG_JSON_MAX_DEPTH
|
|
|
|
#define MG_JSON_MAX_DEPTH 30
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Error return values - negative. Successful returns are >= 0
|
|
|
|
enum { MG_JSON_TOO_DEEP = -1, MG_JSON_INVALID = -2, MG_JSON_NOT_FOUND = -3 };
|
|
|
|
int mg_json_get(const char *buf, int len, const char *path, int *toklen);
|
|
|
|
|
|
|
|
bool mg_json_get_num(struct mg_str json, const char *path, double *v);
|
|
|
|
bool mg_json_get_bool(struct mg_str json, const char *path, bool *v);
|
|
|
|
char *mg_json_get_str(struct mg_str json, const char *path);
|
|
|
|
char *mg_json_get_hex(struct mg_str json, const char *path);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-05-18 21:19:21 +01:00
|
|
|
struct mip_driver {
|
|
|
|
void *data; // Driver-specific data
|
|
|
|
void (*init)(void *data); // Initialise driver
|
|
|
|
size_t (*tx)(const void *, size_t, void *data); // Transmit frame
|
|
|
|
size_t (*rx)(void *buf, size_t len, void *data); // Receive frame (polling)
|
|
|
|
bool (*status)(void *data); // Up/down status
|
|
|
|
// Set receive callback for interrupt-driven drivers
|
|
|
|
void (*rxcb)(void (*fn)(void *buf, size_t len, void *rxdata), void *rxdata);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mip_ipcfg {
|
|
|
|
uint8_t mac[6]; // MAC address. Must not be 0
|
|
|
|
uint32_t ip, mask, gw; // IP, netmask, GW. If IP is 0, DHCP is used
|
|
|
|
};
|
|
|
|
|
|
|
|
void mip_init(struct mg_mgr *, struct mip_ipcfg *, struct mip_driver *);
|
|
|
|
|
2022-06-11 17:29:45 +01:00
|
|
|
extern struct mip_driver mip_driver_stm32;
|
2022-06-09 12:39:48 +01:00
|
|
|
|
2021-07-13 06:58:34 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
2021-07-19 09:04:18 +01:00
|
|
|
#endif // MONGOOSE_H
|