Commit 12437fd7 authored by Sergey Lyubka's avatar Sergey Lyubka Committed by Cesanta Bot

Refactor Mongoose documentation

PUBLISHED_FROM=e9a4e5c7b4a1d03b93a2a79e29de19e60e919929
parent 4120f953
--- ---
title: "CoAP" title: "CoAP API reference"
symbol_kind: "intro" symbol_kind: "intro"
decl_name: "coap.h" decl_name: "coap.h"
items: items:
- { type: file, name: mg_set_protocol_coap.md } - { name: mg_set_protocol_coap.md }
- { type: file, name: mg_coap_add_option.md } - { name: mg_coap_add_option.md }
- { type: file, name: mg_coap_free_options.md } - { name: mg_coap_free_options.md }
- { type: file, name: mg_coap_send_message.md } - { name: mg_coap_send_message.md }
- { type: file, name: mg_coap_send_ack.md } - { name: mg_coap_send_ack.md }
- { type: file, name: mg_coap_parse.md } - { name: mg_coap_parse.md }
- { type: file, name: mg_coap_compose.md } - { name: mg_coap_compose.md }
- { type: file, name: struct_mg_coap_option.md } - { name: struct_mg_coap_option.md }
- { type: file, name: struct_mg_coap_message.md } - { name: struct_mg_coap_message.md }
--- ---
CoAP message format: CoAP message format:
......
--- ---
title: "DNS" title: "DNS API reference"
symbol_kind: "intro" symbol_kind: "intro"
decl_name: "dns.h" decl_name: "dns.h"
items: items:
- { type: file, name: mg_dns_parse_record_data.md } - { name: mg_dns_parse_record_data.md }
- { type: file, name: mg_send_dns_query.md } - { name: mg_send_dns_query.md }
- { type: file, name: mg_dns_insert_header.md } - { name: mg_dns_insert_header.md }
- { type: file, name: mg_dns_copy_questions.md } - { name: mg_dns_copy_questions.md }
- { type: file, name: mg_dns_encode_record.md } - { name: mg_dns_encode_record.md }
- { type: file, name: mg_parse_dns.md } - { name: mg_parse_dns.md }
- { type: file, name: mg_dns_uncompress_name.md } - { name: mg_dns_uncompress_name.md }
- { type: file, name: mg_set_protocol_dns.md } - { name: mg_set_protocol_dns.md }
- { type: file, name: struct_mg_dns_resource_record.md } - { name: struct_mg_dns_resource_record.md }
- { type: file, name: struct_mg_dns_message.md } - { name: struct_mg_dns_message.md }
--- ---
......
--- ---
title: "DNS server" title: "DNS server API reference"
symbol_kind: "intro" symbol_kind: "intro"
decl_name: "dns-server.h" decl_name: "dns_server.h"
items: items:
- { type: file, name: mg_dns_create_reply.md } - { name: mg_dns_create_reply.md }
- { type: file, name: mg_dns_reply_record.md } - { name: mg_dns_reply_record.md }
- { type: file, name: mg_dns_send_reply.md } - { name: mg_dns_send_reply.md }
--- ---
Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`. Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`.
......
--- ---
title: "HTTP + Websocket" title: "Common API reference"
symbol_kind: "intro" symbol_kind: "intro"
decl_name: "http.h" decl_name: "http.h"
items: items:
- { type: file, name: mg_set_protocol_http_websocket.md } - { name: mg_set_protocol_http_websocket.md }
- { type: file, name: mg_send_websocket_handshake.md } - { name: mg_send_websocket_handshake.md }
- { type: file, name: mg_send_websocket_handshake2.md } - { name: mg_send_websocket_handshake2.md }
- { type: file, name: mg_connect_ws.md } - { name: mg_connect_ws.md }
- { type: file, name: mg_connect_ws_opt.md } - { name: mg_connect_ws_opt.md }
- { type: file, name: mg_send_websocket_frame.md } - { name: mg_send_websocket_frame.md }
- { type: file, name: mg_send_websocket_framev.md } - { name: mg_send_websocket_framev.md }
- { type: file, name: mg_printf_websocket_frame.md } - { name: mg_printf_websocket_frame.md }
- { type: file, name: mg_send_http_chunk.md } - { name: mg_url_decode.md }
- { type: file, name: mg_printf_http_chunk.md } - { name: struct_http_message.md }
- { type: file, name: mg_send_response_line.md } - { name: struct_websocket_message.md }
- { type: file, name: mg_send_head.md } - { name: struct_mg_http_multipart_part.md }
- { type: file, name: mg_printf_html_escape.md }
- { type: file, name: mg_parse_http.md }
- { type: file, name: mg_get_http_header.md }
- { type: file, name: mg_http_parse_header.md }
- { type: file, name: mg_parse_multipart.md }
- { type: file, name: mg_get_http_var.md }
- { type: file, name: mg_url_decode.md }
- { type: file, name: mg_http_create_digest_auth_header.md }
- { type: file, name: mg_connect_http.md }
- { type: file, name: mg_connect_http_opt.md }
- { type: file, name: mg_serve_http.md }
- { type: file, name: mg_http_serve_file.md }
- { type: file, name: mg_register_http_endpoint.md }
- { type: file, name: mg_file_upload_handler.md }
- { type: file, name: mg_http_check_digest_auth.md }
- { type: file, name: mg_fu_fname_fn.md }
- { type: file, name: struct_http_message.md }
- { type: file, name: struct_websocket_message.md }
- { type: file, name: struct_mg_http_multipart_part.md }
- { type: file, name: struct_mg_serve_http_opts.md }
--- ---
......
...@@ -7,12 +7,12 @@ signature: | ...@@ -7,12 +7,12 @@ signature: |
int is_form_url_encoded); int is_form_url_encoded);
--- ---
Decodes URL-encoded string. Decodes a URL-encoded string.
Source string is specified by (`src`, `src_len`), and destination is Source string is specified by (`src`, `src_len`), and destination is
(`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then (`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then
`+` character is decoded as a blank space character. This function `+` character is decoded as a blank space character. This function
guarantees to `\0`-terminate the destination. If destination is too small, 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 decoded string is returned, not counting final `\0`. a length of the decoded string is returned, not counting final NUL.
---
title: "Client API reference"
symbol_kind: "intro"
decl_name: "http_client.h"
items:
- { name: mg_connect_http.md }
- { name: mg_connect_http_opt.md }
- { name: mg_http_create_digest_auth_header.md }
---
...@@ -12,7 +12,7 @@ signature: | ...@@ -12,7 +12,7 @@ signature: |
Helper function that creates an outbound HTTP connection. Helper function that creates an outbound HTTP connection.
`url` is a URL to fetch. It must be properly URL-encoded, e.g. have `url` is the URL to fetch. It must be properly URL-encoded, e.g. have
no spaces, etc. By default, `mg_connect_http()` sends the Connection and no spaces, etc. By default, `mg_connect_http()` sends the Connection and
Host headers. `extra_headers` is an extra HTTP header to send, e.g. Host headers. `extra_headers` is an extra HTTP header to send, e.g.
`"User-Agent: my-app\r\n"`. `"User-Agent: my-app\r\n"`.
......
---
title: "Server API reference"
symbol_kind: "intro"
decl_name: "http_server.h"
items:
- { name: mg_parse_http.md }
- { name: mg_get_http_header.md }
- { name: mg_http_parse_header.md }
- { name: mg_parse_multipart.md }
- { name: mg_get_http_var.md }
- { name: mg_serve_http.md }
- { name: mg_http_serve_file.md }
- { name: mg_register_http_endpoint.md }
- { name: mg_file_upload_handler.md }
- { name: mg_http_check_digest_auth.md }
- { name: mg_send_http_chunk.md }
- { name: mg_printf_http_chunk.md }
- { name: mg_send_response_line.md }
- { name: mg_send_head.md }
- { name: mg_printf_html_escape.md }
- { name: mg_fu_fname_fn.md }
- { name: struct_mg_serve_http_opts.md }
---
...@@ -7,8 +7,9 @@ signature: | ...@@ -7,8 +7,9 @@ signature: |
int64_t content_length, const char *extra_headers); int64_t content_length, const char *extra_headers);
--- ---
Sends a response line and headers. Sends the response line and headers.
This function sends a response line with the `status_code`, and automatically This function sends the response line with the `status_code`, and
automatically
sends one header: either "Content-Length" or "Transfer-Encoding". sends one header: either "Content-Length" or "Transfer-Encoding".
If `content_length` is negative, then "Transfer-Encoding: chunked" header If `content_length` is negative, then "Transfer-Encoding: chunked" header
is sent, otherwise, "Content-Length" header is sent. is sent, otherwise, "Content-Length" header is sent.
......
...@@ -9,9 +9,8 @@ signature: | ...@@ -9,9 +9,8 @@ signature: |
Sends buffer `buf` of size `len` to the client using chunked HTTP encoding. 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 This function sends the buffer size as hex number + newline first, then
the buffer itself, then the newline. For example, 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)` whill append the `3\r\nfoo\r\n` string
*to to the `nc->send_mbuf` output IO buffer.
the `nc->send_mbuf` output IO buffer.
NOTE: The HTTP header "Transfer-Encoding: chunked" should be sent prior to NOTE: The HTTP header "Transfer-Encoding: chunked" should be sent prior to
using this function. using this function.
......
...@@ -7,7 +7,7 @@ signature: | ...@@ -7,7 +7,7 @@ signature: |
const char *extra_headers); const char *extra_headers);
--- ---
Sends a response status line. Sends the response status line.
If `extra_headers` is not NULL, then `extra_headers` are also sent 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 reponse line. `extra_headers` must NOT end end with new line.
Example: Example:
......
--- ---
items: items:
- { type: dir, name: mbuf.h } - { name: mbuf.h }
- { type: dir, name: net.h } - { name: net.h }
- { type: dir, name: http.h } - { name: http.h }
- { type: dir, name: dns.h } - { name: http_server.h }
- { type: dir, name: dns-server.h } - { name: http_client.h }
- { type: dir, name: mqtt.h } - { name: dns.h }
- { type: dir, name: mqtt-broker.h } - { name: dns_server.h }
- { type: dir, name: coap.h } - { name: resolv.h }
- { type: dir, name: util.h } - { name: mqtt.h }
- { name: mqtt_server.h }
- { name: coap.h }
- { name: util.h }
- { name: uri.h }
--- ---
...@@ -3,14 +3,14 @@ title: "Memory Buffers" ...@@ -3,14 +3,14 @@ title: "Memory Buffers"
symbol_kind: "intro" symbol_kind: "intro"
decl_name: "mbuf.h" decl_name: "mbuf.h"
items: items:
- { type: file, name: mbuf_init.md } - { name: mbuf_init.md }
- { type: file, name: mbuf_free.md } - { name: mbuf_free.md }
- { type: file, name: mbuf_append.md } - { name: mbuf_append.md }
- { type: file, name: mbuf_insert.md } - { name: mbuf_insert.md }
- { type: file, name: mbuf_remove.md } - { name: mbuf_remove.md }
- { type: file, name: mbuf_resize.md } - { name: mbuf_resize.md }
- { type: file, name: mbuf_trim.md } - { name: mbuf_trim.md }
- { type: file, name: struct_mbuf.md } - { name: struct_mbuf.md }
--- ---
Mbufs are mutable/growing memory buffers, like C++ strings. Mbufs are mutable/growing memory buffers, like C++ strings.
......
---
title: "MQTT Broker"
symbol_kind: "intro"
decl_name: "mqtt-broker.h"
items:
- { type: file, name: mg_mqtt_broker_init.md }
- { type: file, name: mg_mqtt_broker.md }
- { type: file, name: mg_mqtt_next.md }
- { type: file, name: struct_mg_mqtt_session.md }
- { type: file, name: struct_mg_mqtt_broker.md }
---
--- ---
title: "MQTT" title: "MQTT API reference"
symbol_kind: "intro" symbol_kind: "intro"
decl_name: "mqtt.h" decl_name: "mqtt.h"
items: items:
- { type: file, name: mg_set_protocol_mqtt.md } - { name: mg_set_protocol_mqtt.md }
- { type: file, name: mg_send_mqtt_handshake.md } - { name: mg_send_mqtt_handshake.md }
- { type: file, name: mg_send_mqtt_handshake_opt.md } - { name: mg_send_mqtt_handshake_opt.md }
- { type: file, name: mg_mqtt_publish.md } - { name: mg_mqtt_publish.md }
- { type: file, name: mg_mqtt_subscribe.md } - { name: mg_mqtt_subscribe.md }
- { type: file, name: mg_mqtt_unsubscribe.md } - { name: mg_mqtt_unsubscribe.md }
- { type: file, name: mg_mqtt_disconnect.md } - { name: mg_mqtt_disconnect.md }
- { type: file, name: mg_mqtt_connack.md } - { name: mg_mqtt_connack.md }
- { type: file, name: mg_mqtt_puback.md } - { name: mg_mqtt_puback.md }
- { type: file, name: mg_mqtt_pubrec.md } - { name: mg_mqtt_pubrec.md }
- { type: file, name: mg_mqtt_pubrel.md } - { name: mg_mqtt_pubrel.md }
- { type: file, name: mg_mqtt_pubcomp.md } - { name: mg_mqtt_pubcomp.md }
- { type: file, name: mg_mqtt_suback.md } - { name: mg_mqtt_suback.md }
- { type: file, name: mg_mqtt_unsuback.md } - { name: mg_mqtt_unsuback.md }
- { type: file, name: mg_mqtt_ping.md } - { name: mg_mqtt_ping.md }
- { type: file, name: mg_mqtt_pong.md } - { name: mg_mqtt_pong.md }
- { type: file, name: mg_mqtt_next_subscribe_topic.md } - { name: mg_mqtt_next_subscribe_topic.md }
- { type: file, name: struct_mg_mqtt_topic_expression.md } - { name: struct_mg_mqtt_topic_expression.md }
--- ---
......
---
title: "MQTT Server API reference"
symbol_kind: "intro"
decl_name: "mqtt_server.h"
items:
- { name: mg_mqtt_broker_init.md }
- { name: mg_mqtt_broker.md }
- { name: mg_mqtt_next.md }
- { name: struct_mg_mqtt_session.md }
- { name: struct_mg_mqtt_broker.md }
---
--- ---
title: "Core: TCP/UDP/SSL" title: "Core API: TCP/UDP/SSL"
symbol_kind: "intro" symbol_kind: "intro"
decl_name: "net.h" decl_name: "net.h"
items: items:
- { type: file, name: mg_mgr_init.md } - { name: mg_mgr_init.md }
- { type: file, name: mg_mgr_free.md } - { name: mg_mgr_free.md }
- { type: file, name: mg_mgr_poll.md } - { name: mg_mgr_poll.md }
- { type: file, name: mg_broadcast.md } - { name: mg_broadcast.md }
- { type: file, name: mg_next.md } - { name: mg_next.md }
- { type: file, name: mg_add_sock.md } - { name: mg_add_sock.md }
- { type: file, name: mg_add_sock_opt.md } - { name: mg_add_sock_opt.md }
- { type: file, name: mg_bind.md } - { name: mg_bind.md }
- { type: file, name: mg_bind_opt.md } - { name: mg_bind_opt.md }
- { type: file, name: mg_connect.md } - { name: mg_connect.md }
- { type: file, name: mg_connect_opt.md } - { name: mg_connect_opt.md }
- { type: file, name: mg_set_ssl.md } - { name: mg_set_ssl.md }
- { type: file, name: mg_send.md } - { name: mg_send.md }
- { type: file, name: mg_printf.md } - { name: mg_printf.md }
- { type: file, name: mg_vprintf.md } - { name: mg_vprintf.md }
- { type: file, name: mg_socketpair.md } - { name: mg_socketpair.md }
- { type: file, name: mg_check_ip_acl.md } - { name: mg_check_ip_acl.md }
- { type: file, name: mg_enable_multithreading.md } - { name: mg_enable_multithreading.md }
- { type: file, name: mg_enable_javascript.md } - { name: mg_enable_javascript.md }
- { type: file, name: mg_set_timer.md } - { name: mg_set_timer.md }
- { type: file, name: mg_time.md } - { name: mg_time.md }
- { type: file, name: mg_event_handler_t.md } - { name: mg_event_handler_t.md }
- { type: file, name: struct_mg_mgr.md } - { name: struct_mg_mgr.md }
- { type: file, name: struct_mg_connection.md } - { name: struct_mg_connection.md }
- { type: file, name: struct_mg_add_sock_opts.md } - { name: struct_mg_add_sock_opts.md }
- { type: file, name: struct_mg_bind_opts.md } - { name: struct_mg_bind_opts.md }
- { type: file, name: struct_mg_connect_opts.md } - { name: struct_mg_connect_opts.md }
--- ---
NOTE: Mongoose manager is single threaded. It does not protect NOTE: Mongoose manager is single threaded. It does not protect
......
---
title: "API reference"
symbol_kind: "intro"
decl_name: "resolv.h"
items:
- { name: mg_resolve_async.md }
- { name: mg_resolve_async_opt.md }
- { name: mg_resolve_from_hosts_file.md }
- { name: struct_mg_resolve_async_opts.md }
---
---
title: "mg_resolve_async()"
decl_name: "mg_resolve_async"
symbol_kind: "func"
signature: |
int mg_resolve_async(struct mg_mgr *mgr, const char *name, int query,
mg_resolve_callback_t cb, void *data);
---
See `mg_resolve_async_opt()`
---
title: "mg_resolve_async_opt()"
decl_name: "mg_resolve_async_opt"
symbol_kind: "func"
signature: |
int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
mg_resolve_callback_t cb, void *data,
struct mg_resolve_async_opts opts);
---
Resolved a DNS name asynchronously.
Upon successful resolution, the user callback will be invoked
with the full DNS response message and a pointer to the user's
context `data`.
In case of timeout while performing the resolution the callback
will receive a NULL `msg`.
The DNS answers can be extracted with `mg_next_record` and
`mg_dns_parse_record_data`:
[source,c]
----
struct in_addr ina;
struct mg_dns_resource_record *rr = mg_next_record(msg, MG_DNS_A_RECORD,
NULL);
mg_dns_parse_record_data(msg, rr, &ina, sizeof(ina));
----
---
title: "mg_resolve_from_hosts_file()"
decl_name: "mg_resolve_from_hosts_file"
symbol_kind: "func"
signature: |
int mg_resolve_from_hosts_file(const char *host, union socket_address *usa);
---
Resolve a name from `/etc/hosts`.
Returns 0 on success, -1 on failure.
---
title: "struct mg_resolve_async_opts"
decl_name: "struct mg_resolve_async_opts"
symbol_kind: "struct"
signature: |
struct mg_resolve_async_opts {
const char *nameserver_url;
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 */
int only_literal; /* only resolves literal addrs; sync cb invocation */
struct mg_connection **dns_conn; /* return DNS connection */
};
---
Options for `mg_resolve_async_opt`.
---
title: "URI"
symbol_kind: "intro"
decl_name: "uri.h"
items:
- { name: mg_parse_uri.md }
---
---
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,
struct mg_str *user_info, struct mg_str *host,
unsigned int *port, struct mg_str *path, struct mg_str *query,
struct mg_str *fragment);
---
Parses an URI and fills string chunks with locations of the respective
uri components within the input uri string. NULL pointers will be
ignored.
General syntax:
[scheme://[user_info@]]host[:port][/path][?query][#fragment]
Example:
foo.com:80
tcp://foo.com:1234
http://foo.com:80/bar?baz=1
https://user:pw@foo.com:443/blah
`path` will include the leading slash. `query` won't include the leading `?`.
`host` can contain embedded colons if surrounded by square brackets in order
to support IPv6 literal addresses.
Returns 0 on success, -1 on error.
--- ---
title: "Utilities" title: "Utility API"
symbol_kind: "intro" symbol_kind: "intro"
decl_name: "util.h" decl_name: "util.h"
items: items:
- { type: file, name: mg_skip.md } - { name: mg_skip.md }
- { type: file, name: mg_ncasecmp.md } - { name: mg_ncasecmp.md }
- { type: file, name: mg_casecmp.md } - { name: mg_casecmp.md }
- { type: file, name: mg_base64_decode.md } - { name: mg_base64_decode.md }
- { type: file, name: mg_base64_encode.md } - { name: mg_base64_encode.md }
- { type: file, name: mg_stat.md } - { name: mg_stat.md }
- { type: file, name: mg_fopen.md } - { name: mg_fopen.md }
- { type: file, name: mg_open.md } - { name: mg_open.md }
- { type: file, name: mg_start_thread.md } - { name: mg_start_thread.md }
- { type: file, name: mg_conn_addr_to_str.md } - { name: mg_conn_addr_to_str.md }
- { type: file, name: mg_sock_to_str.md } - { name: mg_sock_to_str.md }
- { type: file, name: mg_sock_addr_to_str.md } - { name: mg_sock_addr_to_str.md }
- { type: file, name: mg_hexdump.md } - { name: mg_hexdump.md }
- { type: file, name: mg_hexdump_connection.md } - { name: mg_hexdump_connection.md }
- { type: file, name: mg_avprintf.md } - { name: mg_avprintf.md }
- { type: file, name: mg_is_big_endian.md } - { name: mg_is_big_endian.md }
- { type: file, name: mg_next_comma_list_entry.md } - { name: mg_next_comma_list_entry.md }
- { type: file, name: mg_match_prefix.md } - { name: mg_match_prefix.md }
--- ---
......
---
title: CoAP client example
---
TBD
---
title: CoAP
items:
- { name: server_example.md }
- { name: client_example.md }
- { name: ../c-api/coap.h/ }
---
---
title: CoAP server example
---
TBD
---
title: Misc API
items:
- { name: ../c-api/net.h }
- { name: ../c-api/util.h }
- { name: ../c-api/uri.h }
- { name: ../c-api/mbuf.h }
---
---
title: DNS client example
---
TBD
---
title: DNS
items:
- { name: server_example.md }
- { name: client_example.md }
- { name: ../c-api/dns.h/ }
- { name: ../c-api/dns_server.h/ }
---
---
title: DNS server example
---
TBD
---
title: Async DNS resolver
items:
- { name: overview.md }
- { name: ../c-api/resolv.h/ }
---
---
title: Overview
---
TBD
---
title: CGI
---
[CGI](https://en.wikipedia.org/wiki/Common_Gateway_Interface)
is a simple mechanism to generate dynamic content.
In order to use CGI, call `mg_serve_http()` function and use
`.cgi` file extension for the CGI files. To be more precise,
all files that match `cgi_file_pattern` setting in the
`struct mg_serve_http_opts` are treated as CGI.
If `cgi_file_pattern` is NULL, `**.cgi$|**.php$` is used.
If Mongoose recognises a file as CGI, it executes it, and sends the output
back to the client. Therefore,
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
of the respective CGI scripts.
It is possible to hardcode the path to the CGI interpreter for all
CGI scripts and disregard the shebang line. To do that, set the
`cgi_interpreter` setting in the `struct mg_serve_http_opts`.
NOTE: PHP scripts must use `php-cgi.exe` as CGI interpreter, not `php.exe`.
Example:
```c
opts.cgi_interpreter = "C:\\ruby\\ruby.exe";
```
---
title: HTTP client example
---
To create an HTTP client, follow this pattern:
1. Create an outbound connection by calling `mg_connect_http()`
2. Create an event handler function that handles `MG_EV_HTTP_REPLY` event
Here's an example of the simplest HTTP client.
Error checking is omitted for the sake of clarity:
```c
#include "mongoose.h"
static const char *url = "http://www.google.com";
static int exit_flag = 0;
static void ev_handler(struct mg_connection *c, int ev, void *p) {
if (ev == MG_EV_HTTP_REPLY) {
c->flags |= MG_F_CLOSE_IMMEDIATELY;
fwrite(hm->message.p, 1, hm->message.len, stdout);
putchar('\n');
exit_flag = 1;
}
}
int main(void) {
struct mg_mgr mgr;
mg_mgr_init(&mgr, NULL);
mg_connect_http(mgr, ev_handler, url, NULL, NULL);
while (exit_flag == 0) {
mg_mgr_poll(&mgr, 1000);
}
mg_mgr_free(&mgr);
return 0;
}
```
See full source code at [HTTP client example](https://github.com/cesanta/dev/tree/master/mongoose/examples/http_client).
---
title: Digest Authentication
---
TBD
---
title: HTTP events
---
As discussed in the overview, `mg_set_protocol_http_websocket()` function
parses incoming data, treats it as HTTP or WebSocket, and triggers high-level
HTTP or WebSocket events. Here is a list of events specific to HTTP.
- MG_EV_HTTP_REQUEST: An HTTP request has arrived. Parsed request
is passed as
`struct http_message` through the handler's `void *ev_data` pointer.
- MG_EV_HTTP_REPLY: An HTTP reply has arrived. Parsed reply is
passed as `struct http_message` through the handler's `void *ev_data`
pointer.
- MG_EV_HTTP_MULTIPART_REQUEST: A multipart POST request has arrived.
This event is sent before body is parsed. After this, the user
should expect a sequence of MG_EV_HTTP_PART_BEGIN/DATA/END requests.
This is also the last time when headers and other request fields are
accessible.
- MG_EV_HTTP_CHUNK: An HTTP chunked-encoding chunk has arrived.
The parsed HTTP reply is passed as `struct http_message` through the
handler's `void *ev_data` pointer. `http_message::body` would contain
incomplete, reassembled HTTP body.
It will grow with every new chunk that arrives, and it can
potentially consume a lot of memory. The event handler may process
the body as chunks are coming, and signal Mongoose to delete processed
body by setting `MG_F_DELETE_CHUNK` in `mg_connection::flags`. When
the last zero chunk is received,
Mongoose sends `MG_EV_HTTP_REPLY` event with
full reassembled body (if handler did not signal to delete chunks) or
with empty body (if handler did signal to delete chunks).
- MG_EV_HTTP_PART_BEGIN: a new part of multipart message is started,
extra parameters are passed in mg_http_multipart_part
- MG_EV_HTTP_PART_DATA: a new portion of data from the multiparted message
no additional headers are available, only data and data size
- MG_EV_HTTP_PART_END: a final boundary received, analogue to maybe used to
find the end of packet
Note: Mongoose should be compiled with MG_ENABLE_HTTP_STREAMING_MULTIPART
to enable multipart events.
---
title: Serving files
---
API function `mg_serve_http()` makes it easy to serve files from a filesystem.
Generally speaking, that function is an implementation of the HTTP server
that serves static files, CGI and SSI. It's behavior is driven by a list
of options that are consolidated into the `struct mg_serve_http_opts`
structure. See [struct mg_serve_http_opts](#) definition for the full list
of capabilities of `mg_serve_http()`.
For example, in order to create a web server that serves static files
from the current directory, implement event handler function as follows:
```c
static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_HTTP_REQUEST) {
struct mg_serve_http_opts opts;
memset(&opts, 0, sizeof(opts); // Reset all options to defaults
opts.document_root = "."; // Serve files from the current directory
mg_serve_http(c, (struct http_message *) ev_data, s_http_server_opts);
}
}
```
See working example at [simplest web server](https://github.com/cesanta/mongoose/tree/master/examples/simplest_web_server).
Sometimes there is no need to implement a full static web server, for example
if one works on a RESTful server. If certain endpoints must return the contents
of a static file, a simpler `mg_http_serve_file()` function can be used:
```c
static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
switch (ev) {
case MG_EV_HTTP_REQUEST: {
struct http_message *hm = (struct http_message *) ev_data;
mg_http_serve_file(c, hm, "file.txt",
mg_mk_str("text/plain"), mg_mk_str(""));
break;
}
...
}
}
```
---
title: HTTP
items:
- { name: server_example.md }
- { name: client_example.md }
- { name: events.md }
- { name: files.md }
- { name: cgi.md }
- { name: ssi.md }
- { name: upload.md }
- { name: ssl.md }
- { name: digest_auth.md }
- { name: ../c-api/http.h/ }
- { name: ../c-api/http_server.h/ }
- { name: ../c-api/http_client.h/ }
---
---
title: HTTP server example
---
To create an HTTP server, follow this pattern:
1. Create a listening connection by calling `mg_bind()` or `mg_bind_opt()`
2. Call `mg_set_protocol_http_websocket()` for that listening connection.
That attaches a built-in HTTP event handler which parses incoming
data and triggers HTTP-specific events. For example, when an HTTP request
is fully buffered, a built-in HTTP handler parses the request and
calls user-defined event handler with `MG_EV_HTTP_REQUEST` event and
parsed HTTP request as an event data.
3. Create event handler function. Note that event handler receives all
events - low level TCP events like `MG_EV_RECV` and high-level HTTP
events like `MG_EV_HTTP_REQUEST`. Normally, an event handler function
should only handle `MG_EV_HTTP_REQUEST` event.
Here's an example of the simplest HTTP server. Error checking is omitted for
the sake of clarity:
```c
#include "mongoose.h"
static const char *s_http_port = "8000";
static void ev_handler(struct mg_connection *c, int ev, void *p) {
if (ev == MG_EV_HTTP_REQUEST) {
struct http_message *hm = (struct http_message *) 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);
}
}
int main(void) {
struct mg_mgr mgr;
struct mg_connection *c;
mg_mgr_init(&mgr, NULL);
c = mg_bind(&mgr, s_http_port, ev_handler);
mg_set_protocol_http_websocket(c);
for (;;) {
mg_mgr_poll(&mgr, 1000);
}
mg_mgr_free(&mgr);
return 0;
}
```
---
title: SSI
---
Server Side Includes (SSI) is a simple interpreted server-side scripting
language which is most commonly used to include the contents of a file
into a web page. It can be useful when it is desirable to include a common
piece of code throughout a website, for example, headers and footers.
In order to use SSI, call `mg_serve_http()` function and use
`.shtml` file extension for the SSI files. To be more precise,
all files that match `ssi_pattern` setting in the
`struct mg_serve_http_opts` are treated as SSI.
If `ssi_pattern` is NULL, `**.shtml$|**.shtm$` is used.
Unknown SSI directives are silently ignored by Mongoose. Currently,
the following SSI directives are supported:
- `<!--#include FILE_TO_INCLUDE -->` - inject the content of some other file
- `<!--#exec "COMMAND_TO_EXECUTE" -->` - runs a command and inject the output
- `<!--#call COMMAND -->` - triggers `MG_EV_SSI_CALL` event
Note that `<!--#include ... -->` directive supports three path specifications:
- `<!--#include virtual="path" -->` Path is relative to web server root
- `<!--#include abspath="path" -->` Path is absolute or relative to the
web server working dir
- `<!--#include file="path" -->`, `<!--#include "path" -->`
Path is relative to current document
The include directive may be used to include the contents of a file or
the result of running a CGI script.
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,
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
`mg_printf()`. This is a flexible way of generating a web page on
server side by calling a C event handler. Example:
`<!--#call foo --> <!--#call bar -->`
In the event handler:
```c
case MG_EV_SSI_CALL: {
const char *param = (const char *) ev_data;
if (strcmp(param, "foo") == 0) {
mg_printf(c, "hello from foo");
} else if (strcmp(param, "bar") == 0) {
mg_printf(c, "hello from bar");
}
break;
}
```
---
title: Enabling HTTPS
---
To enable SSL on the server side, please follow these steps:
- Obtain SSL certificate file and private key file
- Declare `struct mg_bind_opts`, initialize `ssl_cert` and `ssl_key`
- Use `mg_bind_opt()` to create listening socket
Example:
```c
int main(void) {
struct mg_mgr mgr;
struct mg_connection *c;
struct mg_bind_opts bind_opts;
mg_mgr_init(&mgr, NULL);
memset(&bind_opts, 0, sizeof(bind_opts));
bind_opts.ssl_cert = "server.pem";
bind_opts.ssl_key = "key.pem";
// Use bind_opts to specify SSL certificate & key file
c = mg_bind_opt(&mgr, "443", ev_handler, bind_opts);
mg_set_protocol_http_websocket(c);
...
}
```
For the full example, please see the [Simplest HTTPS server example](https://github.com/cesanta/dev/tree/master/mongoose/examples/simplest_web_server_ssl).
---
title: Handling file uploads
---
In order to handle file uploads, use the following HTML snippet:
```HTML
&lt;form method="POST" action="/upload" enctype="multipart/form-data"&gt;
&lt;input type="file" name="file"&gt;
&lt;input type="submit" value="Upload"&gt;
&lt;/form&gt;
```
Uploaded files will be sent to the `/upload` endpoint via the `POST` request.
HTTP body will contain multipart-encoded buffer with the file contents.
To save the uploaded file, use this code snippet:
```c
struct mg_str cb(struct mg_connection *c, struct mg_str file_name) {
// Return the same filename. Do not actually do this except in test!
// fname is user-controlled and needs to be sanitized.
return file_name;
}
void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
switch (ev) {
...
case MG_EV_HTTP_PART_BEGIN:
case MG_EV_HTTP_PART_DATA:
case MG_EV_HTTP_PART_END:
mg_file_upload_handler(c, ev, ev_data, cb);
break;
}
}
```
...@@ -3,9 +3,11 @@ title: Mongoose - a networking library ...@@ -3,9 +3,11 @@ title: Mongoose - a networking library
color: '#1D6482' color: '#1D6482'
repo: https://github.com/cesanta/mongoose repo: https://github.com/cesanta/mongoose
items: items:
- { type: file, name: overview.md } - { name: overview }
- { type: dir, name: usage-example } - { name: http }
- { type: dir, name: design-concept } - { name: mqtt }
- { type: dir, name: build-options } - { name: dns }
- { type: flat, name: c-api } - { name: coap }
- { name: dns_resolver }
- { name: core }
--- ---
---
title: MQTT client example
---
TBD
---
title: MQTT
items:
- { name: server_example.md }
- { name: client_example.md }
- { name: ../c-api/mqtt.h/ }
- { name: ../c-api/mqtt_server.h/ }
---
---
title: MQTT server example
---
TBD
--- ---
title: Design Concept title: Design Concept
items:
- { type: file, name: memory-buffers.md }
- { type: file, name: event-handler.md }
- { type: file, name: events.md }
- { type: file, name: conn-flags.md }
--- ---
Mongoose is a multi-protocol networking library that implements non-blocking, Mongoose has three basic data structures:
asyncronous IO and provides event-based APIs. It has three basic data
structures:
- `struct mg_mgr` is an event manager that holds all active connections - `struct mg_mgr` is an event manager that holds all active connections
- `struct mg_connection` describes a connection - `struct mg_connection` describes a connection
...@@ -22,8 +15,33 @@ listening connection. Each connection is described by the `struct mg_connection` ...@@ -22,8 +15,33 @@ listening connection. Each connection is described by the `struct mg_connection`
structure, which has a number of fields like socket, event handler function, structure, which has a number of fields like socket, event handler function,
send/receive buffer, flags, etc. send/receive buffer, flags, etc.
Mongoose's usage pattern is to declare and initialise event manager, create An application that uses mongoose should follow a standard pattern of
connections and create an event loop by calling `mg_mgr_poll()` in a loop. event-driven application:
1. declare and initialise event manager:
```c
struct mg_mgr mgr;
mg_mgr_init(&mgr, NULL);
```
2. Create connections. For example, a server application should create
listening connections:
```c
struct mg_connection *c = mg_bind(&mgr, "80", ev_handler_function);
mg_set_protocol_http_websocket(c);
```
3. create an event loop by calling `mg_mgr_poll()` in a loop:
```c
for (;;) {
mg_mgr_poll(&mgr, 1000);
}
```
`mg_mgr_poll()` iterates over all sockets, accepts new connections, sends and `mg_mgr_poll()` iterates over all sockets, accepts new connections, sends and
receives data, closes connections and calls event handler functions for the receives data, closes connections and calls event handler functions for the
respective events. respective events. For the full example, see
[Usage Example](#/overview/usage-example.md/)
which implements TCP echo server.
--- ---
title: Overview title: Overview
items:
# - { name: usage-example.md }
- { name: concept.md }
- { name: mbufs.md }
- { name: event-handler.md }
- { name: events.md }
- { name: conn-flags.md }
- { name: build-options }
- { name: usage-example.md }
--- ---
Mongoose is a swiss army knife for embedded network programming. Mongoose is a networking library written in C.
It is a swiss army knife for embedded network programming.
It implements event-driven non-blocking APIs for TCP, UDP, HTTP, It implements event-driven non-blocking APIs for TCP, UDP, HTTP,
WebSocket, CoAP, MQTT for client and server mode. WebSocket, CoAP, MQTT for client and server mode.
Features include: Features include:
- Cross-platform: works on Linux/UNIX, MacOS, QNX, eCos, Windows, Android, - Cross-platform: works on Linux/UNIX, MacOS, QNX, eCos, Windows, Android,
iPhone, FreeRTOS (TI CC3200, ESP8266) and more iPhone, FreeRTOS
- Single-threaded, asynchronous, non-blocking core with simple event-based API
- Native support for [PicoTCP embedded TCP/IP stack](http://www.picotcp.com), - Native support for [PicoTCP embedded TCP/IP stack](http://www.picotcp.com),
[LWIP embedded TCP/IP stack](https://en.wikipedia.org/wiki/LwIP) [LWIP embedded TCP/IP stack](https://en.wikipedia.org/wiki/LwIP)
- Works on a variety of embedded boards: TI CC3200, TI MSP430, STM32, ESP8266;
on all Linux-based boards like Raspberry PI, BeagleBone, etc
- Single-threaded, asynchronous, non-blocking core with simple event-based API
- Built-in protocols: - Built-in protocols:
- plain TCP, plain UDP, SSL/TLS (over TCP, one-way or two-way) - plain TCP, plain UDP, SSL/TLS (one-way or two-way), client and server
- HTTP client and server - HTTP client and server
- WebSocket client and server - WebSocket client and server
- MQTT client and server - MQTT client and server
......
--- ---
title: Usage Example title: Example - TCP echo server
--- ---
- Copy `mongoose.c` and `mongoose.h` to your build tree - Copy `mongoose.c` and `mongoose.h` to your build tree
......
...@@ -8148,7 +8148,7 @@ void mg_mqtt_disconnect(struct mg_connection *nc) { ...@@ -8148,7 +8148,7 @@ void mg_mqtt_disconnect(struct mg_connection *nc) {
#endif /* MG_DISABLE_MQTT */ #endif /* MG_DISABLE_MQTT */
#ifdef MG_MODULE_LINES #ifdef MG_MODULE_LINES
#line 1 "./src/mqtt-broker.c" #line 1 "./src/mqtt_server.c"
#endif #endif
/* /*
* Copyright (c) 2014 Cesanta Software Limited * Copyright (c) 2014 Cesanta Software Limited
...@@ -8693,7 +8693,7 @@ void mg_set_protocol_dns(struct mg_connection *nc) { ...@@ -8693,7 +8693,7 @@ void mg_set_protocol_dns(struct mg_connection *nc) {
#endif /* MG_DISABLE_DNS */ #endif /* MG_DISABLE_DNS */
#ifdef MG_MODULE_LINES #ifdef MG_MODULE_LINES
#line 1 "./src/dns-server.c" #line 1 "./src/dns_server.c"
#endif #endif
/* /*
* Copyright (c) 2014 Cesanta Software Limited * Copyright (c) 2014 Cesanta Software Limited
......
...@@ -1065,7 +1065,7 @@ const char *c_strnstr(const char *s, const char *find, size_t slen); ...@@ -1065,7 +1065,7 @@ const char *c_strnstr(const char *s, const char *find, size_t slen);
*/ */
/* /*
* === Core: TCP/UDP/SSL * === Core API: TCP/UDP/SSL
* *
* NOTE: Mongoose manager is single threaded. It does not protect * NOTE: Mongoose manager is single threaded. It does not protect
* its data structures by mutexes, therefore all functions that are dealing * its data structures by mutexes, therefore all functions that are dealing
...@@ -1730,7 +1730,7 @@ int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out); ...@@ -1730,7 +1730,7 @@ int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out);
*/ */
/* /*
* === Utilities * === Utility API
*/ */
#ifndef CS_MONGOOSE_SRC_UTIL_H_ #ifndef CS_MONGOOSE_SRC_UTIL_H_
...@@ -1940,7 +1940,7 @@ int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str); ...@@ -1940,7 +1940,7 @@ int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str);
*/ */
/* /*
* === HTTP + Websocket * === Common API reference
*/ */
#ifndef CS_MONGOOSE_SRC_HTTP_H_ #ifndef CS_MONGOOSE_SRC_HTTP_H_
...@@ -2208,70 +2208,6 @@ void mg_printf_websocket_frame(struct mg_connection *nc, int op_and_flags, ...@@ -2208,70 +2208,6 @@ void mg_printf_websocket_frame(struct mg_connection *nc, int op_and_flags,
const char *fmt, ...); const char *fmt, ...);
#endif /* MG_DISABLE_HTTP_WEBSOCKET */ #endif /* MG_DISABLE_HTTP_WEBSOCKET */
/*
* 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
*to
* the `nc->send_mbuf` output IO buffer.
*
* NOTE: The HTTP header "Transfer-Encoding: chunked" should be sent prior to
* using this function.
*
* NOTE: do not forget to send an empty chunk at the end of the response,
* to tell the client that everything was sent. Example:
*
* ```
* mg_printf_http_chunk(nc, "%s", "my response!");
* mg_send_http_chunk(nc, "", 0); // Tell the client we're finished
* ```
*/
void mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len);
/*
* Sends a printf-formatted HTTP chunk.
* Functionality is similar to `mg_send_http_chunk()`.
*/
void mg_printf_http_chunk(struct mg_connection *nc, const char *fmt, ...);
/*
* Sends a 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.
* Example:
*
* mg_send_response_line(nc, 200, "Access-Control-Allow-Origin: *");
*
* Will result in:
*
* HTTP/1.1 200 OK\r\n
* Access-Control-Allow-Origin: *\r\n
*/
void mg_send_response_line(struct mg_connection *c, int status_code,
const char *extra_headers);
/*
* Sends a response line and headers.
* This function sends a response line with the `status_code`, and automatically
* sends one header: either "Content-Length" or "Transfer-Encoding".
* If `content_length` is negative, then "Transfer-Encoding: chunked" header
* is sent, otherwise, "Content-Length" header is sent.
*
* NOTE: If `Transfer-Encoding` is `chunked`, then message body must be sent
* using `mg_send_http_chunk()` or `mg_printf_http_chunk()` functions.
* Otherwise, `mg_send()` or `mg_printf()` must be used.
* Extra headers could be set through `extra_headers`. Note `extra_headers`
* must NOT be terminated by a new line.
*/
void mg_send_head(struct mg_connection *n, int status_code,
int64_t content_length, const char *extra_headers);
/*
* Sends a printf-formatted HTTP chunk, escaping HTML tags.
*/
void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
/* Websocket opcodes, from http://tools.ietf.org/html/rfc6455 */ /* Websocket opcodes, from http://tools.ietf.org/html/rfc6455 */
#define WEBSOCKET_OP_CONTINUE 0 #define WEBSOCKET_OP_CONTINUE 0
#define WEBSOCKET_OP_TEXT 1 #define WEBSOCKET_OP_TEXT 1
...@@ -2294,6 +2230,34 @@ void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...); ...@@ -2294,6 +2230,34 @@ void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
*/ */
#define WEBSOCKET_DONT_FIN 0x100 #define WEBSOCKET_DONT_FIN 0x100
/*
* Decodes a URL-encoded string.
*
* Source string is specified by (`src`, `src_len`), and destination is
* (`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then
* `+` character is decoded as a blank space character. This function
* guarantees to NUL-terminate the destination. If destination is too small,
* then the source string is partially decoded and `-1` is returned. Otherwise,
* a length of the decoded string is returned, not counting final NUL.
*/
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len,
int is_form_url_encoded);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CS_MONGOOSE_SRC_HTTP_H_ */
/*
* === Server API reference
*/
#ifndef CS_MONGOOSE_SRC_HTTP_SERVER_H_
#define CS_MONGOOSE_SRC_HTTP_SERVER_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* /*
* Parses a HTTP message. * Parses a HTTP message.
* *
...@@ -2382,68 +2346,6 @@ size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name, ...@@ -2382,68 +2346,6 @@ size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst, int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst,
size_t dst_len); size_t dst_len);
/*
* Decodes URL-encoded string.
*
* Source string is specified by (`src`, `src_len`), and destination is
* (`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then
* `+` character is decoded as a blank space character. This function
* guarantees to `\0`-terminate the destination. If destination is too small,
* then the source string is partially decoded and `-1` is returned. Otherwise,
* a length of decoded string is returned, not counting final `\0`.
*/
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len,
int is_form_url_encoded);
/* Creates digest authentication header for a client request. */
int mg_http_create_digest_auth_header(char *buf, size_t buf_len,
const char *method, const char *uri,
const char *auth_domain, const char *user,
const char *passwd);
/*
* Helper function that creates an outbound HTTP connection.
*
* `url` is a URL to fetch. It must be properly URL-encoded, e.g. have
* no spaces, etc. By default, `mg_connect_http()` sends the Connection and
* Host headers. `extra_headers` is an extra HTTP header to send, e.g.
* `"User-Agent: my-app\r\n"`.
* If `post_data` is NULL, then a GET request is created. Otherwise, a POST
* request is created with the specified POST data. Note that if the data being
* posted is a form submission, the `Content-Type` header should be set
* accordingly (see example below).
*
* Examples:
*
* ```c
* nc1 = mg_connect_http(mgr, ev_handler_1, "http://www.google.com", NULL,
* NULL);
* nc2 = mg_connect_http(mgr, ev_handler_1, "https://github.com", NULL, NULL);
* nc3 = mg_connect_http(
* mgr, ev_handler_1, "my_server:8000/form_submit/",
* "Content-Type: application/x-www-form-urlencoded\r\n",
* "var_1=value_1&var_2=value_2");
* ```
*/
struct mg_connection *mg_connect_http(struct mg_mgr *mgr,
mg_event_handler_t event_handler,
const char *url,
const char *extra_headers,
const char *post_data);
/*
* Helper function that creates an outbound HTTP connection.
*
* Mostly identical to mg_connect_http, but allows you to provide extra
*parameters
* (for example, SSL parameters)
*/
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);
/* /*
* This structure defines how `mg_serve_http()` works. * This structure defines how `mg_serve_http()` works.
* Best practice is to set only required settings, and leave the rest as NULL. * Best practice is to set only required settings, and leave the rest as NULL.
...@@ -2725,10 +2627,139 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data, ...@@ -2725,10 +2627,139 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain, int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain,
FILE *fp); FILE *fp);
/*
* 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
* to the `nc->send_mbuf` output IO buffer.
*
* NOTE: The HTTP header "Transfer-Encoding: chunked" should be sent prior to
* using this function.
*
* NOTE: do not forget to send an empty chunk at the end of the response,
* to tell the client that everything was sent. Example:
*
* ```
* mg_printf_http_chunk(nc, "%s", "my response!");
* mg_send_http_chunk(nc, "", 0); // Tell the client we're finished
* ```
*/
void mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len);
/*
* Sends a printf-formatted HTTP chunk.
* Functionality is similar to `mg_send_http_chunk()`.
*/
void mg_printf_http_chunk(struct mg_connection *nc, const char *fmt, ...);
/*
* 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.
* Example:
*
* mg_send_response_line(nc, 200, "Access-Control-Allow-Origin: *");
*
* Will result in:
*
* HTTP/1.1 200 OK\r\n
* Access-Control-Allow-Origin: *\r\n
*/
void mg_send_response_line(struct mg_connection *c, int status_code,
const char *extra_headers);
/*
* Sends the response line and headers.
* This function sends the response line with the `status_code`, and
* automatically
* sends one header: either "Content-Length" or "Transfer-Encoding".
* If `content_length` is negative, then "Transfer-Encoding: chunked" header
* is sent, otherwise, "Content-Length" header is sent.
*
* NOTE: If `Transfer-Encoding` is `chunked`, then message body must be sent
* using `mg_send_http_chunk()` or `mg_printf_http_chunk()` functions.
* Otherwise, `mg_send()` or `mg_printf()` must be used.
* Extra headers could be set through `extra_headers`. Note `extra_headers`
* must NOT be terminated by a new line.
*/
void mg_send_head(struct mg_connection *n, int status_code,
int64_t content_length, const char *extra_headers);
/*
* Sends a printf-formatted HTTP chunk, escaping HTML tags.
*/
void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* CS_MONGOOSE_SRC_HTTP_H_ */ #endif /* CS_MONGOOSE_SRC_HTTP_SERVER_H_ */
/*
* === Client API reference
*/
#ifndef CS_MONGOOSE_SRC_HTTP_CLIENT_H_
#define CS_MONGOOSE_SRC_HTTP_CLIENT_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
* Helper function that creates an outbound HTTP connection.
*
* `url` is the URL to fetch. It must be properly URL-encoded, e.g. have
* no spaces, etc. By default, `mg_connect_http()` sends the Connection and
* Host headers. `extra_headers` is an extra HTTP header to send, e.g.
* `"User-Agent: my-app\r\n"`.
* If `post_data` is NULL, then a GET request is created. Otherwise, a POST
* request is created with the specified POST data. Note that if the data being
* posted is a form submission, the `Content-Type` header should be set
* accordingly (see example below).
*
* Examples:
*
* ```c
* nc1 = mg_connect_http(mgr, ev_handler_1, "http://www.google.com", NULL,
* NULL);
* nc2 = mg_connect_http(mgr, ev_handler_1, "https://github.com", NULL, NULL);
* nc3 = mg_connect_http(
* mgr, ev_handler_1, "my_server:8000/form_submit/",
* "Content-Type: application/x-www-form-urlencoded\r\n",
* "var_1=value_1&var_2=value_2");
* ```
*/
struct mg_connection *mg_connect_http(struct mg_mgr *mgr,
mg_event_handler_t event_handler,
const char *url,
const char *extra_headers,
const char *post_data);
/*
* Helper function that creates an outbound HTTP connection.
*
* Mostly identical to mg_connect_http, but allows you to provide extra
*parameters
* (for example, SSL parameters)
*/
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);
/* Creates digest authentication header for a client request. */
int mg_http_create_digest_auth_header(char *buf, size_t buf_len,
const char *method, const char *uri,
const char *auth_domain, const char *user,
const char *passwd);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CS_MONGOOSE_SRC_HTTP_CLIENT_H_ */
/* /*
* Copyright (c) 2014 Cesanta Software Limited * Copyright (c) 2014 Cesanta Software Limited
* All rights reserved * All rights reserved
...@@ -2747,7 +2778,7 @@ int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain, ...@@ -2747,7 +2778,7 @@ int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain,
*/ */
/* /*
* === MQTT * === MQTT API reference
*/ */
#ifndef CS_MONGOOSE_SRC_MQTT_H_ #ifndef CS_MONGOOSE_SRC_MQTT_H_
...@@ -2942,7 +2973,7 @@ int mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *msg, ...@@ -2942,7 +2973,7 @@ int mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *msg,
*/ */
/* /*
* === MQTT Broker * === MQTT Server API reference
*/ */
#ifndef CS_MONGOOSE_SRC_MQTT_BROKER_H_ #ifndef CS_MONGOOSE_SRC_MQTT_BROKER_H_
...@@ -3030,7 +3061,7 @@ struct mg_mqtt_session *mg_mqtt_next(struct mg_mqtt_broker *brk, ...@@ -3030,7 +3061,7 @@ struct mg_mqtt_session *mg_mqtt_next(struct mg_mqtt_broker *brk,
*/ */
/* /*
* === DNS * === DNS API reference
*/ */
#ifndef CS_MONGOOSE_SRC_DNS_H_ #ifndef CS_MONGOOSE_SRC_DNS_H_
...@@ -3183,7 +3214,7 @@ void mg_set_protocol_dns(struct mg_connection *nc); ...@@ -3183,7 +3214,7 @@ void mg_set_protocol_dns(struct mg_connection *nc);
*/ */
/* /*
* === DNS server * === DNS server API reference
* *
* Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`. * Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`.
*/ */
...@@ -3276,7 +3307,7 @@ void mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r); ...@@ -3276,7 +3307,7 @@ void mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r);
*/ */
/* /*
* === Asynchronouns DNS resolver * === API reference
*/ */
#ifndef CS_MONGOOSE_SRC_RESOLV_H_ #ifndef CS_MONGOOSE_SRC_RESOLV_H_
...@@ -3365,7 +3396,7 @@ int mg_resolve_from_hosts_file(const char *host, union socket_address *usa); ...@@ -3365,7 +3396,7 @@ int mg_resolve_from_hosts_file(const char *host, union socket_address *usa);
*/ */
/* /*
* === CoAP * === CoAP API reference
* *
* CoAP message format: * CoAP message format:
* *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment