mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-29 12:41:03 +00:00
Refactor Mongoose documentation
PUBLISHED_FROM=e9a4e5c7b4a1d03b93a2a79e29de19e60e919929
This commit is contained in:
1 parent
4120f953c7
commit
12437fd7fe
87 files changed
+977
-332
No files matched your search
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: Disabling flags
|
||||
---
|
||||
|
||||
- `MG_DISABLE_HTTP_WEBSOCKET` disable HTTP + WebSocket protocol support
|
||||
- `MG_DISABLE_HTTP_DIGEST_AUTH` disable HTTP Digest (MD5) authorisation support
|
||||
- `MG_DISABLE_MQTT` disable MQTT support
|
||||
- `MG_DISABLE_SHA1` disable SHA1 support (used by WebSocket)
|
||||
- `MG_DISABLE_MD5` disable MD5 support (used by HTTP auth)
|
||||
- `MG_DISABLE_SOCKETPAIR` disable `mg_broadcast()` API
|
||||
- `MG_DISABLE_HTTP_KEEP_ALIVE` useful for embedded systems to save resources
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: Enabling flags
|
||||
---
|
||||
|
||||
- `MG_ENABLE_SSL` Enable OpenSSL support
|
||||
- `MG_ENABLE_IPV6` Enable IPV6 support
|
||||
- `MG_ENABLE_THREADS` enable `mg_start_thread()` API
|
||||
- `MG_ENABLE_MQTT_BROKER` enable MQTT broker
|
||||
- `MG_ENABLE_DNS_SERVER` enable DNS server
|
||||
- `MG_ENABLE_COAP` enable CoAP protocol
|
||||
- `MG_ENABLE_GETADDRINFO` enable `getaddrinfo()` in `mg_resolve2()`
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: Build Options
|
||||
items:
|
||||
- { type: file, name: enabling-flags.md }
|
||||
- { type: file, name: disabling-flags.md }
|
||||
- { type: file, name: platform-spec.md }
|
||||
- { type: file, name: tunables.md }
|
||||
---
|
||||
|
||||
Mongoose source code ships in a single .c file that contains functionality
|
||||
for all supported protocols (modules). Modules can be disabled at compile
|
||||
time which reduces the executable's size. That can be done by setting preprocessor
|
||||
flags. Also, some preprocessor flags can be used to tune internal Mongoose
|
||||
parameters.
|
||||
|
||||
To set a preprocessor flag during compile time, use the `-D <PREPROCESSOR_FLAG>`
|
||||
compiler option. For example, to disable both MQTT and CoAP,
|
||||
compile the application `my_app.c` like this (assumed UNIX system):
|
||||
|
||||
```
|
||||
$ cc my_app.c mongoose.c -D MG_DISABLE_MQTT -D MG_DISABLE_COAP
|
||||
```
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Platform specific
|
||||
---
|
||||
|
||||
Mongoose tries to detect the target platform whenever possible, but in some cases you have
|
||||
to explicitly declare some peculiarities of your target, such as:
|
||||
|
||||
- `MG_LWIP`: use LWIP networking stack
|
||||
- `MG_CC3200`: enable workarounds for the TI CC3200 target.
|
||||
- `MG_ESP8266`: enable workarounds for the ESP8266 target, add `RTOS_SDK` to specify the RTOS SDK flavour.
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: Tunables
|
||||
---
|
||||
|
||||
- `MG_MALLOC`, `MG_CALLOC`, `MG_REALLOC`, `MG_FREE` allow you to a use custom
|
||||
memory allocator, e.g. `-DMG_MALLOC=my_malloc`
|
||||
- `MG_USE_READ_WRITE` when set replaces calls to `recv` with `read` and `send` with `write`,
|
||||
thus enabling to add any kind of file descriptor (files, serial devices) to an event manager.
|
||||
- `MG_SSL_CRYPTO_MODERN`, `MG_SSL_CRYPTO_OLD` - choose either "Modern" or "Old" ciphers
|
||||
instead of the default "Intermediate" setting.
|
||||
See [this article](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations) for details.
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: Design Concept
|
||||
---
|
||||
|
||||
Mongoose has three basic data structures:
|
||||
|
||||
- `struct mg_mgr` is an event manager that holds all active connections
|
||||
- `struct mg_connection` describes a connection
|
||||
- `struct mbuf` describes data buffer (received or sent data)
|
||||
|
||||
Connections could be either *listening*, *outbound* or *inbound*. Outbound
|
||||
connections are created by the `mg_connect()` call. Listening connections are
|
||||
created by the `mg_bind()` call. Inbound connections are those accepted by a
|
||||
listening connection. Each connection is described by the `struct mg_connection`
|
||||
structure, which has a number of fields like socket, event handler function,
|
||||
send/receive buffer, flags, etc.
|
||||
|
||||
An application that uses mongoose should follow a standard pattern of
|
||||
event-driven application:
|
||||
|
||||
1. declare and initialise event manager:
|
||||
|
||||
```c
|
||||
struct mg_mgr mgr;
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
```
|
||||
2. Create connections. For example, a server application should create
|
||||
listening connections:
|
||||
|
||||
```c
|
||||
struct mg_connection *c = mg_bind(&mgr, "80", ev_handler_function);
|
||||
mg_set_protocol_http_websocket(c);
|
||||
```
|
||||
|
||||
3. create an event loop by calling `mg_mgr_poll()` in a loop:
|
||||
|
||||
```c
|
||||
for (;;) {
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
}
|
||||
```
|
||||
|
||||
`mg_mgr_poll()` iterates over all sockets, accepts new connections, sends and
|
||||
receives data, closes connections and calls event handler functions for the
|
||||
respective events. For the full example, see
|
||||
[Usage Example](#/overview/usage-example.md/)
|
||||
which implements TCP echo server.
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Connection flags
|
||||
---
|
||||
|
||||
Each connection has a `flags` bit field. Some flags are set by Mongoose, for
|
||||
example if a user creates an outbound UDP connection using a `udp://1.2.3.4:5678`
|
||||
address, Mongoose is going to set a `MG_F_UDP` flag for that connection. Other
|
||||
flags are meant to be set only by the user event handler to tell Mongoose how to
|
||||
behave. Below is a list of connection flags that are meant to be set by event
|
||||
handlers:
|
||||
|
||||
* `MG_F_FINISHED_SENDING_DATA` tells Mongoose that all data has been appended
|
||||
to the `send_mbuf`. As soon as Mongoose sends it to the socket, the
|
||||
connection will be closed.
|
||||
* `MG_F_BUFFER_BUT_DONT_SEND` tells Mongoose to append data to the `send_mbuf`
|
||||
but hold on sending it, because the data will be modified later and then will
|
||||
be sent by clearing the `MG_F_BUFFER_BUT_DONT_SEND` flag.
|
||||
* `MG_F_CLOSE_IMMEDIATELY` tells Mongoose to close the connection immediately,
|
||||
usually after an error.
|
||||
* `MG_F_USER_1`, `MG_F_USER_2`, `MG_F_USER_3`, `MG_F_USER_4` could be used by a
|
||||
developer to store an application-specific state.
|
||||
|
||||
Flags below are set by Mongoose:
|
||||
|
||||
* `MG_F_SSL_HANDSHAKE_DONE` SSL only, set when SSL handshake is done.
|
||||
* `MG_F_CONNECTING` set when the connection is in connecting state after
|
||||
`mg_connect()` call but connect did not finish yet.
|
||||
* `MG_F_LISTENING` set for all listening connections.
|
||||
* `MG_F_UDP` set if the connection is UDP.
|
||||
* `MG_F_IS_WEBSOCKET` set if the connection is a WebSocket connection.
|
||||
* `MG_F_WEBSOCKET_NO_DEFRAG` should be set by a user if the user wants to switch
|
||||
off automatic WebSocket frame defragmentation.
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: Event handler function
|
||||
---
|
||||
|
||||
Each connection has an event handler function associated with it. That function
|
||||
must be implemented by the user. Event handler is the key element of the Mongoose
|
||||
application, since it defines the application's behaviour. This is what an event
|
||||
handler function looks like:
|
||||
|
||||
```c
|
||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
switch (ev) {
|
||||
/* Event handler code that defines behavior of the connection */
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `struct mg_connection *nc`: Connection that has received an event.
|
||||
- `int ev`: Event number, defined in `mongoose.h`. For example, when data
|
||||
arrives on an inbound connection, `ev` would be `MG_EV_RECV`.
|
||||
- `void *ev_data`: This pointer points to the event-specific data, and it has
|
||||
a different meaning for different events. For example, for an `MG_EV_RECV` event,
|
||||
`ev_data` is an `int *` pointer, pointing to the number of bytes received
|
||||
from the remote peer and saved into the receive IO buffer. The exact meaning of
|
||||
`ev_data` is described for each event. Protocol-specific events usually have
|
||||
`ev_data` pointing to structures that hold protocol-specific information.
|
||||
|
||||
NOTE: `struct mg_connection` has `void *user_data` which is a placeholder for
|
||||
application-specific data. Mongoose does not use that pointer. Event handler
|
||||
can store any kind of information there.
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
title: Events
|
||||
---
|
||||
|
||||
Mongoose accepts incoming connections, reads and writes data and calls
|
||||
specified event handlers for each connection when appropriate. A typical event
|
||||
sequence is this:
|
||||
|
||||
- For an outbound connection: `MG_EV_CONNECT` -> (`MG_EV_RECV`, `MG_EV_SEND`,
|
||||
`MG_EV_POLL` ...) -> `MG_EV_CLOSE`
|
||||
- For an inbound connection: `MG_EV_ACCEPT` -> (`MG_EV_RECV`, `MG_EV_SEND`,
|
||||
`MG_EV_POLL` ...) -> `MG_EV_CLOSE`
|
||||
|
||||
|
||||
Below is a list of core events triggered by Mongoose (note that each protocol
|
||||
triggers protocol-specific events in addition to the core ones):
|
||||
|
||||
- `MG_EV_ACCEPT`: sent when a new server connection is accepted by a listening
|
||||
connection. `void *ev_data` is `union socket_address` of the remote peer.
|
||||
|
||||
- `MG_EV_CONNECT`: sent when a new outbound connection created by `mg_connect()`
|
||||
either failed or succeeded. `void *ev_data` is `int *success`. If `success`
|
||||
is 0, then the connection has been established, otherwise it contains an error code.
|
||||
See `mg_connect_opt()` function for code example.
|
||||
|
||||
- `MG_EV_RECV`: New data is received and appended to the end of `recv_mbuf`.
|
||||
`void *ev_data` is `int *num_received_bytes`. Typically, event handler should
|
||||
check received data in `nc->recv_mbuf`, discard processed data by calling
|
||||
`mbuf_remove()`, set connection flags `nc->flags` if necessary (see `struct
|
||||
mg_connection`) and write data the remote peer by output functions like
|
||||
`mg_send()`.
|
||||
|
||||
**WARNING**: Mongoose uses `realloc()` to expand the receive buffer. It is
|
||||
the user's responsibility to discard processed data from the beginning of the receive
|
||||
buffer, note the `mbuf_remove()` call in the example above.
|
||||
|
||||
- `MG_EV_SEND`: Mongoose has written data to the remote peer and discarded
|
||||
written data from the `mg_connection::send_mbuf`. `void *ev_data` is `int
|
||||
*num_sent_bytes`.
|
||||
|
||||
**NOTE**: Mongoose output functions only append data to the
|
||||
`mg_connection::send_mbuf`. They do not do any socket writes. An actual IO
|
||||
is done by `mg_mgr_poll()`. An `MG_EV_SEND` event is just a notification about
|
||||
an IO has been done.
|
||||
|
||||
- `MG_EV_POLL`: Sent to all connections on each invocation of `mg_mgr_poll()`.
|
||||
This event could be used to do any housekeeping, for example check whether a
|
||||
certain timeout has expired and closes the connection or send heartbeat
|
||||
message, etc.
|
||||
|
||||
- `MG_EV_TIMER`: Sent to the connection if `mg_set_timer()` was called.
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: Overview
|
||||
items:
|
||||
# - { name: usage-example.md }
|
||||
- { name: concept.md }
|
||||
- { name: mbufs.md }
|
||||
- { name: event-handler.md }
|
||||
- { name: events.md }
|
||||
- { name: conn-flags.md }
|
||||
- { name: build-options }
|
||||
- { name: usage-example.md }
|
||||
---
|
||||
|
||||
Mongoose is a networking library written in C.
|
||||
It is a swiss army knife for embedded network programming.
|
||||
It implements event-driven non-blocking APIs for TCP, UDP, HTTP,
|
||||
WebSocket, CoAP, MQTT for client and server mode.
|
||||
Features include:
|
||||
|
||||
- Cross-platform: works on Linux/UNIX, MacOS, QNX, eCos, Windows, Android,
|
||||
iPhone, FreeRTOS
|
||||
- Native support for [PicoTCP embedded TCP/IP stack](http://www.picotcp.com),
|
||||
[LWIP embedded TCP/IP stack](https://en.wikipedia.org/wiki/LwIP)
|
||||
- Works on a variety of embedded boards: TI CC3200, TI MSP430, STM32, ESP8266;
|
||||
on all Linux-based boards like Raspberry PI, BeagleBone, etc
|
||||
- Single-threaded, asynchronous, non-blocking core with simple event-based API
|
||||
- Built-in protocols:
|
||||
- plain TCP, plain UDP, SSL/TLS (one-way or two-way), client and server
|
||||
- HTTP client and server
|
||||
- WebSocket client and server
|
||||
- MQTT client and server
|
||||
- CoAP client and server
|
||||
- DNS client and server
|
||||
- asynchronous DNS resolver
|
||||
- Tiny static and run-time footprint
|
||||
- Source code is both ISO C and ISO C++ compliant
|
||||
- Very easy to integrate: just copy
|
||||
[mongoose.c](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.c) and
|
||||
[mongoose.h](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.h)
|
||||
files to your build tree
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
title: Memory buffers
|
||||
---
|
||||
|
||||
Each connection has a send and receive buffer, `struct mg_connection::send_mbuf`
|
||||
and `struct mg_connection::recv_mbuf` respectively. When data arrives,
|
||||
Mongoose appends received data to the `recv_mbuf` and triggers an `MG_EV_RECV`
|
||||
event. The user may send data back by calling one of the output functions, like
|
||||
`mg_send()` or `mg_printf()`. Output functions append data to the `send_mbuf`.
|
||||
When Mongoose successfully writes data to the socket, it discards data from
|
||||
`struct mg_connection::send_mbuf` and sends an `MG_EV_SEND` event. When the connection
|
||||
is closed, an `MG_EV_CLOSE` event is sent.
|
||||
|
||||

|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: Example - TCP echo server
|
||||
---
|
||||
|
||||
- Copy `mongoose.c` and `mongoose.h` to your build tree
|
||||
- Write code that uses the Mongoose API, e.g. in `my_app.c`
|
||||
- Compile application: `$ cc my_app.c mongoose.c`
|
||||
|
||||
```c
|
||||
#include "mongoose.h" // Include Mongoose API definitions
|
||||
|
||||
// Define an event handler function
|
||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
struct mbuf *io = &nc->recv_mbuf;
|
||||
|
||||
switch (ev) {
|
||||
case MG_EV_RECV:
|
||||
// This event handler implements simple TCP echo server
|
||||
mg_send(nc, io->buf, io->len); // Echo received data back
|
||||
mbuf_remove(io, io->len); // Discard data from recv buffer
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
|
||||
mg_mgr_init(&mgr, NULL); // Initialize event manager object
|
||||
|
||||
// Note that many connections can be added to a single event manager
|
||||
// Connections can be created at any point, e.g. in event handler function
|
||||
mg_bind(&mgr, "1234", ev_handler); // Create listening connection and add it to the event manager
|
||||
|
||||
for (;;) { // Start infinite event loop
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
}
|
||||
|
||||
mg_mgr_free(&mgr);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Reference in new issue
Block a user