From c09a2b4ff0fe025853fba44d6b29dc44ffdaf059 Mon Sep 17 00:00:00 2001 From: Darren Smith Date: Sun, 24 Dec 2017 10:30:35 +0000 Subject: [PATCH] client wrongly offers json & msgpack during connect, issue #18 --- CHANGELOG.md | 2 ++ examples/basic/demo_client.cc | 20 +++++++++----------- include/wampcc/rawsocket_protocol.h | 4 ++++ include/wampcc/websocket_protocol.h | 4 ++++ libs/wampcc/rawsocket_protocol.cc | 8 +++++++- tests/wampcc/test_common.h | 11 ++++++----- utils/admin.cc | 16 +++++++++++++--- 7 files changed, 45 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22199000..2b62369f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ unreleased generated Makefile, causing break when configure done inside source tree (issue #3, @sashakh) +- rawsocket client wrongly offers multiple serialisers on connect (issue #18) + version 1.5 =========== diff --git a/examples/basic/demo_client.cc b/examples/basic/demo_client.cc index eba8a3a8..e3dc1138 100644 --- a/examples/basic/demo_client.cc +++ b/examples/basic/demo_client.cc @@ -11,18 +11,16 @@ #include #include -using namespace wampcc; - int main(int argc, char** argv) { try { /* Create the wampcc kernel. */ - kernel the_kernel; + wampcc::kernel the_kernel; /* Create the TCP socket and attempt to connect. */ - std::unique_ptr socket(new tcp_socket(&the_kernel)); + std::unique_ptr socket(new wampcc::tcp_socket(&the_kernel)); socket->connect("127.0.0.1", 55555).wait_for(std::chrono::seconds(3)); if (!socket->is_connected()) @@ -31,8 +29,8 @@ int main(int argc, char** argv) /* With the connected socket, create a wamp session & logon to the realm * called 'default_realm'. */ - auto session = wamp_session::create(&the_kernel, - std::move(socket)); + auto session = wampcc::wamp_session::create(&the_kernel, + std::move(socket)); session->hello("default_realm").wait_for(std::chrono::seconds(3)); @@ -42,11 +40,11 @@ int main(int argc, char** argv) /* Subscribe to a topic. */ session->subscribe("random_number", {}, - [](wamp_session&, subscribed_info info) { + [](wampcc::wamp_session&, wampcc::subscribed_info info) { std::cout << "subscribed " << (info ? "ok" : "failed") << std::endl; }, - [](wamp_session&, event_info info) { + [](wampcc::wamp_session&, wampcc::event_info info) { for (auto& x : info.args.args_list) std::cout << "got update: " << x << " "; std::cout << std::endl; @@ -55,7 +53,7 @@ int main(int argc, char** argv) /* Register a procedure that can sum an array of numbers. */ session->provide("math.service.add", {}, - [](wamp_session&, registered_info info) { + [](wampcc::wamp_session&, wampcc::registered_info info) { if (info) std::cout << "procedure registered with id " << info.registration_id << std::endl; @@ -63,7 +61,7 @@ int main(int argc, char** argv) std::cout << "procedure registration failed, error " << info.error_uri << std::endl; }, - [](wamp_session& ws, invocation_info info) { + [](wampcc::wamp_session& ws, wampcc::invocation_info info) { int total = 0; for (auto& item : info.args.args_list) if (item.is_int()) @@ -74,7 +72,7 @@ int main(int argc, char** argv) /* Call a remote procedure. */ session->call("math.service.add", {}, {{100, 200}, {}}, - [](wamp_session&, result_info result) { + [](wampcc::wamp_session&, wampcc::result_info result) { if (result) std::cout << "got result: " << result.args.args_list[0] << std::endl; }); diff --git a/include/wampcc/rawsocket_protocol.h b/include/wampcc/rawsocket_protocol.h index f4c90469..13d5f3e4 100644 --- a/include/wampcc/rawsocket_protocol.h +++ b/include/wampcc/rawsocket_protocol.h @@ -51,6 +51,10 @@ class rawsocket_protocol : public protocol struct options : public protocol::options { max_msg_size_flag inbound_max_msg_size; + + /** Default serialiser for client initiated connection */ + static const int default_client_serialiser = static_cast(serialiser_type::json); + options() : protocol::options(), inbound_max_msg_size(rawsocket_protocol::default_max_rxmsg_size) diff --git a/include/wampcc/websocket_protocol.h b/include/wampcc/websocket_protocol.h index 4edf8964..2c98a366 100644 --- a/include/wampcc/websocket_protocol.h +++ b/include/wampcc/websocket_protocol.h @@ -24,6 +24,10 @@ class websocket_protocol : public protocol public: struct options : public protocol::options { + + /** Default serialiser for client initiated connection */ + static const int default_client_serialiser = all_serialisers; + options(std::string __request_uri = "/") : host_header(host_header_mode::automatic), request_uri(std::move(__request_uri)) { } diff --git a/libs/wampcc/rawsocket_protocol.cc b/libs/wampcc/rawsocket_protocol.cc index 9ded4e8b..91473a22 100644 --- a/libs/wampcc/rawsocket_protocol.cc +++ b/libs/wampcc/rawsocket_protocol.cc @@ -78,6 +78,12 @@ void rawsocket_protocol::initiate(t_initiate_cb cb) codecs |= (m_options.serialisers & serialiser_type::json)? e_JSON : 0; codecs |= (m_options.serialisers & serialiser_type::msgpack)? e_MSGPACK : 0; + /* During rawsocket client initiation the client cannot advertise more than + * one protocol (like websocket is able to do). So reject attempt if the + * protocol is not uniquely specified.*/ + if (codecs != e_JSON && codecs != e_MSGPACK) + throw std::runtime_error("rawsocket client must choose only one serialiser"); + format_handshake( handshake, m_options.inbound_max_msg_size, codecs); std::pair buf; @@ -163,7 +169,7 @@ void rawsocket_protocol::io_on_read(char* src, size_t len) os << " (" << err_str << ")"; throw handshake_error(os.str()); } - + create_codec(m_options.serialisers & to_serialiser(serializer)); if (!m_codec) throw handshake_error("failed to negotiate rawsocket message serialiser"); diff --git a/tests/wampcc/test_common.h b/tests/wampcc/test_common.h index 0c33218c..8358f51a 100644 --- a/tests/wampcc/test_common.h +++ b/tests/wampcc/test_common.h @@ -75,7 +75,7 @@ class internal_server m_salt{"saltxx",32, 1500} { std::random_device rd; // used for seed - std::mt19937 gen(rd()); + std::mt19937 gen(rd()); std::uniform_int_distribution<> dis(-1000, 1000); m_salt.iterations += dis(gen); @@ -277,7 +277,7 @@ std::unique_ptr tcp_connect(kernel& k, int port) std::shared_ptr establish_session( std::unique_ptr& the_kernel, int port, int protocols = wampcc::all_protocols, - int serialisers = wampcc::all_serialisers) + int serialisers = static_cast(serialiser_type::none)) { static int count = 0; count++; @@ -295,11 +295,12 @@ std::shared_ptr establish_session( throw std::runtime_error("tcp connect failed during establish_session()"); websocket_protocol::options ws_opts; - ws_opts.serialisers = serialisers; + ws_opts.serialisers = (serialisers==static_cast(serialiser_type::none))? + websocket_protocol::options::default_client_serialiser : serialisers; rawsocket_protocol::options rs_opts; - rs_opts.serialisers = serialisers; - + rs_opts.serialisers = (serialisers==static_cast(serialiser_type::none))? + rawsocket_protocol::options::default_client_serialiser : serialisers; /* attempt to create a session */ std::shared_ptr session; diff --git a/utils/admin.cc b/utils/admin.cc index 78e2bc81..729f5e2b 100644 --- a/utils/admin.cc +++ b/utils/admin.cc @@ -27,7 +27,9 @@ struct user_options websocket, } session_transport = transport::websocket; - int serialisers = wampcc::all_serialisers; + /* We cannot define a general purpose default serialiser for a wamp client to + * use because the concept of a default varies between WAMP transports. */ + int serialisers = static_cast(wampcc::serialiser_type::none); wampcc::user_optional username; wampcc::user_optional password; @@ -52,6 +54,14 @@ struct user_options bool use_ssl = false; std::string request_uri_path = "/"; + + /* Get actual client serialiser to use, which depends on what options the user + * has provided and the default for the given transport */ + template + int get_serialiser() { + return (serialisers == static_cast(wampcc::serialiser_type::none))? + T::options::default_client_serialiser : serialisers; + } } uopts; @@ -447,7 +457,7 @@ int main_impl(int argc, char** argv) switch (uopts.session_transport) { case user_options::transport::websocket: { wampcc::websocket_protocol::options proto_opts(uopts.request_uri_path); - proto_opts.serialisers = uopts.serialisers; + proto_opts.serialisers = uopts.get_serialiser(); ws = wampcc::wamp_session::create( g_kernel.get(), std::move(sock), @@ -458,7 +468,7 @@ int main_impl(int argc, char** argv) } case user_options::transport::rawsocket: { wampcc::rawsocket_protocol::options proto_opts; - proto_opts.serialisers = uopts.serialisers; + proto_opts.serialisers = uopts.get_serialiser(); ws = wampcc::wamp_session::create( g_kernel.get(), std::move(sock),