diff --git a/docs/c-api/coap.h/intro.md b/docs/c-api/coap.h/intro.md index 8f3f30841ea024a53f21820a93393c9b906acaea..ced6828b6a9758d64c9da0d87184c60337251ea7 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 50f967958c79121eb3b0ed383b03dc5577eca73d..0000000000000000000000000000000000000000 --- 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 c36f5b75fb101a8149301e2ef7dce0b266b01846..5f52c16f9b603ede69063c1a81d3c2221ada93f2 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 0000000000000000000000000000000000000000..16ba0fc90d6bc8e9b19e21233aac8a16db99fe8e --- /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 3cb77d7765133938e6658d84e95599f70da01068..f070b4b5a1e837dc2b58703b15724e1a75695e4f 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 b0edaadaef3d9bed3f9568aab7fa02aa4f6c9c64..2343adfa2c434f207dc10e0b29802ecb25ce42dd 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 0000000000000000000000000000000000000000..d3bc1d6a5c2c8ccc6792c841588f0050d5ded359 --- /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 c99d80d72f6d4065125a45952769e859d3e3ca58..fcf5f04687585192eade1234648ae79dd0217480 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 0000000000000000000000000000000000000000..0879399c74a79dda6f532b0ebc7da84454e529c2 --- /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 698c8cd845fe157bafb246607b1583a7857cb33f..cd3348668fc99f54f49794d652cedc8e2a04214e 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 8ad31e5e89dc1ce01b3f2eecc352eb3e69d4a9b6..2ce64a1a92664c1dd10a88ec84256ae2eb3c3bbc 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 bd72b0da47a9570e2a973a9e240cc1f37a562849..213927dd53a802cc82f9ad61962b04bc082b254e 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 342101e198a4c33080f05eff3cd6099d9de79db4..34f3610220ef388c6dc7f1d794cce48af0c52036 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 2fa91c3df6f13cef064c55ada804e3eed160adb9..ea2e850561ea209b7d63da2ad48bafaef23453ed 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 621b3f640e3e82bbad454af1251bcb9e3c0f7e4a..0000000000000000000000000000000000000000 --- 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 d8a6aba8a783b855b4a9996248587d790ae1d28d..a5c1ba66da1de80890483d3f27572af277b7166b 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 0000000000000000000000000000000000000000..39da65b2d6ffb1146ecd8a9f2bfe88352ae0efb5 --- /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 10df58ba2c4e402fc03755b2493f71f3d2b11a5c..d102bac1ec6bcde1557881e68b4b09fc8038ddb7 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 0000000000000000000000000000000000000000..3fc5fc069f796ebaf1ff3939e7290805f2ea1d58 --- /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 0000000000000000000000000000000000000000..e4dc5d5d0ca3618f04c26ac77fd4452e38790edc --- /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 0000000000000000000000000000000000000000..56f209a74abd9dc7b7f11ecdfd8f7ff74de57344 --- /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 0000000000000000000000000000000000000000..42aa1e67c99cf1c54d9d042f19dfa666d600a0c2 --- /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 0000000000000000000000000000000000000000..6c39e2f1a2c09644a56c0aa884530f53d448122b --- /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 0000000000000000000000000000000000000000..154aea63c0cea2a85116944a648df50adf6ef92b --- /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 0000000000000000000000000000000000000000..48cb6d943b29ba9849e58a29e0b8f329e82a6b43 --- /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 e157a5267a79c5ed50f51c55f73a9780459fdfb6..2d8024a0536755fe2f1bda0c901c09fe32fa9708 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 0000000000000000000000000000000000000000..2dc108019fd41d9989235352b77f11ae6507a8d5 --- /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 0000000000000000000000000000000000000000..5561044f88b13673042ddab8bd71419a16efe40d --- /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 0000000000000000000000000000000000000000..2345755d51bf3831106f3c76261156e18223bb03 --- /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 0000000000000000000000000000000000000000..d07c65f024b3bb3080a522846e6ee6bd4ed974fb --- /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 0000000000000000000000000000000000000000..e30cd436ca1a8991346149d5981bf122feb31223 --- /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 0000000000000000000000000000000000000000..fb2b7a76ed6a90df91dc4bdcf4f8a4db041632a5 --- /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 0000000000000000000000000000000000000000..a4ed52e1c3c3ae943cc4050f98fc32cd0e8cf3a2 --- /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 0000000000000000000000000000000000000000..3b92e7486e67731c306cc2c15cce4c3bacd6f3bd --- /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 0000000000000000000000000000000000000000..4d20f230fa40b50dfcf8eb9ef21014e9c17cea27 --- /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 0000000000000000000000000000000000000000..8e2309db58223b754923078da640c110a5823ab1 --- /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 0000000000000000000000000000000000000000..0875824b86b86c9f55d3f5f7850b80cbbee1535d --- /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 0000000000000000000000000000000000000000..cbdc4bbc673923ad29af37c77b42df55da346c1f --- /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 0000000000000000000000000000000000000000..5bd432fcbbd0ec5cbf258e8a26f936499524dfa2 --- /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 0000000000000000000000000000000000000000..e59d25195e6bec25e50f9c0a0957ae84d8f555df --- /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 0000000000000000000000000000000000000000..52e325c66bfe63574866b431a07979464fa3d35c --- /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 0000000000000000000000000000000000000000..a3c2840f164be18f89829b2f4ef99955f9405d41 --- /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 0000000000000000000000000000000000000000..2fcfbc4db5a07e6c80b6798089dc5ac4403ec9c2 --- /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 0000000000000000000000000000000000000000..9908f1906c996f0366ddfbf97c6e37b71eda6218 --- /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 0000000000000000000000000000000000000000..21caf07e560e9f2b38eac369b5f49af98f49583e --- /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 +<form method="POST" action="/upload" enctype="multipart/form-data"> + <input type="file" name="file"> + <input type="submit" value="Upload"> +</form> +``` + +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 df56ea73293be77c5b61288f1155d93f6da5cee3..c5a8b516a46bf3c46b51f592f2fd7a074b543fc3 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 0000000000000000000000000000000000000000..993be0f0672ff403716dd98a9744df034d6a651c --- /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 0000000000000000000000000000000000000000..9771d02f174ead92a7525b18bf9a7d754941795e --- /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 0000000000000000000000000000000000000000..706fb5e52cae8e302041d0ed944d13b290125eb9 --- /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 4f2a3b5e80e075a5347a93cd4a88ab42ddb7f218..034dfb92911d4018138bfd26929ea1296a3cd70b 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 2a61eab1e28fef812fa272e3234f6dfeae1220df..9f8a0809bb52b89554dfdcbbd60676c7fc545b3d 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 fff444f3e2f2a82d177ee03fb90c1574eaed29d2..9c2ce0fd12d54a535cd6f1e06edac42d1e3a2add 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 593254abfca12009db607db365b4a26f2e042da2..e8ad3704d159b14ca61a5baa9cfc8cba31dfa0e4 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 db35824c9fad160f8d3534714e407157a1f129bc..2047cda2e2fdb5399bc078ad22a7a366f8eaebad 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: *