Compare commits

..
44 Commits
Author SHA1 Message Date
Deomid Ryabkov 81d977c720 Introduce mg_time() and use it internally
PUBLISHED_FROM=024a2d7849a800381d58460877eacccfc93b1cdd
2016-01-11 12:24:40 +03:00
Alexander Alashkin f477898c7c Mongoose 6.1 -> 6.2
PUBLISHED_FROM=24146cf7f4cf86cfd76260fb906d50889b9d6f7e
2016-01-11 12:24:40 +03:00
Marko Mikulicic 566193a1eb Implement freezing V7 object graph
PUBLISHED_FROM=1670ce871ed2c9391edb10ff413d3d454997d1fe
2016-01-11 12:24:40 +03:00
Deomid Ryabkov 5d6eeb5d1d Add a note about Content-Type for form submissions
PUBLISHED_FROM=6079258be24fa0255f5a58e4d364be224435394b
2016-01-11 12:24:39 +03:00
Dmitry Frank d9b9d71b2d v7_apply() and friends take res as last argument
PUBLISHED_FROM=4b064f5e4554c5a016481bf8104c0ba9dd244083
2016-01-11 12:24:38 +03:00
Dmitry Frank 643ee1df14 cfunctions API refactored to return enum v7_err
PUBLISHED_FROM=f96a4ab2016c0125c1e94b3c5c9ada2c365bd39d
2016-01-11 12:24:36 +03:00
Deomid Ryabkov 6c4d37ee68 Free previous ssl context in mg_set_ssl
PUBLISHED_FROM=9f595222bce1fe8d0917649e36ce3be40eee1775
2015-12-23 17:02:52 +01:00
Sergey Lyubka 97b79cd04a Add MacOS to mongoose README
PUBLISHED_FROM=679b640e3de8b0fbd65b38263093dd6049db4cd3
2015-12-23 17:02:52 +01:00
Sergey Lyubka 56c6229dd6 Update Mongoose readme
PUBLISHED_FROM=ac117f203ef11b9c3877a6dd1919e8409d04cdb1
2015-12-22 07:42:12 +00:00
Dmitry Frank 0fe2dd9b48 Added param names to mongoose headers
PUBLISHED_FROM=07bd8163c4e1df49ab3dc7a1640efa2adff34e33
2015-12-22 07:42:11 +00:00
Sergey Lyubka 910aee7f7b Re-enable mongosoe FS support on ESP
PUBLISHED_FROM=cfa1c79bb5429feddf38c68c25195b97deef9a62
2015-12-22 07:33:06 +00:00
Sergey Lyubka 97063937ff Add vanilla forum to forum.cesanta.com
PUBLISHED_FROM=bff863108d0fb80a6139ac34be04fb999e18e62e
2015-12-22 07:33:06 +00:00
Sergey Lyubka 7e68b097d1 Close https://github.com/cesanta/mongoose/pull/603
PUBLISHED_FROM=ab934b21ed67878f47ccd569d88030e53e914bf7
2015-12-21 08:37:20 +00:00
Marko Mikulicic 4d41dff4fd Fix includes
PUBLISHED_FROM=58d764bb224968d5368b21a8eb572602055cb26b
2015-12-21 08:37:19 +00:00
Deomid Ryabkov 05082cec88 Use sub-second time for timers in MG
PUBLISHED_FROM=2b5bd1589465a5f43bc888c689842332cf7cdf98
2015-12-20 17:49:13 +00:00
Marko Mikulicic f05733da69 Fix COAP example, reduce number of ctx switches
PUBLISHED_FROM=7010fff404826c3dfc783d2cbdcbd0936a8a2b85
2015-12-15 11:36:34 +01:00
Marko Mikulicic 3c53909e82 Foolproof Smartjs publishing
PUBLISHED_FROM=8ade849890746baa95fd8a5d92baf3dda656a719
2015-12-15 11:28:39 +01:00
Deomid Ryabkov 1e53ec47a9 Peeple TLS support for updates
PUBLISHED_FROM=1abdacaece6dc63b6148c605c4c2cc41c3cc4ac6
2015-12-15 11:28:38 +01:00
Sergey Lyubka 17802735d7 Spiffy config for cc3200
PUBLISHED_FROM=34b3678cb2510adfd5f26183ae7c16aadb97e6c9
2015-12-14 00:12:12 +01:00
Marko Mikulicic d2eb67a1ae Sanitize mongoose headers
PUBLISHED_FROM=d3790d175b8d714865c7eb5f12e82d31844a863f
2015-12-14 00:12:12 +01:00
Marko Mikulicic 3f254dd3fc Simplify include paths
PUBLISHED_FROM=4e38db207dc2634e410339c81c5a2a87e8b188b0
2015-12-14 00:12:12 +01:00
Deomid Ryabkov e139bde6ae A couple SSL-related fixes for Mongoose
PUBLISHED_FROM=03297850f7a620588de851ef86be25e17a04ad28
2015-12-11 13:02:13 +00:00
Sergey Lyubka 5f62951143 Runtime DAV auth disable. Implement MOVE
PUBLISHED_FROM=aec49928891972ecd6af9999fe3e1cb5ef00f24c
2015-12-11 13:02:13 +00:00
Sergey Lyubka 2207e87c8f Fix DAV for non-existent files. Improve logging
PUBLISHED_FROM=39a2810ad9bebcf1676b982f7523aa9c2339cc4f
2015-12-11 13:02:12 +00:00
Sergey Lyubka 5bd59c7b70 Shut up spiffs. Proper DAV report
PUBLISHED_FROM=125379f6c624b4e938b5d543cb8ed5fe906de98f
2015-12-11 13:02:12 +00:00
Alexander Alashkin 02f6867a2f Implement %lld in c_vsnprintf. Closes cesanta/dev#2120
PUBLISHED_FROM=1f24878425356f625b4f5b2b0fe40ab5f17501ab
2015-12-11 13:02:11 +00:00
Deomid Ryabkov b93fa3144a First cut of TLS support for LWIP event manager
PUBLISHED_FROM=98cf23ea090ffb4e83edd4d600bee57dfd7d94d4
2015-12-11 13:02:11 +00:00
Alexander Alashkin a68e0d9a3f Add WebDAV move stub
PUBLISHED_FROM=b1f712862b81dfe8da6547338f77ff3bfefa5051
2015-12-11 13:02:10 +00:00
Alexander Alashkin cfe80ba9b7 Add WebDAV support to sjs/esp8266
PUBLISHED_FROM=a68a2f205cb2f10809183d5160709981585538b7
2015-12-11 13:02:10 +00:00
Deomid Ryabkov 35abfd44dd Fix windows build
PUBLISHED_FROM=3b3788da8c2dcc57897044701c5252ea46db0249
2015-12-08 13:38:05 +00:00
Sergey Lyubka e98b5a691e Implement Http_request.setTimeout()
PUBLISHED_FROM=7a72e485aad2be859b9452dc1687a922778959d1
2015-12-08 13:38:05 +00:00
Sergey Lyubka ed24afd172 Connect timeouts for resolving connections
PUBLISHED_FROM=068b6f75550b10913d7f13106f9a7f7dce5babec
2015-12-08 12:35:29 +00:00
Deomid Ryabkov 714556de65 Added debug line to mg_mgr_handle_ctl_sock
PUBLISHED_FROM=a4c1d105cb4f18d982bd28190691b6ea65ee37fc
2015-12-08 12:35:29 +00:00
Deomid Ryabkov 547ec85b58 Properly disable socketpair-related stuff
PUBLISHED_FROM=f3a236470281af80848c8f78163980083190c081
2015-12-08 12:35:29 +00:00
Marko Mikulicic 845d751e87 Fix C String API confusion
PUBLISHED_FROM=af34acd81d877bfbd8441c14451d8c81f18c207d
2015-12-08 12:35:29 +00:00
Alexander Alashkin 518a7f8a71 Fix MG DAV
PUBLISHED_FROM=132db6ed9c9e1eb9ec19b4f9299448b901b92231
2015-12-08 12:35:29 +00:00
Sergey Lyubka 31323b01bc Introduce MG_EV_TIMER event
PUBLISHED_FROM=2e90ee87eda8bc742e427671bb9df1ce0cd8bc25
2015-12-08 12:35:28 +00:00
Deomid Ryabkov 3a138ecc83 Move more of SSL-specific code into net_if
PUBLISHED_FROM=47dc4712c0ea2012c0774ad260f0451371cfe8b7
2015-12-08 12:35:28 +00:00
Dmitry Frank 7294674a8b Remove custom strnlen for VC 16+
PUBLISHED_FROM=9c28b64267408929f5c565b87978816f3a93f06b
2015-12-08 12:35:27 +00:00
Sergey Lyubka 423b978395 Report read-only vars to UI
PUBLISHED_FROM=2ca4b52e777a54d9bb05a177e57a8b73bb962fdb
2015-12-08 12:35:27 +00:00
Sergey Lyubka ecf20ec7b8 Add error_log_file, use extended log format
PUBLISHED_FROM=d189b44857723871159826944bde9b87089bb0bd
2015-12-08 12:35:27 +00:00
Sergey Lyubka c948a509fb Export mg_url_decode() to public
PUBLISHED_FROM=442534f52992be612a98a549e5ab2191081a9d52
2015-12-03 22:05:52 +00:00
Sergey Lyubka f5ad19d76b Fix g++ build for mongoose example
PUBLISHED_FROM=c581f33e26819d05c9b8484c9dc10c2a3615a34a
2015-12-02 17:04:44 +00:00
Deomid Ryabkov d665d9e90e Always Be Closing
PUBLISHED_FROM=29ca7cdd9024790bd75892f9f67b3f83a6bd00d1
2015-12-01 18:03:19 +00:00
8 changed files with 639 additions and 265 deletions

No files matched your search

+10 -13
View File
@@ -1,12 +1,9 @@
# <img src="http://www.cesanta.com/hubfs/www.cesanta.com/Images/mongoose_library.png" width="64" height="64"> Mongoose - Embedded Web Server
[![Join the chat at https://gitter.im/cesanta/mongoose](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/cesanta/mongoose?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
![](https://img.shields.io/badge/license-GPL_2-green.svg "License")
Mongoose is ideal for embedded environments, it has been designed as an open
source platform for connecting devices and bringing them online.
Mongoose is ideal for embedded environments. It has been designed
for connecting devices and bringing them online.
[Mongoose](https://www.cesanta.com/products)
has been on the market since 2004 and attracted
over 1 million cumulative downloads.
@@ -16,7 +13,10 @@ network protocols or scalable network applications with little effort.
Mongoose helps developers to manage the complexity of network programming
and let them concentrate on the logic, saving time and money.
[Download Mongoose Source Code here](http://hubs.ly/H01bWvx0)
- [Download Mongoose Source Code here](http://hubs.ly/H01bWvx0)
- [Ask questions on support forum](http://forum.cesanta.com/index.php?p=/categories/mongoose)
- [Read User Guide and API reference](https://docs.cesanta.com/mongoose)
- [Study mongoose example code](https://github.com/cesanta/mongoose/tree/master/examples)
> Nothing overdone. Nothing less. So unbelievably easy to use.
> Just how good software should be! -- Pritin Tyagaraj, SAP
@@ -24,8 +24,11 @@ and let them concentrate on the logic, saving time and money.
# Features
* Cross-platform: works on Linux/UNIX, QNX, eCos, Windows, Android, iPhone, etc
* Cross-platform: works on Linux/UNIX, MacOS, QNX, eCos, Windows, Android,
iPhone, FreeRTOS (TI CC3200, ESP8266), etc
* Single-threaded, asynchronous, non-blocking core with simple event-based API
* Native support for [PicoTCP embedded TCP/IP stack](http://www.picotcp.com),
[LWIP embedded TCP/IP stack](https://en.wikipedia.org/wiki/LwIP)
* Builtin protocols:
- plain TCP, plain UDP, SSL/TLS (over TCP, one-way or two-way)
- HTTP client, HTTP server
@@ -42,12 +45,6 @@ and let them concentrate on the logic, saving time and money.
files to your build tree
* Extensively tested and production-ready, trusted by many blue chip businesses
# Examples & Documentation
- [User Guide](https://docs.cesanta.com/mongoose) - Detailed User Guide and API reference
- [examples](examples) - Collection of well-commented examples. To build any example,
go into respective directory and type `make`
# Dashboard Example
Mongoose is often used to implement device dashboards and real-time
+9 -10
View File
@@ -2,14 +2,14 @@
* Copyright (c) 2015 Cesanta Software Limited
* All rights reserved
*
* This program sends CoAP CON-message to server (coap.me by default)
* This program sends CoAP CON-message to server (coap.me by default)
* and waits for answer.
*/
#include "mongoose.h"
static int s_time_to_exit = 0;
static char* s_default_address = "udp://coap.me:5683";
static char *s_default_address = "udp://coap.me:5683";
static void coap_handler(struct mg_connection *nc, int ev, void *p) {
switch (ev) {
@@ -31,17 +31,16 @@ static void coap_handler(struct mg_connection *nc, int ev, void *p) {
break;
}
case MG_EV_COAP_ACK:
case MG_EV_COAP_RST: {
struct mg_coap_message *cm = (struct mg_coap_message *)p;
printf("ACK/RST for message with msg_id = %d received\n",
cm->msg_id);
case MG_EV_COAP_RST: {
struct mg_coap_message *cm = (struct mg_coap_message *) p;
printf("ACK/RST for message with msg_id = %d received\n", cm->msg_id);
s_time_to_exit = 1;
break;
}
}
}
int main(int argc, char* argv[]) {
int main(int argc, char *argv[]) {
struct mg_mgr mgr;
struct mg_connection *nc;
char *address = s_default_address;
@@ -50,7 +49,7 @@ int main(int argc, char* argv[]) {
address = argv[1];
}
printf("Using %s as CoAP server\n", address);
printf("Using %s as CoAP server\n", address);
mg_mgr_init(&mgr, 0);
@@ -63,10 +62,10 @@ int main(int argc, char* argv[]) {
mg_set_protocol_coap(nc);
while (!s_time_to_exit) {
mg_mgr_poll(&mgr, 1);
mg_mgr_poll(&mgr, 1000000);
}
mg_mgr_free(&mgr);
return 0;
}
+9 -10
View File
@@ -2,18 +2,18 @@
* Copyright (c) 2015 Cesanta Software Limited
* All rights reserved
*
* This program listens on 5683 for CoAP messages,
* This program listens on 5683 for CoAP messages,
* sends ACK is nessesary and dump everything received.
* It is possible to use ../coap_client to send message.
*/
#include "mongoose.h"
static char* s_default_address = "udp://:5683";
static char *s_default_address = "udp://:5683";
static int s_sig_received = 0;
static void signal_handler(int sig_num) {
signal(sig_num, signal_handler);
signal(sig_num, signal_handler);
s_sig_received = sig_num;
}
@@ -21,7 +21,7 @@ static void coap_handler(struct mg_connection *nc, int ev, void *p) {
switch (ev) {
case MG_EV_COAP_CON: {
uint32_t res;
struct mg_coap_message *cm = (struct mg_coap_message *)p;
struct mg_coap_message *cm = (struct mg_coap_message *) p;
printf("CON with msg_id = %d received\n", cm->msg_id);
res = mg_coap_send_ack(nc, cm->msg_id);
if (res == 0) {
@@ -34,10 +34,9 @@ static void coap_handler(struct mg_connection *nc, int ev, void *p) {
}
case MG_EV_COAP_NOC:
case MG_EV_COAP_ACK:
case MG_EV_COAP_RST: {
struct mg_coap_message *cm = (struct mg_coap_message *)p;
printf("ACK/RST/NOC with msg_id = %d received\n",
cm->msg_id);
case MG_EV_COAP_RST: {
struct mg_coap_message *cm = (struct mg_coap_message *) p;
printf("ACK/RST/NOC with msg_id = %d received\n", cm->msg_id);
break;
}
}
@@ -58,12 +57,12 @@ int main() {
return -1;
}
printf("Listening for CoAP messages at %s\n", s_default_address);
printf("Listening for CoAP messages at %s\n", s_default_address);
mg_set_protocol_coap(nc);
while (!s_sig_received) {
mg_mgr_poll(&mgr, 1);
mg_mgr_poll(&mgr, 1000000);
}
printf("Exiting on signal %d\n", s_sig_received);
+10 -2
View File
@@ -233,6 +233,12 @@ static void forward(struct conn_data *conn, struct http_message *hm,
/* We always rewrite the connection header depending on the settings. */
if (mg_vcasecmp(&hn, "Connection") == 0) continue;
/* Don't pass chunked transfer encoding to the client */
if (mg_vcasecmp(&hn, "Transfer-encoding") == 0 &&
mg_vcasecmp(&hv, "chunked") == 0) {
continue;
}
mg_printf(dst, "%.*s: %.*s\r\n", (int) hn.len, hn.p, (int) hv.len, hv.p);
}
@@ -272,7 +278,7 @@ static int connect_backend(struct conn_data *conn, struct http_message *hm) {
struct http_backend *be = choose_backend(hm);
write_log("%.*s %.*s backend=%s\n", (int) hm->method.len, hm->method.p,
(int) hm->uri.len, hm->uri.p, be->host_port);
(int) hm->uri.len, hm->uri.p, be ? be->host_port : "not defined");
if (be == NULL) return 0;
if (be->redirect != 0) {
@@ -413,7 +419,9 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
}
return;
} else {
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
if (ev != MG_EV_POLL) {
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
}
return;
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
PROG = simplest_web_server
SOURCES = $(PROG).c ../../mongoose.c
CFLAGS = -W -Wall -I../.. $(CFLAGS_EXTRA)
CFLAGS = -W -Wall -I../.. $(CFLAGS_EXTRA) -DMG_DISABLE_DAV_AUTH
all: $(PROG)
@@ -8,7 +8,7 @@ static struct mg_serve_http_opts s_http_server_opts;
static void ev_handler(struct mg_connection *nc, int ev, void *p) {
if (ev == MG_EV_HTTP_REQUEST) {
mg_serve_http(nc, p, s_http_server_opts);
mg_serve_http(nc, (struct http_message *) p, s_http_server_opts);
}
}
@@ -22,6 +22,7 @@ int main(void) {
// Set up HTTP server parameters
mg_set_protocol_http_websocket(nc);
s_http_server_opts.document_root = "."; // Serve current directory
s_http_server_opts.dav_document_root = "."; // Allow access via WebDav
s_http_server_opts.enable_directory_listing = "yes";
printf("Starting web server on port %s\n", s_http_port);
+406 -164
View File
File diff suppressed because it is too large. Load diff
+192 -64
View File
@@ -20,7 +20,7 @@
* license, as set out in <https://www.cesanta.com/license>.
*/
#define MG_VERSION "6.1"
#define MG_VERSION "6.2"
/* Local tweaks, applied before any of Mongoose's own headers. */
#ifdef MG_LOCALS
@@ -30,6 +30,7 @@
#if defined(MG_ENABLE_DEBUG) && !defined(CS_ENABLE_DEBUG)
#define CS_ENABLE_DEBUG
#endif
/*
* Copyright (c) 2015 Cesanta Software Limited
* All rights reserved
@@ -172,6 +173,7 @@ typedef uint32_t in_addr_t;
#define pid_t HANDLE
#endif
#define INT64_FMT "I64d"
#define INT64_X_FMT "I64x"
#define SIZE_T_FMT "Iu"
#ifdef __MINGW32__
typedef struct stat cs_stat_t;
@@ -251,6 +253,7 @@ struct dirent *readdir(DIR *dir);
#define INVALID_SOCKET (-1)
#define INT64_FMT PRId64
#define INT64_X_FMT PRIx64
#if defined(ESP8266) || defined(MG_ESP8266) || defined(MG_CC3200)
#define SIZE_T_FMT "u"
#else
@@ -271,6 +274,18 @@ int64_t strtoll(const char *str, char **endptr, int base);
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
#endif
#ifdef __GNUC__
#define NORETURN __attribute__((noreturn))
#define UNUSED __attribute__((unused))
#define NOINLINE __attribute__((noinline))
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define NORETURN
#define UNUSED
#define NOINLINE
#define WARN_UNUSED_RESULT
#endif
#endif /* OSDEP_HEADER_INCLUDED */
#ifndef _CS_DBG_H_
#define _CS_DBG_H_
@@ -287,8 +302,6 @@ enum cs_log_level {
_LL_MAX = 5,
};
#ifndef CS_NDEBUG
extern enum cs_log_level s_cs_log_level;
void cs_log_set_level(enum cs_log_level level);
@@ -300,6 +313,8 @@ void cs_log_printf(const char *fmt, ...);
cs_log_printf x; \
}
#ifndef CS_NDEBUG
#define DBG(x) \
if (s_cs_log_level >= LL_VERBOSE_DEBUG) { \
fprintf(stderr, "%-20s ", __func__); \
@@ -308,14 +323,18 @@ void cs_log_printf(const char *fmt, ...);
#else /* NDEBUG */
#define cs_log_set_level(l)
#define LOG(l, x)
#define DBG(x)
#endif
#endif /* _CS_DBG_H_ */
#ifndef _CS_TIME_H_
#define _CS_TIME_H_
/* Sub-second granularity time(). */
double cs_time();
#endif /* _CS_TIME_H_ */
/*
* Copyright (c) 2015 Cesanta Software Limited
* All rights reserved
@@ -526,7 +545,7 @@ int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap);
!(defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L) && \
!(defined(__DARWIN_C_LEVEL) && __DARWIN_C_LEVEL >= 200809L) && \
!defined(RTOS_SDK)) || \
defined(_WIN32)
(defined(_MSC_VER) && _MSC_VER < 1600 /*Visual Studio 2010*/)
#define _MG_PROVIDE_STRNLEN
size_t strnlen(const char *s, size_t maxlen);
#endif
@@ -603,6 +622,33 @@ int json_emit_va(char *buf, int buf_len, const char *fmt, va_list);
#endif /* __cplusplus */
#endif /* FROZEN_HEADER_INCLUDED */
#ifndef DIRENT_H_INCLUDED
#define DIRENT_H_INCLUDED
#ifdef CS_ENABLE_SPIFFS
#include <spiffs.h>
typedef struct {
spiffs_DIR dh;
struct spiffs_dirent de;
} DIR;
#define d_name name
#define dirent spiffs_dirent
int rmdir(const char *path);
int mkdir(const char *path, mode_t mode);
#endif
#if defined(_WIN32) || defined(CS_ENABLE_SPIFFS)
DIR *opendir(const char *dir_name);
int closedir(DIR *dir);
struct dirent *readdir(DIR *dir);
#endif
#endif
/*
* Copyright (c) 2014 Cesanta Software Limited
* All rights reserved
@@ -649,6 +695,10 @@ typedef void *SSL;
typedef void *SSL_CTX;
#endif
#ifndef MG_VPRINTF_BUFFER_SIZE
#define MG_VPRINTF_BUFFER_SIZE 100
#endif
#ifdef MG_USE_READ_WRITE
#define MG_RECV_FUNC(s, b, l, f) read(s, b, l)
#define MG_SEND_FUNC(s, b, l, f) write(s, b, l)
@@ -694,6 +744,7 @@ typedef void (*mg_event_handler_t)(struct mg_connection *, int ev, void *);
#define MG_EV_RECV 3 /* Data has benn received. int *num_bytes */
#define MG_EV_SEND 4 /* Data has been written to a socket. int *num_bytes */
#define MG_EV_CLOSE 5 /* Connection is closed. NULL */
#define MG_EV_TIMER 6 /* now >= conn->ev_timer_time. double * */
/*
* Mongoose event manager.
@@ -701,9 +752,11 @@ typedef void (*mg_event_handler_t)(struct mg_connection *, int ev, void *);
struct mg_mgr {
struct mg_connection *active_connections;
const char *hexdump_file; /* Debug hexdump file path */
sock_t ctl[2]; /* Socketpair for mg_wakeup() */
void *user_data; /* User data */
void *mgr_data; /* Implementation-specific event manager's data. */
#ifndef MG_DISABLE_SOCKETPAIR
sock_t ctl[2]; /* Socketpair for mg_wakeup() */
#endif
void *user_data; /* User data */
void *mgr_data; /* Implementation-specific event manager's data. */
#ifdef MG_ENABLE_JAVASCRIPT
struct v7 *v7;
#endif
@@ -726,6 +779,7 @@ struct mg_connection {
SSL *ssl;
SSL_CTX *ssl_ctx;
time_t last_io_time; /* Timestamp of the last socket IO */
double ev_timer_time; /* Timestamp of the future MG_EV_TIMER */
mg_event_handler_t proto_handler; /* Protocol-specific event handler */
void *proto_data; /* Protocol-specific data */
mg_event_handler_t handler; /* Event handler function */
@@ -1055,6 +1109,36 @@ enum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,
const char *init_js_file_name);
#endif
/*
* Schedule MG_EV_TIMER event to be delivered at `timestamp` time.
* `timestamp` is a UNIX time (a number of seconds since Epoch). It is
* `double` instead of `time_t` to allow for sub-second precision.
* Return the old timer value.
*
* Example: set connect timeout to 1.5 seconds:
*
* ```
* c = mg_connect(&mgr, "cesanta.com", ev_handler);
* mg_set_timer(c, mg_time() + 1.5);
* ...
*
* void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
* switch (ev) {
* case MG_EV_CONNECT:
* mg_set_timer(c, 0); // Clear connect timer
* break;
* case MG_EV_TIMER:
* log("Connect timeout");
* c->flags |= MG_F_CLOSE_IMMEDIATELY;
* break;
*/
double mg_set_timer(struct mg_connection *c, double timestamp);
/*
* A sub-second precision version of time().
*/
double mg_time();
#ifdef __cplusplus
}
#endif /* __cplusplus */
@@ -1112,6 +1196,12 @@ void mg_if_recved(struct mg_connection *nc, size_t len);
/* Deliver a POLL event to the connection. */
void mg_if_poll(struct mg_connection *nc, time_t now);
/* Deliver a TIMER event to the connection. */
void mg_if_timer(struct mg_connection *c, double now);
/* Perform interface-related connection initialization. Return 1 on success. */
int mg_if_create_conn(struct mg_connection *nc);
/* Perform interface-related cleanup on connection before destruction. */
void mg_if_destroy_conn(struct mg_connection *nc);
@@ -1226,7 +1316,7 @@ FILE *mg_fopen(const char *path, const char *mode);
int mg_open(const char *path, int flag, int mode);
#endif /* MG_DISABLE_FILESYSTEM */
#ifdef _WIN32
#if defined(_WIN32) && !defined(MG_ENABLE_THREADS)
#define MG_ENABLE_THREADS
#endif
@@ -1543,7 +1633,7 @@ void mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len);
* Send printf-formatted HTTP chunk.
* Functionality is similar to `mg_send_http_chunk()`.
*/
void mg_printf_http_chunk(struct mg_connection *, const char *, ...);
void mg_printf_http_chunk(struct mg_connection *nc, const char *fmt, ...);
/*
* Send response status line.
@@ -1580,7 +1670,7 @@ void mg_send_head(struct mg_connection *n, int status_code,
/*
* Send printf-formatted HTTP chunk, escaping HTML tags.
*/
void mg_printf_html_escape(struct mg_connection *, const char *, ...);
void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
/* Websocket opcodes, from http://tools.ietf.org/html/rfc6455 */
#define WEBSOCKET_OP_CONTINUE 0
@@ -1688,7 +1778,21 @@ size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
* of a fetched variable. If not found, 0 is returned. `buf` must be
* valid url-encoded buffer. If destination is too small, `-1` is returned.
*/
int mg_get_http_var(const struct mg_str *, const char *, char *dst, size_t);
int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst,
size_t dst_len);
/*
* Decode URL-encoded string.
*
* Source string is specified by (`src`, `src_len`), and destination is
* (`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then
* `+` character is decoded as a blank space character. This function
* guarantees to `\0`-terminate the destination. If destination is too small,
* then source string is partially decoded and `-1` is returned. Otherwise,
* a length of decoded string is returned, not counting final `\0`.
*/
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len,
int is_form_url_encoded);
/* Create Digest authentication header for client request. */
int mg_http_create_digest_auth_header(char *buf, size_t buf_len,
@@ -1703,18 +1807,24 @@ int mg_http_create_digest_auth_header(char *buf, size_t buf_len,
* Host headers. `extra_headers` is an extra HTTP headers to send, e.g.
* `"User-Agent: my-app\r\n"`.
* If `post_data` is NULL, then GET request is created. Otherwise, POST request
* is created with the specified POST data. Examples:
* is created with the specified POST data. Note that if the data being posted
* is a form submission, the `Content-Type` header should be set accordingly
* (see example below).
*
* Examples:
*
* [source,c]
* ----
* nc1 = mg_connect_http(mgr, ev_handler_1, "http://www.google.com", NULL,
* NULL);
* nc2 = mg_connect_http(mgr, ev_handler_1, "https://github.com", NULL, NULL);
* nc3 = mg_connect_http(mgr, ev_handler_1, "my_server:8000/form_submit/",
* NULL, "var_1=value_1&var_2=value_2");
* nc3 = mg_connect_http(
* mgr, ev_handler_1, "my_server:8000/form_submit/",
* "Content-Type: application/x-www-form-urlencoded\r\n",
* "var_1=value_1&var_2=value_2");
* ----
*/
struct mg_connection *mg_connect_http(struct mg_mgr *,
struct mg_connection *mg_connect_http(struct mg_mgr *mgr,
mg_event_handler_t event_handler,
const char *url,
const char *extra_headers,
@@ -1731,9 +1841,6 @@ struct mg_serve_http_opts {
/* List of index files. Default is "" */
const char *index_files;
/* Path to a HTTP requests log file. Leave as NULL to disable access log. */
const char *access_log_file;
/*
* Leave as NULL to disable authentication.
* To enable directory protection with authentication, set this to ".htpasswd"
@@ -1794,7 +1901,10 @@ struct mg_serve_http_opts {
/* DAV document root. If NULL, DAV requests are going to fail. */
const char *dav_document_root;
/* DAV passwords file. If NULL, DAV requests are going to fail. */
/*
* DAV passwords file. If NULL, DAV requests are going to fail.
* If passwords file is set to "-", then DAV auth is disabled.
*/
const char *dav_auth_file;
/* Glob pattern for the files to hide. */
@@ -1841,8 +1951,8 @@ struct mg_serve_http_opts {
* }
* ----
*/
void mg_serve_http(struct mg_connection *, struct http_message *,
struct mg_serve_http_opts);
void mg_serve_http(struct mg_connection *nc, struct http_message *hm,
struct mg_serve_http_opts opts);
#ifdef __cplusplus
}
@@ -1962,9 +2072,10 @@ int mg_rpc_create_error(char *buf, int len, struct mg_rpc_request *req,
* - #define JSON_RPC_INTERNAL_ERROR (-32603)
* - #define JSON_RPC_SERVER_ERROR (-32000)
*/
int mg_rpc_create_std_error(char *, int, struct mg_rpc_request *, int code);
int mg_rpc_create_std_error(char *buf, int len, struct mg_rpc_request *req,
int code);
typedef int (*mg_rpc_handler_t)(char *buf, int len, struct mg_rpc_request *);
typedef int (*mg_rpc_handler_t)(char *buf, int len, struct mg_rpc_request *req);
/*
* Dispatches a JSON-RPC request.
@@ -2108,13 +2219,13 @@ extern "C" {
* - MG_EV_MQTT_PUBCOMP
* - MG_EV_MQTT_SUBACK
*/
void mg_set_protocol_mqtt(struct mg_connection *);
void mg_set_protocol_mqtt(struct mg_connection *nc);
/* Send MQTT handshake. */
void mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id);
/* Send MQTT handshake with optional parameters. */
void mg_send_mqtt_handshake_opt(struct mg_connection *, const char *client_id,
void mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id,
struct mg_send_mqtt_handshake_opts);
/* Publish a message to a given topic. */
@@ -2135,34 +2246,35 @@ void mg_mqtt_unsubscribe(struct mg_connection *nc, char **topics,
void mg_mqtt_disconnect(struct mg_connection *nc);
/* Send a CONNACK command with a given `return_code`. */
void mg_mqtt_connack(struct mg_connection *, uint8_t);
void mg_mqtt_connack(struct mg_connection *nc, uint8_t return_code);
/* Send a PUBACK command with a given `message_id`. */
void mg_mqtt_puback(struct mg_connection *, uint16_t);
void mg_mqtt_puback(struct mg_connection *nc, uint16_t message_id);
/* Send a PUBREC command with a given `message_id`. */
void mg_mqtt_pubrec(struct mg_connection *, uint16_t);
void mg_mqtt_pubrec(struct mg_connection *nc, uint16_t message_id);
/* Send a PUBREL command with a given `message_id`. */
void mg_mqtt_pubrel(struct mg_connection *, uint16_t);
void mg_mqtt_pubrel(struct mg_connection *nc, uint16_t message_id);
/* Send a PUBCOMP command with a given `message_id`. */
void mg_mqtt_pubcomp(struct mg_connection *, uint16_t);
void mg_mqtt_pubcomp(struct mg_connection *nc, uint16_t message_id);
/*
* Send a SUBACK command with a given `message_id`
* and a sequence of granted QoSs.
*/
void mg_mqtt_suback(struct mg_connection *, uint8_t *, size_t, uint16_t);
void mg_mqtt_suback(struct mg_connection *nc, uint8_t *qoss, size_t qoss_len,
uint16_t message_id);
/* Send a UNSUBACK command with a given `message_id`. */
void mg_mqtt_unsuback(struct mg_connection *, uint16_t);
void mg_mqtt_unsuback(struct mg_connection *nc, uint16_t message_id);
/* Send a PINGREQ command. */
void mg_mqtt_ping(struct mg_connection *);
void mg_mqtt_ping(struct mg_connection *nc);
/* Send a PINGRESP command. */
void mg_mqtt_pong(struct mg_connection *);
void mg_mqtt_pong(struct mg_connection *nc);
/*
* Extract the next topic expression from a SUBSCRIBE command payload.
@@ -2171,8 +2283,8 @@ void mg_mqtt_pong(struct mg_connection *);
* Return the pos of the next topic expression or -1 when the list
* of topics is exhausted.
*/
int mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *, struct mg_str *,
uint8_t *, int);
int mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *msg,
struct mg_str *topic, uint8_t *qos, int pos);
#ifdef __cplusplus
}
@@ -2231,7 +2343,7 @@ struct mg_mqtt_broker {
};
/* Initialize a MQTT broker. */
void mg_mqtt_broker_init(struct mg_mqtt_broker *, void *);
void mg_mqtt_broker_init(struct mg_mqtt_broker *brk, void *user_data);
/*
* Process a MQTT broker message.
@@ -2259,7 +2371,7 @@ void mg_mqtt_broker_init(struct mg_mqtt_broker *, void *);
* Since only the MG_EV_ACCEPT message is processed by the listening socket,
* for most events the `user_data` will thus point to a `mg_mqtt_session`.
*/
void mg_mqtt_broker(struct mg_connection *, int, void *);
void mg_mqtt_broker(struct mg_connection *brk, int ev, void *data);
/*
* Iterate over all mqtt sessions connections. Example:
@@ -2269,8 +2381,8 @@ void mg_mqtt_broker(struct mg_connection *, int, void *);
* // Do something
* }
*/
struct mg_mqtt_session *mg_mqtt_next(struct mg_mqtt_broker *,
struct mg_mqtt_session *);
struct mg_mqtt_session *mg_mqtt_next(struct mg_mqtt_broker *brk,
struct mg_mqtt_session *s);
#ifdef __cplusplus
}
@@ -2333,7 +2445,7 @@ struct mg_dns_message {
};
struct mg_dns_resource_record *mg_dns_next_record(
struct mg_dns_message *, int, struct mg_dns_resource_record *);
struct mg_dns_message *msg, int query, struct mg_dns_resource_record *prev);
/*
* Parse the record data from a DNS resource record.
@@ -2346,20 +2458,23 @@ struct mg_dns_resource_record *mg_dns_next_record(
*
* TODO(mkm): MX
*/
int mg_dns_parse_record_data(struct mg_dns_message *,
struct mg_dns_resource_record *, void *, size_t);
int mg_dns_parse_record_data(struct mg_dns_message *msg,
struct mg_dns_resource_record *rr, void *data,
size_t data_len);
/*
* Send a DNS query to the remote end.
*/
void mg_send_dns_query(struct mg_connection *, const char *, int);
void mg_send_dns_query(struct mg_connection *nc, const char *name,
int query_type);
/*
* Insert a DNS header to an IO buffer.
*
* Return number of bytes inserted.
*/
int mg_dns_insert_header(struct mbuf *, size_t, struct mg_dns_message *);
int mg_dns_insert_header(struct mbuf *io, size_t pos,
struct mg_dns_message *msg);
/*
* Append already encoded body from an existing message.
@@ -2369,7 +2484,7 @@ int mg_dns_insert_header(struct mbuf *, size_t, struct mg_dns_message *);
*
* Return number of appened bytes.
*/
int mg_dns_copy_body(struct mbuf *, struct mg_dns_message *);
int mg_dns_copy_body(struct mbuf *io, struct mg_dns_message *msg);
/*
* Encode and append a DNS resource record to an IO buffer.
@@ -2387,11 +2502,12 @@ int mg_dns_copy_body(struct mbuf *, struct mg_dns_message *);
*
* Return the number of bytes appened or -1 in case of error.
*/
int mg_dns_encode_record(struct mbuf *, struct mg_dns_resource_record *,
const char *, size_t, const void *, size_t);
int mg_dns_encode_record(struct mbuf *io, struct mg_dns_resource_record *rr,
const char *name, size_t nlen, const void *rdata,
size_t rlen);
/* Low-level: parses a DNS response. */
int mg_parse_dns(const char *, int, struct mg_dns_message *);
int mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg);
/*
* Uncompress a DNS compressed name.
@@ -2406,8 +2522,8 @@ int mg_parse_dns(const char *, int, struct mg_dns_message *);
* If `dst_len` is 0 `dst` can be NULL.
* Return the uncompressed name length.
*/
size_t mg_dns_uncompress_name(struct mg_dns_message *, struct mg_str *, char *,
int);
size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name,
char *dst, int dst_len);
/*
* Attach built-in DNS event handler to the given listening connection.
@@ -2421,7 +2537,7 @@ size_t mg_dns_uncompress_name(struct mg_dns_message *, struct mg_str *, char *,
* https://github.com/cesanta/mongoose/tree/master/examples/captive_dns_server[captive_dns_server]
* example on how to handle DNS request and send DNS reply.
*/
void mg_set_protocol_dns(struct mg_connection *);
void mg_set_protocol_dns(struct mg_connection *nc);
#ifdef __cplusplus
}
@@ -2485,7 +2601,8 @@ struct mg_dns_reply {
* mg_dns_send_reply(nc, &reply);
* -----
*/
struct mg_dns_reply mg_dns_create_reply(struct mbuf *, struct mg_dns_message *);
struct mg_dns_reply mg_dns_create_reply(struct mbuf *io,
struct mg_dns_message *msg);
/*
* Append a DNS reply record to the IO buffer and to the DNS message.
@@ -2495,8 +2612,10 @@ struct mg_dns_reply mg_dns_create_reply(struct mbuf *, struct mg_dns_message *);
*
* Returns -1 on error.
*/
int mg_dns_reply_record(struct mg_dns_reply *, struct mg_dns_resource_record *,
const char *, int, int, const void *, size_t);
int mg_dns_reply_record(struct mg_dns_reply *reply,
struct mg_dns_resource_record *question,
const char *name, int rtype, int ttl, const void *rdata,
size_t rdata_len);
/*
* Send a DNS reply through a connection.
@@ -2510,7 +2629,7 @@ int mg_dns_reply_record(struct mg_dns_reply *, struct mg_dns_resource_record *,
* Once sent, the IO buffer will be trimmed unless the reply IO buffer
* is the connection's send buffer and the connection is not in UDP mode.
*/
void mg_dns_send_reply(struct mg_connection *, struct mg_dns_reply *);
void mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r);
#ifdef __cplusplus
}
@@ -2535,7 +2654,15 @@ void mg_dns_send_reply(struct mg_connection *, struct mg_dns_reply *);
extern "C" {
#endif /* __cplusplus */
typedef void (*mg_resolve_callback_t)(struct mg_dns_message *, void *);
enum mg_resolve_err {
MG_RESOLVE_OK = 0,
MG_RESOLVE_NO_ANSWERS = 1,
MG_RESOLVE_EXCEEDED_RETRY_COUNT = 2,
MG_RESOLVE_TIMEOUT = 3
};
typedef void (*mg_resolve_callback_t)(struct mg_dns_message *dns_message,
void *user_data, enum mg_resolve_err);
/* Options for `mg_resolve_async_opt`. */
struct mg_resolve_async_opts {
@@ -2544,11 +2671,12 @@ struct mg_resolve_async_opts {
int timeout; /* in seconds; defaults to 5 if zero */
int accept_literal; /* pseudo-resolve literal ipv4 and ipv6 addrs */
int only_literal; /* only resolves literal addrs; sync cb invocation */
struct mg_connection **dns_conn; /* return DNS connection */
};
/* See `mg_resolve_async_opt()` */
int mg_resolve_async(struct mg_mgr *, const char *, int, mg_resolve_callback_t,
void *data);
int mg_resolve_async(struct mg_mgr *mgr, const char *name, int query,
mg_resolve_callback_t cb, void *data);
/*
* Resolved a DNS name asynchronously.
@@ -2571,8 +2699,8 @@ int mg_resolve_async(struct mg_mgr *, const char *, int, mg_resolve_callback_t,
* mg_dns_parse_record_data(msg, rr, &ina, sizeof(ina));
* ----
*/
int mg_resolve_async_opt(struct mg_mgr *, const char *, int,
mg_resolve_callback_t, void *data,
int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
mg_resolve_callback_t cb, void *data,
struct mg_resolve_async_opts opts);
/*