From 12437fd7feb0705f43c78adc656756d1184e5e7f Mon Sep 17 00:00:00 2001
From: Sergey Lyubka <lsm@cesanta.com>
Date: Thu, 1 Sep 2016 15:19:01 +0100
Subject: [PATCH] Refactor Mongoose documentation

PUBLISHED_FROM=e9a4e5c7b4a1d03b93a2a79e29de19e60e919929
---
 docs/c-api/coap.h/intro.md                    |  20 +-
 docs/c-api/dns-server.h/intro.md              |  12 -
 docs/c-api/dns.h/intro.md                     |  22 +-
 docs/c-api/dns_server.h/intro.md              |  12 +
 .../mg_dns_create_reply.md                    |   0
 .../mg_dns_reply_record.md                    |   0
 .../mg_dns_send_reply.md                      |   0
 docs/c-api/http.h/intro.md                    |  46 +--
 docs/c-api/http.h/mg_url_decode.md            |   6 +-
 docs/c-api/http_client.h/intro.md             |  12 +
 .../mg_connect_http.md                        |   2 +-
 .../mg_connect_http_opt.md                    |   0
 .../mg_http_create_digest_auth_header.md      |   0
 docs/c-api/http_server.h/intro.md             |  26 ++
 .../mg_file_upload_handler.md                 |   0
 .../mg_fu_fname_fn.md                         |   0
 .../mg_get_http_header.md                     |   0
 .../mg_get_http_var.md                        |   0
 .../mg_http_check_digest_auth.md              |   0
 .../mg_http_parse_header.md                   |   0
 .../mg_http_serve_file.md                     |   0
 .../mg_parse_http.md                          |   0
 .../mg_parse_multipart.md                     |   0
 .../mg_printf_html_escape.md                  |   0
 .../mg_printf_http_chunk.md                   |   0
 .../mg_register_http_endpoint.md              |   0
 .../{http.h => http_server.h}/mg_send_head.md |   5 +-
 .../mg_send_http_chunk.md                     |   5 +-
 .../mg_send_response_line.md                  |   2 +-
 .../mg_serve_http.md                          |   0
 .../struct_mg_serve_http_opts.md              |   0
 docs/c-api/intro.md                           |  22 +-
 docs/c-api/mbuf.h/intro.md                    |  16 +-
 docs/c-api/mqtt-broker.h/intro.md             |  14 -
 docs/c-api/mqtt.h/intro.md                    |  38 +--
 docs/c-api/mqtt_server.h/intro.md             |  14 +
 .../mg_mqtt_broker.md                         |   0
 .../mg_mqtt_broker_init.md                    |   0
 .../mg_mqtt_next.md                           |   0
 .../struct_mg_mqtt_broker.md                  |   0
 .../struct_mg_mqtt_session.md                 |   0
 docs/c-api/net.h/intro.md                     |  56 ++--
 docs/c-api/resolv.h/intro.md                  |  13 +
 docs/c-api/resolv.h/mg_resolve_async.md       |  11 +
 docs/c-api/resolv.h/mg_resolve_async_opt.md   |  30 ++
 .../resolv.h/mg_resolve_from_hosts_file.md    |  12 +
 .../resolv.h/struct_mg_resolve_async_opts.md  |  17 +
 docs/c-api/uri.h/intro.md                     |  10 +
 docs/c-api/uri.h/mg_parse_uri.md              |  33 ++
 docs/c-api/util.h/intro.md                    |  38 +--
 docs/coap/client_example.md                   |   5 +
 docs/coap/intro.md                            |   7 +
 docs/coap/server_example.md                   |   5 +
 docs/core/intro.md                            |   8 +
 docs/dns/client_example.md                    |   5 +
 docs/dns/intro.md                             |   8 +
 docs/dns/server_example.md                    |   5 +
 docs/dns_resolver/intro.md                    |   6 +
 docs/dns_resolver/overview.md                 |   5 +
 docs/http/cgi.md                              |  31 ++
 docs/http/client_example.md                   |  44 +++
 docs/http/digest_auth.md                      |   5 +
 docs/http/events.md                           |  39 +++
 docs/http/files.md                            |  46 +++
 docs/http/intro.md                            |  16 +
 docs/http/server_example.md                   |  53 +++
 docs/http/ssi.md                              |  59 ++++
 docs/http/ssl.md                              |  33 ++
 docs/http/upload.md                           |  36 +++
 docs/intro.md                                 |  12 +-
 docs/mqtt/client_example.md                   |   5 +
 docs/mqtt/intro.md                            |   8 +
 docs/mqtt/server_example.md                   |   5 +
 .../build-options/disabling-flags.md          |   0
 .../build-options/enabling-flags.md           |   0
 docs/{ => overview}/build-options/intro.md    |   0
 .../build-options/platform-spec.md            |   0
 docs/{ => overview}/build-options/tunables.md |   0
 .../intro.md => overview/concept.md}          |  40 ++-
 .../conn-flags.md                             |   0
 .../event-handler.md                          |   0
 docs/{design-concept => overview}/events.md   |   0
 docs/{overview.md => overview/intro.md}       |  20 +-
 .../memory-buffers.md => overview/mbufs.md}   |   0
 .../intro.md => overview/usage-example.md}    |   2 +-
 mongoose.c                                    |   4 +-
 mongoose.h                                    | 303 ++++++++++--------
 87 files changed, 977 insertions(+), 332 deletions(-)
 delete mode 100644 docs/c-api/dns-server.h/intro.md
 create mode 100644 docs/c-api/dns_server.h/intro.md
 rename docs/c-api/{dns-server.h => dns_server.h}/mg_dns_create_reply.md (100%)
 rename docs/c-api/{dns-server.h => dns_server.h}/mg_dns_reply_record.md (100%)
 rename docs/c-api/{dns-server.h => dns_server.h}/mg_dns_send_reply.md (100%)
 create mode 100644 docs/c-api/http_client.h/intro.md
 rename docs/c-api/{http.h => http_client.h}/mg_connect_http.md (94%)
 rename docs/c-api/{http.h => http_client.h}/mg_connect_http_opt.md (100%)
 rename docs/c-api/{http.h => http_client.h}/mg_http_create_digest_auth_header.md (100%)
 create mode 100644 docs/c-api/http_server.h/intro.md
 rename docs/c-api/{http.h => http_server.h}/mg_file_upload_handler.md (100%)
 rename docs/c-api/{http.h => http_server.h}/mg_fu_fname_fn.md (100%)
 rename docs/c-api/{http.h => http_server.h}/mg_get_http_header.md (100%)
 rename docs/c-api/{http.h => http_server.h}/mg_get_http_var.md (100%)
 rename docs/c-api/{http.h => http_server.h}/mg_http_check_digest_auth.md (100%)
 rename docs/c-api/{http.h => http_server.h}/mg_http_parse_header.md (100%)
 rename docs/c-api/{http.h => http_server.h}/mg_http_serve_file.md (100%)
 rename docs/c-api/{http.h => http_server.h}/mg_parse_http.md (100%)
 rename docs/c-api/{http.h => http_server.h}/mg_parse_multipart.md (100%)
 rename docs/c-api/{http.h => http_server.h}/mg_printf_html_escape.md (100%)
 rename docs/c-api/{http.h => http_server.h}/mg_printf_http_chunk.md (100%)
 rename docs/c-api/{http.h => http_server.h}/mg_register_http_endpoint.md (100%)
 rename docs/c-api/{http.h => http_server.h}/mg_send_head.md (87%)
 rename docs/c-api/{http.h => http_server.h}/mg_send_http_chunk.md (86%)
 rename docs/c-api/{http.h => http_server.h}/mg_send_response_line.md (94%)
 rename docs/c-api/{http.h => http_server.h}/mg_serve_http.md (100%)
 rename docs/c-api/{http.h => http_server.h}/struct_mg_serve_http_opts.md (100%)
 delete mode 100644 docs/c-api/mqtt-broker.h/intro.md
 create mode 100644 docs/c-api/mqtt_server.h/intro.md
 rename docs/c-api/{mqtt-broker.h => mqtt_server.h}/mg_mqtt_broker.md (100%)
 rename docs/c-api/{mqtt-broker.h => mqtt_server.h}/mg_mqtt_broker_init.md (100%)
 rename docs/c-api/{mqtt-broker.h => mqtt_server.h}/mg_mqtt_next.md (100%)
 rename docs/c-api/{mqtt-broker.h => mqtt_server.h}/struct_mg_mqtt_broker.md (100%)
 rename docs/c-api/{mqtt-broker.h => mqtt_server.h}/struct_mg_mqtt_session.md (100%)
 create mode 100644 docs/c-api/resolv.h/intro.md
 create mode 100644 docs/c-api/resolv.h/mg_resolve_async.md
 create mode 100644 docs/c-api/resolv.h/mg_resolve_async_opt.md
 create mode 100644 docs/c-api/resolv.h/mg_resolve_from_hosts_file.md
 create mode 100644 docs/c-api/resolv.h/struct_mg_resolve_async_opts.md
 create mode 100644 docs/c-api/uri.h/intro.md
 create mode 100644 docs/c-api/uri.h/mg_parse_uri.md
 create mode 100644 docs/coap/client_example.md
 create mode 100644 docs/coap/intro.md
 create mode 100644 docs/coap/server_example.md
 create mode 100644 docs/core/intro.md
 create mode 100644 docs/dns/client_example.md
 create mode 100644 docs/dns/intro.md
 create mode 100644 docs/dns/server_example.md
 create mode 100644 docs/dns_resolver/intro.md
 create mode 100644 docs/dns_resolver/overview.md
 create mode 100644 docs/http/cgi.md
 create mode 100644 docs/http/client_example.md
 create mode 100644 docs/http/digest_auth.md
 create mode 100644 docs/http/events.md
 create mode 100644 docs/http/files.md
 create mode 100644 docs/http/intro.md
 create mode 100644 docs/http/server_example.md
 create mode 100644 docs/http/ssi.md
 create mode 100644 docs/http/ssl.md
 create mode 100644 docs/http/upload.md
 create mode 100644 docs/mqtt/client_example.md
 create mode 100644 docs/mqtt/intro.md
 create mode 100644 docs/mqtt/server_example.md
 rename docs/{ => overview}/build-options/disabling-flags.md (100%)
 rename docs/{ => overview}/build-options/enabling-flags.md (100%)
 rename docs/{ => overview}/build-options/intro.md (100%)
 rename docs/{ => overview}/build-options/platform-spec.md (100%)
 rename docs/{ => overview}/build-options/tunables.md (100%)
 rename docs/{design-concept/intro.md => overview/concept.md} (51%)
 rename docs/{design-concept => overview}/conn-flags.md (100%)
 rename docs/{design-concept => overview}/event-handler.md (100%)
 rename docs/{design-concept => overview}/events.md (100%)
 rename docs/{overview.md => overview/intro.md} (63%)
 rename docs/{design-concept/memory-buffers.md => overview/mbufs.md} (100%)
 rename docs/{usage-example/intro.md => overview/usage-example.md} (97%)

diff --git a/docs/c-api/coap.h/intro.md b/docs/c-api/coap.h/intro.md
index 8f3f30841..ced6828b6 100644
--- a/docs/c-api/coap.h/intro.md
+++ b/docs/c-api/coap.h/intro.md
@@ -1,17 +1,17 @@
 ---
-title: "CoAP"
+title: "CoAP API reference"
 symbol_kind: "intro"
 decl_name: "coap.h"
 items:
-  - { type: file, name: mg_set_protocol_coap.md }
-  - { type: file, name: mg_coap_add_option.md }
-  - { type: file, name: mg_coap_free_options.md }
-  - { type: file, name: mg_coap_send_message.md }
-  - { type: file, name: mg_coap_send_ack.md }
-  - { type: file, name: mg_coap_parse.md }
-  - { type: file, name: mg_coap_compose.md }
-  - { type: file, name: struct_mg_coap_option.md }
-  - { type: file, name: struct_mg_coap_message.md }
+  - { name: mg_set_protocol_coap.md }
+  - { name: mg_coap_add_option.md }
+  - { name: mg_coap_free_options.md }
+  - { name: mg_coap_send_message.md }
+  - { name: mg_coap_send_ack.md }
+  - { name: mg_coap_parse.md }
+  - { name: mg_coap_compose.md }
+  - { name: struct_mg_coap_option.md }
+  - { name: struct_mg_coap_message.md }
 ---
 
 CoAP message format:
diff --git a/docs/c-api/dns-server.h/intro.md b/docs/c-api/dns-server.h/intro.md
deleted file mode 100644
index 50f967958..000000000
--- a/docs/c-api/dns-server.h/intro.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-title: "DNS server"
-symbol_kind: "intro"
-decl_name: "dns-server.h"
-items:
-  - { type: file, name: mg_dns_create_reply.md }
-  - { type: file, name: mg_dns_reply_record.md }
-  - { type: file, name: mg_dns_send_reply.md }
----
-
-Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`.
-
diff --git a/docs/c-api/dns.h/intro.md b/docs/c-api/dns.h/intro.md
index c36f5b75f..5f52c16f9 100644
--- a/docs/c-api/dns.h/intro.md
+++ b/docs/c-api/dns.h/intro.md
@@ -1,18 +1,18 @@
 ---
-title: "DNS"
+title: "DNS API reference"
 symbol_kind: "intro"
 decl_name: "dns.h"
 items:
-  - { type: file, name: mg_dns_parse_record_data.md }
-  - { type: file, name: mg_send_dns_query.md }
-  - { type: file, name: mg_dns_insert_header.md }
-  - { type: file, name: mg_dns_copy_questions.md }
-  - { type: file, name: mg_dns_encode_record.md }
-  - { type: file, name: mg_parse_dns.md }
-  - { type: file, name: mg_dns_uncompress_name.md }
-  - { type: file, name: mg_set_protocol_dns.md }
-  - { type: file, name: struct_mg_dns_resource_record.md }
-  - { type: file, name: struct_mg_dns_message.md }
+  - { name: mg_dns_parse_record_data.md }
+  - { name: mg_send_dns_query.md }
+  - { name: mg_dns_insert_header.md }
+  - { name: mg_dns_copy_questions.md }
+  - { name: mg_dns_encode_record.md }
+  - { name: mg_parse_dns.md }
+  - { name: mg_dns_uncompress_name.md }
+  - { name: mg_set_protocol_dns.md }
+  - { name: struct_mg_dns_resource_record.md }
+  - { name: struct_mg_dns_message.md }
 ---
 
 
diff --git a/docs/c-api/dns_server.h/intro.md b/docs/c-api/dns_server.h/intro.md
new file mode 100644
index 000000000..16ba0fc90
--- /dev/null
+++ b/docs/c-api/dns_server.h/intro.md
@@ -0,0 +1,12 @@
+---
+title: "DNS server API reference"
+symbol_kind: "intro"
+decl_name: "dns_server.h"
+items:
+  - { name: mg_dns_create_reply.md }
+  - { name: mg_dns_reply_record.md }
+  - { name: mg_dns_send_reply.md }
+---
+
+Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`.
+
diff --git a/docs/c-api/dns-server.h/mg_dns_create_reply.md b/docs/c-api/dns_server.h/mg_dns_create_reply.md
similarity index 100%
rename from docs/c-api/dns-server.h/mg_dns_create_reply.md
rename to docs/c-api/dns_server.h/mg_dns_create_reply.md
diff --git a/docs/c-api/dns-server.h/mg_dns_reply_record.md b/docs/c-api/dns_server.h/mg_dns_reply_record.md
similarity index 100%
rename from docs/c-api/dns-server.h/mg_dns_reply_record.md
rename to docs/c-api/dns_server.h/mg_dns_reply_record.md
diff --git a/docs/c-api/dns-server.h/mg_dns_send_reply.md b/docs/c-api/dns_server.h/mg_dns_send_reply.md
similarity index 100%
rename from docs/c-api/dns-server.h/mg_dns_send_reply.md
rename to docs/c-api/dns_server.h/mg_dns_send_reply.md
diff --git a/docs/c-api/http.h/intro.md b/docs/c-api/http.h/intro.md
index 3cb77d776..f070b4b5a 100644
--- a/docs/c-api/http.h/intro.md
+++ b/docs/c-api/http.h/intro.md
@@ -1,40 +1,20 @@
 ---
-title: "HTTP + Websocket"
+title: "Common API reference"
 symbol_kind: "intro"
 decl_name: "http.h"
 items:
-  - { type: file, name: mg_set_protocol_http_websocket.md }
-  - { type: file, name: mg_send_websocket_handshake.md }
-  - { type: file, name: mg_send_websocket_handshake2.md }
-  - { type: file, name: mg_connect_ws.md }
-  - { type: file, name: mg_connect_ws_opt.md }
-  - { type: file, name: mg_send_websocket_frame.md }
-  - { type: file, name: mg_send_websocket_framev.md }
-  - { type: file, name: mg_printf_websocket_frame.md }
-  - { type: file, name: mg_send_http_chunk.md }
-  - { type: file, name: mg_printf_http_chunk.md }
-  - { type: file, name: mg_send_response_line.md }
-  - { type: file, name: mg_send_head.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 }
+  - { name: mg_set_protocol_http_websocket.md }
+  - { name: mg_send_websocket_handshake.md }
+  - { name: mg_send_websocket_handshake2.md }
+  - { name: mg_connect_ws.md }
+  - { name: mg_connect_ws_opt.md }
+  - { name: mg_send_websocket_frame.md }
+  - { name: mg_send_websocket_framev.md }
+  - { name: mg_printf_websocket_frame.md }
+  - { name: mg_url_decode.md }
+  - { name: struct_http_message.md }
+  - { name: struct_websocket_message.md }
+  - { name: struct_mg_http_multipart_part.md }
 ---
 
 
diff --git a/docs/c-api/http.h/mg_url_decode.md b/docs/c-api/http.h/mg_url_decode.md
index b0edaadae..2343adfa2 100644
--- a/docs/c-api/http.h/mg_url_decode.md
+++ b/docs/c-api/http.h/mg_url_decode.md
@@ -7,12 +7,12 @@ signature: |
                     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
 (`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,
+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 decoded string is returned, not counting final `\0`. 
+a length of the decoded string is returned, not counting final NUL. 
 
diff --git a/docs/c-api/http_client.h/intro.md b/docs/c-api/http_client.h/intro.md
new file mode 100644
index 000000000..d3bc1d6a5
--- /dev/null
+++ b/docs/c-api/http_client.h/intro.md
@@ -0,0 +1,12 @@
+---
+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 }
+---
+
+
+
diff --git a/docs/c-api/http.h/mg_connect_http.md b/docs/c-api/http_client.h/mg_connect_http.md
similarity index 94%
rename from docs/c-api/http.h/mg_connect_http.md
rename to docs/c-api/http_client.h/mg_connect_http.md
index c99d80d72..fcf5f0468 100644
--- a/docs/c-api/http.h/mg_connect_http.md
+++ b/docs/c-api/http_client.h/mg_connect_http.md
@@ -12,7 +12,7 @@ signature: |
 
 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
 Host headers. `extra_headers` is an extra HTTP header to send, e.g.
 `"User-Agent: my-app\r\n"`.
diff --git a/docs/c-api/http.h/mg_connect_http_opt.md b/docs/c-api/http_client.h/mg_connect_http_opt.md
similarity index 100%
rename from docs/c-api/http.h/mg_connect_http_opt.md
rename to docs/c-api/http_client.h/mg_connect_http_opt.md
diff --git a/docs/c-api/http.h/mg_http_create_digest_auth_header.md b/docs/c-api/http_client.h/mg_http_create_digest_auth_header.md
similarity index 100%
rename from docs/c-api/http.h/mg_http_create_digest_auth_header.md
rename to docs/c-api/http_client.h/mg_http_create_digest_auth_header.md
diff --git a/docs/c-api/http_server.h/intro.md b/docs/c-api/http_server.h/intro.md
new file mode 100644
index 000000000..0879399c7
--- /dev/null
+++ b/docs/c-api/http_server.h/intro.md
@@ -0,0 +1,26 @@
+---
+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 }
+---
+
+
+
diff --git a/docs/c-api/http.h/mg_file_upload_handler.md b/docs/c-api/http_server.h/mg_file_upload_handler.md
similarity index 100%
rename from docs/c-api/http.h/mg_file_upload_handler.md
rename to docs/c-api/http_server.h/mg_file_upload_handler.md
diff --git a/docs/c-api/http.h/mg_fu_fname_fn.md b/docs/c-api/http_server.h/mg_fu_fname_fn.md
similarity index 100%
rename from docs/c-api/http.h/mg_fu_fname_fn.md
rename to docs/c-api/http_server.h/mg_fu_fname_fn.md
diff --git a/docs/c-api/http.h/mg_get_http_header.md b/docs/c-api/http_server.h/mg_get_http_header.md
similarity index 100%
rename from docs/c-api/http.h/mg_get_http_header.md
rename to docs/c-api/http_server.h/mg_get_http_header.md
diff --git a/docs/c-api/http.h/mg_get_http_var.md b/docs/c-api/http_server.h/mg_get_http_var.md
similarity index 100%
rename from docs/c-api/http.h/mg_get_http_var.md
rename to docs/c-api/http_server.h/mg_get_http_var.md
diff --git a/docs/c-api/http.h/mg_http_check_digest_auth.md b/docs/c-api/http_server.h/mg_http_check_digest_auth.md
similarity index 100%
rename from docs/c-api/http.h/mg_http_check_digest_auth.md
rename to docs/c-api/http_server.h/mg_http_check_digest_auth.md
diff --git a/docs/c-api/http.h/mg_http_parse_header.md b/docs/c-api/http_server.h/mg_http_parse_header.md
similarity index 100%
rename from docs/c-api/http.h/mg_http_parse_header.md
rename to docs/c-api/http_server.h/mg_http_parse_header.md
diff --git a/docs/c-api/http.h/mg_http_serve_file.md b/docs/c-api/http_server.h/mg_http_serve_file.md
similarity index 100%
rename from docs/c-api/http.h/mg_http_serve_file.md
rename to docs/c-api/http_server.h/mg_http_serve_file.md
diff --git a/docs/c-api/http.h/mg_parse_http.md b/docs/c-api/http_server.h/mg_parse_http.md
similarity index 100%
rename from docs/c-api/http.h/mg_parse_http.md
rename to docs/c-api/http_server.h/mg_parse_http.md
diff --git a/docs/c-api/http.h/mg_parse_multipart.md b/docs/c-api/http_server.h/mg_parse_multipart.md
similarity index 100%
rename from docs/c-api/http.h/mg_parse_multipart.md
rename to docs/c-api/http_server.h/mg_parse_multipart.md
diff --git a/docs/c-api/http.h/mg_printf_html_escape.md b/docs/c-api/http_server.h/mg_printf_html_escape.md
similarity index 100%
rename from docs/c-api/http.h/mg_printf_html_escape.md
rename to docs/c-api/http_server.h/mg_printf_html_escape.md
diff --git a/docs/c-api/http.h/mg_printf_http_chunk.md b/docs/c-api/http_server.h/mg_printf_http_chunk.md
similarity index 100%
rename from docs/c-api/http.h/mg_printf_http_chunk.md
rename to docs/c-api/http_server.h/mg_printf_http_chunk.md
diff --git a/docs/c-api/http.h/mg_register_http_endpoint.md b/docs/c-api/http_server.h/mg_register_http_endpoint.md
similarity index 100%
rename from docs/c-api/http.h/mg_register_http_endpoint.md
rename to docs/c-api/http_server.h/mg_register_http_endpoint.md
diff --git a/docs/c-api/http.h/mg_send_head.md b/docs/c-api/http_server.h/mg_send_head.md
similarity index 87%
rename from docs/c-api/http.h/mg_send_head.md
rename to docs/c-api/http_server.h/mg_send_head.md
index 698c8cd84..cd3348668 100644
--- a/docs/c-api/http.h/mg_send_head.md
+++ b/docs/c-api/http_server.h/mg_send_head.md
@@ -7,8 +7,9 @@ signature: |
                     int64_t content_length, const char *extra_headers);
 ---
 
-Sends a response line and headers.
-This function sends a response line with the `status_code`, and automatically
+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.
diff --git a/docs/c-api/http.h/mg_send_http_chunk.md b/docs/c-api/http_server.h/mg_send_http_chunk.md
similarity index 86%
rename from docs/c-api/http.h/mg_send_http_chunk.md
rename to docs/c-api/http_server.h/mg_send_http_chunk.md
index 8ad31e5e8..2ce64a1a9 100644
--- a/docs/c-api/http.h/mg_send_http_chunk.md
+++ b/docs/c-api/http_server.h/mg_send_http_chunk.md
@@ -9,9 +9,8 @@ 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
-*to
-the `nc->send_mbuf` output IO buffer.
+`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.
diff --git a/docs/c-api/http.h/mg_send_response_line.md b/docs/c-api/http_server.h/mg_send_response_line.md
similarity index 94%
rename from docs/c-api/http.h/mg_send_response_line.md
rename to docs/c-api/http_server.h/mg_send_response_line.md
index bd72b0da4..213927dd5 100644
--- a/docs/c-api/http.h/mg_send_response_line.md
+++ b/docs/c-api/http_server.h/mg_send_response_line.md
@@ -7,7 +7,7 @@ signature: |
                              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
 after the reponse line. `extra_headers` must NOT end end with new line.
 Example:
diff --git a/docs/c-api/http.h/mg_serve_http.md b/docs/c-api/http_server.h/mg_serve_http.md
similarity index 100%
rename from docs/c-api/http.h/mg_serve_http.md
rename to docs/c-api/http_server.h/mg_serve_http.md
diff --git a/docs/c-api/http.h/struct_mg_serve_http_opts.md b/docs/c-api/http_server.h/struct_mg_serve_http_opts.md
similarity index 100%
rename from docs/c-api/http.h/struct_mg_serve_http_opts.md
rename to docs/c-api/http_server.h/struct_mg_serve_http_opts.md
diff --git a/docs/c-api/intro.md b/docs/c-api/intro.md
index 342101e19..34f361022 100644
--- a/docs/c-api/intro.md
+++ b/docs/c-api/intro.md
@@ -1,12 +1,16 @@
 ---
 items:
-  - { type: dir, name: mbuf.h }
-  - { type: dir, name: net.h }
-  - { type: dir, name: http.h }
-  - { type: dir, name: dns.h }
-  - { type: dir, name: dns-server.h }
-  - { type: dir, name: mqtt.h }
-  - { type: dir, name: mqtt-broker.h }
-  - { type: dir, name: coap.h }
-  - { type: dir, name: util.h }
+  - { name: mbuf.h }
+  - { name: net.h }
+  - { name: http.h }
+  - { name: http_server.h }
+  - { name: http_client.h }
+  - { name: dns.h }
+  - { name: dns_server.h }
+  - { name: resolv.h }
+  - { name: mqtt.h }
+  - { name: mqtt_server.h }
+  - { name: coap.h }
+  - { name: util.h }
+  - { name: uri.h }
 ---
diff --git a/docs/c-api/mbuf.h/intro.md b/docs/c-api/mbuf.h/intro.md
index 2fa91c3df..ea2e85056 100644
--- a/docs/c-api/mbuf.h/intro.md
+++ b/docs/c-api/mbuf.h/intro.md
@@ -3,14 +3,14 @@ title: "Memory Buffers"
 symbol_kind: "intro"
 decl_name: "mbuf.h"
 items:
-  - { type: file, name: mbuf_init.md }
-  - { type: file, name: mbuf_free.md }
-  - { type: file, name: mbuf_append.md }
-  - { type: file, name: mbuf_insert.md }
-  - { type: file, name: mbuf_remove.md }
-  - { type: file, name: mbuf_resize.md }
-  - { type: file, name: mbuf_trim.md }
-  - { type: file, name: struct_mbuf.md }
+  - { name: mbuf_init.md }
+  - { name: mbuf_free.md }
+  - { name: mbuf_append.md }
+  - { name: mbuf_insert.md }
+  - { name: mbuf_remove.md }
+  - { name: mbuf_resize.md }
+  - { name: mbuf_trim.md }
+  - { name: struct_mbuf.md }
 ---
 
 Mbufs are mutable/growing memory buffers, like C++ strings.
diff --git a/docs/c-api/mqtt-broker.h/intro.md b/docs/c-api/mqtt-broker.h/intro.md
deleted file mode 100644
index 621b3f640..000000000
--- a/docs/c-api/mqtt-broker.h/intro.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-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 }
----
-
-
-
diff --git a/docs/c-api/mqtt.h/intro.md b/docs/c-api/mqtt.h/intro.md
index d8a6aba8a..a5c1ba66d 100644
--- a/docs/c-api/mqtt.h/intro.md
+++ b/docs/c-api/mqtt.h/intro.md
@@ -1,26 +1,26 @@
 ---
-title: "MQTT"
+title: "MQTT API reference"
 symbol_kind: "intro"
 decl_name: "mqtt.h"
 items:
-  - { type: file, name: mg_set_protocol_mqtt.md }
-  - { type: file, name: mg_send_mqtt_handshake.md }
-  - { type: file, name: mg_send_mqtt_handshake_opt.md }
-  - { type: file, name: mg_mqtt_publish.md }
-  - { type: file, name: mg_mqtt_subscribe.md }
-  - { type: file, name: mg_mqtt_unsubscribe.md }
-  - { type: file, name: mg_mqtt_disconnect.md }
-  - { type: file, name: mg_mqtt_connack.md }
-  - { type: file, name: mg_mqtt_puback.md }
-  - { type: file, name: mg_mqtt_pubrec.md }
-  - { type: file, name: mg_mqtt_pubrel.md }
-  - { type: file, name: mg_mqtt_pubcomp.md }
-  - { type: file, name: mg_mqtt_suback.md }
-  - { type: file, name: mg_mqtt_unsuback.md }
-  - { type: file, name: mg_mqtt_ping.md }
-  - { type: file, name: mg_mqtt_pong.md }
-  - { type: file, name: mg_mqtt_next_subscribe_topic.md }
-  - { type: file, name: struct_mg_mqtt_topic_expression.md }
+  - { name: mg_set_protocol_mqtt.md }
+  - { name: mg_send_mqtt_handshake.md }
+  - { name: mg_send_mqtt_handshake_opt.md }
+  - { name: mg_mqtt_publish.md }
+  - { name: mg_mqtt_subscribe.md }
+  - { name: mg_mqtt_unsubscribe.md }
+  - { name: mg_mqtt_disconnect.md }
+  - { name: mg_mqtt_connack.md }
+  - { name: mg_mqtt_puback.md }
+  - { name: mg_mqtt_pubrec.md }
+  - { name: mg_mqtt_pubrel.md }
+  - { name: mg_mqtt_pubcomp.md }
+  - { name: mg_mqtt_suback.md }
+  - { name: mg_mqtt_unsuback.md }
+  - { name: mg_mqtt_ping.md }
+  - { name: mg_mqtt_pong.md }
+  - { name: mg_mqtt_next_subscribe_topic.md }
+  - { name: struct_mg_mqtt_topic_expression.md }
 ---
 
 
diff --git a/docs/c-api/mqtt_server.h/intro.md b/docs/c-api/mqtt_server.h/intro.md
new file mode 100644
index 000000000..39da65b2d
--- /dev/null
+++ b/docs/c-api/mqtt_server.h/intro.md
@@ -0,0 +1,14 @@
+---
+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 }
+---
+
+
+
diff --git a/docs/c-api/mqtt-broker.h/mg_mqtt_broker.md b/docs/c-api/mqtt_server.h/mg_mqtt_broker.md
similarity index 100%
rename from docs/c-api/mqtt-broker.h/mg_mqtt_broker.md
rename to docs/c-api/mqtt_server.h/mg_mqtt_broker.md
diff --git a/docs/c-api/mqtt-broker.h/mg_mqtt_broker_init.md b/docs/c-api/mqtt_server.h/mg_mqtt_broker_init.md
similarity index 100%
rename from docs/c-api/mqtt-broker.h/mg_mqtt_broker_init.md
rename to docs/c-api/mqtt_server.h/mg_mqtt_broker_init.md
diff --git a/docs/c-api/mqtt-broker.h/mg_mqtt_next.md b/docs/c-api/mqtt_server.h/mg_mqtt_next.md
similarity index 100%
rename from docs/c-api/mqtt-broker.h/mg_mqtt_next.md
rename to docs/c-api/mqtt_server.h/mg_mqtt_next.md
diff --git a/docs/c-api/mqtt-broker.h/struct_mg_mqtt_broker.md b/docs/c-api/mqtt_server.h/struct_mg_mqtt_broker.md
similarity index 100%
rename from docs/c-api/mqtt-broker.h/struct_mg_mqtt_broker.md
rename to docs/c-api/mqtt_server.h/struct_mg_mqtt_broker.md
diff --git a/docs/c-api/mqtt-broker.h/struct_mg_mqtt_session.md b/docs/c-api/mqtt_server.h/struct_mg_mqtt_session.md
similarity index 100%
rename from docs/c-api/mqtt-broker.h/struct_mg_mqtt_session.md
rename to docs/c-api/mqtt_server.h/struct_mg_mqtt_session.md
diff --git a/docs/c-api/net.h/intro.md b/docs/c-api/net.h/intro.md
index 10df58ba2..d102bac1e 100644
--- a/docs/c-api/net.h/intro.md
+++ b/docs/c-api/net.h/intro.md
@@ -1,35 +1,35 @@
 ---
-title: "Core: TCP/UDP/SSL"
+title: "Core API: TCP/UDP/SSL"
 symbol_kind: "intro"
 decl_name: "net.h"
 items:
-  - { type: file, name: mg_mgr_init.md }
-  - { type: file, name: mg_mgr_free.md }
-  - { type: file, name: mg_mgr_poll.md }
-  - { type: file, name: mg_broadcast.md }
-  - { type: file, name: mg_next.md }
-  - { type: file, name: mg_add_sock.md }
-  - { type: file, name: mg_add_sock_opt.md }
-  - { type: file, name: mg_bind.md }
-  - { type: file, name: mg_bind_opt.md }
-  - { type: file, name: mg_connect.md }
-  - { type: file, name: mg_connect_opt.md }
-  - { type: file, name: mg_set_ssl.md }
-  - { type: file, name: mg_send.md }
-  - { type: file, name: mg_printf.md }
-  - { type: file, name: mg_vprintf.md }
-  - { type: file, name: mg_socketpair.md }
-  - { type: file, name: mg_check_ip_acl.md }
-  - { type: file, name: mg_enable_multithreading.md }
-  - { type: file, name: mg_enable_javascript.md }
-  - { type: file, name: mg_set_timer.md }
-  - { type: file, name: mg_time.md }
-  - { type: file, name: mg_event_handler_t.md }
-  - { type: file, name: struct_mg_mgr.md }
-  - { type: file, name: struct_mg_connection.md }
-  - { type: file, name: struct_mg_add_sock_opts.md }
-  - { type: file, name: struct_mg_bind_opts.md }
-  - { type: file, name: struct_mg_connect_opts.md }
+  - { name: mg_mgr_init.md }
+  - { name: mg_mgr_free.md }
+  - { name: mg_mgr_poll.md }
+  - { name: mg_broadcast.md }
+  - { name: mg_next.md }
+  - { name: mg_add_sock.md }
+  - { name: mg_add_sock_opt.md }
+  - { name: mg_bind.md }
+  - { name: mg_bind_opt.md }
+  - { name: mg_connect.md }
+  - { name: mg_connect_opt.md }
+  - { name: mg_set_ssl.md }
+  - { name: mg_send.md }
+  - { name: mg_printf.md }
+  - { name: mg_vprintf.md }
+  - { name: mg_socketpair.md }
+  - { name: mg_check_ip_acl.md }
+  - { name: mg_enable_multithreading.md }
+  - { name: mg_enable_javascript.md }
+  - { name: mg_set_timer.md }
+  - { name: mg_time.md }
+  - { name: mg_event_handler_t.md }
+  - { name: struct_mg_mgr.md }
+  - { name: struct_mg_connection.md }
+  - { name: struct_mg_add_sock_opts.md }
+  - { name: struct_mg_bind_opts.md }
+  - { name: struct_mg_connect_opts.md }
 ---
 
 NOTE: Mongoose manager is single threaded. It does not protect
diff --git a/docs/c-api/resolv.h/intro.md b/docs/c-api/resolv.h/intro.md
new file mode 100644
index 000000000..3fc5fc069
--- /dev/null
+++ b/docs/c-api/resolv.h/intro.md
@@ -0,0 +1,13 @@
+---
+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 }
+---
+
+
+
diff --git a/docs/c-api/resolv.h/mg_resolve_async.md b/docs/c-api/resolv.h/mg_resolve_async.md
new file mode 100644
index 000000000..e4dc5d5d0
--- /dev/null
+++ b/docs/c-api/resolv.h/mg_resolve_async.md
@@ -0,0 +1,11 @@
+---
+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()` 
+
diff --git a/docs/c-api/resolv.h/mg_resolve_async_opt.md b/docs/c-api/resolv.h/mg_resolve_async_opt.md
new file mode 100644
index 000000000..56f209a74
--- /dev/null
+++ b/docs/c-api/resolv.h/mg_resolve_async_opt.md
@@ -0,0 +1,30 @@
+---
+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));
+---- 
+
diff --git a/docs/c-api/resolv.h/mg_resolve_from_hosts_file.md b/docs/c-api/resolv.h/mg_resolve_from_hosts_file.md
new file mode 100644
index 000000000..42aa1e67c
--- /dev/null
+++ b/docs/c-api/resolv.h/mg_resolve_from_hosts_file.md
@@ -0,0 +1,12 @@
+---
+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. 
+
diff --git a/docs/c-api/resolv.h/struct_mg_resolve_async_opts.md b/docs/c-api/resolv.h/struct_mg_resolve_async_opts.md
new file mode 100644
index 000000000..6c39e2f1a
--- /dev/null
+++ b/docs/c-api/resolv.h/struct_mg_resolve_async_opts.md
@@ -0,0 +1,17 @@
+---
+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`. 
+
diff --git a/docs/c-api/uri.h/intro.md b/docs/c-api/uri.h/intro.md
new file mode 100644
index 000000000..154aea63c
--- /dev/null
+++ b/docs/c-api/uri.h/intro.md
@@ -0,0 +1,10 @@
+---
+title: "URI"
+symbol_kind: "intro"
+decl_name: "uri.h"
+items:
+  - { name: mg_parse_uri.md }
+---
+
+
+
diff --git a/docs/c-api/uri.h/mg_parse_uri.md b/docs/c-api/uri.h/mg_parse_uri.md
new file mode 100644
index 000000000..48cb6d943
--- /dev/null
+++ b/docs/c-api/uri.h/mg_parse_uri.md
@@ -0,0 +1,33 @@
+---
+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. 
+
diff --git a/docs/c-api/util.h/intro.md b/docs/c-api/util.h/intro.md
index e157a5267..2d8024a05 100644
--- a/docs/c-api/util.h/intro.md
+++ b/docs/c-api/util.h/intro.md
@@ -1,26 +1,26 @@
 ---
-title: "Utilities"
+title: "Utility API"
 symbol_kind: "intro"
 decl_name: "util.h"
 items:
-  - { type: file, name: mg_skip.md }
-  - { type: file, name: mg_ncasecmp.md }
-  - { type: file, name: mg_casecmp.md }
-  - { type: file, name: mg_base64_decode.md }
-  - { type: file, name: mg_base64_encode.md }
-  - { type: file, name: mg_stat.md }
-  - { type: file, name: mg_fopen.md }
-  - { type: file, name: mg_open.md }
-  - { type: file, name: mg_start_thread.md }
-  - { type: file, name: mg_conn_addr_to_str.md }
-  - { type: file, name: mg_sock_to_str.md }
-  - { type: file, name: mg_sock_addr_to_str.md }
-  - { type: file, name: mg_hexdump.md }
-  - { type: file, name: mg_hexdump_connection.md }
-  - { type: file, name: mg_avprintf.md }
-  - { type: file, name: mg_is_big_endian.md }
-  - { type: file, name: mg_next_comma_list_entry.md }
-  - { type: file, name: mg_match_prefix.md }
+  - { name: mg_skip.md }
+  - { name: mg_ncasecmp.md }
+  - { name: mg_casecmp.md }
+  - { name: mg_base64_decode.md }
+  - { name: mg_base64_encode.md }
+  - { name: mg_stat.md }
+  - { name: mg_fopen.md }
+  - { name: mg_open.md }
+  - { name: mg_start_thread.md }
+  - { name: mg_conn_addr_to_str.md }
+  - { name: mg_sock_to_str.md }
+  - { name: mg_sock_addr_to_str.md }
+  - { name: mg_hexdump.md }
+  - { name: mg_hexdump_connection.md }
+  - { name: mg_avprintf.md }
+  - { name: mg_is_big_endian.md }
+  - { name: mg_next_comma_list_entry.md }
+  - { name: mg_match_prefix.md }
 ---
 
 
diff --git a/docs/coap/client_example.md b/docs/coap/client_example.md
new file mode 100644
index 000000000..2dc108019
--- /dev/null
+++ b/docs/coap/client_example.md
@@ -0,0 +1,5 @@
+---
+title: CoAP client example
+---
+
+TBD
diff --git a/docs/coap/intro.md b/docs/coap/intro.md
new file mode 100644
index 000000000..5561044f8
--- /dev/null
+++ b/docs/coap/intro.md
@@ -0,0 +1,7 @@
+---
+title: CoAP
+items:
+  - { name: server_example.md }
+  - { name: client_example.md }
+  - { name: ../c-api/coap.h/ }
+---
diff --git a/docs/coap/server_example.md b/docs/coap/server_example.md
new file mode 100644
index 000000000..2345755d5
--- /dev/null
+++ b/docs/coap/server_example.md
@@ -0,0 +1,5 @@
+---
+title: CoAP server example
+---
+
+TBD
diff --git a/docs/core/intro.md b/docs/core/intro.md
new file mode 100644
index 000000000..d07c65f02
--- /dev/null
+++ b/docs/core/intro.md
@@ -0,0 +1,8 @@
+---
+title: Misc API
+items:
+  - { name: ../c-api/net.h }
+  - { name: ../c-api/util.h }
+  - { name: ../c-api/uri.h }
+  - { name: ../c-api/mbuf.h }
+---
diff --git a/docs/dns/client_example.md b/docs/dns/client_example.md
new file mode 100644
index 000000000..e30cd436c
--- /dev/null
+++ b/docs/dns/client_example.md
@@ -0,0 +1,5 @@
+---
+title: DNS client example
+---
+
+TBD
diff --git a/docs/dns/intro.md b/docs/dns/intro.md
new file mode 100644
index 000000000..fb2b7a76e
--- /dev/null
+++ b/docs/dns/intro.md
@@ -0,0 +1,8 @@
+---
+title: DNS
+items:
+  - { name: server_example.md }
+  - { name: client_example.md }
+  - { name: ../c-api/dns.h/ }
+  - { name: ../c-api/dns_server.h/ }
+---
diff --git a/docs/dns/server_example.md b/docs/dns/server_example.md
new file mode 100644
index 000000000..a4ed52e1c
--- /dev/null
+++ b/docs/dns/server_example.md
@@ -0,0 +1,5 @@
+---
+title: DNS server example
+---
+
+TBD
diff --git a/docs/dns_resolver/intro.md b/docs/dns_resolver/intro.md
new file mode 100644
index 000000000..3b92e7486
--- /dev/null
+++ b/docs/dns_resolver/intro.md
@@ -0,0 +1,6 @@
+---
+title: Async DNS resolver
+items:
+  - { name: overview.md }
+  - { name: ../c-api/resolv.h/ }
+---
diff --git a/docs/dns_resolver/overview.md b/docs/dns_resolver/overview.md
new file mode 100644
index 000000000..4d20f230f
--- /dev/null
+++ b/docs/dns_resolver/overview.md
@@ -0,0 +1,5 @@
+---
+title: Overview
+---
+
+TBD
diff --git a/docs/http/cgi.md b/docs/http/cgi.md
new file mode 100644
index 000000000..8e2309db5
--- /dev/null
+++ b/docs/http/cgi.md
@@ -0,0 +1,31 @@
+---
+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";
+```
diff --git a/docs/http/client_example.md b/docs/http/client_example.md
new file mode 100644
index 000000000..0875824b8
--- /dev/null
+++ b/docs/http/client_example.md
@@ -0,0 +1,44 @@
+---
+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).
diff --git a/docs/http/digest_auth.md b/docs/http/digest_auth.md
new file mode 100644
index 000000000..cbdc4bbc6
--- /dev/null
+++ b/docs/http/digest_auth.md
@@ -0,0 +1,5 @@
+---
+title: Digest Authentication
+---
+
+TBD
diff --git a/docs/http/events.md b/docs/http/events.md
new file mode 100644
index 000000000..5bd432fcb
--- /dev/null
+++ b/docs/http/events.md
@@ -0,0 +1,39 @@
+---
+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.
diff --git a/docs/http/files.md b/docs/http/files.md
new file mode 100644
index 000000000..e59d25195
--- /dev/null
+++ b/docs/http/files.md
@@ -0,0 +1,46 @@
+---
+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;
+     }
+     ...
+   }
+  }
+```
diff --git a/docs/http/intro.md b/docs/http/intro.md
new file mode 100644
index 000000000..52e325c66
--- /dev/null
+++ b/docs/http/intro.md
@@ -0,0 +1,16 @@
+---
+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/ }
+---
diff --git a/docs/http/server_example.md b/docs/http/server_example.md
new file mode 100644
index 000000000..a3c2840f1
--- /dev/null
+++ b/docs/http/server_example.md
@@ -0,0 +1,53 @@
+---
+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;
+}
+```
diff --git a/docs/http/ssi.md b/docs/http/ssi.md
new file mode 100644
index 000000000..2fcfbc4db
--- /dev/null
+++ b/docs/http/ssi.md
@@ -0,0 +1,59 @@
+---
+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;
+   }
+```
diff --git a/docs/http/ssl.md b/docs/http/ssl.md
new file mode 100644
index 000000000..9908f1906
--- /dev/null
+++ b/docs/http/ssl.md
@@ -0,0 +1,33 @@
+---
+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).
diff --git a/docs/http/upload.md b/docs/http/upload.md
new file mode 100644
index 000000000..21caf07e5
--- /dev/null
+++ b/docs/http/upload.md
@@ -0,0 +1,36 @@
+---
+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;
+  }
+}
+```
diff --git a/docs/intro.md b/docs/intro.md
index df56ea732..c5a8b516a 100644
--- a/docs/intro.md
+++ b/docs/intro.md
@@ -3,9 +3,11 @@ title: Mongoose - a networking library
 color: '#1D6482'
 repo: https://github.com/cesanta/mongoose
 items:
-  - { type: file, name: overview.md }
-  - { type: dir, name: usage-example }
-  - { type: dir, name: design-concept }
-  - { type: dir, name: build-options }
-  - { type: flat, name: c-api }
+  - { name: overview }
+  - { name: http }
+  - { name: mqtt }
+  - { name: dns }
+  - { name: coap }
+  - { name: dns_resolver }
+  - { name: core }
 ---
diff --git a/docs/mqtt/client_example.md b/docs/mqtt/client_example.md
new file mode 100644
index 000000000..993be0f06
--- /dev/null
+++ b/docs/mqtt/client_example.md
@@ -0,0 +1,5 @@
+---
+title: MQTT client example
+---
+
+TBD
diff --git a/docs/mqtt/intro.md b/docs/mqtt/intro.md
new file mode 100644
index 000000000..9771d02f1
--- /dev/null
+++ b/docs/mqtt/intro.md
@@ -0,0 +1,8 @@
+---
+title: MQTT
+items:
+  - { name: server_example.md }
+  - { name: client_example.md }
+  - { name: ../c-api/mqtt.h/ }
+  - { name: ../c-api/mqtt_server.h/ }
+---
diff --git a/docs/mqtt/server_example.md b/docs/mqtt/server_example.md
new file mode 100644
index 000000000..706fb5e52
--- /dev/null
+++ b/docs/mqtt/server_example.md
@@ -0,0 +1,5 @@
+---
+title: MQTT server example
+---
+
+TBD
diff --git a/docs/build-options/disabling-flags.md b/docs/overview/build-options/disabling-flags.md
similarity index 100%
rename from docs/build-options/disabling-flags.md
rename to docs/overview/build-options/disabling-flags.md
diff --git a/docs/build-options/enabling-flags.md b/docs/overview/build-options/enabling-flags.md
similarity index 100%
rename from docs/build-options/enabling-flags.md
rename to docs/overview/build-options/enabling-flags.md
diff --git a/docs/build-options/intro.md b/docs/overview/build-options/intro.md
similarity index 100%
rename from docs/build-options/intro.md
rename to docs/overview/build-options/intro.md
diff --git a/docs/build-options/platform-spec.md b/docs/overview/build-options/platform-spec.md
similarity index 100%
rename from docs/build-options/platform-spec.md
rename to docs/overview/build-options/platform-spec.md
diff --git a/docs/build-options/tunables.md b/docs/overview/build-options/tunables.md
similarity index 100%
rename from docs/build-options/tunables.md
rename to docs/overview/build-options/tunables.md
diff --git a/docs/design-concept/intro.md b/docs/overview/concept.md
similarity index 51%
rename from docs/design-concept/intro.md
rename to docs/overview/concept.md
index 4f2a3b5e8..034dfb929 100644
--- a/docs/design-concept/intro.md
+++ b/docs/overview/concept.md
@@ -1,15 +1,8 @@
 ---
 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,
-asyncronous IO and provides event-based APIs. It has three basic data
-structures:
+Mongoose has three basic data structures:
 
 - `struct mg_mgr` is an event manager that holds all active connections
 - `struct mg_connection` describes a 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,
 send/receive buffer, flags, etc.
 
-Mongoose's usage pattern is to declare and initialise event manager, create
-connections and create an event loop by calling `mg_mgr_poll()` in a loop.
+An application that uses mongoose should follow a standard pattern of
+event-driven application:
+
+1. declare and initialise event manager:
+
+    ```c
+    struct mg_mgr mgr;
+    mg_mgr_init(&mgr, NULL);
+    ```
+2. Create connections. For example, a server application should create
+   listening connections:
+
+   ```c
+    struct mg_connection *c = mg_bind(&mgr, "80", ev_handler_function);
+    mg_set_protocol_http_websocket(c);
+   ```
+
+3. create an event loop by calling `mg_mgr_poll()` in a loop:
+
+    ```c
+    for (;;) {
+      mg_mgr_poll(&mgr, 1000);
+    }
+    ```
+
 `mg_mgr_poll()` iterates over all sockets, accepts new connections, sends and
 receives data, closes connections and calls event handler functions for the
-respective events.
+respective events. For the full example, see
+[Usage Example](#/overview/usage-example.md/)
+which implements TCP echo server.
diff --git a/docs/design-concept/conn-flags.md b/docs/overview/conn-flags.md
similarity index 100%
rename from docs/design-concept/conn-flags.md
rename to docs/overview/conn-flags.md
diff --git a/docs/design-concept/event-handler.md b/docs/overview/event-handler.md
similarity index 100%
rename from docs/design-concept/event-handler.md
rename to docs/overview/event-handler.md
diff --git a/docs/design-concept/events.md b/docs/overview/events.md
similarity index 100%
rename from docs/design-concept/events.md
rename to docs/overview/events.md
diff --git a/docs/overview.md b/docs/overview/intro.md
similarity index 63%
rename from docs/overview.md
rename to docs/overview/intro.md
index 2a61eab1e..9f8a0809b 100644
--- a/docs/overview.md
+++ b/docs/overview/intro.md
@@ -1,19 +1,31 @@
 ---
 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,
 WebSocket, CoAP, MQTT for client and server mode.
 Features include:
 
 - Cross-platform: works on Linux/UNIX, MacOS, QNX, eCos, Windows, Android,
-  iPhone, FreeRTOS (TI CC3200, ESP8266) and more
-- Single-threaded, asynchronous, non-blocking core with simple event-based API
+  iPhone, FreeRTOS
 - Native support for [PicoTCP embedded TCP/IP stack](http://www.picotcp.com),
   [LWIP embedded TCP/IP stack](https://en.wikipedia.org/wiki/LwIP)
+- Works on a variety of embedded boards: TI CC3200, TI MSP430, STM32, ESP8266;
+  on all Linux-based boards like Raspberry PI, BeagleBone, etc
+- Single-threaded, asynchronous, non-blocking core with simple event-based API
 - Built-in protocols:
-   - plain TCP, plain UDP, SSL/TLS (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
    - WebSocket client and server
    - MQTT client and server
diff --git a/docs/design-concept/memory-buffers.md b/docs/overview/mbufs.md
similarity index 100%
rename from docs/design-concept/memory-buffers.md
rename to docs/overview/mbufs.md
diff --git a/docs/usage-example/intro.md b/docs/overview/usage-example.md
similarity index 97%
rename from docs/usage-example/intro.md
rename to docs/overview/usage-example.md
index fff444f3e..9c2ce0fd1 100644
--- a/docs/usage-example/intro.md
+++ b/docs/overview/usage-example.md
@@ -1,5 +1,5 @@
 ---
-title: Usage Example
+title: Example - TCP echo server
 ---
 
 - Copy `mongoose.c` and `mongoose.h` to your build tree
diff --git a/mongoose.c b/mongoose.c
index 593254abf..e8ad3704d 100644
--- a/mongoose.c
+++ b/mongoose.c
@@ -8148,7 +8148,7 @@ void mg_mqtt_disconnect(struct mg_connection *nc) {
 
 #endif /* MG_DISABLE_MQTT */
 #ifdef MG_MODULE_LINES
-#line 1 "./src/mqtt-broker.c"
+#line 1 "./src/mqtt_server.c"
 #endif
 /*
  * Copyright (c) 2014 Cesanta Software Limited
@@ -8693,7 +8693,7 @@ void mg_set_protocol_dns(struct mg_connection *nc) {
 
 #endif /* MG_DISABLE_DNS */
 #ifdef MG_MODULE_LINES
-#line 1 "./src/dns-server.c"
+#line 1 "./src/dns_server.c"
 #endif
 /*
  * Copyright (c) 2014 Cesanta Software Limited
diff --git a/mongoose.h b/mongoose.h
index db35824c9..2047cda2e 100644
--- a/mongoose.h
+++ b/mongoose.h
@@ -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
  * 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);
  */
 
 /*
- * === Utilities
+ * === Utility API
  */
 
 #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);
  */
 
 /*
- * === HTTP + Websocket
+ * === Common API reference
  */
 
 #ifndef CS_MONGOOSE_SRC_HTTP_H_
@@ -2208,70 +2208,6 @@ void mg_printf_websocket_frame(struct mg_connection *nc, int op_and_flags,
                                const char *fmt, ...);
 #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 */
 #define WEBSOCKET_OP_CONTINUE 0
 #define WEBSOCKET_OP_TEXT 1
@@ -2294,6 +2230,34 @@ void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
  */
 #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.
  *
@@ -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,
                     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.
  * 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,
 int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain,
                               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
 }
 #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
  * All rights reserved
@@ -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_
@@ -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_
@@ -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_
@@ -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`.
  */
@@ -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_
@@ -3365,7 +3396,7 @@ int mg_resolve_from_hosts_file(const char *host, union socket_address *usa);
  */
 
 /*
- * === CoAP
+ * === CoAP API reference
  *
  * CoAP message format:
  *
-- 
GitLab