Server.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include "../include/Server.h"
  2. #include "../include/Config.h"
  3. #include "../include/base64.h"
  4. #include <iostream>
  5. using namespace boost::asio;
  6. using ip::tcp;
  7. /***************
  8. * con_handler *
  9. ***************/
  10. con_handler::con_handler(basic_socket_acceptor<ip::tcp>::executor_type &io_service, boost::asio::ssl::context &context)
  11. : sock(io_service), sslsock(sock, context), usessl(Config::getValue("SSLenabled") == "true"), buf(max_length), jsonCommander(fileManager) {
  12. // disable indentation for json
  13. this->jsonStringBuilder.settings_["indentation"] = "";
  14. // init reader to parse json
  15. Json::CharReaderBuilder builder;
  16. jsonReader = std::unique_ptr<Json::CharReader>(builder.newCharReader());
  17. }
  18. con_handler::~con_handler() {}
  19. con_handler::pointer con_handler::create(basic_socket_acceptor<ip::tcp>::executor_type &io_service, boost::asio::ssl::context &context) {
  20. return pointer(new con_handler(io_service, context));
  21. }
  22. tcp::socket &con_handler::socket() { return sock; }
  23. bool con_handler::handshake() {
  24. boost::system::error_code err;
  25. sslsock.handshake(boost::asio::ssl::stream_base::server, err);
  26. if (err) {
  27. std::cerr << "SSL handshake failed: " << err.message() << std::endl;
  28. close_sock();
  29. return false;
  30. }
  31. return true;
  32. }
  33. void con_handler::close_sock() { sock.close(); }
  34. void con_handler::start() {
  35. if (usessl) {
  36. if (handshake())
  37. read(&con_handler::handle_read_version);
  38. } else
  39. read(&con_handler::handle_read_version);
  40. }
  41. void con_handler::handle_read_version(const boost::system::error_code &err, size_t bytes_transferred) {
  42. if (!err) {
  43. // set up json stuff
  44. Json::Value root = parseMessage();
  45. JsonCommander::Response response = this->jsonCommander.testVersion(root);
  46. switch (response.action) {
  47. case JsonCommander::Action::send:
  48. read(&con_handler::handle_read_login);
  49. sendJson(response.json);
  50. break;
  51. case JsonCommander::Action::closeAndSend:
  52. sendJson(response.json);
  53. default:
  54. close_sock();
  55. }
  56. } else {
  57. std::cerr << __PRETTY_FUNCTION__ << " error: " << err.message() << std::endl;
  58. close_sock();
  59. }
  60. }
  61. void con_handler::handle_read_login(const boost::system::error_code &err, size_t bytes_transferred) {
  62. if (!err) {
  63. // set up json stuff
  64. Json::Value root = parseMessage();
  65. JsonCommander::Response response = this->jsonCommander.checkLogin(root);
  66. switch (response.action) {
  67. case JsonCommander::Action::send:
  68. read(&con_handler::handle_read_command);
  69. sendJson(response.json);
  70. break;
  71. case JsonCommander::Action::closeAndSend:
  72. sendJson(response.json);
  73. default:
  74. close_sock();
  75. }
  76. } else {
  77. std::cerr << __PRETTY_FUNCTION__ << " error: " << err.message() << std::endl;
  78. close_sock();
  79. }
  80. }
  81. void con_handler::handle_read_command(const boost::system::error_code &err, size_t bytes_transferred) {
  82. if (!err) {
  83. // set up json stuff
  84. Json::Value root = parseMessage();
  85. JsonCommander::Response response = this->jsonCommander.execute(root);
  86. switch (response.action) {
  87. case JsonCommander::Action::send:
  88. read(&con_handler::handle_read_command);
  89. sendJson(response.json);
  90. break;
  91. case JsonCommander::Action::closeAndSend:
  92. sendJson(response.json);
  93. default:
  94. close_sock();
  95. }
  96. } else {
  97. std::cerr << __PRETTY_FUNCTION__ << " error: " << err.message() << std::endl;
  98. close_sock();
  99. }
  100. }
  101. void con_handler::handle_write(const boost::system::error_code &err, size_t bytes_transferred) {
  102. if (!err) {
  103. std::cout << "Hello World!" << std::endl;
  104. } else {
  105. std::cerr << __PRETTY_FUNCTION__ << " error: " << err.message() << std::endl;
  106. close_sock();
  107. }
  108. }
  109. void con_handler::read(void (con_handler::*handler)(const boost::system::error_code &err, size_t bytes_transferred)) {
  110. if (usessl)
  111. async_read_until(sslsock, buf, '\n', bind(handler, shared_from_this(), placeholders::error, placeholders::bytes_transferred));
  112. else
  113. async_read_until(sock, buf, '\n', bind(handler, shared_from_this(), placeholders::error, placeholders::bytes_transferred));
  114. }
  115. void con_handler::sendJson(const Json::Value &json) {
  116. std::string jsonString = Json::writeString(jsonStringBuilder, json);
  117. jsonString.append("\n");
  118. if (usessl)
  119. sslsock.async_write_some(buffer(jsonString, max_length),
  120. boost::bind(&con_handler::handle_write, shared_from_this(), placeholders::error, placeholders::bytes_transferred));
  121. else
  122. sock.async_write_some(buffer(jsonString, max_length),
  123. boost::bind(&con_handler::handle_write, shared_from_this(), placeholders::error, placeholders::bytes_transferred));
  124. }
  125. Json::Value con_handler::parseMessage() {
  126. const char *data = buffer_cast<const char *>(buf.data());
  127. std::string dataStr(data, buf.size());
  128. const int lineEnd = dataStr.find('\n');
  129. JSONCPP_STRING err;
  130. Json::Value root;
  131. // parse data
  132. if (!this->jsonReader->parse(data, data + lineEnd, &root, &err)) {
  133. std::cerr << "Json error: " << err << std::endl << "data: " << data;
  134. close_sock();
  135. }
  136. buf.consume(lineEnd + 1);
  137. return root;
  138. }
  139. /**********
  140. * Server *
  141. **********/
  142. void Server::start_accept() {
  143. auto executor = acceptor_.get_executor();
  144. con_handler::pointer connection = con_handler::create(executor, context_);
  145. acceptor_.async_accept(connection->socket(), boost::bind(&Server::handle_accept, this, connection, placeholders::error));
  146. }
  147. Server::Server(io_service &io_service)
  148. : acceptor_(io_service, tcp::endpoint(tcp::v4(), std::stoi(Config::getValue("port")))), context_(boost::asio::ssl::context::sslv23) {
  149. if (Config::getValue("SSLenabled") == "true") {
  150. context_.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::single_dh_use);
  151. context_.use_certificate_chain_file(Config::getValue("SSLcertificate"));
  152. context_.use_private_key_file(Config::getValue("SSLprivatekey"), boost::asio::ssl::context::pem);
  153. context_.use_tmp_dh_file(Config::getValue("SSLdhparams"));
  154. }
  155. start_accept();
  156. }
  157. Server::~Server() {}
  158. void Server::handle_accept(con_handler::pointer connection, const boost::system::error_code &err) {
  159. if (!err) {
  160. connection->start();
  161. }
  162. start_accept();
  163. }