diff options
Diffstat (limited to 'libcmix-network')
| -rw-r--r-- | libcmix-network/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | libcmix-network/acceptor.cpp | 1 | ||||
| -rw-r--r-- | libcmix-network/client.cpp | 5 | ||||
| -rw-r--r-- | libcmix-network/client.hpp | 4 | ||||
| -rw-r--r-- | libcmix-network/connect.cpp | 38 | ||||
| -rw-r--r-- | libcmix-network/connect.hpp | 3 | ||||
| -rw-r--r-- | libcmix-network/uriparser.cpp | 3 | ||||
| -rw-r--r-- | libcmix-network/uriparser.hpp | 59 |
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 : ""); +} |
