diff options
author | eidheim <eidheim@gmail.com> | 2021-04-09 15:33:21 +0300 |
---|---|---|
committer | eidheim <eidheim@gmail.com> | 2021-04-09 15:33:21 +0300 |
commit | 06e60552ae2ca9393dc1f9eae80a9ae6370018ce (patch) | |
tree | 85b01b9b2307231fb1568587d6c93193c2dc3a76 | |
parent | 868588ad1047054e38d33fb872a3bc8859092e5e (diff) |
SocketClient: added parsing of host specified with IPv6 address
-rw-r--r-- | client_ws.hpp | 29 | ||||
-rw-r--r-- | tests/parse_test.cpp | 88 |
2 files changed, 74 insertions, 43 deletions
diff --git a/client_ws.hpp b/client_ws.hpp index f56bf3a..23a8923 100644 --- a/client_ws.hpp +++ b/client_ws.hpp @@ -367,22 +367,33 @@ namespace SimpleWeb { } std::pair<std::string, unsigned short> parse_host_port(const std::string &host_port, unsigned short default_port) const noexcept { - std::pair<std::string, unsigned short> 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<unsigned short>(stoul(host_port.substr(host_end + 1))); + return {std::move(host), static_cast<unsigned short>(std::stoul(port))}; } catch(...) { - parsed_host_port.second = default_port; + return {std::move(host), default_port}; } } - return parsed_host_port; } virtual void connect() = 0; diff --git a/tests/parse_test.cpp b/tests/parse_test.cpp index 45f5476..0427eeb 100644 --- a/tests/parse_test.cpp +++ b/tests/parse_test.cpp @@ -57,30 +57,6 @@ public: void connect() {} - void constructor_parse_test1() { - ASSERT(path == "/test"); - ASSERT(host == "test.org"); - ASSERT(port == 8080); - } - - void constructor_parse_test2() { - ASSERT(path == "/test"); - ASSERT(host == "test.org"); - ASSERT(port == 80); - } - - void constructor_parse_test3() { - ASSERT(path == "/"); - ASSERT(host == "test.org"); - ASSERT(port == 80); - } - - void constructor_parse_test4() { - ASSERT(path == "/"); - ASSERT(host == "test.org"); - ASSERT(port == 8080); - } - void parse_response_header_test() { auto connection = std::shared_ptr<Connection>(new Connection(handler_runner, config.timeout_idle, *io_service)); connection->in_message = std::shared_ptr<InMessage>(new InMessage()); @@ -136,18 +112,62 @@ int main() { serverTest.parse_request_test(); - SocketClientTest clientTest("test.org:8080/test"); - clientTest.constructor_parse_test1(); + { + SocketClientTest clientTest("test.org:8080/test"); + ASSERT(clientTest.path == "/test"); + ASSERT(clientTest.host == "test.org"); + ASSERT(clientTest.port == 8080); + } + + { + SocketClientTest clientTest("test.org/test"); + ASSERT(clientTest.path == "/test"); + ASSERT(clientTest.host == "test.org"); + ASSERT(clientTest.port == 80); + } + + { + SocketClientTest clientTest("test.org"); + ASSERT(clientTest.path == "/"); + ASSERT(clientTest.host == "test.org"); + ASSERT(clientTest.port == 80); + } + + { + SocketClientTest clientTest("[::1]"); + ASSERT(clientTest.path == "/"); + ASSERT(clientTest.host == "::1"); + ASSERT(clientTest.port == 80); + } - SocketClientTest clientTest2("test.org/test"); - clientTest2.constructor_parse_test2(); + { + SocketClientTest clientTest("[::1]/test"); + ASSERT(clientTest.path == "/test"); + ASSERT(clientTest.host == "::1"); + ASSERT(clientTest.port == 80); + } - SocketClientTest clientTest3("test.org"); - clientTest3.constructor_parse_test3(); + { + SocketClientTest clientTest("[::1]:8080"); + ASSERT(clientTest.path == "/"); + ASSERT(clientTest.host == "::1"); + ASSERT(clientTest.port == 8080); + } - SocketClientTest clientTest4("test.org:8080"); - clientTest4.io_service = std::make_shared<io_context>(); - clientTest4.constructor_parse_test4(); + { + SocketClientTest clientTest("[::1]:8080/test"); + ASSERT(clientTest.path == "/test"); + ASSERT(clientTest.host == "::1"); + ASSERT(clientTest.port == 8080); + } - clientTest4.parse_response_header_test(); + { + SocketClientTest clientTest("test.org:8080"); + clientTest.io_service = std::make_shared<io_context>(); + ASSERT(clientTest.path == "/"); + ASSERT(clientTest.host == "test.org"); + ASSERT(clientTest.port == 8080); + + clientTest.parse_response_header_test(); + } } |