From bab4b309cacf41db85fb01035f075861cc458ced Mon Sep 17 00:00:00 2001 From: eidheim Date: Fri, 9 Apr 2021 14:33:43 +0200 Subject: [PATCH] Client: added parsing of host specified with IPv6 address --- client_http.hpp | 29 ++++++++++++++++++++--------- tests/parse_test.cpp | 37 ++++++++++++++++++++++--------------- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/client_http.hpp b/client_http.hpp index 3a08473..f14e3f3 100644 --- a/client_http.hpp +++ b/client_http.hpp @@ -500,22 +500,33 @@ namespace SimpleWeb { } std::pair parse_host_port(const std::string &host_port, unsigned short default_port) const noexcept { - std::pair parsed_host_port; - std::size_t host_end = host_port.find(':'); - if(host_end == std::string::npos) { - parsed_host_port.first = host_port; - parsed_host_port.second = default_port; + std::string host, port; + host.reserve(host_port.size()); + bool parse_port = false; + int square_count = 0; // To parse IPv6 addresses + for(auto chr : host_port) { + if(chr == '[') + ++square_count; + else if(chr == ']') + --square_count; + else if(square_count == 0 && chr == ':') + parse_port = true; + else if(!parse_port) + host += chr; + else + port += chr; } + + if(port.empty()) + return {std::move(host), default_port}; else { - parsed_host_port.first = host_port.substr(0, host_end); try { - parsed_host_port.second = static_cast(std::stoul(host_port.substr(host_end + 1))); + return {std::move(host), static_cast(std::stoul(port))}; } catch(...) { - parsed_host_port.second = default_port; + return {std::move(host), default_port}; } } - return parsed_host_port; } virtual std::shared_ptr create_connection() noexcept = 0; diff --git a/tests/parse_test.cpp b/tests/parse_test.cpp index cb9fde6..b6ea90c 100644 --- a/tests/parse_test.cpp +++ b/tests/parse_test.cpp @@ -61,16 +61,6 @@ public: void connect(const std::shared_ptr &) noexcept override {} - void constructor_parse_test1() { - ASSERT(host == "test.org"); - ASSERT(port == 8080); - } - - void constructor_parse_test2() { - ASSERT(host == "test.org"); - ASSERT(port == 80); - } - void parse_response_header_test() { std::shared_ptr response(new Response(static_cast(-1), nullptr)); @@ -151,13 +141,30 @@ int main() { serverTest->parse_request_test(); - auto clientTest = make_shared("test.org:8080"); - clientTest->constructor_parse_test1(); + { + ClientTest clientTest("test.org"); + ASSERT(clientTest.host == "test.org"); + ASSERT(clientTest.port == 80); + clientTest.parse_response_header_test(); + } - auto clientTest2 = make_shared("test.org"); - clientTest2->constructor_parse_test2(); + { + ClientTest clientTest("test.org:8080"); + ASSERT(clientTest.host == "test.org"); + ASSERT(clientTest.port == 8080); + } - clientTest2->parse_response_header_test(); + { + ClientTest clientTest("[::1]"); + ASSERT(clientTest.host == "::1"); + ASSERT(clientTest.port == 80); + } + + { + ClientTest clientTest("[::1]:8080"); + ASSERT(clientTest.host == "::1"); + ASSERT(clientTest.port == 8080); + } io_context io_service;