|
@@ -0,0 +1,314 @@
|
|
|
+#include "../include/Server.h"
|
|
|
+#include <iostream>
|
|
|
+#include <jsoncpp/json/json.h>
|
|
|
+
|
|
|
+using namespace boost::asio;
|
|
|
+using ip::tcp;
|
|
|
+
|
|
|
+/***************
|
|
|
+ * con_handler *
|
|
|
+ ***************/
|
|
|
+
|
|
|
+con_handler::con_handler(
|
|
|
+ basic_socket_acceptor<ip::tcp>::executor_type &io_service)
|
|
|
+ : sock(io_service) {}
|
|
|
+
|
|
|
+con_handler::~con_handler() {}
|
|
|
+
|
|
|
+con_handler::pointer
|
|
|
+con_handler::create(basic_socket_acceptor<ip::tcp>::executor_type &io_service) {
|
|
|
+ return pointer(new con_handler(io_service));
|
|
|
+}
|
|
|
+
|
|
|
+tcp::socket &con_handler::socket() { return sock; }
|
|
|
+
|
|
|
+void con_handler::start() {
|
|
|
+
|
|
|
+ sock.async_read_some(buffer(data, max_length),
|
|
|
+ boost::bind(&con_handler::handle_read_version,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+}
|
|
|
+
|
|
|
+void con_handler::handle_read(const boost::system::error_code &err,
|
|
|
+ size_t bytes_transferred) {
|
|
|
+ if (!err) {
|
|
|
+ std::cout << this->data << std::endl;
|
|
|
+ } else {
|
|
|
+ std::cerr << "error: " << err.message() << std::endl;
|
|
|
+ sock.close();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void con_handler::handle_read_version(const boost::system::error_code &err,
|
|
|
+ size_t bytes_transferred) {
|
|
|
+ if (!err) {
|
|
|
+ // set up json stuff
|
|
|
+ JSONCPP_STRING err;
|
|
|
+ Json::Value root;
|
|
|
+ Json::CharReaderBuilder builder;
|
|
|
+ const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
|
|
|
+
|
|
|
+ // parse data
|
|
|
+ if (!reader->parse(this->data, this->data + bytes_transferred, &root,
|
|
|
+ &err)) {
|
|
|
+ std::cerr << "Json error: " << err << std::endl << "data: " << this->data;
|
|
|
+ sock.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ // create answer
|
|
|
+ Json::Value answer;
|
|
|
+ Json::StreamWriterBuilder stringBuilder;
|
|
|
+
|
|
|
+ answer["version"] = this->protocolVersion;
|
|
|
+
|
|
|
+ // check version string
|
|
|
+ if (root["version"].compare(this->protocolVersion) == 0) {
|
|
|
+ answer["accept"] = true;
|
|
|
+ const std::string answerString = Json::writeString(stringBuilder, answer);
|
|
|
+
|
|
|
+ // send answer
|
|
|
+ sock.async_write_some(buffer(answerString, max_length),
|
|
|
+ boost::bind(&con_handler::handle_write,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+
|
|
|
+ // read next data
|
|
|
+ sock.async_read_some(buffer(data, max_length),
|
|
|
+ boost::bind(&con_handler::handle_read_login,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+ } else {
|
|
|
+ answer["accept"] = false;
|
|
|
+ const std::string answerString = Json::writeString(stringBuilder, answer);
|
|
|
+
|
|
|
+ // send answer
|
|
|
+ sock.async_write_some(buffer(answerString, max_length),
|
|
|
+ boost::bind(&con_handler::handle_write,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+ // close connection
|
|
|
+ sock.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ std::cerr << "error: " << err.message() << std::endl;
|
|
|
+ sock.close();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void con_handler::handle_read_login(const boost::system::error_code &err,
|
|
|
+ size_t bytes_transferred) {
|
|
|
+ if (!err) {
|
|
|
+ // set up json stuff
|
|
|
+ JSONCPP_STRING err;
|
|
|
+ Json::Value root;
|
|
|
+ Json::CharReaderBuilder builder;
|
|
|
+ const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
|
|
|
+
|
|
|
+ // parse data
|
|
|
+ if (!reader->parse(this->data, this->data + bytes_transferred, &root,
|
|
|
+ &err)) {
|
|
|
+ std::cerr << "Json error: " << err << std::endl << "data: " << this->data;
|
|
|
+ sock.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ Json::Value answer;
|
|
|
+ Json::StreamWriterBuilder stringBuilder;
|
|
|
+
|
|
|
+ // user credentials
|
|
|
+ // TODO check user credentials!!!
|
|
|
+ if (root["user"].compare("user") == 0 &&
|
|
|
+ root["pass"].compare("pass") == 0) {
|
|
|
+ answer["accept"] = true;
|
|
|
+ const std::string answerString = Json::writeString(stringBuilder, answer);
|
|
|
+
|
|
|
+ // send answer
|
|
|
+ sock.async_write_some(buffer(answerString, max_length),
|
|
|
+ boost::bind(&con_handler::handle_write,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+
|
|
|
+ // read next data
|
|
|
+ sock.async_read_some(buffer(data, max_length),
|
|
|
+ boost::bind(&con_handler::handle_read_command,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+ } else {
|
|
|
+ answer["accept"] = false;
|
|
|
+ const std::string answerString = Json::writeString(stringBuilder, answer);
|
|
|
+
|
|
|
+ // send answer
|
|
|
+ sock.async_write_some(buffer(answerString, max_length),
|
|
|
+ boost::bind(&con_handler::handle_write,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+ // close connection
|
|
|
+ sock.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ std::cerr << "error: " << err.message() << std::endl;
|
|
|
+ sock.close();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void con_handler::handle_read_command(const boost::system::error_code &err,
|
|
|
+ size_t bytes_transferred) {
|
|
|
+ if (!err) {
|
|
|
+ // set up json stuff
|
|
|
+ JSONCPP_STRING err;
|
|
|
+ Json::Value root;
|
|
|
+ Json::CharReaderBuilder builder;
|
|
|
+ const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
|
|
|
+
|
|
|
+ // parse data
|
|
|
+ if (!reader->parse(this->data, this->data + bytes_transferred, &root,
|
|
|
+ &err)) {
|
|
|
+ std::cerr << "Json error: " << err << std::endl << "data: " << this->data;
|
|
|
+ sock.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ Json::Value answer;
|
|
|
+ Json::StreamWriterBuilder stringBuilder;
|
|
|
+
|
|
|
+ // check command
|
|
|
+ if (root["command"].compare("status") == 0) {
|
|
|
+ answer["command"] = "status";
|
|
|
+
|
|
|
+ // TODO answer a real status message
|
|
|
+ answer["response"] = "This is a status message :)";
|
|
|
+ const std::string answerString = Json::writeString(stringBuilder, answer);
|
|
|
+
|
|
|
+ // send answer
|
|
|
+ sock.async_write_some(buffer(answerString, max_length),
|
|
|
+ boost::bind(&con_handler::handle_write,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+
|
|
|
+ // read next data
|
|
|
+ sock.async_read_some(buffer(data, max_length),
|
|
|
+ boost::bind(&con_handler::handle_read_command,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+ } else if (root["command"].compare("list") == 0) {
|
|
|
+ answer["command"] = "list";
|
|
|
+
|
|
|
+ // TODO look for real data
|
|
|
+ Json::Value array;
|
|
|
+ array.append("some");
|
|
|
+ array.append("important");
|
|
|
+ array.append("data");
|
|
|
+ answer["names"] = array;
|
|
|
+ answer["remaining"] = 0;
|
|
|
+
|
|
|
+ const std::string answerString = Json::writeString(stringBuilder, answer);
|
|
|
+ // send answer
|
|
|
+ sock.async_write_some(buffer(answerString, max_length),
|
|
|
+ boost::bind(&con_handler::handle_write,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+
|
|
|
+ // read next data
|
|
|
+ sock.async_read_some(buffer(data, max_length),
|
|
|
+ boost::bind(&con_handler::handle_read_command,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+ } else if (root["command"].compare("put") == 0) {
|
|
|
+ answer["command"] = "put";
|
|
|
+
|
|
|
+ // TODO establish real connection and receive file
|
|
|
+ answer["accept"] = false;
|
|
|
+
|
|
|
+ const std::string answerString = Json::writeString(stringBuilder, answer);
|
|
|
+ // send answer
|
|
|
+ sock.async_write_some(buffer(answerString, max_length),
|
|
|
+ boost::bind(&con_handler::handle_write,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+
|
|
|
+ // read next data
|
|
|
+ sock.async_read_some(buffer(data, max_length),
|
|
|
+ boost::bind(&con_handler::handle_read_command,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+ } else if (root["command"].compare("get") == 0) {
|
|
|
+ answer["command"] = "get";
|
|
|
+
|
|
|
+ // TODO establish real connection and send file
|
|
|
+ answer["accept"] = false;
|
|
|
+
|
|
|
+ const std::string answerString = Json::writeString(stringBuilder, answer);
|
|
|
+ // send answer
|
|
|
+ sock.async_write_some(buffer(answerString, max_length),
|
|
|
+ boost::bind(&con_handler::handle_write,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+
|
|
|
+ // read next data
|
|
|
+ sock.async_read_some(buffer(data, max_length),
|
|
|
+ boost::bind(&con_handler::handle_read_command,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+ } else if (root["command"].compare("close") == 0) {
|
|
|
+ answer["command"] = "close";
|
|
|
+ answer["response"] = "bye";
|
|
|
+ const std::string answerString = Json::writeString(stringBuilder, answer);
|
|
|
+
|
|
|
+ // send answer
|
|
|
+ sock.async_write_some(buffer(answerString, max_length),
|
|
|
+ boost::bind(&con_handler::handle_write,
|
|
|
+ shared_from_this(), placeholders::error,
|
|
|
+ placeholders::bytes_transferred));
|
|
|
+
|
|
|
+ // close connection
|
|
|
+ sock.close();
|
|
|
+ } else {
|
|
|
+ // TODO handle error
|
|
|
+
|
|
|
+ // close connection
|
|
|
+ sock.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ std::cerr << "error: " << err.message() << std::endl;
|
|
|
+ sock.close();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void con_handler::handle_write(const boost::system::error_code &err,
|
|
|
+ size_t bytes_transferred) {
|
|
|
+ if (!err) {
|
|
|
+ std::cout << "Hello World!" << std::endl;
|
|
|
+ } else {
|
|
|
+ std::cerr << "error: " << err.message() << std::endl;
|
|
|
+ sock.close();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**********
|
|
|
+ * Server *
|
|
|
+ **********/
|
|
|
+
|
|
|
+void Server::start_accept() {
|
|
|
+ auto executor = acceptor_.get_executor();
|
|
|
+ con_handler::pointer connection = con_handler::create(executor);
|
|
|
+ acceptor_.async_accept(connection->socket(),
|
|
|
+ boost::bind(&Server::handle_accept, this, connection,
|
|
|
+ placeholders::error));
|
|
|
+}
|
|
|
+
|
|
|
+Server::Server(io_service &io_service)
|
|
|
+ : acceptor_(io_service, tcp::endpoint(tcp::v4(), 1234)) {
|
|
|
+ start_accept();
|
|
|
+}
|
|
|
+
|
|
|
+Server::~Server() {}
|
|
|
+
|
|
|
+void Server::handle_accept(con_handler::pointer connection,
|
|
|
+ const boost::system::error_code &err) {
|
|
|
+ if (!err) {
|
|
|
+ connection->start();
|
|
|
+ }
|
|
|
+ start_accept();
|
|
|
+}
|