diff --git a/examples/http-client/main.c b/examples/http-client/main.c index a92a1542..9f8c413b 100644 --- a/examples/http-client/main.c +++ b/examples/http-client/main.c @@ -13,11 +13,20 @@ // The very first web page in history. You can replace it from command line static const char *s_url = "http://info.cern.ch/"; -static const char *s_post = NULL; // POST data +static const char *s_post_data = NULL; // POST data +static const int64_t s_timeout_ms = 1500; // Connect timeout in milliseconds // Print HTTP response and signal that we're done static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { - if (ev == MG_EV_CONNECT) { + if (ev == MG_EV_OPEN) { + // Connection created. Store connect expiration time in c->label + *(int64_t *) c->label = mg_millis() + s_timeout_ms; + } else if (ev == MG_EV_POLL) { + if (mg_millis() > *(int64_t *) c->label && + (c->is_connecting || c->is_resolving)) { + mg_error(c, "Connect timeout"); + } + } else if (ev == MG_EV_CONNECT) { // Connected to server. Extract host name from URL struct mg_str host = mg_url_host(s_url); @@ -28,16 +37,16 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { } // Send request - int content_length = s_post ? strlen(s_post) : 0; + int content_length = s_post_data ? strlen(s_post_data) : 0; mg_printf(c, "%s %s HTTP/1.0\r\n" "Host: %.*s\r\n" "Content-Type: octet-stream\r\n" "Content-Length: %d\r\n" "\r\n", - s_post ? "POST" : "GET", mg_url_uri(s_url), (int) host.len, + s_post_data ? "POST" : "GET", mg_url_uri(s_url), (int) host.len, host.ptr, content_length); - mg_send(c, s_post, content_length); + mg_send(c, s_post_data, content_length); } else if (ev == MG_EV_HTTP_MSG) { // Response is received. Print it struct mg_http_message *hm = (struct mg_http_message *) ev_data; @@ -50,24 +59,13 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { } int main(int argc, char *argv[]) { - struct mg_mgr mgr; // Event manager - bool done = false; // Event handler flips it to true - int i; - - // Parse command-line flags - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-d") == 0) { - s_post = argv[++i]; - } else { - break; - } - } - if (i < argc) s_url = argv[i]; - - mg_log_set("3"); // Set to 0 to disable debug - mg_mgr_init(&mgr); // Initialise event manager + struct mg_mgr mgr; // Event manager + bool done = false; // Event handler flips it to true + if (argc > 1) s_url = argv[1]; // Use URL provided in the command line + mg_log_set("3"); // Set to 0 to disable debug + mg_mgr_init(&mgr); // Initialise event manager mg_http_connect(&mgr, s_url, fn, &done); // Create client connection - while (!done) mg_mgr_poll(&mgr, 1000); // Infinite event loop + while (!done) mg_mgr_poll(&mgr, 50); // Infinite event loop mg_mgr_free(&mgr); // Free resources return 0; } diff --git a/mongoose.c b/mongoose.c index b09fdb13..bd4a45ff 100644 --- a/mongoose.c +++ b/mongoose.c @@ -155,6 +155,7 @@ static size_t mg_dns_parse_name_depth(const uint8_t *s, size_t len, size_t ofs, } if (n & 0xc0) { size_t ptr = (((n & 0x3f) << 8) | s[ofs + i + 1]); // 12 is hdr len + // MG_INFO(("PTR %lu", (unsigned long) ptr)); if (ptr + 1 < len && (s[ptr] & 0xc0) == 0 && mg_dns_parse_name_depth(s, len, ptr, to, tolen, depth + 1) == 0) return 0; diff --git a/src/dns.c b/src/dns.c index b7f8ef6c..8c29c3bc 100644 --- a/src/dns.c +++ b/src/dns.c @@ -43,6 +43,7 @@ static size_t mg_dns_parse_name_depth(const uint8_t *s, size_t len, size_t ofs, } if (n & 0xc0) { size_t ptr = (((n & 0x3f) << 8) | s[ofs + i + 1]); // 12 is hdr len + // MG_INFO(("PTR %lu", (unsigned long) ptr)); if (ptr + 1 < len && (s[ptr] & 0xc0) == 0 && mg_dns_parse_name_depth(s, len, ptr, to, tolen, depth + 1) == 0) return 0; diff --git a/test/unit_test.c b/test/unit_test.c index 6dec315c..43ea6e4e 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -1320,6 +1320,35 @@ static void test_dns(void) { ASSERT(mg_dns_parse(data, sizeof(data), &dm) == 1); ASSERT(strcmp(dm.name, "") == 0); + { + // 0000 00 01 81 80 00 01 00 04 00 00 00 00 05 79 61 68 .............yah + // 0010 6f 6f 05 63 31 31 32 36 03 63 6f 6d 00 00 01 00 oo.c1126.com.... + // 0020 01 c0 0c 00 05 00 01 00 00 0d 34 00 0c 03 77 77 ..........4...ww + // 0030 77 05 79 61 68 6f 6f c0 18 c0 2d 00 05 00 01 00 w.yahoo...-..... + // 0040 00 00 01 00 14 0b 6e 65 77 2d 66 70 2d 73 68 65 ......new-fp-she + // 0050 64 03 77 67 31 01 62 c0 31 c0 45 00 01 00 01 00 d.wg1.b.1.E..... + // 0060 00 00 0a 00 04 57 f8 64 d8 c0 45 00 01 00 01 00 .....W.d..E..... + // 0070 00 00 0a 00 04 57 f8 64 d7 .....W.d. + uint8_t d[] = { + 0x00, 0x01, 0x81, 0x80, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x79, 0x61, 0x68, 0x6f, 0x6f, 0x05, 0x63, 0x31, 0x31, + 0x32, 0x36, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, + 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x0d, 0x34, 0x00, + 0x0c, 0x03, 0x77, 0x77, 0x77, 0x05, 0x79, 0x61, 0x68, 0x6f, 0x6f, + 0xc0, 0x18, 0xc0, 0x2d, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x14, 0x0b, 0x6e, 0x65, 0x77, 0x2d, 0x66, 0x70, 0x2d, + 0x73, 0x68, 0x65, 0x64, 0x03, 0x77, 0x67, 0x31, 0x01, 0x62, 0xc0, + 0x31, 0xc0, 0x45, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x04, 0x57, 0xf8, 0x64, 0xd8, 0xc0, 0x45, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x04, 0x57, 0xf8, 0x64, 0xd7, + }; + MG_INFO(("--------------")); + ASSERT(mg_dns_parse(d, sizeof(d), &dm) == 1); + MG_INFO(("[%s]", dm.name)); + ASSERT(strcmp(dm.name, "com") == 0); + exit(0); + } + test_dns_timeout("udp://127.0.0.1:12345", "DNS timeout"); test_dns_timeout("", "resolver"); test_dns_timeout("tcp://0.0.0.0:0", "DNS error");