mirror of
https://github.com/cesanta/mongoose.git
synced 2025-01-16 20:41:20 +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:
|
||||
|
||||
![](http://www.cesanta.com/hubfs/www.cesanta.com/diagrams/dash_mongoose_diagram.png)
|
||||
![](http://www.cesanta.com/images/dashboard.png)
|
||||
|
||||
[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)
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-42732794-5/project-page)](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…
x
Reference in New Issue
Block a user