aboutsummaryrefslogtreecommitdiff
path: root/libcmix-network
diff options
context:
space:
mode:
Diffstat (limited to 'libcmix-network')
-rw-r--r--libcmix-network/CMakeLists.txt2
-rw-r--r--libcmix-network/acceptor.cpp1
-rw-r--r--libcmix-network/client.cpp5
-rw-r--r--libcmix-network/client.hpp4
-rw-r--r--libcmix-network/connect.cpp38
-rw-r--r--libcmix-network/connect.hpp3
-rw-r--r--libcmix-network/uriparser.cpp3
-rw-r--r--libcmix-network/uriparser.hpp59
8 files changed, 106 insertions, 9 deletions
diff --git a/libcmix-network/CMakeLists.txt b/libcmix-network/CMakeLists.txt
index 6986eea..2574e82 100644
--- a/libcmix-network/CMakeLists.txt
+++ b/libcmix-network/CMakeLists.txt
@@ -7,6 +7,7 @@ add_library(cmix-network
server.hpp server.cpp
client.hpp client.cpp
nodeclient.hpp nodeclient.cpp
+ uriparser.hpp uriparser.cpp
)
target_compile_options(cmix-network
@@ -22,6 +23,7 @@ target_link_libraries(cmix-network
PUBLIC Boost::system
PUBLIC ${CMAKE_THREAD_LIBS_INIT}
PRIVATE cmix
+ PRIVATE log
)
if(WIN32)
diff --git a/libcmix-network/acceptor.cpp b/libcmix-network/acceptor.cpp
index 34b5f0e..69b2807 100644
--- a/libcmix-network/acceptor.cpp
+++ b/libcmix-network/acceptor.cpp
@@ -22,7 +22,6 @@ void accept_connection(tcp::acceptor& acceptor, std::shared_ptr<tcp::socket> soc
ss << ec;
throw std::runtime_error(ss.str());
}
-
}
void accept_loop(tcp::acceptor& acceptor, std::function<void(tcp::socket&&)> f)
diff --git a/libcmix-network/client.cpp b/libcmix-network/client.cpp
index 544dd87..ce9fd4d 100644
--- a/libcmix-network/client.cpp
+++ b/libcmix-network/client.cpp
@@ -1,5 +1,7 @@
#include "client.hpp"
+#include "logging.hpp"
+
#include <boost/asio/placeholders.hpp>
#include <boost/bind.hpp>
@@ -19,10 +21,11 @@ void Client::handle_receive(MessageHandler message_handler, const error_code &ec
buffer.commit(read_bytes);
std::istream is(&buffer);
+ BOOST_LOG_TRIVIAL(trace) << "handling receive";
+
if(!ec) {
std::vector<uint8_t> data(std::istream_iterator<uint8_t>(is), {});
message_handler(data);
- receive(message_handler);
} else {
if(done) {
done();
diff --git a/libcmix-network/client.hpp b/libcmix-network/client.hpp
index 2b6a6df..46b989d 100644
--- a/libcmix-network/client.hpp
+++ b/libcmix-network/client.hpp
@@ -10,8 +10,10 @@ public:
typedef std::function<void(void)> OnDoneFT;
typedef std::function<void(std::vector<uint8_t>)> MessageHandler;
-private:
+protected:
boost::asio::ip::tcp::socket socket;
+
+private:
boost::asio::streambuf buffer;
OnDoneFT done;
diff --git a/libcmix-network/connect.cpp b/libcmix-network/connect.cpp
index 679748e..bf200d5 100644
--- a/libcmix-network/connect.cpp
+++ b/libcmix-network/connect.cpp
@@ -1,23 +1,24 @@
#include "connect.hpp"
+#include "logging.hpp"
+
#include <boost/asio/ip/basic_resolver.hpp>
+#include <boost/asio/ip/address.hpp>
using namespace boost::asio::ip;
using boost::asio::io_service;
-boost::asio::ip::tcp::socket connect(std::string host, std::string port, io_service& io_service) {
+boost::asio::ip::tcp::socket connect(std::string host, io_service& io_service) {
boost::asio::ip::basic_resolver<tcp> resolver(io_service);
- boost::asio::ip::basic_resolver_query<tcp> query(host, port);
- boost::asio::ip::basic_endpoint<tcp> endpoint;
+ boost::asio::ip::basic_resolver_query<tcp> query(host, "");
for(auto it = resolver.resolve(query); it != boost::asio::ip::tcp::resolver::iterator(); ++it)
{
- endpoint = *it;
boost::system::error_code ec;
boost::asio::ip::tcp::socket socket(io_service);
- socket.connect(endpoint, ec);
+ socket.connect(*it, ec);
if(ec) {
continue;
} else {
@@ -27,3 +28,30 @@ boost::asio::ip::tcp::socket connect(std::string host, std::string port, io_serv
throw std::runtime_error("None of the supplied endpoints responded");
}
+
+void async_connect_iteration(tcp::socket& socket, boost::asio::ip::tcp::resolver::iterator it, std::function<void()> on_connect) {
+ if(it == boost::asio::ip::tcp::resolver::iterator()) {
+ throw std::runtime_error("None of the supplied endpoints responded");
+ }
+
+ auto handler = [&socket, it, on_connect](boost::system::error_code const& ec) {
+ if(ec) {
+ BOOST_LOG_TRIVIAL(info) << ec << std::endl;
+ async_connect_iteration(socket, std::next(it), on_connect);
+ } else {
+ on_connect();
+ }
+ };
+
+ socket.async_connect(*it, handler);
+}
+
+void async_connect(tcp::socket& socket, std::string host, std::string next_port, std::function<void()> on_connect)
+{
+ boost::asio::ip::basic_resolver<tcp> resolver(socket.get_io_service());
+ boost::asio::ip::basic_resolver_query<tcp> query(host, next_port);
+
+ auto it = resolver.resolve(query);
+
+ async_connect_iteration(socket, it, on_connect);
+}
diff --git a/libcmix-network/connect.hpp b/libcmix-network/connect.hpp
index 7f5b5c3..071ed9b 100644
--- a/libcmix-network/connect.hpp
+++ b/libcmix-network/connect.hpp
@@ -3,4 +3,5 @@
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/io_service.hpp>
-boost::asio::ip::tcp::socket connect(std::string host, std::string port, boost::asio::io_service& io_service);
+boost::asio::ip::tcp::socket connect(std::string host, boost::asio::io_service& io_service);
+void async_connect(boost::asio::ip::tcp::socket& socket, std::string host, std::string next_port, std::function<void()> on_connect);
diff --git a/libcmix-network/uriparser.cpp b/libcmix-network/uriparser.cpp
new file mode 100644
index 0000000..9cea452
--- /dev/null
+++ b/libcmix-network/uriparser.cpp
@@ -0,0 +1,3 @@
+#include "uriparser.hpp"
+
+
diff --git a/libcmix-network/uriparser.hpp b/libcmix-network/uriparser.hpp
new file mode 100644
index 0000000..c46b70a
--- /dev/null
+++ b/libcmix-network/uriparser.hpp
@@ -0,0 +1,59 @@
+#pragma once
+
+#include <string>
+#include <regex>
+#include <iostream>
+
+struct Uri {
+ std::string scheme;
+ std::string username;
+ std::string password;
+ std::string host;
+ std::string port;
+ std::string query;
+ std::string hash;
+};
+
+Uri parse_uri(std::string str) {
+ std::string scheme = "(?:(.+?)://)?";
+ std::string uname_pass = "(?:(.*?)?(?::(.*?))@)?";
+ std::string host = "(.+?)";
+ std::string port = "(?::(\\d+?))?";
+ std::string query = "(?:\\?(.+?))?";
+ std::string hash = "(?:#(.+?))?";
+
+ std::regex expr("^" + scheme + uname_pass + host + port + query + hash + "$");
+ std::smatch matches;
+ std::regex_match(str, matches, expr);
+
+ return {
+ matches[1].str(),
+ matches[2].str(),
+ matches[3].str(),
+ matches[4].str(),
+ matches[5].str(),
+ matches[6].str(),
+ matches[7].str()
+ };
+}
+
+std::string debug_uri(Uri uri) {
+ std::stringstream ss;
+ ss << "scheme: " << uri.scheme << std::endl
+ << "username: " << uri.username << std::endl
+ << "password: " << uri.password << std::endl
+ << "host: " << uri.host << std::endl
+ << "port: " << uri.port << std::endl
+ << "query: " << uri.query << std::endl
+ << "hash: " << uri.hash << std::endl;
+ return ss.str();
+}
+
+std::string uri_to_string(Uri uri) {
+ return
+ (!uri.scheme.empty() ? uri.scheme + "://" : "") +
+ (!uri.username.empty() ? uri.username + (!uri.password.empty() ? ":" + uri.password : "") + "@" : "") +
+ uri.host +
+ (!uri.port.empty() ? ":" + uri.port : "") +
+ (!uri.query.empty() ? "?" + uri.query : "");
+}