Server.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. #include "../include/Server.h"
  2. #include "../include/base64.h"
  3. #include <iostream>
  4. #include <jsoncpp/json/json.h>
  5. using namespace boost::asio;
  6. using ip::tcp;
  7. /***************
  8. * con_handler *
  9. ***************/
  10. con_handler::con_handler(
  11. basic_socket_acceptor<ip::tcp>::executor_type &io_service)
  12. : sock(io_service) {}
  13. con_handler::~con_handler() {}
  14. con_handler::pointer
  15. con_handler::create(basic_socket_acceptor<ip::tcp>::executor_type &io_service) {
  16. return pointer(new con_handler(io_service));
  17. }
  18. tcp::socket &con_handler::socket() { return sock; }
  19. void con_handler::start() {
  20. sock.async_read_some(buffer(data, max_length),
  21. boost::bind(&con_handler::handle_read_version,
  22. shared_from_this(), placeholders::error,
  23. placeholders::bytes_transferred));
  24. }
  25. void con_handler::handle_read(const boost::system::error_code &err,
  26. size_t bytes_transferred) {
  27. if (!err) {
  28. std::cout << this->data << std::endl;
  29. } else {
  30. std::cerr << "error: " << err.message() << std::endl;
  31. sock.close();
  32. }
  33. }
  34. void con_handler::handle_read_version(const boost::system::error_code &err,
  35. size_t bytes_transferred) {
  36. if (!err) {
  37. // set up json stuff
  38. JSONCPP_STRING err;
  39. Json::Value root;
  40. Json::CharReaderBuilder builder;
  41. const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
  42. // parse data
  43. if (!reader->parse(this->data, this->data + bytes_transferred, &root,
  44. &err)) {
  45. std::cerr << "Json error: " << err << std::endl << "data: " << this->data;
  46. sock.close();
  47. }
  48. // create answer
  49. Json::Value answer;
  50. Json::StreamWriterBuilder stringBuilder;
  51. answer["version"] = this->protocolVersion;
  52. // check version string
  53. if (root["version"].compare(this->protocolVersion) == 0) {
  54. answer["accept"] = true;
  55. const std::string answerString = Json::writeString(stringBuilder, answer);
  56. // read next data
  57. sock.async_read_some(buffer(data, max_length),
  58. boost::bind(&con_handler::handle_read_login,
  59. shared_from_this(), placeholders::error,
  60. placeholders::bytes_transferred));
  61. // send answer
  62. sock.async_write_some(buffer(answerString, max_length),
  63. boost::bind(&con_handler::handle_write,
  64. shared_from_this(), placeholders::error,
  65. placeholders::bytes_transferred));
  66. } else {
  67. answer["accept"] = false;
  68. const std::string answerString = Json::writeString(stringBuilder, answer);
  69. // send answer
  70. sock.async_write_some(buffer(answerString, max_length),
  71. boost::bind(&con_handler::handle_write,
  72. shared_from_this(), placeholders::error,
  73. placeholders::bytes_transferred));
  74. // close connection
  75. sock.close();
  76. }
  77. } else {
  78. std::cerr << "error: " << err.message() << std::endl;
  79. sock.close();
  80. }
  81. }
  82. void con_handler::handle_read_login(const boost::system::error_code &err,
  83. size_t bytes_transferred) {
  84. if (!err) {
  85. // set up json stuff
  86. JSONCPP_STRING err;
  87. Json::Value root;
  88. Json::CharReaderBuilder builder;
  89. const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
  90. // parse data
  91. if (!reader->parse(this->data, this->data + bytes_transferred, &root,
  92. &err)) {
  93. std::cerr << "Json error: " << err << std::endl << "data: " << this->data;
  94. sock.close();
  95. }
  96. Json::Value answer;
  97. Json::StreamWriterBuilder stringBuilder;
  98. // user credentials
  99. // TODO check user credentials!!!
  100. if (root["user"].compare("user") == 0 &&
  101. root["pass"].compare("pass") == 0) {
  102. answer["accept"] = true;
  103. const std::string answerString = Json::writeString(stringBuilder, answer);
  104. // read next data
  105. sock.async_read_some(buffer(data, max_length),
  106. boost::bind(&con_handler::handle_read_command,
  107. shared_from_this(), placeholders::error,
  108. placeholders::bytes_transferred));
  109. // send answer
  110. sock.async_write_some(buffer(answerString, max_length),
  111. boost::bind(&con_handler::handle_write,
  112. shared_from_this(), placeholders::error,
  113. placeholders::bytes_transferred));
  114. } else {
  115. answer["accept"] = false;
  116. const std::string answerString = Json::writeString(stringBuilder, answer);
  117. // send answer
  118. sock.async_write_some(buffer(answerString, max_length),
  119. boost::bind(&con_handler::handle_write,
  120. shared_from_this(), placeholders::error,
  121. placeholders::bytes_transferred));
  122. // close connection
  123. sock.close();
  124. }
  125. } else {
  126. std::cerr << "error: " << err.message() << std::endl;
  127. sock.close();
  128. }
  129. }
  130. void con_handler::handle_read_command(const boost::system::error_code &err,
  131. size_t bytes_transferred) {
  132. if (!err) {
  133. // set up json stuff
  134. JSONCPP_STRING err;
  135. Json::Value root;
  136. Json::CharReaderBuilder builder;
  137. const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
  138. // parse data
  139. if (!reader->parse(this->data, this->data + bytes_transferred, &root,
  140. &err)) {
  141. std::cerr << "Json error: " << err << std::endl << "data: " << this->data;
  142. sock.close();
  143. }
  144. Json::Value answer;
  145. Json::StreamWriterBuilder stringBuilder;
  146. // check command
  147. if (root["command"].compare("status") == 0) {
  148. // read next data
  149. sock.async_read_some(buffer(data, max_length),
  150. boost::bind(&con_handler::handle_read_command,
  151. shared_from_this(), placeholders::error,
  152. placeholders::bytes_transferred));
  153. answer["command"] = "status";
  154. // TODO answer a real status message
  155. answer["response"] = "This is a status message :)";
  156. const std::string answerString = Json::writeString(stringBuilder, answer);
  157. // send answer
  158. sock.async_write_some(buffer(answerString, max_length),
  159. boost::bind(&con_handler::handle_write,
  160. shared_from_this(), placeholders::error,
  161. placeholders::bytes_transferred));
  162. } else if (root["command"].compare("list") == 0) {
  163. // read next data
  164. sock.async_read_some(buffer(data, max_length),
  165. boost::bind(&con_handler::handle_read_command,
  166. shared_from_this(), placeholders::error,
  167. placeholders::bytes_transferred));
  168. answer["command"] = "list";
  169. // TODO look for real data
  170. Json::Value array;
  171. array.append("some");
  172. array.append("important");
  173. array.append("data");
  174. answer["names"] = array;
  175. answer["remaining"] = 0;
  176. const std::string answerString = Json::writeString(stringBuilder, answer);
  177. // send answer
  178. sock.async_write_some(buffer(answerString, max_length),
  179. boost::bind(&con_handler::handle_write,
  180. shared_from_this(), placeholders::error,
  181. placeholders::bytes_transferred));
  182. } else if (root["command"].compare("put") == 0) {
  183. // read next data
  184. sock.async_read_some(buffer(data, max_length),
  185. boost::bind(&con_handler::handle_read_command,
  186. shared_from_this(), placeholders::error,
  187. placeholders::bytes_transferred));
  188. answer["command"] = "put";
  189. if (this->putFile.is_open() && root["cancel"].asBool() == true) {
  190. // cancel upload
  191. this->putFile.close();
  192. std::remove(this->putFileName.c_str());
  193. } else if (this->putFile.is_open()) {
  194. // upload chunks
  195. // decode base64 string
  196. const std::string data = base64::decode(root["data"].asString());
  197. this->putFile << data;
  198. // close file if put sends remaining = 0
  199. if (root["remaining"].asInt() == 0) {
  200. this->putFile.close();
  201. }
  202. } else {
  203. // start upload
  204. const std::string filename = root["file"].asString();
  205. if (filename.find("/") != std::string::npos) {
  206. // slashes in file names are illegal
  207. answer["accept"] = false;
  208. const std::string answerString =
  209. Json::writeString(stringBuilder, answer);
  210. // send answer
  211. sock.async_write_some(buffer(answerString, max_length),
  212. boost::bind(&con_handler::handle_write,
  213. shared_from_this(),
  214. placeholders::error,
  215. placeholders::bytes_transferred));
  216. } else {
  217. // build file path
  218. this->putFileName = this->fileDirectory;
  219. this->putFileName.append(filename);
  220. // open file and test if it already exists
  221. this->putFile.open(this->putFileName,
  222. std::ios::app | std::ios::binary);
  223. if (this->putFile.tellp() != std::ios::beg) {
  224. // file already exists
  225. this->putFile.close();
  226. answer["accept"] = false;
  227. const std::string answerString =
  228. Json::writeString(stringBuilder, answer);
  229. // send answer
  230. sock.async_write_some(buffer(answerString, max_length),
  231. boost::bind(&con_handler::handle_write,
  232. shared_from_this(),
  233. placeholders::error,
  234. placeholders::bytes_transferred));
  235. } else {
  236. // accept file
  237. answer["accept"] = true;
  238. const std::string answerString =
  239. Json::writeString(stringBuilder, answer);
  240. // send answer
  241. sock.async_write_some(buffer(answerString, max_length),
  242. boost::bind(&con_handler::handle_write,
  243. shared_from_this(),
  244. placeholders::error,
  245. placeholders::bytes_transferred));
  246. }
  247. }
  248. }
  249. } else if (root["command"].compare("get") == 0) {
  250. // read next data
  251. sock.async_read_some(buffer(data, max_length),
  252. boost::bind(&con_handler::handle_read_command,
  253. shared_from_this(), placeholders::error,
  254. placeholders::bytes_transferred));
  255. answer["command"] = "get";
  256. // a get request is already being progressed
  257. if (this->getFile.is_open()) {
  258. answer["accept"] = false;
  259. const std::string answerString =
  260. Json::writeString(stringBuilder, answer);
  261. // send answer
  262. sock.async_write_some(
  263. buffer(answerString, max_length),
  264. boost::bind(&con_handler::handle_write, shared_from_this(),
  265. placeholders::error, placeholders::bytes_transferred));
  266. } else {
  267. // open file
  268. const std::string filename = root["file"].asString();
  269. if (filename.find("/") != std::string::npos) {
  270. // slashes in file names are illegal
  271. answer["accept"] = false;
  272. const std::string answerString =
  273. Json::writeString(stringBuilder, answer);
  274. // send answer
  275. sock.async_write_some(buffer(answerString, max_length),
  276. boost::bind(&con_handler::handle_write,
  277. shared_from_this(),
  278. placeholders::error,
  279. placeholders::bytes_transferred));
  280. } else {
  281. std::string file = this->fileDirectory;
  282. file.append(filename);
  283. this->getFile = std::ifstream(file, std::ios::ate | std::ios::binary);
  284. if (this->getFile.is_open() == 0) {
  285. // file does not exist or cannot be opened
  286. answer["accept"] = false;
  287. const std::string answerString =
  288. Json::writeString(stringBuilder, answer);
  289. // send answer
  290. sock.async_write_some(buffer(answerString, max_length),
  291. boost::bind(&con_handler::handle_write,
  292. shared_from_this(),
  293. placeholders::error,
  294. placeholders::bytes_transferred));
  295. } else {
  296. // get size of file
  297. size_t size = this->getFile.tellg();
  298. this->getFile.seekg(std::ios::beg);
  299. char fileBuffer[9];
  300. while (size_t read = this->getFile.readsome(fileBuffer, 8)) {
  301. fileBuffer[read] = 0;
  302. size -= read;
  303. int remaining = size / 8 + (size % 8 == 0 ? 0 : 1);
  304. answer["remaining"] = remaining;
  305. answer["cancel"] = false;
  306. answer["data"] = base64::encode(fileBuffer);
  307. const std::string answerString =
  308. Json::writeString(stringBuilder, answer);
  309. sock.async_write_some(
  310. buffer(answerString, max_length),
  311. boost::bind(&con_handler::handle_write, shared_from_this(),
  312. placeholders::error,
  313. placeholders::bytes_transferred));
  314. }
  315. this->getFile.close();
  316. }
  317. }
  318. }
  319. } else if (root["command"].compare("close") == 0) {
  320. answer["command"] = "close";
  321. answer["response"] = "bye";
  322. const std::string answerString = Json::writeString(stringBuilder, answer);
  323. // send answer
  324. sock.async_write_some(buffer(answerString, max_length),
  325. boost::bind(&con_handler::handle_write,
  326. shared_from_this(), placeholders::error,
  327. placeholders::bytes_transferred));
  328. // close connection
  329. sock.close();
  330. } else {
  331. // TODO handle error
  332. // close connection
  333. sock.close();
  334. }
  335. } else {
  336. std::cerr << "error: " << err.message() << std::endl;
  337. sock.close();
  338. }
  339. }
  340. void con_handler::handle_write(const boost::system::error_code &err,
  341. size_t bytes_transferred) {
  342. if (!err) {
  343. std::cout << "Hello World!" << std::endl;
  344. } else {
  345. std::cerr << "error: " << err.message() << std::endl;
  346. sock.close();
  347. }
  348. }
  349. /**********
  350. * Server *
  351. **********/
  352. void Server::start_accept() {
  353. auto executor = acceptor_.get_executor();
  354. con_handler::pointer connection = con_handler::create(executor);
  355. acceptor_.async_accept(connection->socket(),
  356. boost::bind(&Server::handle_accept, this, connection,
  357. placeholders::error));
  358. }
  359. Server::Server(io_service &io_service)
  360. : acceptor_(io_service, tcp::endpoint(tcp::v4(), 1234)) {
  361. start_accept();
  362. }
  363. Server::~Server() {}
  364. void Server::handle_accept(con_handler::pointer connection,
  365. const boost::system::error_code &err) {
  366. if (!err) {
  367. connection->start();
  368. }
  369. start_accept();
  370. }