diff --git a/Development/cpprest/http_utils.cpp b/Development/cpprest/http_utils.cpp index 227a5228a..f9160b431 100644 --- a/Development/cpprest/http_utils.cpp +++ b/Development/cpprest/http_utils.cpp @@ -27,7 +27,10 @@ namespace web if (req.headers().end() != header) { auto first = header->second.substr(0, header->second.find(',')); - auto colon = first.find(':'); + // an IPv6 address is enclosed in square brackets, e.g. "[2001:db8::1]:42", so look for the port after the closing bracket + // see https://tools.ietf.org/html/rfc3986#section-3.2.2 + const auto bracket = first.find(']'); + auto colon = first.find(':', utility::string_t::npos != bracket ? bracket : 0); if (utility::string_t::npos == colon) return{ std::move(first), 0 }; return{ first.substr(0, colon), utility::conversions::details::scan_string(first.substr(colon + 1), 0) }; } diff --git a/Development/cpprest/test/http_utils_test.cpp b/Development/cpprest/test/http_utils_test.cpp index a930a68ae..338c74008 100644 --- a/Development/cpprest/test/http_utils_test.cpp +++ b/Development/cpprest/test/http_utils_test.cpp @@ -35,6 +35,12 @@ BST_TEST_CASE(testGetHostPort) req.headers().add(U("Host"), U("29.31.37.41:42")); BST_REQUIRE_EQUAL(std::make_pair(utility::string_t{ U("29.31.37.41") }, 42), web::http::get_host_port(req)); } + // IPv6 address and port + { + web::http::http_request req; + req.headers().add(U("Host"), U("[2001:db8::1]:42")); + BST_REQUIRE_EQUAL(std::make_pair(utility::string_t{ U("[2001:db8::1]") }, 42), web::http::get_host_port(req)); + } // 'X-Forwarded-Host'