mirror of
https://github.com/cesanta/mongoose.git
synced 2025-08-06 13:37:34 +08:00
commit
34eb3f1e66
22
README.md
22
README.md
@ -8,7 +8,7 @@ used by vast number of open source and
|
||||
commercial products - it even runs on the International Space station!
|
||||
Mongoose makes embedded network programming fast, robust, and easy.
|
||||
|
||||
- [Download Mongoose Source Code here](https://www.cesanta.com)
|
||||
- [Download Mongoose Source Code here](https://www.cesanta.com/download.html)
|
||||
|
||||
Looking for a complete IoT firmware solution?
|
||||
|
||||
@ -17,9 +17,9 @@ Check out [Mongoose OS](https://mongoose-os.com) - open source embedded operatin
|
||||
# Support
|
||||
- [Study mongoose example code](https://github.com/cesanta/mongoose/tree/master/examples)
|
||||
- [Read User Guide and API reference](https://docs.cesanta.com/mongoose)
|
||||
- [Support Forum - ask your technical questions here] (http://forum.cesanta.com/index.php?p=/categories/mongoose)
|
||||
- [Commercial licensing and support available] (https://www.cesanta.com/services-support)
|
||||
- [Check our latest releases] (https://github.com/cesanta/mongoose/releases)
|
||||
- [Support Forum - ask your technical questions here](https://forum.mongoose-os.com/categories/mongoose)
|
||||
- [Commercial licensing and support available](https://www.cesanta.com/licensing.html)
|
||||
- [Check our latest releases](https://github.com/cesanta/mongoose/releases)
|
||||
|
||||
# Features
|
||||
|
||||
@ -47,7 +47,7 @@ Check out [Mongoose OS](https://mongoose-os.com) - open source embedded operatin
|
||||
|
||||
Mongoose is released under Commercial and [GNU GPL v.2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) open source licenses.
|
||||
|
||||
Commercial Projects: [Contact us for commercial license.] (https://www.cesanta.com/contact)
|
||||
Commercial Projects: [Contact us for commercial license.](https://www.cesanta.com/contact.html)
|
||||
|
||||
# Dashboard Example
|
||||
|
||||
@ -55,18 +55,14 @@ Mongoose is often used to implement device dashboards and real-time
|
||||
data exchange over Websocket. Here is a dashboard example that illustrates
|
||||
the functionality:
|
||||
|
||||

|
||||

|
||||
|
||||
[Developing a new product? Contact us today to discuss how Mongoose can help.
|
||||
](https://www.cesanta.com/contact)
|
||||
[Developing a new product? Contact us today to discuss how Mongoose can help.](https://www.cesanta.com/contact.html)
|
||||
|
||||
# Contributions
|
||||
|
||||
To submit contributions, sign
|
||||
[Cesanta CLA](https://docs.cesanta.com/contributors_la.shtml)
|
||||
To submit contributions, sign [Cesanta CLA](https://cesanta.com/cla.html)
|
||||
and send GitHub pull request. You retain the copyright on your contributions.
|
||||
|
||||
# Looking for a pre-compiled Mongoose web server Windows or Mac binary?
|
||||
- [Download pre-compiled Mongoose web server binary.](https://www.cesanta.com/products/binary)
|
||||
|
||||
[](https://github.com/cesanta/mongoose)
|
||||
- [Download pre-compiled Mongoose web server binary.](https://www.cesanta.com/binary.html)
|
||||
|
@ -7,5 +7,5 @@ signature: |
|
||||
---
|
||||
|
||||
Frees the memory allocated for options.
|
||||
If the cm paramater doesn't contain any option it does nothing.
|
||||
If the cm parameter doesn't contain any option it does nothing.
|
||||
|
||||
|
@ -21,5 +21,5 @@ This function doesn't update the `name` and `rdata` pointers in the `rr`
|
||||
struct because they might be invalidated as soon as the IO buffer grows
|
||||
again.
|
||||
|
||||
Returns the number of bytes appened or -1 in case of error.
|
||||
Returns the number of bytes appended or -1 in case of error.
|
||||
|
||||
|
@ -11,6 +11,7 @@ items:
|
||||
- { name: mg_send_websocket_handshake.md }
|
||||
- { name: mg_send_websocket_handshake2.md }
|
||||
- { name: mg_send_websocket_handshake3.md }
|
||||
- { name: mg_send_websocket_handshake3v.md }
|
||||
- { name: mg_set_protocol_http_websocket.md }
|
||||
- { name: mg_url_decode.md }
|
||||
- { name: struct_http_message.md }
|
||||
|
@ -4,9 +4,8 @@ decl_name: "mg_connect_ws"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
struct mg_connection *mg_connect_ws(struct mg_mgr *mgr,
|
||||
mg_event_handler_t event_handler,
|
||||
const char *url, const char *protocol,
|
||||
const char *extra_headers);
|
||||
MG_CB(mg_event_handler_t event_handler,
|
||||
void *user_data);
|
||||
---
|
||||
|
||||
Helper function that creates an outbound WebSocket connection.
|
||||
|
@ -3,11 +3,8 @@ title: "mg_connect_ws_opt()"
|
||||
decl_name: "mg_connect_ws_opt"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
struct mg_connection *mg_connect_ws_opt(struct mg_mgr *mgr,
|
||||
mg_event_handler_t ev_handler,
|
||||
struct mg_connect_opts opts,
|
||||
const char *url, const char *protocol,
|
||||
const char *extra_headers);
|
||||
struct mg_connection *mg_connect_ws_opt(
|
||||
struct mg_mgr *mgr, MG_CB(mg_event_handler_t ev_handler, void *user_data);
|
||||
---
|
||||
|
||||
Helper function that creates an outbound WebSocket connection
|
||||
|
@ -9,5 +9,6 @@ signature: |
|
||||
|
||||
Sends multiple websocket frames.
|
||||
|
||||
Like `mg_send_websocket_frame()`, but composes a frame from multiple buffers.
|
||||
Like `mg_send_websocket_frame()`, but composes a frame from multiple
|
||||
*buffers.
|
||||
|
||||
|
17
docs/c-api/http.h/mg_send_websocket_handshake3v.md
Normal file
17
docs/c-api/http.h/mg_send_websocket_handshake3v.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
title: "mg_send_websocket_handshake3v()"
|
||||
decl_name: "mg_send_websocket_handshake3v"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
void mg_send_websocket_handshake3v(struct mg_connection *nc,
|
||||
const struct mg_str path,
|
||||
const struct mg_str host,
|
||||
const struct mg_str protocol,
|
||||
const struct mg_str extra_headers,
|
||||
const struct mg_str user,
|
||||
const struct mg_str pass);
|
||||
---
|
||||
|
||||
Same as mg_send_websocket_handshake3 but with strings not necessarily
|
||||
NUL-temrinated
|
||||
|
@ -13,6 +13,7 @@ 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 NUL-terminate the destination. If destination is too small,
|
||||
then the source string is partially decoded and `-1` is returned. Otherwise,
|
||||
then the source string is partially decoded and `-1` is returned.
|
||||
*Otherwise,
|
||||
a length of the decoded string is returned, not counting final NUL.
|
||||
|
||||
|
@ -5,6 +5,7 @@ symbol_kind: "struct"
|
||||
signature: |
|
||||
struct http_message {
|
||||
struct mg_str message; /* Whole message: request line + headers + body */
|
||||
struct mg_str body; /* Message body. 0-length for requests with no body */
|
||||
|
||||
/* HTTP Request line (or HTTP response line) */
|
||||
struct mg_str method; /* "GET" */
|
||||
@ -28,9 +29,6 @@ signature: |
|
||||
/* Headers */
|
||||
struct mg_str header_names[MG_MAX_HTTP_HEADERS];
|
||||
struct mg_str header_values[MG_MAX_HTTP_HEADERS];
|
||||
|
||||
/* Message body */
|
||||
struct mg_str body; /* Zero-length for requests with no body */
|
||||
};
|
||||
---
|
||||
|
||||
|
@ -3,11 +3,9 @@ title: "mg_connect_http()"
|
||||
decl_name: "mg_connect_http"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
struct mg_connection *mg_connect_http(struct mg_mgr *mgr,
|
||||
mg_event_handler_t event_handler,
|
||||
const char *url,
|
||||
const char *extra_headers,
|
||||
const char *post_data);
|
||||
struct mg_connection *mg_connect_http(
|
||||
struct mg_mgr *mgr,
|
||||
MG_CB(mg_event_handler_t event_handler, void *user_data);
|
||||
---
|
||||
|
||||
Helper function that creates an outbound HTTP connection.
|
||||
|
@ -3,12 +3,8 @@ title: "mg_connect_http_opt()"
|
||||
decl_name: "mg_connect_http_opt"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
struct mg_connection *mg_connect_http_opt(struct mg_mgr *mgr,
|
||||
mg_event_handler_t ev_handler,
|
||||
struct mg_connect_opts opts,
|
||||
const char *url,
|
||||
const char *extra_headers,
|
||||
const char *post_data);
|
||||
struct mg_connection *mg_connect_http_opt(
|
||||
struct mg_mgr *mgr, MG_CB(mg_event_handler_t ev_handler, void *user_data);
|
||||
---
|
||||
|
||||
Helper function that creates an outbound HTTP connection.
|
||||
|
@ -3,6 +3,7 @@ title: "Server API reference"
|
||||
symbol_kind: "intro"
|
||||
decl_name: "http_server.h"
|
||||
items:
|
||||
- { name: mg_check_digest_auth.md }
|
||||
- { name: mg_file_upload_handler.md }
|
||||
- { name: mg_get_http_basic_auth.md }
|
||||
- { name: mg_get_http_header.md }
|
||||
|
17
docs/c-api/http_server.h/mg_check_digest_auth.md
Normal file
17
docs/c-api/http_server.h/mg_check_digest_auth.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
title: "mg_check_digest_auth()"
|
||||
decl_name: "mg_check_digest_auth"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
int mg_check_digest_auth(struct mg_str method, struct mg_str uri,
|
||||
struct mg_str username, struct mg_str cnonce,
|
||||
struct mg_str response, struct mg_str qop,
|
||||
struct mg_str nc, struct mg_str nonce,
|
||||
struct mg_str auth_domain, FILE *fp);
|
||||
---
|
||||
|
||||
Authenticates given response params against an opened password file.
|
||||
Returns 1 if authenticated, 0 otherwise.
|
||||
|
||||
It's used by mg_http_check_digest_auth().
|
||||
|
@ -4,7 +4,8 @@ decl_name: "mg_file_upload_handler"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
|
||||
mg_fu_fname_fn local_name_fn);
|
||||
mg_fu_fname_fn local_name_fn
|
||||
MG_UD_ARG(void *user_data);
|
||||
---
|
||||
|
||||
File upload handler.
|
||||
|
@ -12,5 +12,6 @@ Fetches a HTTP form variable.
|
||||
Fetches a variable `name` from a `buf` into a buffer specified by `dst`,
|
||||
`dst_len`. The destination is always zero-terminated. Returns the length 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.
|
||||
url-encoded buffer. If destination is too small or an error occured,
|
||||
negative number is returned.
|
||||
|
||||
|
@ -12,7 +12,7 @@ Sends a redirect response.
|
||||
`status_code` should be either 301 or 302 and `location` point to the
|
||||
new location.
|
||||
If `extra_headers` is not empty, then `extra_headers` are also sent
|
||||
after the reponse line. `extra_headers` must NOT end end with new line.
|
||||
after the response line. `extra_headers` must NOT end end with new line.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -4,7 +4,8 @@ decl_name: "mg_register_http_endpoint"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,
|
||||
mg_event_handler_t handler);
|
||||
MG_CB(mg_event_handler_t handler,
|
||||
void *user_data);
|
||||
---
|
||||
|
||||
Registers a callback for a specified http endpoint
|
||||
@ -20,7 +21,7 @@ static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
}
|
||||
|
||||
static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
static void handle_hello2(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
(void) ev; (void) ev_data;
|
||||
mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello2]");
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
|
@ -9,7 +9,7 @@ signature: |
|
||||
Sends buffer `buf` of size `len` to the client using chunked HTTP encoding.
|
||||
This function sends the buffer size as hex number + newline first, then
|
||||
the buffer itself, then the newline. For example,
|
||||
`mg_send_http_chunk(nc, "foo", 3)` whill append the `3\r\nfoo\r\n` string
|
||||
`mg_send_http_chunk(nc, "foo", 3)` will append the `3\r\nfoo\r\n` string
|
||||
to the `nc->send_mbuf` output IO buffer.
|
||||
|
||||
NOTE: The HTTP header "Transfer-Encoding: chunked" should be sent prior to
|
||||
|
@ -9,7 +9,7 @@ signature: |
|
||||
|
||||
Sends the response status line.
|
||||
If `extra_headers` is not NULL, then `extra_headers` are also sent
|
||||
after the reponse line. `extra_headers` must NOT end end with new line.
|
||||
after the response line. `extra_headers` must NOT end end with new line.
|
||||
Example:
|
||||
|
||||
mg_send_response_line(nc, 200, "Access-Control-Allow-Origin: *");
|
||||
|
@ -5,6 +5,7 @@ decl_name: "mqtt.h"
|
||||
items:
|
||||
- { name: mg_mqtt_connack.md }
|
||||
- { name: mg_mqtt_disconnect.md }
|
||||
- { name: mg_mqtt_match_topic_expression.md }
|
||||
- { name: mg_mqtt_next_subscribe_topic.md }
|
||||
- { name: mg_mqtt_ping.md }
|
||||
- { name: mg_mqtt_pong.md }
|
||||
@ -17,6 +18,7 @@ items:
|
||||
- { name: mg_mqtt_subscribe.md }
|
||||
- { name: mg_mqtt_unsuback.md }
|
||||
- { name: mg_mqtt_unsubscribe.md }
|
||||
- { name: mg_mqtt_vmatch_topic_expression.md }
|
||||
- { name: mg_send_mqtt_handshake.md }
|
||||
- { name: mg_send_mqtt_handshake_opt.md }
|
||||
- { name: mg_set_protocol_mqtt.md }
|
||||
|
12
docs/c-api/mqtt.h/mg_mqtt_match_topic_expression.md
Normal file
12
docs/c-api/mqtt.h/mg_mqtt_match_topic_expression.md
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
title: "mg_mqtt_match_topic_expression()"
|
||||
decl_name: "mg_mqtt_match_topic_expression"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
int mg_mqtt_match_topic_expression(struct mg_str exp, struct mg_str topic);
|
||||
---
|
||||
|
||||
Matches a topic against a topic expression
|
||||
|
||||
Returns 1 if it matches; 0 otherwise.
|
||||
|
11
docs/c-api/mqtt.h/mg_mqtt_vmatch_topic_expression.md
Normal file
11
docs/c-api/mqtt.h/mg_mqtt_vmatch_topic_expression.md
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
title: "mg_mqtt_vmatch_topic_expression()"
|
||||
decl_name: "mg_mqtt_vmatch_topic_expression"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
int mg_mqtt_vmatch_topic_expression(const char *exp, struct mg_str topic);
|
||||
---
|
||||
|
||||
Same as `mg_mqtt_match_topic_expression()`, but takes `exp` as a
|
||||
NULL-terminated string.
|
||||
|
@ -5,6 +5,7 @@ symbol_kind: "struct"
|
||||
signature: |
|
||||
struct mg_mqtt_proto_data {
|
||||
uint16_t keep_alive;
|
||||
double last_control_time;
|
||||
};
|
||||
---
|
||||
|
||||
|
@ -11,7 +11,6 @@ items:
|
||||
- { name: mg_check_ip_acl.md }
|
||||
- { name: mg_connect.md }
|
||||
- { name: mg_connect_opt.md }
|
||||
- { name: mg_enable_javascript.md }
|
||||
- { name: mg_mgr_free.md }
|
||||
- { name: mg_mgr_init.md }
|
||||
- { name: mg_mgr_init_opt.md }
|
||||
|
@ -3,7 +3,9 @@ title: "mg_add_sock()"
|
||||
decl_name: "mg_add_sock"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
struct mg_connection *mg_add_sock(struct mg_mgr *, sock_t, mg_event_handler_t);
|
||||
struct mg_connection *mg_add_sock(struct mg_mgr *mgr, sock_t sock,
|
||||
MG_CB(mg_event_handler_t handler,
|
||||
void *user_data);
|
||||
---
|
||||
|
||||
Creates a connection, associates it with the given socket and event handler
|
||||
|
@ -3,9 +3,9 @@ title: "mg_add_sock_opt()"
|
||||
decl_name: "mg_add_sock_opt"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
struct mg_connection *mg_add_sock_opt(struct mg_mgr *, sock_t,
|
||||
mg_event_handler_t,
|
||||
struct mg_add_sock_opts);
|
||||
struct mg_connection *mg_add_sock_opt(struct mg_mgr *mgr, sock_t sock,
|
||||
MG_CB(mg_event_handler_t handler,
|
||||
void *user_data);
|
||||
---
|
||||
|
||||
Creates a connection, associates it with the given socket and event handler
|
||||
|
@ -3,8 +3,9 @@ title: "mg_bind()"
|
||||
decl_name: "mg_bind"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
struct mg_connection *mg_bind(struct mg_mgr *, const char *,
|
||||
mg_event_handler_t);
|
||||
struct mg_connection *mg_bind(struct mg_mgr *mgr, const char *address,
|
||||
MG_CB(mg_event_handler_t handler,
|
||||
void *user_data);
|
||||
---
|
||||
|
||||
Creates a listening connection.
|
||||
|
@ -4,8 +4,8 @@ decl_name: "mg_bind_opt"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,
|
||||
mg_event_handler_t handler,
|
||||
struct mg_bind_opts opts);
|
||||
MG_CB(mg_event_handler_t handler,
|
||||
void *user_data);
|
||||
---
|
||||
|
||||
Creates a listening connection.
|
||||
@ -15,7 +15,7 @@ the same as for the `mg_connect()` call, where `HOST` part is optional.
|
||||
`address` can be just a port number, e.g. `:8000`. To bind to a specific
|
||||
interface, an IP address can be specified, e.g. `1.2.3.4:8000`. By default,
|
||||
a TCP connection is created. To create UDP connection, prepend `udp://`
|
||||
prefix, e.g. `udp://:8000`. To summarize, `address` paramer has following
|
||||
prefix, e.g. `udp://:8000`. To summarize, `address` parameter has following
|
||||
format: `[PROTO://][IP_ADDRESS]:PORT`, where `PROTO` could be `tcp` or
|
||||
`udp`.
|
||||
|
||||
|
@ -3,7 +3,8 @@ title: "mg_broadcast()"
|
||||
decl_name: "mg_broadcast"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
void mg_broadcast(struct mg_mgr *, mg_event_handler_t func, void *, size_t);
|
||||
void mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data,
|
||||
size_t len);
|
||||
---
|
||||
|
||||
Passes a message of a given length to all connections.
|
||||
|
@ -18,7 +18,7 @@ Subnet masks may vary from 0 to 32, inclusive. The default setting
|
||||
is to allow all access. On each request the full list is traversed,
|
||||
and the last match wins. Example:
|
||||
|
||||
`-0.0.0.0/0,+192.168/16` - deny all acccesses, only allow 192.168/16 subnet
|
||||
`-0.0.0.0/0,+192.168/16` - deny all accesses, only allow 192.168/16 subnet
|
||||
|
||||
To learn more about subnet masks, see this
|
||||
link:https://en.wikipedia.org/wiki/Subnetwork[Wikipedia page on Subnetwork].
|
||||
|
@ -4,7 +4,8 @@ decl_name: "mg_connect"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,
|
||||
mg_event_handler_t handler);
|
||||
MG_CB(mg_event_handler_t handler,
|
||||
void *user_data);
|
||||
---
|
||||
|
||||
Connects to a remote host.
|
||||
|
@ -4,8 +4,8 @@ decl_name: "mg_connect_opt"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
|
||||
mg_event_handler_t handler,
|
||||
struct mg_connect_opts opts);
|
||||
MG_CB(mg_event_handler_t handler,
|
||||
void *user_data);
|
||||
---
|
||||
|
||||
Connects to a remote host.
|
||||
|
@ -1,14 +0,0 @@
|
||||
---
|
||||
title: "mg_enable_javascript()"
|
||||
decl_name: "mg_enable_javascript"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
enum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,
|
||||
const char *init_js_file_name);
|
||||
---
|
||||
|
||||
Enables server-side JavaScript scripting.
|
||||
Requires a `-DMG_ENABLE_JAVASCRIPT` compilation flag and V7 engine sources.
|
||||
V7 instance must not be destroyed during manager's lifetime.
|
||||
Returns a V7 error.
|
||||
|
@ -4,7 +4,7 @@ decl_name: "mg_event_handler_t"
|
||||
symbol_kind: "typedef"
|
||||
signature: |
|
||||
typedef void (*mg_event_handler_t)(struct mg_connection *nc, int ev,
|
||||
void *ev_data);
|
||||
void *ev_data MG_UD_ARG(void *user_data));
|
||||
---
|
||||
|
||||
Callback function (event handler) prototype. Must be defined by the user.
|
||||
|
@ -3,7 +3,7 @@ title: "mg_next()"
|
||||
decl_name: "mg_next"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
struct mg_connection *mg_next(struct mg_mgr *, struct mg_connection *);
|
||||
struct mg_connection *mg_next(struct mg_mgr *mgr, struct mg_connection *c);
|
||||
---
|
||||
|
||||
Iterates over all active connections.
|
||||
|
@ -8,6 +8,7 @@ signature: |
|
||||
unsigned int flags; /* Extra connection flags */
|
||||
const char **error_string; /* Placeholder for the error string */
|
||||
struct mg_iface *iface; /* Interface instance */
|
||||
const char *nameserver; /* DNS server to use, NULL for default */
|
||||
#if MG_ENABLE_SSL
|
||||
/*
|
||||
* SSL settings.
|
||||
|
@ -14,9 +14,7 @@ signature: |
|
||||
void *user_data; /* User data */
|
||||
int num_ifaces;
|
||||
struct mg_iface **ifaces; /* network interfaces */
|
||||
#if MG_ENABLE_JAVASCRIPT
|
||||
struct v7 *v7;
|
||||
#endif
|
||||
const char *nameserver; /* DNS server to use */
|
||||
};
|
||||
---
|
||||
|
||||
|
@ -4,9 +4,10 @@ decl_name: "struct mg_mgr_init_opts"
|
||||
symbol_kind: "struct"
|
||||
signature: |
|
||||
struct mg_mgr_init_opts {
|
||||
struct mg_iface_vtable *main_iface;
|
||||
const struct mg_iface_vtable *main_iface;
|
||||
int num_ifaces;
|
||||
struct mg_iface_vtable **ifaces;
|
||||
const struct mg_iface_vtable **ifaces;
|
||||
const char *nameserver;
|
||||
};
|
||||
---
|
||||
|
||||
|
@ -6,6 +6,7 @@ items:
|
||||
- { name: mg_resolve_async.md }
|
||||
- { name: mg_resolve_async_opt.md }
|
||||
- { name: mg_resolve_from_hosts_file.md }
|
||||
- { name: mg_set_nameserver.md }
|
||||
- { name: struct_mg_resolve_async_opts.md }
|
||||
---
|
||||
|
||||
|
10
docs/c-api/resolv.h/mg_set_nameserver.md
Normal file
10
docs/c-api/resolv.h/mg_set_nameserver.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
title: "mg_set_nameserver()"
|
||||
decl_name: "mg_set_nameserver"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
void mg_set_nameserver(struct mg_mgr *mgr, const char *nameserver);
|
||||
---
|
||||
|
||||
Set default DNS server
|
||||
|
@ -4,7 +4,7 @@ decl_name: "struct mg_resolve_async_opts"
|
||||
symbol_kind: "struct"
|
||||
signature: |
|
||||
struct mg_resolve_async_opts {
|
||||
const char *nameserver_url;
|
||||
const char *nameserver;
|
||||
int max_retries; /* defaults to 2 if zero */
|
||||
int timeout; /* in seconds; defaults to 5 if zero */
|
||||
int accept_literal; /* pseudo-resolve literal ipv4 and ipv6 addrs */
|
||||
|
@ -3,6 +3,7 @@ title: "URI"
|
||||
symbol_kind: "intro"
|
||||
decl_name: "uri.h"
|
||||
items:
|
||||
- { name: mg_assemble_uri.md }
|
||||
- { name: mg_parse_uri.md }
|
||||
---
|
||||
|
||||
|
20
docs/c-api/uri.h/mg_assemble_uri.md
Normal file
20
docs/c-api/uri.h/mg_assemble_uri.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
title: "mg_assemble_uri()"
|
||||
decl_name: "mg_assemble_uri"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
int mg_assemble_uri(const struct mg_str *scheme, const struct mg_str *user_info,
|
||||
const struct mg_str *host, unsigned int port,
|
||||
const struct mg_str *path, const struct mg_str *query,
|
||||
const struct mg_str *fragment, int normalize_path,
|
||||
struct mg_str *uri);
|
||||
---
|
||||
|
||||
Assemble URI from parts. Any of the inputs can be NULL or zero-length mg_str.
|
||||
|
||||
If normalize_path is true, path is normalized by resolving relative refs.
|
||||
|
||||
Result is a heap-allocated string (uri->p must be free()d after use).
|
||||
|
||||
Returns 0 on success, -1 on error.
|
||||
|
@ -3,7 +3,7 @@ title: "mg_parse_uri()"
|
||||
decl_name: "mg_parse_uri"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
int mg_parse_uri(struct mg_str uri, struct mg_str *scheme,
|
||||
int mg_parse_uri(const struct mg_str uri, struct mg_str *scheme,
|
||||
struct mg_str *user_info, struct mg_str *host,
|
||||
unsigned int *port, struct mg_str *path, struct mg_str *query,
|
||||
struct mg_str *fragment);
|
||||
|
@ -8,20 +8,21 @@ items:
|
||||
- { name: mg_basic_auth_header.md }
|
||||
- { name: mg_conn_addr_to_str.md }
|
||||
- { name: mg_fopen.md }
|
||||
- { name: mg_fread.md }
|
||||
- { name: mg_fwrite.md }
|
||||
- { name: mg_hexdump.md }
|
||||
- { name: mg_hexdump_connection.md }
|
||||
- { name: mg_hexdumpf.md }
|
||||
- { name: mg_is_big_endian.md }
|
||||
- { name: mg_match_prefix.md }
|
||||
- { name: mg_mbuf_append_base64.md }
|
||||
- { name: mg_mbuf_append_base64_putc.md }
|
||||
- { name: mg_next_comma_list_entry.md }
|
||||
- { name: mg_open.md }
|
||||
- { name: mg_skip.md }
|
||||
- { name: mg_sock_addr_to_str.md }
|
||||
- { name: mg_sock_to_str.md }
|
||||
- { name: mg_start_thread.md }
|
||||
- { name: mg_stat.md }
|
||||
- { name: mg_url_encode.md }
|
||||
---
|
||||
|
||||
|
||||
|
@ -3,7 +3,8 @@ title: "mg_basic_auth_header()"
|
||||
decl_name: "mg_basic_auth_header"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
void mg_basic_auth_header(const char *user, const char *pass, struct mbuf *buf);
|
||||
void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass,
|
||||
struct mbuf *buf);
|
||||
---
|
||||
|
||||
Generate a Basic Auth header and appends it to buf.
|
||||
|
@ -3,8 +3,8 @@ title: "mg_conn_addr_to_str()"
|
||||
decl_name: "mg_conn_addr_to_str"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
void mg_conn_addr_to_str(struct mg_connection *nc, char *buf, size_t len,
|
||||
int flags);
|
||||
int mg_conn_addr_to_str(struct mg_connection *c, char *buf, size_t len,
|
||||
int flags);
|
||||
---
|
||||
|
||||
Converts a connection's local or remote address into string.
|
||||
@ -17,5 +17,6 @@ see `MG_SOCK_STRINGIFY_*` definitions.
|
||||
- MG_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address
|
||||
|
||||
If both port number and IP address are printed, they are separated by `:`.
|
||||
If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported.
|
||||
If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported.
|
||||
Return length of the stringified address.
|
||||
|
||||
|
12
docs/c-api/util.h/mg_fread.md
Normal file
12
docs/c-api/util.h/mg_fread.md
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
title: "mg_fread()"
|
||||
decl_name: "mg_fread"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
size_t mg_fread(void *ptr, size_t size, size_t count, FILE *f);
|
||||
---
|
||||
|
||||
Reads data from the given file stream.
|
||||
|
||||
Return value is a number of bytes readen.
|
||||
|
12
docs/c-api/util.h/mg_fwrite.md
Normal file
12
docs/c-api/util.h/mg_fwrite.md
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
title: "mg_fwrite()"
|
||||
decl_name: "mg_fwrite"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
size_t mg_fwrite(const void *ptr, size_t size, size_t count, FILE *f);
|
||||
---
|
||||
|
||||
Writes data to the given file stream.
|
||||
|
||||
Return value is a number of bytes wtitten.
|
||||
|
@ -1,14 +0,0 @@
|
||||
---
|
||||
title: "mg_match_prefix()"
|
||||
decl_name: "mg_match_prefix"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
int mg_match_prefix(const char *pattern, int pattern_len, const char *str);
|
||||
---
|
||||
|
||||
Matches 0-terminated string (mg_match_prefix) or string with given length
|
||||
mg_match_prefix_n against a glob pattern.
|
||||
|
||||
Match is case-insensitive. Returns number of bytes matched, or -1 if no
|
||||
match.
|
||||
|
@ -1,21 +0,0 @@
|
||||
---
|
||||
title: "mg_next_comma_list_entry()"
|
||||
decl_name: "mg_next_comma_list_entry"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
|
||||
struct mg_str *eq_val);
|
||||
---
|
||||
|
||||
A helper function for traversing a comma separated list of values.
|
||||
It returns a list pointer shifted to the next value or NULL if the end
|
||||
of the list found.
|
||||
The value is stored in a val vector. If the value has a form "x=y", then
|
||||
eq_val vector is initialised to point to the "y" part, and val vector length
|
||||
is adjusted to point only to "x".
|
||||
If the list is just a comma separated list of entries, like "aa,bb,cc" then
|
||||
`eq_val` will contain zero-length string.
|
||||
|
||||
The purpose of this function is to parse comma separated string without
|
||||
any copying/memory allocation.
|
||||
|
@ -3,8 +3,8 @@ title: "mg_sock_addr_to_str()"
|
||||
decl_name: "mg_sock_addr_to_str"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
void mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
|
||||
int flags);
|
||||
int mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
|
||||
int flags);
|
||||
---
|
||||
|
||||
Convert the socket's address into string.
|
||||
|
13
docs/c-api/util.h/mg_url_encode.md
Normal file
13
docs/c-api/util.h/mg_url_encode.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
title: "mg_url_encode()"
|
||||
decl_name: "mg_url_encode"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
struct mg_str mg_url_encode(const struct mg_str src);
|
||||
---
|
||||
|
||||
URL-escape the specified string.
|
||||
All non-printable characters are escaped, plus `._-$,;~()/`.
|
||||
Input need not be NUL-terminated, but the returned string is.
|
||||
Returned string is heap-allocated and must be free()'d.
|
||||
|
@ -16,7 +16,7 @@ CGI file must be executable. Mongoose honours the shebang line - see
|
||||
http://en.wikipedia.org/wiki/Shebang_(Unix).
|
||||
|
||||
For example, if both PHP and Perl CGIs are used, then
|
||||
``#!/path/to/php-cgi.exe` and ``#!/path/to/perl.exe` must be the first lines
|
||||
`#!/path/to/php-cgi.exe` and `#!/path/to/perl.exe` must be the first lines
|
||||
of the respective CGI scripts.
|
||||
|
||||
It is possible to hardcode the path to the CGI interpreter for all
|
||||
@ -29,3 +29,7 @@ Example:
|
||||
```c
|
||||
opts.cgi_interpreter = "C:\\ruby\\ruby.exe";
|
||||
```
|
||||
NOTE: In the CGI handler we don't use explicitly a system call waitpid() for
|
||||
reaping zombie processes. Instead, we set the SIGCHLD handler to SIG_IGN.
|
||||
It will cause zombie processes to be reaped automatically.
|
||||
CAUTION: not all OSes (e.g. QNX) reap zombies if SIGCHLD is ignored.
|
@ -18,8 +18,9 @@ static int exit_flag = 0;
|
||||
|
||||
static void ev_handler(struct mg_connection *c, int ev, void *p) {
|
||||
if (ev == MG_EV_HTTP_REPLY) {
|
||||
struct http_message *hm = (struct http_message *)p;
|
||||
c->flags |= MG_F_CLOSE_IMMEDIATELY;
|
||||
fwrite(hm->message.p, 1, hm->message.len, stdout);
|
||||
fwrite(hm->message.p, 1, (int)hm->message.len, stdout);
|
||||
putchar('\n');
|
||||
exit_flag = 1;
|
||||
} else if (ev == MG_EV_CLOSE) {
|
||||
@ -31,7 +32,7 @@ int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
mg_connect_http(mgr, ev_handler, url, NULL, NULL);
|
||||
mg_connect_http(&mgr, ev_handler, url, NULL, NULL);
|
||||
|
||||
|
||||
while (exit_flag == 0) {
|
||||
|
@ -30,8 +30,8 @@ static void ev_handler(struct mg_connection *c, int ev, void *p) {
|
||||
|
||||
// We have received an HTTP request. Parsed request is contained in `hm`.
|
||||
// Send HTTP reply to the client which shows full original request.
|
||||
mg_send_head(c, 200, hm.message.len, "Content-Type: text/plain");
|
||||
mg_printf(c, "%.*s", hm.message.len, hm.message.p);
|
||||
mg_send_head(c, 200, hm->message.len, "Content-Type: text/plain");
|
||||
mg_printf(c, "%.*s", (int)hm->message.len, hm->message.p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ The exec directive is used to execute a command on a server,
|
||||
and show command's output. Example: `<!--#exec "ls -l" -->`
|
||||
|
||||
The call directive is a way to invoke a C handler from the HTML page.
|
||||
On each occurence of `<!--#call PARAMS -->` directive,
|
||||
On each occurrence of `<!--#call PARAMS -->` directive,
|
||||
Mongoose calls a registered event handler with `MG_EV_SSI_CALL` event.
|
||||
Event parameter will point to the `PARAMS` string.
|
||||
An event handler can output any text, for example by calling
|
||||
|
@ -30,4 +30,4 @@ int main(void) {
|
||||
}
|
||||
```
|
||||
|
||||
For the full example, please see the [Simplest HTTPS server example](https://github.com/cesanta/dev/tree/master/mongoose/examples/simplest_web_server_ssl).
|
||||
For the full example, please see the [Simplest HTTPS server example](https://github.com/cesanta/mongoose/tree/master/examples/simplest_web_server_ssl).
|
||||
|
@ -3,6 +3,6 @@ title: Disabling flags
|
||||
---
|
||||
|
||||
- `MG_DISABLE_HTTP_DIGEST_AUTH` disable HTTP Digest (MD5) authorisation support
|
||||
- `MG_DISABLE_SHA1` disable SHA1 support (used by WebSocket)
|
||||
- `MG_DISABLE_MD5` disable MD5 support (used by HTTP auth)
|
||||
- `CS_DISABLE_SHA1` disable SHA1 support (used by WebSocket)
|
||||
- `CS_DISABLE_MD5` disable MD5 support (used by HTTP auth)
|
||||
- `MG_DISABLE_HTTP_KEEP_ALIVE` useful for embedded systems to save resources
|
||||
|
@ -9,3 +9,4 @@ title: Tunables
|
||||
- `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.
|
||||
- `MG_USER_FILE_FUNCTIONS` allow you to use custom file operation, by defining you own `mg_stat`, `mg_fopen`, `mg_open`, `mg_fread` and `mg_fwrite` functions
|
@ -22,7 +22,7 @@ IPATH = . ../.. $(REPO_PATH)
|
||||
|
||||
VPATH = ../..
|
||||
|
||||
MONGOOSE_FEATURES = -DMG_ENABLE_SSL -DMG_ENABLE_HTTP_STREAMING_MULTIPART
|
||||
MONGOOSE_FEATURES = -DMG_ENABLE_SSL -DMG_ENABLE_HTTP_STREAMING_MULTIPART -DMG_MODULE_LINES
|
||||
|
||||
SDK_FLAGS = -DUSE_FREERTOS -DSL_PLATFORM_MULTI_THREADED
|
||||
# -DTARGET_IS_CC3200 would reduce code size by using functions in ROM
|
||||
@ -58,11 +58,11 @@ $(FW_DIR):
|
||||
$(FW_ZIP): $(FW_ELF) $(FW_BIN) $(SLFS_FILES)
|
||||
@echo " Code size: $(shell ls -l $(FW_BIN) | awk '{print $$5}')"
|
||||
@echo " GEN $(FW_MANIFEST)"
|
||||
@fw_meta gen_build_info \
|
||||
@fw_meta.py gen_build_info \
|
||||
--json_output=$(BUILD_INFO_JSON)
|
||||
@cp -v $(SLFS_FILES) out/
|
||||
@cp $(CC3200_SP_FILE)* $(FW_DIR)
|
||||
@fw_meta create_manifest \
|
||||
@fw_meta.py create_manifest \
|
||||
--name=$(PROG) --platform=$(PLATFORM) \
|
||||
--build_info=$(BUILD_INFO_JSON) \
|
||||
--output=$(FW_MANIFEST) \
|
||||
@ -72,14 +72,14 @@ $(FW_ZIP): $(FW_ELF) $(FW_BIN) $(SLFS_FILES)
|
||||
/sys/mcuimg.bin:type=app,src=$(notdir $(FW_BIN)) \
|
||||
$(foreach f,$(SLFS_FILES), $(notdir $(f)):type=slfile,src=$(notdir $(f)))
|
||||
@echo " ZIP $@"
|
||||
@fw_meta create_fw \
|
||||
@fw_meta.py create_fw \
|
||||
--manifest=$(FW_MANIFEST) \
|
||||
--src_dir=$(FW_DIR) \
|
||||
--output=$@
|
||||
|
||||
FREERTOS_SRCS = timers.c list.c queue.c tasks.c port.c heap_3.c osi_freertos.c
|
||||
DRIVER_SRCS = cpu.c gpio.c gpio_if.c i2c.c i2c_if.c interrupt.c pin.c prcm.c spi.c uart.c udma.c utils.c
|
||||
SL_SRCS = socket.c wlan.c driver.c device.c netapp.c netcfg.c network_common.c cc_pal.c fs.c
|
||||
SL_SRCS = socket.c wlan.c driver.c device.c netapp.c netcfg.c network_common.c timer.c cc_pal.c fs.c
|
||||
SDK_SRCS = startup_gcc.c $(FREERTOS_SRCS) $(DRIVER_SRCS) $(SL_SRCS)
|
||||
IPATH += $(SDK_PATH) $(SDK_PATH)/inc $(SDK_PATH)/driverlib \
|
||||
$(SDK_PATH)/example/common $(SDK_PATH)/oslib \
|
||||
|
@ -40,22 +40,22 @@ void cs_log_set_level(enum cs_log_level level);
|
||||
|
||||
void cs_log_set_file(FILE *file);
|
||||
|
||||
extern enum cs_log_level cs_log_level;
|
||||
extern enum cs_log_level cs_log_threshold;
|
||||
void cs_log_print_prefix(const char *func);
|
||||
void cs_log_printf(const char *fmt, ...);
|
||||
|
||||
#define LOG(l, x) \
|
||||
if (cs_log_level >= l) { \
|
||||
if (cs_log_threshold >= l) { \
|
||||
cs_log_print_prefix(__func__); \
|
||||
cs_log_printf x; \
|
||||
}
|
||||
|
||||
#ifndef CS_NDEBUG
|
||||
|
||||
#define DBG(x) \
|
||||
if (cs_log_level >= LL_VERBOSE_DEBUG) { \
|
||||
cs_log_print_prefix(__func__); \
|
||||
cs_log_printf x; \
|
||||
#define DBG(x) \
|
||||
if (cs_log_threshold >= LL_VERBOSE_DEBUG) { \
|
||||
cs_log_print_prefix(__func__); \
|
||||
cs_log_printf x; \
|
||||
}
|
||||
|
||||
#else /* NDEBUG */
|
||||
|
@ -294,3 +294,16 @@ void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *e) {
|
||||
LOG(LL_ERROR, ("status %d sender %d", e->EventData.deviceEvent.status,
|
||||
e->EventData.deviceEvent.sender));
|
||||
}
|
||||
|
||||
#ifndef __TI_COMPILER_VERSION__
|
||||
int _gettimeofday_r(struct _reent *r, struct timeval *tp, void *tz) {
|
||||
#else
|
||||
int gettimeofday(struct timeval *tp, void *tz) {
|
||||
#endif
|
||||
unsigned long sec;
|
||||
unsigned short msec;
|
||||
MAP_PRCMRTCGet(&sec, &msec);
|
||||
tp->tv_sec = sec;
|
||||
tp->tv_usec = ((unsigned long) msec) * 1000;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
docker.cesanta.com/cc3200-build:1.2.0-r8
|
||||
docker.cesanta.com/cc3200-build:1.3.0-r2
|
||||
|
16
examples/ESP32_IDF/Makefile
Normal file
16
examples/ESP32_IDF/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
SDK_VER=$(shell cat sdk.version)
|
||||
|
||||
.PHONY: all
|
||||
|
||||
MG_PATH = $(realpath $(PWD)/../../)
|
||||
|
||||
all:
|
||||
docker run --rm -it -v $(MG_PATH):/esp32_idf \
|
||||
$(SDK_VER) \
|
||||
bash -c "cd esp32_idf/examples/ESP32_IDF && \
|
||||
make -f Makefile.build defconfig && make -f Makefile.build"
|
||||
|
||||
clean:
|
||||
docker run --rm -it -v $(MG_PATH):/esp32_idf \
|
||||
$(SDK_VER) \
|
||||
bash -c "rm -rf esp32_idf/examples/ESP32_IDF/build"
|
9
examples/ESP32_IDF/Makefile.build
Normal file
9
examples/ESP32_IDF/Makefile.build
Normal file
@ -0,0 +1,9 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := esp32_idf
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
18
examples/ESP32_IDF/README.md
Normal file
18
examples/ESP32_IDF/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
This is a Mongoose "Hello, world" that can be compiled under Espressif IoT Development Framework for ESP32
|
||||
|
||||
It connects to WiFi network and serves a "hello world" page.
|
||||
|
||||
Most of the the boilerplate comes from [project_template](https://github.com/espressif/esp-idf-template) with minimal changes.
|
||||
|
||||
For building the example, you need to have [Docker](https://www.docker.com/products/docker) and use our pre-built SDK container.
|
||||
To build just run in the example directory
|
||||
```
|
||||
$ make
|
||||
```
|
||||
|
||||
Note: before building, change `WIFI_SSID` and `WIFI_PASS` macros in main/main.c file
|
||||
|
||||
Once built, use [esptool](https://github.com/espressif/esptool) for flashing
|
||||
```
|
||||
$ python esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 115200 --before default_reset --after hard_reset write_flash -u --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 build/bootloader/bootloader.bin 0x10000 build/esp32_idf.bin 0x8000 build/partitions_singleapp.bin
|
||||
```
|
17
examples/ESP32_IDF/main/component.mk
Normal file
17
examples/ESP32_IDF/main/component.mk
Normal file
@ -0,0 +1,17 @@
|
||||
#
|
||||
# Main component makefile.
|
||||
#
|
||||
# This Makefile can be left empty. By default, it will take the sources in the
|
||||
# src/ directory, compile them and link them into lib(subdirectory_name).a
|
||||
# in the build directory. This behaviour is entirely configurable,
|
||||
# please read the ESP-IDF documents if you need to do this.
|
||||
#
|
||||
|
||||
COMPONENT_OBJS = main.o mongoose.o
|
||||
|
||||
mongoose.o: ../../../../mongoose.c
|
||||
$(summary) "CC $@"
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) \
|
||||
$(addprefix -I ,$(COMPONENT_INCLUDES)) \
|
||||
$(addprefix -I ,$(COMPONENT_EXTRA_INCLUDES)) \
|
||||
-c $< -o $@
|
93
examples/ESP32_IDF/main/main.c
Normal file
93
examples/ESP32_IDF/main/main.c
Normal file
@ -0,0 +1,93 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#include "esp_event.h"
|
||||
#include "esp_event_loop.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
#include "./../../../mongoose.h"
|
||||
|
||||
#define WIFI_SSID "ssid"
|
||||
#define WIFI_PASS "pass"
|
||||
|
||||
#define MG_LISTEN_ADDR "80"
|
||||
|
||||
static esp_err_t event_handler(void *ctx, system_event_t *event) {
|
||||
(void) ctx;
|
||||
(void) event;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void mg_ev_handler(struct mg_connection *nc, int ev, void *p) {
|
||||
static const char *reply_fmt =
|
||||
"HTTP/1.0 200 OK\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Content-Type: text/plain\r\n"
|
||||
"\r\n"
|
||||
"Hello %s\n";
|
||||
|
||||
switch (ev) {
|
||||
case MG_EV_ACCEPT: {
|
||||
char addr[32];
|
||||
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
|
||||
MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
|
||||
printf("Connection %p from %s\n", nc, addr);
|
||||
break;
|
||||
}
|
||||
case MG_EV_HTTP_REQUEST: {
|
||||
char addr[32];
|
||||
struct http_message *hm = (struct http_message *) p;
|
||||
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
|
||||
MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
|
||||
printf("HTTP request from %s: %.*s %.*s\n", addr, (int) hm->method.len,
|
||||
hm->method.p, (int) hm->uri.len, hm->uri.p);
|
||||
mg_printf(nc, reply_fmt, addr);
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
break;
|
||||
}
|
||||
case MG_EV_CLOSE: {
|
||||
printf("Connection %p closed\n", nc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void) {
|
||||
nvs_flash_init();
|
||||
tcpip_adapter_init();
|
||||
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
|
||||
|
||||
/* Initializing WiFi */
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
wifi_config_t sta_config = {
|
||||
.sta = {.ssid = WIFI_SSID, .password = WIFI_PASS, .bssid_set = false}};
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config));
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
ESP_ERROR_CHECK(esp_wifi_connect());
|
||||
|
||||
/* Starting Mongoose */
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *nc;
|
||||
|
||||
printf("Starting web-server on port %s\n", MG_LISTEN_ADDR);
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
|
||||
nc = mg_bind(&mgr, MG_LISTEN_ADDR, mg_ev_handler);
|
||||
if (nc == NULL) {
|
||||
printf("Error setting up listener!\n");
|
||||
return;
|
||||
}
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
|
||||
/* Processing events */
|
||||
while (1) {
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
}
|
||||
}
|
1
examples/ESP32_IDF/sdk.version
Normal file
1
examples/ESP32_IDF/sdk.version
Normal file
@ -0,0 +1 @@
|
||||
docker.cesanta.com/esp32-build:1.0-r13
|
@ -1,7 +1,8 @@
|
||||
#!/bin/bash
|
||||
REPO=$(cd ../.. && pwd)
|
||||
|
||||
docker run \
|
||||
--rm -i -v $(realpath ${PWD}/../..):/src \
|
||||
--rm -i -v $REPO:/src \
|
||||
--entrypoint=/bin/bash $(cat sdk.version) -l -c -x '
|
||||
export SDK_PATH=/opt/Espressif/ESP8266_RTOS_SDK;
|
||||
export BIN_PATH=./bin;
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
# `wildcard ./*/` works in both linux and linux/wine, while `wildcard */` enumerates nothing under wine
|
||||
SUBDIRS = $(sort $(dir $(wildcard ./*/)))
|
||||
SUBDIRS:=$(filter-out ./ ./CC3200/ ./ESP8266_RTOS/ ./mbed/ ./MSP432/ ./nRF51/ ./nRF52/ ./NXP_K64/ ./NXP_LPC4088/ ./PIC32/ ./STM32F4_CC3100/ ./TM4C129/ ./WinCE/, $(SUBDIRS))
|
||||
SUBDIRS:=$(filter-out ./ ./CC3200/ ./ESP32_IDF/ ./ESP8266_RTOS/ ./mbed/ ./MSP432/ ./nRF51/ ./nRF52/ ./NXP_K64/ ./NXP_LPC4088/ ./PIC32/ ./STM32F4_CC3100/ ./TM4C129/ ./WinCE/, $(SUBDIRS))
|
||||
|
||||
ifeq ($(OS), Windows_NT)
|
||||
SUBDIRS:=$(filter-out ./netcat/ ./raspberry_pi_mjpeg_led/ ./captive_dns_server/, $(SUBDIRS))
|
||||
|
@ -10,28 +10,13 @@
|
||||
#include "mongoose.h"
|
||||
|
||||
static const char *s_http_port = "8000";
|
||||
static struct mg_serve_http_opts s_http_server_opts;
|
||||
|
||||
struct file_writer_data {
|
||||
FILE *fp;
|
||||
size_t bytes_written;
|
||||
};
|
||||
|
||||
static void handle_request(struct mg_connection *nc) {
|
||||
// This handler gets for all endpoints but /upload
|
||||
mg_printf(nc, "%s",
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: text/html\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n"
|
||||
"<html><body>Upload example."
|
||||
"<form method=\"POST\" action=\"/upload\" "
|
||||
" enctype=\"multipart/form-data\">"
|
||||
"<input type=\"file\" name=\"file\" /> <br/>"
|
||||
"<input type=\"submit\" value=\"Upload\" />"
|
||||
"</form></body></html>");
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
}
|
||||
|
||||
static void handle_upload(struct mg_connection *nc, int ev, void *p) {
|
||||
struct file_writer_data *data = (struct file_writer_data *) nc->user_data;
|
||||
struct mg_http_multipart_part *mp = (struct mg_http_multipart_part *) p;
|
||||
@ -82,25 +67,27 @@ static void handle_upload(struct mg_connection *nc, int ev, void *p) {
|
||||
}
|
||||
|
||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
(void) ev_data;
|
||||
switch (ev) {
|
||||
case MG_EV_HTTP_REQUEST:
|
||||
// Invoked when the full HTTP request is in the buffer (including body).
|
||||
handle_request(nc);
|
||||
break;
|
||||
if (ev == MG_EV_HTTP_REQUEST) {
|
||||
mg_serve_http(nc, ev_data, s_http_server_opts);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *nc;
|
||||
struct mg_connection *c;
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
nc = mg_bind(&mgr, s_http_port, ev_handler);
|
||||
c = mg_bind(&mgr, s_http_port, ev_handler);
|
||||
if (c == NULL) {
|
||||
fprintf(stderr, "Cannot start server on port %s\n", s_http_port);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
s_http_server_opts.document_root = "."; // Serve current directory
|
||||
mg_register_http_endpoint(c, "/upload", handle_upload MG_UD_ARG(NULL));
|
||||
|
||||
mg_register_http_endpoint(nc, "/upload", handle_upload);
|
||||
// Set up HTTP server parameters
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
mg_set_protocol_http_websocket(c);
|
||||
|
||||
printf("Starting web server on port %s\n", s_http_port);
|
||||
for (;;) {
|
||||
|
54
examples/big_upload/index.html
Normal file
54
examples/big_upload/index.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>AJAX Upload Example</title>
|
||||
<script src="//code.jquery.com/jquery-1.9.1.js"></script>
|
||||
<script type="text/javascript">
|
||||
function updateProgress(evt) {
|
||||
if (evt.lengthComputable) {
|
||||
document.getElementById("output").textContent =
|
||||
"Uploaded " + evt.loaded + " of " + evt.total + " bytes";
|
||||
}
|
||||
}
|
||||
function uploadFile() {
|
||||
var file_data = new FormData(document.getElementById('filename'));
|
||||
$.ajax({
|
||||
url: "/upload",
|
||||
type: "POST",
|
||||
data: file_data,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
cache: false,
|
||||
xhr: function() {
|
||||
myXhr = $.ajaxSettings.xhr();
|
||||
if(myXhr.upload){
|
||||
myXhr.upload.addEventListener('progress',updateProgress, false); // for handling the progress of the upload
|
||||
}
|
||||
return myXhr;
|
||||
},
|
||||
}).done(function(data) {
|
||||
document.getElementById("output").textContent = "Result: " + data;
|
||||
});
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Upload file using standard form upload</h1>
|
||||
|
||||
<form method="POST" action="/upload" enctype="multipart/form-data">
|
||||
<label>Select a file:</label><br>
|
||||
<input type="file" name="file" />
|
||||
<input type="submit" value="Upload" />
|
||||
</form>
|
||||
|
||||
<h1>Upload file using Ajax - that also gives progress report</h1>
|
||||
<form method="post" id="filename" name="filename" onsubmit="return uploadFile();">
|
||||
<label>Select a file:</label><br>
|
||||
<input type="file" id="file" name="file" required />
|
||||
<input type="submit" value="Upload" />
|
||||
</form>
|
||||
<br><br><div id="output"></div>
|
||||
</body>
|
||||
</html>
|
@ -1,4 +1,4 @@
|
||||
PROG = mqtt_broker
|
||||
MODULE_CFLAGS = -DMG_ENABLE_MQTT_BROKER -DMG_ENABLE_HTTP=0
|
||||
SSL_LIB=openssl
|
||||
#SSL_LIB=openssl
|
||||
include ../examples.mk
|
||||
|
@ -17,22 +17,31 @@
|
||||
|
||||
#include "../../mongoose.h"
|
||||
|
||||
static const char *s_listening_address = "0.0.0.0:1883";
|
||||
|
||||
static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||
if (ev != MG_EV_POLL) printf("USER HANDLER GOT EVENT %d\n", ev);
|
||||
/* Do your custom event processing here */
|
||||
mg_mqtt_broker(c, ev, ev_data);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
const char *address = "0.0.0.0:1883";
|
||||
struct mg_connection *nc;
|
||||
struct mg_connection *c;
|
||||
struct mg_mqtt_broker brk;
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
mg_mqtt_broker_init(&brk, NULL);
|
||||
|
||||
if ((nc = mg_bind(&mgr, address, mg_mqtt_broker)) == NULL) {
|
||||
fprintf(stderr, "mg_bind(%s) failed\n", address);
|
||||
if ((c = mg_bind(&mgr, s_listening_address, ev_handler)) == NULL) {
|
||||
fprintf(stderr, "mg_bind(%s) failed\n", s_listening_address);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
nc->user_data = &brk;
|
||||
mg_mqtt_broker_init(&brk, NULL);
|
||||
c->user_data = &brk;
|
||||
mg_set_protocol_mqtt(c);
|
||||
|
||||
printf("MQTT broker started on %s\n", address);
|
||||
printf("MQTT broker started on %s\n", s_listening_address);
|
||||
|
||||
/*
|
||||
* TODO: Add a HTTP status page that shows current sessions
|
||||
|
@ -27,10 +27,7 @@ static void ev_handler(struct mg_connection *nc, int ev, void *p) {
|
||||
struct mg_mqtt_message *msg = (struct mg_mqtt_message *) p;
|
||||
(void) nc;
|
||||
|
||||
#if 0
|
||||
if (ev != MG_EV_POLL)
|
||||
printf("USER HANDLER GOT %d\n", ev);
|
||||
#endif
|
||||
if (ev != MG_EV_POLL) printf("USER HANDLER GOT EVENT %d\n", ev);
|
||||
|
||||
switch (ev) {
|
||||
case MG_EV_CONNECT: {
|
||||
|
4
examples/mqtt_over_websocket_server/Makefile
Normal file
4
examples/mqtt_over_websocket_server/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
PROG = mqtt_over_websocket_server
|
||||
MODULE_CFLAGS = -DMG_ENABLE_MQTT_BROKER=1
|
||||
#SSL_LIB=mbedtls
|
||||
include ../examples.mk
|
124
examples/mqtt_over_websocket_server/mqtt_over_websocket_server.c
Normal file
124
examples/mqtt_over_websocket_server/mqtt_over_websocket_server.c
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Cesanta Software Limited
|
||||
* 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
|
||||
* license, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
* license, as set out in <https://www.cesanta.com/license>.
|
||||
*/
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
static const char *s_mqtt_address = "0.0.0.0:1883";
|
||||
static const char *s_http_address = "0.0.0.0:8080";
|
||||
|
||||
static void unproxy(struct mg_connection *c) {
|
||||
struct mg_connection *pc = (struct mg_connection *) c->user_data;
|
||||
if (pc != NULL) {
|
||||
pc->flags |= MG_F_CLOSE_IMMEDIATELY;
|
||||
pc->user_data = NULL;
|
||||
c->user_data = NULL;
|
||||
}
|
||||
printf("Closing connection %p\n", c);
|
||||
}
|
||||
|
||||
static void proxy_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||
if (ev == MG_EV_POLL) return;
|
||||
printf("%p %s EVENT %d %p\n", c, __func__, ev, ev_data);
|
||||
switch (ev) {
|
||||
case MG_EV_CLOSE: {
|
||||
unproxy(c);
|
||||
break;
|
||||
}
|
||||
case MG_EV_RECV: {
|
||||
struct mg_connection *pc = (struct mg_connection *) c->user_data;
|
||||
if (pc != NULL) {
|
||||
mg_send_websocket_frame(pc, WEBSOCKET_OP_BINARY, c->recv_mbuf.buf,
|
||||
c->recv_mbuf.len);
|
||||
mbuf_remove(&c->recv_mbuf, c->recv_mbuf.len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void http_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||
struct mg_connection *pc = (struct mg_connection *) c->user_data;
|
||||
if (ev == MG_EV_POLL) return;
|
||||
printf("%p %s EVENT %d %p\n", c, __func__, ev, ev_data);
|
||||
/* Do your custom event processing here */
|
||||
switch (ev) {
|
||||
case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
|
||||
pc = mg_connect(c->mgr, s_mqtt_address, proxy_handler);
|
||||
pc->user_data = c;
|
||||
c->user_data = pc;
|
||||
printf("Created proxy connection %p\n", pc);
|
||||
break;
|
||||
}
|
||||
case MG_EV_WEBSOCKET_FRAME: {
|
||||
struct websocket_message *wm = (struct websocket_message *) ev_data;
|
||||
if (pc != NULL) {
|
||||
printf("Forwarding %d bytes\n", (int) wm->size);
|
||||
mg_send(pc, wm->data, wm->size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MG_EV_CLOSE: {
|
||||
unproxy(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mqtt_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||
if (ev == MG_EV_POLL) return;
|
||||
printf("%p %s EVENT %d %p\n", c, __func__, ev, ev_data);
|
||||
/* Do your custom event processing here */
|
||||
switch (ev) {
|
||||
case MG_EV_CLOSE:
|
||||
printf("Closing MQTT connection %p\n", c);
|
||||
break;
|
||||
}
|
||||
mg_mqtt_broker(c, ev, ev_data);
|
||||
}
|
||||
|
||||
static void start_mqtt_server(struct mg_mgr *mgr, const char *addr) {
|
||||
struct mg_connection *c;
|
||||
static struct mg_mqtt_broker brk; // static is important - must not perish
|
||||
if ((c = mg_bind(mgr, addr, mqtt_handler)) == NULL) {
|
||||
fprintf(stderr, "Cannot start MQTT server on port [%s]\n", addr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
mg_mqtt_broker_init(&brk, NULL);
|
||||
c->user_data = &brk;
|
||||
mg_set_protocol_mqtt(c);
|
||||
printf("MQTT server started on %s\n", addr);
|
||||
}
|
||||
|
||||
static void start_http_server(struct mg_mgr *mgr, const char *addr) {
|
||||
struct mg_connection *c;
|
||||
if ((c = mg_bind(mgr, addr, http_handler)) == NULL) {
|
||||
fprintf(stderr, "Cannot start HTTP server on port [%s]\n", addr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
mg_set_protocol_http_websocket(c);
|
||||
printf("HTTP server started on %s\n", addr);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
start_http_server(&mgr, s_http_address);
|
||||
start_mqtt_server(&mgr, s_mqtt_address);
|
||||
for (;;) {
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
}
|
||||
}
|
3
examples/multithreaded/Makefile
Normal file
3
examples/multithreaded/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
PROG = multithreaded
|
||||
MODULE_CFLAGS=-DMG_ENABLE_THREADS
|
||||
include ../examples.mk
|
124
examples/multithreaded/multithreaded.c
Normal file
124
examples/multithreaded/multithreaded.c
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Cesanta Software Limited
|
||||
* All rights reserved
|
||||
*/
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
static sig_atomic_t s_received_signal = 0;
|
||||
static const char *s_http_port = "8000";
|
||||
static const int s_num_worker_threads = 5;
|
||||
static unsigned long s_next_id = 0;
|
||||
|
||||
static void signal_handler(int sig_num) {
|
||||
signal(sig_num, signal_handler);
|
||||
s_received_signal = sig_num;
|
||||
}
|
||||
static struct mg_serve_http_opts s_http_server_opts;
|
||||
static sock_t sock[2];
|
||||
|
||||
// This info is passed to the worker thread
|
||||
struct work_request {
|
||||
unsigned long conn_id; // needed to identify the connection where to send the reply
|
||||
// optionally, more data that could be required by worker
|
||||
};
|
||||
|
||||
// This info is passed by the worker thread to mg_broadcast
|
||||
struct work_result {
|
||||
unsigned long conn_id;
|
||||
int sleep_time;
|
||||
};
|
||||
|
||||
static void on_work_complete(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
(void) ev;
|
||||
char s[32];
|
||||
struct mg_connection *c;
|
||||
for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) {
|
||||
if (c->user_data != NULL) {
|
||||
struct work_result *res = (struct work_result *)ev_data;
|
||||
if ((unsigned long)c->user_data == res->conn_id) {
|
||||
sprintf(s, "conn_id:%lu sleep:%d", res->conn_id, res->sleep_time);
|
||||
mg_send_head(c, 200, strlen(s), "Content-Type: text/plain");
|
||||
mg_printf(c, "%s", s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *worker_thread_proc(void *param) {
|
||||
struct mg_mgr *mgr = (struct mg_mgr *) param;
|
||||
struct work_request req = {0};
|
||||
|
||||
while (s_received_signal == 0) {
|
||||
if (read(sock[1], &req, sizeof(req)) < 0)
|
||||
perror("Reading worker sock");
|
||||
int r = rand() % 10;
|
||||
sleep(r);
|
||||
struct work_result res = {req.conn_id, r};
|
||||
mg_broadcast(mgr, on_work_complete, (void *)&res, sizeof(res));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
(void) nc;
|
||||
(void) ev_data;
|
||||
|
||||
switch (ev) {
|
||||
case MG_EV_ACCEPT:
|
||||
nc->user_data = (void *)++s_next_id;
|
||||
break;
|
||||
case MG_EV_HTTP_REQUEST: {
|
||||
struct work_request req = {(unsigned long)nc->user_data};
|
||||
|
||||
if (write(sock[0], &req, sizeof(req)) < 0)
|
||||
perror("Writing worker sock");
|
||||
break;
|
||||
}
|
||||
case MG_EV_CLOSE: {
|
||||
if (nc->user_data) nc->user_data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *nc;
|
||||
int i;
|
||||
|
||||
if (mg_socketpair(sock, SOCK_STREAM) == 0) {
|
||||
perror("Opening socket pair");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
signal(SIGTERM, signal_handler);
|
||||
signal(SIGINT, signal_handler);
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
|
||||
nc = mg_bind(&mgr, s_http_port, ev_handler);
|
||||
if (nc == NULL) {
|
||||
printf("Failed to create listener\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
s_http_server_opts.document_root = "."; // Serve current directory
|
||||
s_http_server_opts.enable_directory_listing = "no";
|
||||
|
||||
for (i = 0; i < s_num_worker_threads; i++) {
|
||||
mg_start_thread(worker_thread_proc, &mgr);
|
||||
}
|
||||
|
||||
printf("Started on port %s\n", s_http_port);
|
||||
while (s_received_signal == 0) {
|
||||
mg_mgr_poll(&mgr, 200);
|
||||
}
|
||||
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
closesocket(sock[0]);
|
||||
closesocket(sock[1]);
|
||||
|
||||
return 0;
|
||||
}
|
@ -3,7 +3,7 @@ PROJECT_NAME := iot_lwip_tcp_server_pca10028
|
||||
export OUTPUT_FILENAME
|
||||
#MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
|
||||
MAKEFILE_NAME := $(MAKEFILE_LIST)
|
||||
MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) )
|
||||
MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) )
|
||||
|
||||
TEMPLATE_PATH = ../../../../nrf51_iot_sdk/components/toolchain/gcc
|
||||
ifeq ($(OS),Windows_NT)
|
||||
@ -17,7 +17,7 @@ RM := rm -rf
|
||||
|
||||
#echo suspend
|
||||
ifeq ("$(VERBOSE)","1")
|
||||
NO_ECHO :=
|
||||
NO_ECHO :=
|
||||
else
|
||||
NO_ECHO := @
|
||||
endif
|
||||
@ -118,7 +118,7 @@ BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LIS
|
||||
# Mongoose features
|
||||
MG_FEATURES_TINY = \
|
||||
-DMG_DISABLE_HTTP_DIGEST_AUTH \
|
||||
-DMG_DISABLE_MD5 \
|
||||
-DCS_DISABLE_MD5 \
|
||||
-DMG_DISABLE_HTTP_KEEP_ALIVE \
|
||||
-DMG_ENABLE_HTTP_SSI=0 \
|
||||
-DMG_ENABLE_HTTP_STREAMING_MULTIPART
|
||||
@ -251,7 +251,7 @@ genbin:
|
||||
$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin
|
||||
|
||||
## Create binary .hex file from the .out file
|
||||
genhex:
|
||||
genhex:
|
||||
@echo Preparing: $(OUTPUT_FILENAME).hex
|
||||
$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
|
||||
|
||||
|
@ -3,7 +3,7 @@ PROJECT_NAME := iot_lwip_tcp_server_pca10040
|
||||
export OUTPUT_FILENAME
|
||||
#MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
|
||||
MAKEFILE_NAME := $(MAKEFILE_LIST)
|
||||
MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) )
|
||||
MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) )
|
||||
|
||||
TEMPLATE_PATH = ../../../../nrf5_iot_sdk/components/toolchain/gcc
|
||||
ifeq ($(OS),Windows_NT)
|
||||
@ -17,7 +17,7 @@ RM := rm -rf
|
||||
|
||||
#echo suspend
|
||||
ifeq ("$(VERBOSE)","1")
|
||||
NO_ECHO :=
|
||||
NO_ECHO :=
|
||||
else
|
||||
NO_ECHO := @
|
||||
endif
|
||||
@ -165,7 +165,7 @@ BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LIS
|
||||
# Mongoose features
|
||||
MG_FEATURES_TINY = \
|
||||
-DMG_DISABLE_HTTP_DIGEST_AUTH \
|
||||
-DMG_DISABLE_MD5 \
|
||||
-DCS_DISABLE_MD5 \
|
||||
-DMG_DISABLE_HTTP_KEEP_ALIVE \
|
||||
-DMG_ENABLE_HTTP_SSI=0 \
|
||||
-DMG_ENABLE_HTTP_STREAMING_MULTIPART
|
||||
@ -297,7 +297,7 @@ genbin:
|
||||
$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin
|
||||
|
||||
## Create binary .hex file from the .out file
|
||||
genhex:
|
||||
genhex:
|
||||
@echo Preparing: $(OUTPUT_FILENAME).hex
|
||||
$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
|
||||
echosize:
|
||||
|
@ -1,3 +1,3 @@
|
||||
PROG = websocket_chat
|
||||
MODULE_CFLAGS = -DMG_ENABLE_FILESYSTEM=0
|
||||
MODULE_CFLAGS = -DMG_ENABLE_FILESYSTEM=1
|
||||
include ../examples.mk
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
static sig_atomic_t s_signal_received = 0;
|
||||
static const char *s_http_port = "8000";
|
||||
static struct mg_serve_http_opts s_http_server_opts;
|
||||
|
||||
static void signal_handler(int sig_num) {
|
||||
signal(sig_num, signal_handler); // Reinstantiate signal handler
|
||||
@ -46,6 +47,10 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
broadcast(nc, d);
|
||||
break;
|
||||
}
|
||||
case MG_EV_HTTP_REQUEST: {
|
||||
mg_serve_http(nc, (struct http_message *) ev_data, s_http_server_opts);
|
||||
break;
|
||||
}
|
||||
case MG_EV_CLOSE: {
|
||||
/* Disconnect. Tell everybody. */
|
||||
if (is_websocket(nc)) {
|
||||
@ -69,6 +74,8 @@ int main(void) {
|
||||
|
||||
nc = mg_bind(&mgr, s_http_port, ev_handler);
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
s_http_server_opts.document_root = "."; // Serve current directory
|
||||
s_http_server_opts.enable_directory_listing = "yes";
|
||||
|
||||
printf("Started on port %s\n", s_http_port);
|
||||
while (s_signal_received == 0) {
|
||||
|
3637
mongoose.c
3637
mongoose.c
File diff suppressed because it is too large
Load Diff
705
mongoose.h
705
mongoose.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user