diff --git a/mongoose.c b/mongoose.c index 2730aff739d4ec90876848b2c11093ce0f169269..696ec388b7ebd3cb79b413767779044d73ac8360 100644 --- a/mongoose.c +++ b/mongoose.c @@ -5969,9 +5969,10 @@ struct mg_connection *mg_connect_http(struct mg_mgr *mgr, const char *url, const char *extra_headers, const char *post_data) { - struct mg_connection *nc; - char addr[1100], path[4096]; /* NOTE: keep sizes in sync with sscanf below */ - int use_ssl = 0, addr_len = 0; + struct mg_connection *nc = NULL; + char *addr = NULL; + const char *path = NULL; + int use_ssl = 0, addr_len = 0, port_i = -1; if (memcmp(url, "http://", 7) == 0) { url += 7; @@ -5983,15 +5984,32 @@ struct mg_connection *mg_connect_http(struct mg_mgr *mgr, #endif } - addr[0] = path[0] = '\0'; - - /* addr buffer size made smaller to allow for port to be prepended */ - sscanf(url, "%1095[^/]/%4095s", addr, path); - if (strchr(addr, ':') == NULL) { - addr_len = strlen(addr); - strncat(addr, use_ssl ? ":443" : ":80", sizeof(addr) - (addr_len + 1)); + while (*url != '\0') { + addr = (char *) MG_REALLOC(addr, addr_len + 5 /* space for port too. */); + if (addr == NULL) { + DBG(("OOM")); + return NULL; + } + if (*url == '/') { + url++; + break; + } + if (*url == ':') port_i = addr_len; + addr[addr_len++] = *url; + addr[addr_len] = '\0'; + url++; + } + if (addr_len == 0) goto cleanup; + if (port_i < 0) { + port_i = addr_len; + strcpy(addr + port_i, use_ssl ? ":443" : ":80"); + } else { + port_i = -1; } + if (path == NULL) path = url; + + DBG(("%s %s", addr, path)); if ((nc = mg_connect(mgr, addr, ev_handler)) != NULL) { mg_set_protocol_http_websocket(nc); @@ -6001,10 +6019,8 @@ struct mg_connection *mg_connect_http(struct mg_mgr *mgr, #endif } - if (addr_len) { - /* Do not add port. See https://github.com/cesanta/mongoose/pull/304 */ - addr[addr_len] = '\0'; - } + /* If the port was addred by us, restore the original host. */ + if (port_i >= 0) addr[port_i] = '\0'; mg_printf(nc, "%s /%s HTTP/1.1\r\nHost: %s\r\nContent-Length: %" SIZE_T_FMT "\r\n%s\r\n%s", post_data == NULL ? "GET" : "POST", path, addr, @@ -6013,6 +6029,8 @@ struct mg_connection *mg_connect_http(struct mg_mgr *mgr, post_data == NULL ? "" : post_data); } +cleanup: + MG_FREE(addr); return nc; }