From 5608cb3b4f872ed67415522982109803289edbcb Mon Sep 17 00:00:00 2001
From: Konstantinos Sideris <sideris.konstantin@gmail.com>
Date: Mon, 4 Jun 2018 23:03:57 +0300
Subject: [PATCH] Allow the port number along with the domain in set_server

---
 include/mtxclient/http/client.hpp |  2 +-
 include/mtxclient/utils.hpp       |  4 ++++
 lib/http/client.cpp               | 15 +++++++++++++++
 lib/utils.cpp                     |  7 +++++++
 tests/connection.cpp              | 13 +++++++++++++
 5 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/include/mtxclient/http/client.hpp b/include/mtxclient/http/client.hpp
index 88df02aac..b90e7f574 100644
--- a/include/mtxclient/http/client.hpp
+++ b/include/mtxclient/http/client.hpp
@@ -73,7 +73,7 @@ public:
         //! Wait for the client to close.
         void close();
         //! Set the homeserver domain name.
-        void set_server(const std::string &server) { server_ = server; };
+        void set_server(const std::string &server);
         //! Retrieve the homeserver domain name.
         std::string server() { return server_; };
         //! Set the homeserver port.
diff --git a/include/mtxclient/utils.hpp b/include/mtxclient/utils.hpp
index 0752ddb87..92816027e 100644
--- a/include/mtxclient/utils.hpp
+++ b/include/mtxclient/utils.hpp
@@ -10,6 +10,10 @@ namespace mtx {
 namespace client {
 namespace utils {
 
+//! Check if the given string represents a number.
+bool
+is_number(const std::string &s);
+
 //! Generates a random string of the given size.
 std::string
 random_token(uint8_t len = 12, bool with_symbols = true) noexcept;
diff --git a/lib/http/client.cpp b/lib/http/client.cpp
index 1a1039a54..8397756c5 100644
--- a/lib/http/client.cpp
+++ b/lib/http/client.cpp
@@ -22,6 +22,21 @@ Client::Client(const std::string &server, uint16_t port)
                 thread_group_.add_thread(new boost::thread([this]() { ios_.run(); }));
 }
 
+void
+Client::set_server(const std::string &server)
+{
+        // Check if the input also contains the port.
+        std::vector<std::string> parts;
+        boost::split(parts, server, [](char c) { return c == ':'; });
+
+        if (parts.size() == 2 && mtx::client::utils::is_number(parts.at(1))) {
+                server_ = parts.at(0);
+                port_   = std::stoi(parts.at(1));
+        } else {
+                server_ = server;
+        }
+};
+
 void
 Client::close()
 {
diff --git a/lib/utils.cpp b/lib/utils.cpp
index 7a36b37a8..3f6a73fc7 100644
--- a/lib/utils.cpp
+++ b/lib/utils.cpp
@@ -14,6 +14,13 @@
 #include <boost/random/random_device.hpp>
 #include <boost/random/uniform_int_distribution.hpp>
 
+bool
+mtx::client::utils::is_number(const std::string &s)
+{
+        return !s.empty() &&
+               std::find_if(s.begin(), s.end(), [](char c) { return !std::isdigit(c); }) == s.end();
+}
+
 std::string
 mtx::client::utils::random_token(uint8_t len, bool with_symbols) noexcept
 {
diff --git a/tests/connection.cpp b/tests/connection.cpp
index 3d5168546..0445dfd3c 100644
--- a/tests/connection.cpp
+++ b/tests/connection.cpp
@@ -25,6 +25,19 @@ TEST(Basic, Connection)
         alice->close();
 }
 
+TEST(Basic, ServerWithPort)
+{
+        auto alice = std::make_shared<Client>("matrix.org");
+        alice->set_server("localhost:8448");
+
+        EXPECT_EQ(alice->server(), "localhost");
+        EXPECT_EQ(alice->port(), 8448);
+
+        alice->versions(
+          [](const mtx::responses::Versions &, RequestErr err) { ASSERT_FALSE(err); });
+        alice->close();
+}
+
 TEST(Basic, Failure)
 {
         auto alice = std::make_shared<Client>("not-resolvable-example-domain.wrong");
-- 
GitLab