RpcMethodImpl.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. /* <!-- copyright */
  2. /*
  3. * aria2 - The high speed download utility
  4. *
  5. * Copyright (C) 2009 Tatsuhiro Tsujikawa
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * In addition, as a special exception, the copyright holders give
  22. * permission to link the code of portions of this program with the
  23. * OpenSSL library under certain conditions as described in each
  24. * individual source file, and distribute linked combinations
  25. * including the two.
  26. * You must obey the GNU General Public License in all respects
  27. * for all of the code used other than OpenSSL. If you modify
  28. * file(s) with this exception, you may extend this exception to your
  29. * version of the file(s), but you are not obligated to do so. If you
  30. * do not wish to do so, delete this exception statement from your
  31. * version. If you delete this exception statement from all source
  32. * files in the program, then also delete it here.
  33. */
  34. /* copyright --> */
  35. #ifndef D_RPC_METHOD_IMPL_H
  36. #define D_RPC_METHOD_IMPL_H
  37. #include "RpcMethod.h"
  38. #include <cassert>
  39. #include <deque>
  40. #include <algorithm>
  41. #include "RpcRequest.h"
  42. #include "ValueBase.h"
  43. #include "TorrentAttribute.h"
  44. #include "DlAbortEx.h"
  45. #include "fmt.h"
  46. #include "IndexedList.h"
  47. #include "GroupId.h"
  48. #include "RequestGroupMan.h"
  49. namespace aria2 {
  50. struct DownloadResult;
  51. class RequestGroup;
  52. class CheckIntegrityEntry;
  53. namespace rpc {
  54. template <typename T>
  55. const T* checkParam(const RpcRequest& req, size_t index, bool required = false)
  56. {
  57. const T* p = 0;
  58. if (req.params->size() > index) {
  59. if ((p = downcast<T>(req.params->get(index))) == 0) {
  60. throw DL_ABORT_EX(fmt("The parameter at %lu has wrong type.",
  61. static_cast<unsigned long>(index)));
  62. }
  63. }
  64. else if (required) {
  65. throw DL_ABORT_EX(fmt("The parameter at %lu is required but missing.",
  66. static_cast<unsigned long>(index)));
  67. }
  68. return p;
  69. }
  70. template <typename T>
  71. const T* checkRequiredParam(const RpcRequest& req, size_t index)
  72. {
  73. return checkParam<T>(req, index, true);
  74. }
  75. struct IntegerGE {
  76. IntegerGE(int32_t min) : min(min) {}
  77. bool operator()(const Integer* param, std::string* error) const
  78. {
  79. if (min <= param->i()) {
  80. return true;
  81. }
  82. else {
  83. if (error) {
  84. *error = fmt("the value must be greater than or equal to %d.", min);
  85. }
  86. return false;
  87. }
  88. }
  89. int32_t min;
  90. };
  91. template <typename Validator>
  92. const Integer* checkRequiredInteger(const RpcRequest& req, size_t index,
  93. Validator validator)
  94. {
  95. const Integer* param = checkRequiredParam<Integer>(req, index);
  96. std::string error;
  97. if (!validator(param, &error)) {
  98. throw DL_ABORT_EX(fmt("The integer parameter at %lu has invalid value: %s",
  99. static_cast<unsigned long>(index), error.c_str()));
  100. }
  101. return param;
  102. }
  103. template <typename OutputIterator>
  104. void toStringList(OutputIterator out, const List* src)
  105. {
  106. if (!src) {
  107. return;
  108. }
  109. for (auto& elem : *src) {
  110. const String* s = downcast<String>(elem);
  111. if (s) {
  112. *out++ = s->s();
  113. }
  114. }
  115. }
  116. class AddUriRpcMethod : public RpcMethod {
  117. protected:
  118. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  119. DownloadEngine* e) CXX11_OVERRIDE;
  120. public:
  121. static const char* getMethodName() { return "aria2.addUri"; }
  122. };
  123. class RemoveRpcMethod : public RpcMethod {
  124. protected:
  125. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  126. DownloadEngine* e) CXX11_OVERRIDE;
  127. public:
  128. static const char* getMethodName() { return "aria2.remove"; }
  129. };
  130. class ForceRemoveRpcMethod : public RpcMethod {
  131. protected:
  132. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  133. DownloadEngine* e) CXX11_OVERRIDE;
  134. public:
  135. static const char* getMethodName() { return "aria2.forceRemove"; }
  136. };
  137. class PauseRpcMethod : public RpcMethod {
  138. protected:
  139. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  140. DownloadEngine* e) CXX11_OVERRIDE;
  141. public:
  142. static const char* getMethodName() { return "aria2.pause"; }
  143. };
  144. class ForcePauseRpcMethod : public RpcMethod {
  145. protected:
  146. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  147. DownloadEngine* e) CXX11_OVERRIDE;
  148. public:
  149. static const char* getMethodName() { return "aria2.forcePause"; }
  150. };
  151. class PauseAllRpcMethod : public RpcMethod {
  152. protected:
  153. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  154. DownloadEngine* e) CXX11_OVERRIDE;
  155. public:
  156. static const char* getMethodName() { return "aria2.pauseAll"; }
  157. };
  158. class ForcePauseAllRpcMethod : public RpcMethod {
  159. protected:
  160. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  161. DownloadEngine* e) CXX11_OVERRIDE;
  162. public:
  163. static const char* getMethodName() { return "aria2.forcePauseAll"; }
  164. };
  165. class UnpauseRpcMethod : public RpcMethod {
  166. protected:
  167. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  168. DownloadEngine* e) CXX11_OVERRIDE;
  169. public:
  170. static const char* getMethodName() { return "aria2.unpause"; }
  171. };
  172. class UnpauseAllRpcMethod : public RpcMethod {
  173. protected:
  174. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  175. DownloadEngine* e) CXX11_OVERRIDE;
  176. public:
  177. static const char* getMethodName() { return "aria2.unpauseAll"; }
  178. };
  179. #ifdef ENABLE_BITTORRENT
  180. class AddTorrentRpcMethod : public RpcMethod {
  181. protected:
  182. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  183. DownloadEngine* e) CXX11_OVERRIDE;
  184. public:
  185. static const char* getMethodName() { return "aria2.addTorrent"; }
  186. };
  187. #endif // ENABLE_BITTORRENT
  188. #ifdef ENABLE_METALINK
  189. class AddMetalinkRpcMethod : public RpcMethod {
  190. protected:
  191. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  192. DownloadEngine* e) CXX11_OVERRIDE;
  193. public:
  194. static const char* getMethodName() { return "aria2.addMetalink"; }
  195. };
  196. #endif // ENABLE_METALINK
  197. class PurgeDownloadResultRpcMethod : public RpcMethod {
  198. protected:
  199. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  200. DownloadEngine* e) CXX11_OVERRIDE;
  201. public:
  202. static const char* getMethodName() { return "aria2.purgeDownloadResult"; }
  203. };
  204. class RemoveDownloadResultRpcMethod : public RpcMethod {
  205. protected:
  206. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  207. DownloadEngine* e) CXX11_OVERRIDE;
  208. public:
  209. static const char* getMethodName() { return "aria2.removeDownloadResult"; }
  210. };
  211. class GetUrisRpcMethod : public RpcMethod {
  212. protected:
  213. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  214. DownloadEngine* e) CXX11_OVERRIDE;
  215. public:
  216. static const char* getMethodName() { return "aria2.getUris"; }
  217. };
  218. class GetFilesRpcMethod : public RpcMethod {
  219. protected:
  220. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  221. DownloadEngine* e) CXX11_OVERRIDE;
  222. public:
  223. static const char* getMethodName() { return "aria2.getFiles"; }
  224. };
  225. #ifdef ENABLE_BITTORRENT
  226. class GetPeersRpcMethod : public RpcMethod {
  227. protected:
  228. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  229. DownloadEngine* e) CXX11_OVERRIDE;
  230. public:
  231. static const char* getMethodName() { return "aria2.getPeers"; }
  232. };
  233. #endif // ENABLE_BITTORRENT
  234. class GetServersRpcMethod : public RpcMethod {
  235. protected:
  236. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  237. DownloadEngine* e) CXX11_OVERRIDE;
  238. public:
  239. static const char* getMethodName() { return "aria2.getServers"; }
  240. };
  241. class TellStatusRpcMethod : public RpcMethod {
  242. protected:
  243. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  244. DownloadEngine* e) CXX11_OVERRIDE;
  245. public:
  246. static const char* getMethodName() { return "aria2.tellStatus"; }
  247. };
  248. class TellActiveRpcMethod : public RpcMethod {
  249. protected:
  250. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  251. DownloadEngine* e) CXX11_OVERRIDE;
  252. public:
  253. static const char* getMethodName() { return "aria2.tellActive"; }
  254. };
  255. template <typename T> class AbstractPaginationRpcMethod : public RpcMethod {
  256. private:
  257. template <typename InputIterator>
  258. std::pair<InputIterator, InputIterator>
  259. getPaginationRange(int64_t offset, int64_t num, InputIterator first,
  260. InputIterator last)
  261. {
  262. if (num <= 0) {
  263. return std::make_pair(last, last);
  264. }
  265. int64_t size = std::distance(first, last);
  266. if (offset < 0) {
  267. int64_t tempoffset = offset + size;
  268. if (tempoffset < 0) {
  269. return std::make_pair(last, last);
  270. }
  271. offset = tempoffset - (num - 1);
  272. if (offset < 0) {
  273. offset = 0;
  274. num = tempoffset + 1;
  275. }
  276. }
  277. else if (size <= offset) {
  278. return std::make_pair(last, last);
  279. }
  280. int64_t lastDistance;
  281. if (size < offset + num) {
  282. lastDistance = size;
  283. }
  284. else {
  285. lastDistance = offset + num;
  286. }
  287. last = first;
  288. std::advance(first, offset);
  289. std::advance(last, lastDistance);
  290. return std::make_pair(first, last);
  291. }
  292. protected:
  293. typedef IndexedList<a2_gid_t, std::shared_ptr<T>> ItemListType;
  294. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  295. DownloadEngine* e) CXX11_OVERRIDE
  296. {
  297. const Integer* offsetParam = checkRequiredParam<Integer>(req, 0);
  298. const Integer* numParam = checkRequiredInteger(req, 1, IntegerGE(0));
  299. const List* keysParam = checkParam<List>(req, 2);
  300. int64_t offset = offsetParam->i();
  301. int64_t num = numParam->i();
  302. std::vector<std::string> keys;
  303. toStringList(std::back_inserter(keys), keysParam);
  304. const ItemListType& items = getItems(e);
  305. auto range =
  306. getPaginationRange(offset, num, std::begin(items), std::end(items));
  307. auto list = List::g();
  308. for (; range.first != range.second; ++range.first) {
  309. auto entryDict = Dict::g();
  310. createEntry(entryDict.get(), *range.first, e, keys);
  311. list->append(std::move(entryDict));
  312. }
  313. if (offset < 0) {
  314. std::reverse(list->begin(), list->end());
  315. }
  316. return std::move(list);
  317. }
  318. virtual const ItemListType& getItems(DownloadEngine* e) const = 0;
  319. virtual void createEntry(Dict* entryDict, const std::shared_ptr<T>& item,
  320. DownloadEngine* e,
  321. const std::vector<std::string>& keys) const = 0;
  322. };
  323. class TellWaitingRpcMethod : public AbstractPaginationRpcMethod<RequestGroup> {
  324. protected:
  325. virtual const RequestGroupList&
  326. getItems(DownloadEngine* e) const CXX11_OVERRIDE;
  327. virtual void
  328. createEntry(Dict* entryDict, const std::shared_ptr<RequestGroup>& item,
  329. DownloadEngine* e,
  330. const std::vector<std::string>& keys) const CXX11_OVERRIDE;
  331. public:
  332. static const char* getMethodName() { return "aria2.tellWaiting"; }
  333. };
  334. class TellStoppedRpcMethod
  335. : public AbstractPaginationRpcMethod<DownloadResult> {
  336. protected:
  337. virtual const DownloadResultList&
  338. getItems(DownloadEngine* e) const CXX11_OVERRIDE;
  339. virtual void
  340. createEntry(Dict* entryDict, const std::shared_ptr<DownloadResult>& item,
  341. DownloadEngine* e,
  342. const std::vector<std::string>& keys) const CXX11_OVERRIDE;
  343. public:
  344. static const char* getMethodName() { return "aria2.tellStopped"; }
  345. };
  346. class ChangeOptionRpcMethod : public RpcMethod {
  347. protected:
  348. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  349. DownloadEngine* e) CXX11_OVERRIDE;
  350. public:
  351. static const char* getMethodName() { return "aria2.changeOption"; }
  352. };
  353. class ChangeGlobalOptionRpcMethod : public RpcMethod {
  354. protected:
  355. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  356. DownloadEngine* e) CXX11_OVERRIDE;
  357. public:
  358. static const char* getMethodName() { return "aria2.changeGlobalOption"; }
  359. };
  360. class GetVersionRpcMethod : public RpcMethod {
  361. protected:
  362. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  363. DownloadEngine* e) CXX11_OVERRIDE;
  364. public:
  365. static const char* getMethodName() { return "aria2.getVersion"; }
  366. };
  367. class GetOptionRpcMethod : public RpcMethod {
  368. protected:
  369. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  370. DownloadEngine* e) CXX11_OVERRIDE;
  371. public:
  372. static const char* getMethodName() { return "aria2.getOption"; }
  373. };
  374. class GetGlobalOptionRpcMethod : public RpcMethod {
  375. protected:
  376. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  377. DownloadEngine* e) CXX11_OVERRIDE;
  378. public:
  379. static const char* getMethodName() { return "aria2.getGlobalOption"; }
  380. };
  381. class ChangePositionRpcMethod : public RpcMethod {
  382. protected:
  383. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  384. DownloadEngine* e) CXX11_OVERRIDE;
  385. public:
  386. static const char* getMethodName() { return "aria2.changePosition"; }
  387. };
  388. class ChangeUriRpcMethod : public RpcMethod {
  389. protected:
  390. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  391. DownloadEngine* e) CXX11_OVERRIDE;
  392. public:
  393. static const char* getMethodName() { return "aria2.changeUri"; }
  394. };
  395. class GetSessionInfoRpcMethod : public RpcMethod {
  396. protected:
  397. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  398. DownloadEngine* e) CXX11_OVERRIDE;
  399. public:
  400. static const char* getMethodName() { return "aria2.getSessionInfo"; }
  401. };
  402. class ShutdownRpcMethod : public RpcMethod {
  403. protected:
  404. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  405. DownloadEngine* e) CXX11_OVERRIDE;
  406. public:
  407. static const char* getMethodName() { return "aria2.shutdown"; }
  408. };
  409. class GetGlobalStatRpcMethod : public RpcMethod {
  410. protected:
  411. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  412. DownloadEngine* e) CXX11_OVERRIDE;
  413. public:
  414. static const char* getMethodName() { return "aria2.getGlobalStat"; }
  415. };
  416. class ForceShutdownRpcMethod : public RpcMethod {
  417. protected:
  418. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  419. DownloadEngine* e) CXX11_OVERRIDE;
  420. public:
  421. static const char* getMethodName() { return "aria2.forceShutdown"; }
  422. };
  423. class SaveSessionRpcMethod : public RpcMethod {
  424. protected:
  425. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  426. DownloadEngine* e) CXX11_OVERRIDE;
  427. public:
  428. static const char* getMethodName() { return "aria2.saveSession"; }
  429. };
  430. class SystemMulticallRpcMethod : public RpcMethod {
  431. protected:
  432. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  433. DownloadEngine* e) CXX11_OVERRIDE;
  434. public:
  435. virtual RpcResponse execute(RpcRequest req, DownloadEngine* e) CXX11_OVERRIDE;
  436. static const char* getMethodName() { return "system.multicall"; }
  437. };
  438. class SystemListMethodsRpcMethod : public RpcMethod {
  439. protected:
  440. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  441. DownloadEngine* e) CXX11_OVERRIDE;
  442. public:
  443. virtual RpcResponse execute(RpcRequest req, DownloadEngine* e) CXX11_OVERRIDE;
  444. static const char* getMethodName() { return "system.listMethods"; }
  445. };
  446. class SystemListNotificationsRpcMethod : public RpcMethod {
  447. protected:
  448. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  449. DownloadEngine* e) CXX11_OVERRIDE;
  450. public:
  451. virtual RpcResponse execute(RpcRequest req, DownloadEngine* e) CXX11_OVERRIDE;
  452. static const char* getMethodName() { return "system.listNotifications"; }
  453. };
  454. class NoSuchMethodRpcMethod : public RpcMethod {
  455. protected:
  456. virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
  457. DownloadEngine* e) CXX11_OVERRIDE;
  458. };
  459. // Helper function to store data to entryDict from ds. This function
  460. // is used by tellStatus method.
  461. void gatherStoppedDownload(Dict* entryDict,
  462. const std::shared_ptr<DownloadResult>& ds,
  463. const std::vector<std::string>& keys);
  464. // Helper function to store data to entryDict from group. This
  465. // function is used by tellStatus/tellActive/tellWaiting method
  466. void gatherProgressCommon(Dict* entryDict,
  467. const std::shared_ptr<RequestGroup>& group,
  468. const std::vector<std::string>& keys);
  469. #ifdef ENABLE_BITTORRENT
  470. // Helper function to store BitTorrent metadata from torrentAttrs.
  471. void gatherBitTorrentMetadata(Dict* btDict, TorrentAttribute* torrentAttrs);
  472. #endif // ENABLE_BITTORRENT
  473. } // namespace rpc
  474. bool pauseRequestGroup(const std::shared_ptr<RequestGroup>& group,
  475. bool reserved, bool forcePause);
  476. void changeOption(const std::shared_ptr<RequestGroup>& group,
  477. const Option& option, DownloadEngine* e);
  478. void changeGlobalOption(const Option& option, DownloadEngine* e);
  479. } // namespace aria2
  480. #endif // D_RPC_METHOD_IMPL_H