JsonCommander.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. #include "../include/JsonCommander.h"
  2. #include "../include/Config.h"
  3. #include "../include/Notifications.h"
  4. #include "../include/Queue.h"
  5. #include "../include/UserManager.h"
  6. #include "../include/base64.h"
  7. JsonCommander::JsonCommander(FileManager &fileManager) : fileManager(fileManager) {
  8. commandsMap["status"] = &JsonCommander::executeStatus;
  9. commandsMap["close"] = &JsonCommander::executeClose;
  10. commandsMap["list"] = &JsonCommander::executeList;
  11. commandsMap["listdata"] = &JsonCommander::executeListData;
  12. commandsMap["put"] = &JsonCommander::executePut;
  13. commandsMap["putdata"] = &JsonCommander::executePutdata;
  14. commandsMap["get"] = &JsonCommander::executeGet;
  15. commandsMap["getdata"] = &JsonCommander::executeGetdata;
  16. commandsMap["head"] = &JsonCommander::executeHead;
  17. commandsMap["deleteme"] = &JsonCommander::executeDeleteMe;
  18. commandsMap["deletefile"] = &JsonCommander::executeDeleteFile;
  19. commandsMap["extendedstatus"] = &JsonCommander::executeExtendedStatus;
  20. commandsMap["notifications"] = &JsonCommander::executeNotifications;
  21. commandsMap["queue"] = &JsonCommander::executeQueue;
  22. commandsMap["dequeue"] = &JsonCommander::executeDequeue;
  23. }
  24. JsonCommander::~JsonCommander() {}
  25. JsonCommander::Response JsonCommander::execute(const Json::Value &message) {
  26. JsonCommander::Response response;
  27. Response (JsonCommander::*commandExecutor)(const Json::Value &) = commandsMap[message["command"].asString()];
  28. if (commandExecutor != nullptr) {
  29. response = (this->*commandExecutor)(message);
  30. } else {
  31. // command does not exist
  32. response.action = close;
  33. }
  34. return response;
  35. }
  36. JsonCommander::Response JsonCommander::executeStatus(const Json::Value &message) {
  37. JsonCommander::Response response;
  38. response.action = send;
  39. response.json["command"] = "status";
  40. // answer a real status message
  41. std::string status;
  42. if (this->fileManager.isUploading() && this->fileManager.isDownloading()) {
  43. status = "download and upload running";
  44. } else if (this->fileManager.isUploading()) {
  45. status = "upload running";
  46. } else if (this->fileManager.isDownloading()) {
  47. status = "download running";
  48. } else {
  49. status = "ok";
  50. }
  51. response.json["response"] = status;
  52. return response;
  53. }
  54. JsonCommander::Response JsonCommander::executeClose(const Json::Value &message) {
  55. JsonCommander::Response response;
  56. response.action = closeAndSend;
  57. response.json["command"] = "close";
  58. response.json["response"] = "bye";
  59. return response;
  60. }
  61. JsonCommander::Response JsonCommander::executeList(const Json::Value &message) {
  62. JsonCommander::Response response;
  63. response.action = send;
  64. response.json["command"] = "list";
  65. int chunks;
  66. if (fileManager.getRemainingListChunks() > 0) {
  67. response.json["accept"] = false;
  68. response.json["chunks"] = -1;
  69. response.json["items"] = -1;
  70. response.json["error"] = "there is already an open list command";
  71. } else if ((chunks = fileManager.openList()) == -1) { // TODO do we need to check? maybe. Think about it
  72. response.json["accept"] = false;
  73. response.json["chunks"] = -1;
  74. response.json["items"] = -1;
  75. response.json["error"] = "there is a filename which is too long";
  76. } else {
  77. response.json["accept"] = true;
  78. response.json["chunks"] = chunks;
  79. response.json["items"] = fileManager.getListSize();
  80. response.json["error"] = "";
  81. }
  82. return response;
  83. }
  84. JsonCommander::Response JsonCommander::executeListData(const Json::Value &message) {
  85. JsonCommander::Response response;
  86. response.action = send;
  87. response.json["command"] = "listdata";
  88. Json::Value array;
  89. const int remainingListchunks = fileManager.getRemainingListChunks();
  90. if (!message["chunk"].isInt() || !message["cancel"].isBool()) {
  91. response.action = closeAndSend;
  92. response.json["cancel"] = true;
  93. response.json["remaining"] = -1;
  94. response.json["names"] = Json::arrayValue;
  95. response.json["error"] = "incorrect listdata command request";
  96. } else if (remainingListchunks == 0) {
  97. response.json["cancel"] = true;
  98. response.json["remaining"] = -1;
  99. response.json["names"] = Json::arrayValue;
  100. response.json["error"] = "there are no chunks to send";
  101. } else if (message["cancel"].asBool()) {
  102. response.json["cancel"] = true;
  103. response.json["remaining"] = message["chunk"].asInt(); // so it can be associated to the request
  104. response.json["names"] = Json::arrayValue;
  105. response.json["error"] = "";
  106. fileManager.cancelList();
  107. } else if (remainingListchunks - 1 != message["chunk"].asInt()) {
  108. response.action = closeAndSend;
  109. response.json["cancel"] = true;
  110. response.json["remaining"] = -1;
  111. response.json["names"] = Json::arrayValue;
  112. response.json["error"] = "wrong chunk number";
  113. } else {
  114. std::vector<std::string> v = fileManager.getNextChunkFromList();
  115. for (int i = 0; i < v.size(); i++)
  116. array.append(v.at(i));
  117. response.json["remaining"] = message["chunk"].asInt();
  118. response.json["cancel"] = false;
  119. response.json["names"] = array;
  120. response.json["error"] = "";
  121. }
  122. return response;
  123. }
  124. JsonCommander::Response JsonCommander::executePut(const Json::Value &message) {
  125. JsonCommander::Response response;
  126. response.json["command"] = "put";
  127. response.json["file"] = message["file"].asString();
  128. if (!message["file"].isString() || !message["size"].isInt() || !message["chunks"].isInt()) {
  129. // if request is incomplete close connection
  130. response.action = closeAndSend;
  131. response.json["accept"] = false;
  132. response.json["error"] = "incorrect put command request";
  133. } else if (fileManager.isUploading()) {
  134. // if an upload is alread running deny request
  135. response.action = send;
  136. response.json["accept"] = false;
  137. response.json["error"] = "upload already running";
  138. } else if (message["chunks"].asInt() <= 0) {
  139. response.action = send;
  140. response.json["accept"] = false;
  141. response.json["error"] = "there must be at least one chunk";
  142. } else if (fileManager.checkFilename(message["file"].asString())) {
  143. // accept request
  144. response.action = send;
  145. bool opened = fileManager.openPutFile(message["file"].asString());
  146. if (opened) {
  147. response.json["accept"] = true;
  148. response.json["error"] = "";
  149. this->putFileReceived = message["chunks"].asInt();
  150. this->putSize = message["chunks"].asInt();
  151. } else {
  152. response.json["accept"] = false;
  153. response.json["error"] = "file already exists";
  154. }
  155. } else {
  156. // deny request if file name is not valid
  157. response.action = send;
  158. response.json["accept"] = false;
  159. response.json["error"] = "invalid file name";
  160. }
  161. return response;
  162. }
  163. JsonCommander::Response JsonCommander::executePutdata(const Json::Value &message) {
  164. JsonCommander::Response response;
  165. response.json["command"] = "putdata";
  166. response.json["file"] = message["file"].asString();
  167. response.json["received"] = message["remaining"].asInt();
  168. if (!message["file"].isString() || !message["data"].isString() || !message["remaining"].isInt() || !message["cancel"].isBool()) {
  169. // if request is incomplete close connection
  170. response.action = closeAndSend;
  171. response.json["cancel"] = true;
  172. response.json["error"] = "incorrect putdata command request";
  173. this->fileManager.cancelPut();
  174. } else if (!fileManager.isUploading()) {
  175. // no upload running -> command
  176. response.action = send;
  177. response.json["cancel"] = true;
  178. response.json["error"] = "no upload running";
  179. } else if (message["cancel"].asBool()) {
  180. response.action = send;
  181. response.json["cancel"] = true;
  182. response.json["error"] = "";
  183. this->fileManager.cancelPut();
  184. } else if (message["file"].asString().compare(fileManager.getPutBaseFileName()) == 0) {
  185. if (--this->putFileReceived == message["remaining"].asInt()) {
  186. // accept request
  187. response.action = send;
  188. response.json["cancel"] = false;
  189. response.json["error"] = "";
  190. const std::vector<char> data = base64::decode<std::vector<char>>(message["data"].asString());
  191. fileManager.writePut(data);
  192. this->putFileReceived = message["remaining"].asInt();
  193. if (this->putFileReceived == 0) {
  194. // close file after last chunk was received
  195. this->fileManager.closePutFile();
  196. }
  197. } else {
  198. // wrong remaining number
  199. response.action = send;
  200. response.json["cancel"] = true;
  201. response.json["error"] = "wrong remaining number";
  202. this->fileManager.cancelPut();
  203. }
  204. } else {
  205. // wrong file name
  206. response.action = send;
  207. response.json["cancel"] = true;
  208. response.json["error"] = "another file was already being uploaded";
  209. this->fileManager.cancelPut();
  210. }
  211. return response;
  212. }
  213. JsonCommander::Response JsonCommander::executeGet(const Json::Value &message) {
  214. JsonCommander::Response response;
  215. response.json["command"] = "get";
  216. response.json["file"] = message["file"].asString();
  217. if (!message["file"].isString()) {
  218. // if request is incomplete close connection
  219. response.action = closeAndSend;
  220. response.json["accept"] = false;
  221. response.json["chunks"] = -1;
  222. response.json["error"] = "incorrect get command request";
  223. } else if (fileManager.isDownloading()) {
  224. // if an upload is alread running deny request
  225. response.action = send;
  226. response.json["accept"] = false;
  227. response.json["chunks"] = -1;
  228. response.json["error"] = "download already running";
  229. } else if (fileManager.checkFilename(message["file"].asString())) {
  230. // accept request
  231. response.action = send;
  232. std::pair<bool, int> opened = fileManager.openGetFile(message["file"].asString());
  233. if (opened.first) {
  234. this->getFileRemaining = opened.second;
  235. this->getSize = opened.second;
  236. response.json["accept"] = true;
  237. response.json["chunks"] = this->getFileRemaining;
  238. response.json["error"] = "";
  239. } else {
  240. response.json["accept"] = false;
  241. response.json["chunks"] = -1;
  242. response.json["error"] = "file does not exist";
  243. }
  244. } else {
  245. // deny request if file name is not valid
  246. response.action = send;
  247. response.json["accept"] = false;
  248. response.json["chunks"] = -1;
  249. response.json["error"] = "invalid file name";
  250. }
  251. return response;
  252. }
  253. JsonCommander::Response JsonCommander::executeGetdata(const Json::Value &message) {
  254. JsonCommander::Response response;
  255. response.json["command"] = "getdata";
  256. response.json["file"] = message["file"].asString();
  257. response.json["remaining"] = message["chunk"].asInt();
  258. if (!message["file"].isString() || !message["chunk"].isInt() || !message["cancel"].isBool()) {
  259. // if request is incomplete close connection
  260. response.action = closeAndSend;
  261. response.json["cancel"] = true;
  262. response.json["data"] = "";
  263. response.json["error"] = "incorrect putdata command request";
  264. this->fileManager.closeGetFile();
  265. } else if (!fileManager.isDownloading()) {
  266. // no upload running -> command
  267. response.action = send;
  268. response.json["cancel"] = true;
  269. response.json["data"] = "";
  270. response.json["error"] = "no download running";
  271. } else if (message["cancel"].asBool()) {
  272. response.action = send;
  273. response.json["cancel"] = true;
  274. response.json["data"] = "";
  275. response.json["error"] = "";
  276. this->fileManager.closeGetFile();
  277. } else if (message["file"].asString().compare(fileManager.getGetBaseFileName()) == 0) {
  278. if (--this->getFileRemaining == message["chunk"].asInt()) {
  279. // accept request
  280. response.action = send;
  281. response.json["cancel"] = false;
  282. response.json["error"] = "";
  283. const std::vector<char> data = fileManager.readGet();
  284. response.json["data"] = base64::encode<std::vector<char>>(data);
  285. fileManager.writePut(data);
  286. if (this->getFileRemaining == 0) {
  287. // close file after last chunk was sent
  288. this->fileManager.closeGetFile();
  289. }
  290. } else {
  291. // wrong chunk number
  292. response.action = send;
  293. response.json["cancel"] = true;
  294. response.json["data"] = "";
  295. response.json["error"] = "wrong chunk number";
  296. this->fileManager.closeGetFile();
  297. }
  298. } else {
  299. // wrong file name
  300. response.action = send;
  301. response.json["cancel"] = true;
  302. response.json["data"] = "";
  303. response.json["error"] = "another file was already being downloaded";
  304. this->fileManager.closeGetFile();
  305. }
  306. return response;
  307. }
  308. JsonCommander::Response JsonCommander::executeHead(const Json::Value &message) {
  309. JsonCommander::Response response;
  310. response.action = send;
  311. response.json["command"] = "head";
  312. if (!message["file"].isString()) {
  313. response.json["accept"] = false;
  314. response.json["file"] = "";
  315. response.json["data"] = "";
  316. response.json["error"] = "incorrect head command request";
  317. } else {
  318. std::pair<std::vector<char>, FileManager::Error> res = fileManager.getBytesFromFile(message["file"].asString(), 4);
  319. switch (res.second) {
  320. case FileManager::Error::no_error:
  321. response.json["accept"] = true;
  322. response.json["file"] = message["file"].asString();
  323. response.json["data"] = base64::encode<std::vector<char>>(res.first);
  324. response.json["error"] = "";
  325. break;
  326. case FileManager::Error::no_such_file:
  327. response.json["accept"] = false;
  328. response.json["file"] = message["file"].asString();
  329. response.json["data"] = "";
  330. response.json["error"] = "no such file";
  331. break;
  332. case FileManager::Error::file_too_small:
  333. response.json["accept"] = false;
  334. response.json["file"] = message["file"].asString();
  335. response.json["data"] = "";
  336. response.json["error"] = "file is smaller than specified size";
  337. break;
  338. default:
  339. response.action = closeAndSend;
  340. response.json["accept"] = false;
  341. response.json["file"] = message["file"];
  342. response.json["data"] = "";
  343. response.json["error"] = "internal error. Please fix this!!!";
  344. }
  345. }
  346. return response;
  347. }
  348. JsonCommander::Response JsonCommander::executeDeleteMe(const Json::Value &message) {
  349. JsonCommander::Response response;
  350. response.json["command"] = "deleteme";
  351. if (!message["pass"].isString()) {
  352. response.action = closeAndSend;
  353. response.json["accept"] = false;
  354. response.json["error"] = "incorrect deleteme command request";
  355. } else if (UserManager::deleteUser(currentUser, message["pass"].asString())) {
  356. // success
  357. response.action = closeAndSend;
  358. response.json["accept"] = true;
  359. response.json["error"] = "";
  360. } else {
  361. response.action = send;
  362. response.json["accept"] = false;
  363. response.json["error"] = "wrong password";
  364. }
  365. return response;
  366. }
  367. JsonCommander::Response JsonCommander::testVersion(const Json::Value &message) {
  368. JsonCommander::Response response;
  369. response.json["major"] = this->protocolMajorVersion;
  370. response.json["minor"] = this->protocolMinorVersion;
  371. if (!message["major"].isInt() || !message["minor"].isInt()) {
  372. response.action = closeAndSend;
  373. response.json["accept"] = false;
  374. } else if (message["major"].asInt() == this->protocolMajorVersion && message["minor"].asInt() <= this->protocolMinorVersion) {
  375. response.action = send;
  376. response.json["accept"] = true;
  377. } else {
  378. response.action = closeAndSend;
  379. response.json["accept"] = false;
  380. }
  381. return response;
  382. }
  383. JsonCommander::Response JsonCommander::checkLogin(const Json::Value &message) {
  384. JsonCommander::Response response;
  385. if (!message["login"].isBool() || !message["user"].isString() || !message["pass"].isString() || !message["cancel"].isBool()) {
  386. // invalid login request
  387. response.action = closeAndSend;
  388. response.json["accept"] = false;
  389. response.json["error"] = "invalid login request";
  390. } else if (message["cancel"].asBool()) {
  391. response.action = close;
  392. } else if (message["login"].asBool() && UserManager::isAllowed(message["user"].asString(), message["pass"].asString())) {
  393. // credential check
  394. response.action = send;
  395. response.json["accept"] = true;
  396. response.json["error"] = "";
  397. currentUser = message["user"].asString();
  398. } else if (!message["login"].asBool()) {
  399. // add user. Check if already exists before
  400. if (!UserManager::addUser(message["user"].asString(), message["pass"].asString())) {
  401. response.action = closeAndSend;
  402. response.json["accept"] = false;
  403. response.json["error"] = "user does already exist";
  404. } else {
  405. response.action = send;
  406. response.json["accept"] = true;
  407. response.json["error"] = "";
  408. currentUser = message["user"].asString();
  409. }
  410. } else {
  411. // reject user
  412. response.action = closeAndSend;
  413. response.json["accept"] = false;
  414. response.json["error"] = "wrong username or password";
  415. }
  416. return response;
  417. }
  418. JsonCommander::Response JsonCommander::executeDeleteFile(const Json::Value &message) {
  419. JsonCommander::Response response;
  420. response.json["command"] = "deletefile";
  421. if (!message["file"].isString()) {
  422. response.action = closeAndSend;
  423. response.json["accept"] = false;
  424. response.json["error"] = "incorrect deletefile command request";
  425. response.json["file"] = "";
  426. } else {
  427. response.action = send;
  428. FileManager::Error err = fileManager.deleteFile(message["file"].asString());
  429. switch (err) {
  430. case FileManager::Error::no_error:
  431. response.json["accept"] = true;
  432. response.json["error"] = "";
  433. response.json["file"] = message["file"];
  434. break;
  435. case FileManager::Error::not_allowed:
  436. response.json["accept"] = false;
  437. response.json["error"] = "deleting files is disabled";
  438. response.json["file"] = message["file"];
  439. break;
  440. case FileManager::Error::no_such_file:
  441. response.json["accept"] = false;
  442. response.json["error"] = "no such file";
  443. response.json["file"] = message["file"];
  444. break;
  445. default:
  446. response.action = closeAndSend;
  447. response.json["accept"] = false;
  448. response.json["error"] = "internal error. Please fix this!!!";
  449. response.json["file"] = message["file"];
  450. }
  451. }
  452. return response;
  453. }
  454. JsonCommander::Response JsonCommander::executeExtendedStatus(const Json::Value &message) {
  455. JsonCommander::Response response;
  456. response.json["command"] = "extendedstatus";
  457. // get status from client server transfers
  458. int index = 0;
  459. if (fileManager.isUploading()) {
  460. response.json["transfersclientserver"][index]["upload"] = true;
  461. response.json["transfersclientserver"][index]["file"] = fileManager.getPutBaseFileName();
  462. int progress = 0;
  463. if (this->putSize != 0) {
  464. double d = (double)this->putFileReceived / (double)this->putSize;
  465. progress = (int)(d * 100);
  466. }
  467. response.json["transfersclientserver"][index]["progress"] = progress;
  468. index++;
  469. }
  470. if (fileManager.isDownloading()) {
  471. response.json["transfersclientserver"][index]["upload"] = false;
  472. response.json["transfersclientserver"][index]["file"] = fileManager.getGetBaseFileName();
  473. int progress = 0;
  474. if (this->getSize != 0) {
  475. double d = 1 - ((double)this->getFileRemaining / (double)this->getSize);
  476. progress = (int)(d * 100);
  477. }
  478. response.json["transfersclientserver"][index]["progress"] = progress;
  479. }
  480. // get status from covert channel
  481. index = 0;
  482. if (Queue::channel != nullptr && Queue::channel->isTransferRunning()) {
  483. response.json["transfersserverserver"][index]["type"] = Config::getValue("passiveMode").compare("true") == 0 ? "download" : "upload";
  484. response.json["transfersserverserver"][index]["file"] = Queue::curTransfer;
  485. auto rawprogress = Queue::channel->getProgress();
  486. double d = ((double)rawprogress.first / (double)rawprogress.second);
  487. int progress = (int)(d * 100);
  488. response.json["transfersserverserver"][index]["progress"] = progress;
  489. std::time_t startTime = Queue::channel->getTransferStart();
  490. std::time_t curTime = std::time(nullptr);
  491. std::time_t diffTime = curTime - startTime;
  492. double speed = (double)rawprogress.first / (double)diffTime;
  493. response.json["transfersserverserver"][index]["speed"] = speed;
  494. response.json["transfersserverserver"][index]["method"] = Config::getValue("covertChannelMode");
  495. index++;
  496. }
  497. for (int i = 0; i < Queue::queue.size(); i++) {
  498. response.json["transfersserverserver"][index]["type"] = "queued";
  499. response.json["transfersserverserver"][index]["file"] = Queue::queue[i];
  500. response.json["transfersserverserver"][index]["progress"] = 0;
  501. response.json["transfersserverserver"][index]["speed"] = 0;
  502. response.json["transfersserverserver"][index]["method"] = Config::getValue("covertChannelMode");
  503. index++;
  504. }
  505. response.json["accept"] = true;
  506. response.json["error"] = "";
  507. response.action = send;
  508. return response;
  509. }
  510. JsonCommander::Response JsonCommander::executeNotifications(const Json::Value &message) {
  511. JsonCommander::Response response;
  512. response.json["command"] = "notifications";
  513. Json::Value array;
  514. std::vector<std::string> v = Notifications::getMessages(currentUser);
  515. for (int i = 0; i < v.size(); i++)
  516. array.append(v.at(i));
  517. response.action = send;
  518. response.json["messages"] = array;
  519. response.json["accept"] = true;
  520. response.json["error"] = "";
  521. return response;
  522. }
  523. JsonCommander::Response JsonCommander::executeQueue(const Json::Value &message) {
  524. JsonCommander::Response response;
  525. response.json["command"] = "queue";
  526. if (!message["file"].isString()) {
  527. response.action = closeAndSend;
  528. response.json["file"] = "";
  529. response.json["accept"] = false;
  530. response.json["error"] = "invalid request";
  531. } else {
  532. bool res = Queue::push(message["file"].asString());
  533. if (res) {
  534. response.action = send;
  535. response.json["file"] = message["file"].asString();
  536. response.json["accept"] = true;
  537. response.json["error"] = "";
  538. } else {
  539. response.action = send;
  540. response.json["file"] = message["file"].asString();
  541. response.json["accept"] = false;
  542. response.json["error"] = "file could not be queued";
  543. }
  544. }
  545. return response;
  546. }
  547. JsonCommander::Response JsonCommander::executeDequeue(const Json::Value &message) {
  548. JsonCommander::Response response;
  549. response.json["command"] = "dequeue";
  550. if (!message["file"].isString()) {
  551. response.action = closeAndSend;
  552. response.json["file"] = "";
  553. response.json["accept"] = false;
  554. response.json["error"] = "invalid request";
  555. } else {
  556. bool res = Queue::remove(message["file"].asString());
  557. if (res) {
  558. response.action = send;
  559. response.json["file"] = message["file"].asString();
  560. response.json["accept"] = true;
  561. response.json["error"] = "";
  562. } else {
  563. response.action = send;
  564. response.json["file"] = message["file"].asString();
  565. response.json["accept"] = false;
  566. response.json["error"] = "cannot remove this file from queue";
  567. }
  568. }
  569. return response;
  570. }