summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShobhit Adlakha <adlakhashobhit@gmail.com>2019-05-08 10:23:00 -0400
committerShobhit Adlakha <adlakhashobhit@gmail.com>2019-05-08 10:23:00 -0400
commit96f9ba68ea0ff0f73a927bf3deeca58f4a5bae99 (patch)
tree037dd682a565d67ad12e36e60f6d1ebc41b8bb03
parent27c36487854b6725eddaddb069a5effd1b99ff7c (diff)
downloadsdl_core-96f9ba68ea0ff0f73a927bf3deeca58f4a5bae99.tar.gz
Separated interface and implementation for sample_websocket_server
-rw-r--r--src/components/transport_manager/test/CMakeLists.txt1
-rw-r--r--src/components/transport_manager/test/include/transport_manager/cloud/sample_websocket_server.h221
-rw-r--r--src/components/transport_manager/test/sample_websocket_server.cc213
-rw-r--r--src/components/transport_manager/test/websocket_connection_test.cc11
4 files changed, 242 insertions, 204 deletions
diff --git a/src/components/transport_manager/test/CMakeLists.txt b/src/components/transport_manager/test/CMakeLists.txt
index 489b35b796..f6e1212b36 100644
--- a/src/components/transport_manager/test/CMakeLists.txt
+++ b/src/components/transport_manager/test/CMakeLists.txt
@@ -49,6 +49,7 @@ set(EXCLUDE_PATHS
if (NOT BUILD_CLOUD_APP_SUPPORT)
list(APPEND EXCLUDE_PATHS
${CMAKE_CURRENT_SOURCE_DIR}/websocket_connection_test.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/sample_websocket_server.cc
)
endif()
diff --git a/src/components/transport_manager/test/include/transport_manager/cloud/sample_websocket_server.h b/src/components/transport_manager/test/include/transport_manager/cloud/sample_websocket_server.h
index 86c776bffb..141fa1ff89 100644
--- a/src/components/transport_manager/test/include/transport_manager/cloud/sample_websocket_server.h
+++ b/src/components/transport_manager/test/include/transport_manager/cloud/sample_websocket_server.h
@@ -54,6 +54,9 @@
#include <thread>
#include <vector>
+namespace sample {
+namespace websocket {
+
namespace beast = boost::beast; // from <boost/beast.hpp>
namespace http = beast::http; // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
@@ -61,34 +64,14 @@ namespace net = boost::asio; // from <boost/asio.hpp>
namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
-//------------------------------------------------------------------------------
-
-// Report a failure
-void Fail(char const* tag, boost::system::error_code ec) {
- std::cerr << tag << ": " << ec.message() << "\n";
-}
-
// Accepts incoming connections and launches the WSServer
class WSSession : public std::enable_shared_from_this<WSSession> {
private:
class WSServer : public std::enable_shared_from_this<WSServer> {
public:
- explicit WSServer(tcp::socket&& socket)
- : ws_(std::move(socket)), strand_(ws_.get_executor()) {}
-
- void Run() {
- // Accept the websocket handshake
- ws_.async_accept(boost::asio::bind_executor(
- strand_,
- std::bind(
- &WSServer::OnAccept, shared_from_this(), std::placeholders::_1)));
- }
-
- void OnAccept(beast::error_code ec) {
- if (ec) {
- return Fail("ERROR_CONNECTION_ACCEPT", ec);
- }
- }
+ explicit WSServer(tcp::socket&& socket);
+ void Run();
+ void OnAccept(beast::error_code ec);
private:
websocket::stream<tcp::socket> ws_;
@@ -97,71 +80,12 @@ class WSSession : public std::enable_shared_from_this<WSSession> {
};
public:
- WSSession(const std::string& address, uint16_t port)
- : address_(address), port_(port), acceptor_(ioc_), socket_(ioc_) {
- endpoint_ = {boost::asio::ip::make_address(address), port};
- boost::system::error_code error;
-
- // Open the acceptor
- acceptor_.open(endpoint_.protocol(), error);
- if (error) {
- Fail("ERROR_ACCEPTOR_OPEN", error);
- return;
- }
-
- // Allow address reuse
- acceptor_.set_option(boost::asio::socket_base::reuse_address(true), error);
- if (error) {
- Fail("ERROR_SET_OPTION", error);
- return;
- }
-
- // Bind to the server address
- acceptor_.bind(endpoint_, error);
- if (error) {
- Fail("ERROR_BIND", error);
- return;
- }
-
- // Start listening for connections
- acceptor_.listen(boost::asio::socket_base::max_listen_connections, error);
- if (error) {
- Fail("ERROR_LISTEN", error);
- return;
- }
- }
-
- void Run() {
- if (acceptor_.is_open()) {
- acceptor_.async_accept(
- socket_,
- std::bind(&WSSession::on_accept, this, std::placeholders::_1));
- ioc_.run();
- }
- }
-
- void Stop() {
- try {
- ioc_.stop();
- acceptor_.close();
- } catch (...) {
- std::cerr << "Failed to close connection" << std::endl;
- }
- }
+ WSSession(const std::string& address, uint16_t port);
+ void Run();
+ void Stop();
private:
- void on_accept(boost::system::error_code ec) {
- if (ec) {
- Fail("ERROR_ON_ACCEPT", ec);
- ioc_.stop();
- return;
- }
-
- // Make websocket object and start
- ws_ = std::make_shared<WSServer>(std::move(socket_));
- ws_->Run();
- }
-
+ void on_accept(boost::system::error_code ec);
boost::asio::io_context ioc_;
const std::string& address_;
uint16_t port_;
@@ -175,37 +99,14 @@ class WSSession : public std::enable_shared_from_this<WSSession> {
// Accepts incoming connections and launches the sessions
class WSSSession : public std::enable_shared_from_this<WSSSession> {
private:
- // Echoes back all received WebSocket messages
class WSSServer : public std::enable_shared_from_this<WSSServer> {
public:
// Take ownership of the socket
- WSSServer(tcp::socket&& socket, ssl::context& ctx)
- : wss_(std::move(socket), ctx) {}
-
+ WSSServer(tcp::socket&& socket, ssl::context& ctx);
// Start the asynchronous operation
- void Run() {
- // Perform the SSL handshake
- wss_.next_layer().async_handshake(ssl::stream_base::server,
- std::bind(&WSSServer::OnSSLHandshake,
- shared_from_this(),
- std::placeholders::_1));
- }
-
- void OnSSLHandshake(beast::error_code ec) {
- if (ec) {
- return Fail("ERROR_SSL_HANDSHAKE", ec);
- }
-
- // Accept the websocket handshake
- wss_.async_accept(std::bind(
- &WSSServer::OnAccept, shared_from_this(), std::placeholders::_1));
- }
-
- void OnAccept(beast::error_code ec) {
- if (ec) {
- return Fail("ERROR_ON_ACCEPT", ec);
- }
- }
+ void Run();
+ void OnSSLHandshake(beast::error_code ec);
+ void OnAccept(beast::error_code ec);
private:
websocket::stream<ssl::stream<tcp::socket> > wss_;
@@ -216,95 +117,14 @@ class WSSSession : public std::enable_shared_from_this<WSSSession> {
WSSSession(const std::string& address,
uint16_t port,
const std::string& certificate,
- const std::string& private_key)
- : acceptor_(ioc_), socket_(ioc_), ctx_(ssl::context::sslv23_server) {
- beast::error_code ec;
- endpoint_ = {boost::asio::ip::make_address(address), port};
-
- // Load the certificate
- ctx_.use_certificate(
- boost::asio::buffer(certificate.c_str(), certificate.size()),
- ssl::context::file_format::pem,
- ec);
- if (ec) {
- Fail("ERROR_USE_CERTIFICATE", ec);
- return;
- }
-
- // Load the private key
- ctx_.use_rsa_private_key(
- boost::asio::buffer(private_key.c_str(), private_key.size()),
- ssl::context::file_format::pem,
- ec);
- if (ec) {
- Fail("ERROR_USE_RSA_PRIVATE_KEY", ec);
- return;
- }
-
- // Open the acceptor
- acceptor_.open(endpoint_.protocol(), ec);
- if (ec) {
- Fail("EEROR_ACCEPTOR_OPEN", ec);
- return;
- }
-
- // Allow address reuse
- acceptor_.set_option(net::socket_base::reuse_address(true), ec);
- if (ec) {
- Fail("ERROR_SET_OPTION", ec);
- return;
- }
-
- // Bind to the server address
- acceptor_.bind(endpoint_, ec);
- if (ec) {
- Fail("ERROR_BIND", ec);
- return;
- }
-
- // Start listening for connections
- acceptor_.listen(net::socket_base::max_listen_connections, ec);
- if (ec) {
- Fail("ERROR_LISTEN", ec);
- return;
- }
- }
-
+ const std::string& private_key);
// Start accepting incoming connections
- void Run() {
- do_accept();
- }
-
- void Stop() {
- try {
- ioc_.stop();
- acceptor_.close();
- } catch (...) {
- std::cerr << "Failed to close connection" << std::endl;
- }
- }
+ void Run();
+ void Stop();
private:
- void do_accept() {
- if (acceptor_.is_open()) {
- acceptor_.async_accept(socket_,
- std::bind(&WSSSession::on_accept,
- shared_from_this(),
- std::placeholders::_1));
- ioc_.run();
- }
- }
-
- void on_accept(boost::system::error_code ec) {
- if (ec) {
- Fail("ERROR_ON_ACCEPT", ec);
- ioc_.stop();
- return;
- }
- // Create the session and run it
- wss_ = std::make_shared<WSSServer>(std::move(socket_), ctx_);
- wss_->Run();
- }
+ void do_accept();
+ void on_accept(boost::system::error_code ec);
private:
boost::asio::io_context ioc_;
@@ -315,4 +135,7 @@ class WSSSession : public std::enable_shared_from_this<WSSSession> {
std::shared_ptr<WSSServer> wss_;
};
+} // namespace websocket
+} // namespace sample
+
#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_TEST_INCLUDE_TRANSPORT_MANAGER_CLOUD_SAMPLE_WEBSOCKET_SERVER_H_ \ No newline at end of file
diff --git a/src/components/transport_manager/test/sample_websocket_server.cc b/src/components/transport_manager/test/sample_websocket_server.cc
new file mode 100644
index 0000000000..ae15d46b62
--- /dev/null
+++ b/src/components/transport_manager/test/sample_websocket_server.cc
@@ -0,0 +1,213 @@
+#include "transport_manager/cloud/sample_websocket_server.h"
+
+namespace {
+// Report a failure
+void Fail(char const* tag, boost::system::error_code ec) {
+ std::cerr << tag << ": " << ec.message() << "\n";
+}
+} // namespace
+
+namespace sample {
+namespace websocket {
+
+WSSession::WSServer::WSServer(tcp::socket&& socket)
+ : ws_(std::move(socket)), strand_(ws_.get_executor()) {}
+
+void WSSession::WSServer::Run() {
+ // Accept the websocket handshake
+ ws_.async_accept(boost::asio::bind_executor(
+ strand_,
+ std::bind(
+ &WSServer::OnAccept, shared_from_this(), std::placeholders::_1)));
+}
+
+void WSSession::WSServer::OnAccept(beast::error_code ec) {
+ if (ec) {
+ return Fail("ERROR_CONNECTION_ACCEPT", ec);
+ }
+}
+
+WSSession::WSSession(const std::string& address, uint16_t port)
+ : address_(address), port_(port), acceptor_(ioc_), socket_(ioc_) {
+ endpoint_ = {boost::asio::ip::make_address(address), port};
+ boost::system::error_code error;
+
+ // Open the acceptor
+ acceptor_.open(endpoint_.protocol(), error);
+ if (error) {
+ Fail("ERROR_ACCEPTOR_OPEN", error);
+ return;
+ }
+
+ // Allow address reuse
+ acceptor_.set_option(boost::asio::socket_base::reuse_address(true), error);
+ if (error) {
+ Fail("ERROR_SET_OPTION", error);
+ return;
+ }
+
+ // Bind to the server address
+ acceptor_.bind(endpoint_, error);
+ if (error) {
+ Fail("ERROR_BIND", error);
+ return;
+ }
+
+ // Start listening for connections
+ acceptor_.listen(boost::asio::socket_base::max_listen_connections, error);
+ if (error) {
+ Fail("ERROR_LISTEN", error);
+ return;
+ }
+}
+
+void WSSession::Run() {
+ if (acceptor_.is_open()) {
+ acceptor_.async_accept(
+ socket_, std::bind(&WSSession::on_accept, this, std::placeholders::_1));
+ ioc_.run();
+ }
+}
+
+void WSSession::Stop() {
+ try {
+ ioc_.stop();
+ acceptor_.close();
+ } catch (...) {
+ std::cerr << "Failed to close connection" << std::endl;
+ }
+}
+
+void WSSession::on_accept(boost::system::error_code ec) {
+ if (ec) {
+ Fail("ERROR_ON_ACCEPT", ec);
+ ioc_.stop();
+ return;
+ }
+
+ // Make websocket object and start
+ ws_ = std::make_shared<WSServer>(std::move(socket_));
+ ws_->Run();
+}
+
+WSSSession::WSSServer::WSSServer(tcp::socket&& socket, ssl::context& ctx)
+ : wss_(std::move(socket), ctx) {}
+
+void WSSSession::WSSServer::Run() {
+ // Perform the SSL handshake
+ wss_.next_layer().async_handshake(ssl::stream_base::server,
+ std::bind(&WSSServer::OnSSLHandshake,
+ shared_from_this(),
+ std::placeholders::_1));
+}
+
+void WSSSession::WSSServer::OnSSLHandshake(beast::error_code ec) {
+ if (ec) {
+ return Fail("ERROR_SSL_HANDSHAKE", ec);
+ }
+
+ // Accept the websocket handshake
+ wss_.async_accept(std::bind(
+ &WSSServer::OnAccept, shared_from_this(), std::placeholders::_1));
+}
+
+void WSSSession::WSSServer::OnAccept(beast::error_code ec) {
+ if (ec) {
+ return Fail("ERROR_ON_ACCEPT", ec);
+ }
+}
+
+WSSSession::WSSSession(const std::string& address,
+ uint16_t port,
+ const std::string& certificate,
+ const std::string& private_key)
+ : acceptor_(ioc_), socket_(ioc_), ctx_(ssl::context::sslv23_server) {
+ beast::error_code ec;
+ endpoint_ = {boost::asio::ip::make_address(address), port};
+
+ // Load the certificate
+ ctx_.use_certificate(
+ boost::asio::buffer(certificate.c_str(), certificate.size()),
+ ssl::context::file_format::pem,
+ ec);
+ if (ec) {
+ Fail("ERROR_USE_CERTIFICATE", ec);
+ return;
+ }
+
+ // Load the private key
+ ctx_.use_rsa_private_key(
+ boost::asio::buffer(private_key.c_str(), private_key.size()),
+ ssl::context::file_format::pem,
+ ec);
+ if (ec) {
+ Fail("ERROR_USE_RSA_PRIVATE_KEY", ec);
+ return;
+ }
+
+ // Open the acceptor
+ acceptor_.open(endpoint_.protocol(), ec);
+ if (ec) {
+ Fail("EEROR_ACCEPTOR_OPEN", ec);
+ return;
+ }
+
+ // Allow address reuse
+ acceptor_.set_option(net::socket_base::reuse_address(true), ec);
+ if (ec) {
+ Fail("ERROR_SET_OPTION", ec);
+ return;
+ }
+
+ // Bind to the server address
+ acceptor_.bind(endpoint_, ec);
+ if (ec) {
+ Fail("ERROR_BIND", ec);
+ return;
+ }
+
+ // Start listening for connections
+ acceptor_.listen(net::socket_base::max_listen_connections, ec);
+ if (ec) {
+ Fail("ERROR_LISTEN", ec);
+ return;
+ }
+}
+
+// Start accepting incoming connections
+void WSSSession::Run() {
+ do_accept();
+}
+
+void WSSSession::Stop() {
+ try {
+ ioc_.stop();
+ acceptor_.close();
+ } catch (...) {
+ std::cerr << "Failed to close connection" << std::endl;
+ }
+}
+
+void WSSSession::do_accept() {
+ if (acceptor_.is_open()) {
+ acceptor_.async_accept(
+ socket_,
+ std::bind(
+ &WSSSession::on_accept, shared_from_this(), std::placeholders::_1));
+ ioc_.run();
+ }
+}
+
+void WSSSession::on_accept(boost::system::error_code ec) {
+ if (ec) {
+ Fail("ERROR_ON_ACCEPT", ec);
+ ioc_.stop();
+ return;
+ }
+ // Create the session and run it
+ wss_ = std::make_shared<WSSServer>(std::move(socket_), ctx_);
+ wss_->Run();
+}
+
+} // namespace websocket
+} // namespace sample \ No newline at end of file
diff --git a/src/components/transport_manager/test/websocket_connection_test.cc b/src/components/transport_manager/test/websocket_connection_test.cc
index 774b477795..2b458a7427 100644
--- a/src/components/transport_manager/test/websocket_connection_test.cc
+++ b/src/components/transport_manager/test/websocket_connection_test.cc
@@ -49,6 +49,7 @@ using ::testing::NiceMock;
using ::testing::Return;
using namespace ::transport_manager;
using namespace ::transport_manager::transport_adapter;
+namespace websocket = sample::websocket;
class WebsocketConnectionTest : public ::testing::Test {
public:
@@ -84,13 +85,13 @@ class WebsocketConnectionTest : public ::testing::Test {
}
void StartWSServer() {
- ws_session = std::make_shared<WSSession>(kHost, kPort);
+ ws_session = std::make_shared<websocket::WSSession>(kHost, kPort);
ws_session->Run();
}
void StartWSSServer() {
- wss_session =
- std::make_shared<WSSSession>(kHost, kPort, kCertificate, kPrivateKey);
+ wss_session = std::make_shared<websocket::WSSSession>(
+ kHost, kPort, kCertificate, kPrivateKey);
wss_session->Run();
}
@@ -111,8 +112,8 @@ class WebsocketConnectionTest : public ::testing::Test {
std::string dev_id;
std::string uniq_id;
int app_handle;
- std::shared_ptr<WSSession> ws_session;
- std::shared_ptr<WSSSession> wss_session;
+ std::shared_ptr<websocket::WSSession> ws_session;
+ std::shared_ptr<websocket::WSSSession> wss_session;
std::string kHost = "127.0.0.1";
uint16_t kPort = 8080;
// Sample certificate for localhost