RpcMethodImpl.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  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. namespace rpc {
  53. template<typename T>
  54. const T* checkParam(const RpcRequest& req, size_t index, bool required = false)
  55. {
  56. const T* p = 0;
  57. if(req.params->size() > index) {
  58. if((p = downcast<T>(req.params->get(index))) == 0) {
  59. throw DL_ABORT_EX(fmt("The parameter at %lu has wrong type.",
  60. static_cast<unsigned long>(index)));
  61. }
  62. } else if(required) {
  63. throw DL_ABORT_EX(fmt("The parameter at %lu is required but missing.",
  64. static_cast<unsigned long>(index)));
  65. }
  66. return p;
  67. }
  68. template<typename T>
  69. const T* checkRequiredParam(const RpcRequest& req, size_t index)
  70. {
  71. return checkParam<T>(req, index, true);
  72. }
  73. struct IntegerGE {
  74. IntegerGE(int32_t min):min(min) {}
  75. bool operator()(const Integer* param, std::string* error) const
  76. {
  77. if(min <= param->i()) {
  78. return true;
  79. } else {
  80. if(error) {
  81. *error = fmt("the value must be greater than or equal to %d.", min);
  82. }
  83. return false;
  84. }
  85. }
  86. int32_t min;
  87. };
  88. template<typename Validator>
  89. const Integer* checkRequiredInteger(const RpcRequest& req, size_t index,
  90. Validator validator)
  91. {
  92. const Integer* param = checkRequiredParam<Integer>(req, index);
  93. std::string error;
  94. if(!validator(param, &error)) {
  95. throw DL_ABORT_EX(fmt("The integer parameter at %lu has invalid value: %s",
  96. static_cast<unsigned long>(index), error.c_str()));
  97. }
  98. return param;
  99. }
  100. template<typename OutputIterator>
  101. void toStringList(OutputIterator out, const List* src)
  102. {
  103. if(!src) {
  104. return;
  105. }
  106. for(auto & elem : *src) {
  107. const String* s = downcast<String>(elem);
  108. if(s) {
  109. *out++ = s->s();
  110. }
  111. }
  112. }
  113. class AddUriRpcMethod:public RpcMethod {
  114. protected:
  115. virtual std::unique_ptr<ValueBase> process
  116. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  117. public:
  118. static const char* getMethodName()
  119. {
  120. return "aria2.addUri";
  121. }
  122. };
  123. class RemoveRpcMethod:public RpcMethod {
  124. protected:
  125. virtual std::unique_ptr<ValueBase> process
  126. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  127. public:
  128. static const char* getMethodName()
  129. {
  130. return "aria2.remove";
  131. }
  132. };
  133. class ForceRemoveRpcMethod:public RpcMethod {
  134. protected:
  135. virtual std::unique_ptr<ValueBase> process
  136. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  137. public:
  138. static const char* getMethodName()
  139. {
  140. return "aria2.forceRemove";
  141. }
  142. };
  143. class PauseRpcMethod:public RpcMethod {
  144. protected:
  145. virtual std::unique_ptr<ValueBase> process
  146. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  147. public:
  148. static const char* getMethodName()
  149. {
  150. return "aria2.pause";
  151. }
  152. };
  153. class ForcePauseRpcMethod:public RpcMethod {
  154. protected:
  155. virtual std::unique_ptr<ValueBase> process
  156. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  157. public:
  158. static const char* getMethodName()
  159. {
  160. return "aria2.forcePause";
  161. }
  162. };
  163. class PauseAllRpcMethod:public RpcMethod {
  164. protected:
  165. virtual std::unique_ptr<ValueBase> process
  166. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  167. public:
  168. static const char* getMethodName()
  169. {
  170. return "aria2.pauseAll";
  171. }
  172. };
  173. class ForcePauseAllRpcMethod:public RpcMethod {
  174. protected:
  175. virtual std::unique_ptr<ValueBase> process
  176. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  177. public:
  178. static const char* getMethodName()
  179. {
  180. return "aria2.forcePauseAll";
  181. }
  182. };
  183. class UnpauseRpcMethod:public RpcMethod {
  184. protected:
  185. virtual std::unique_ptr<ValueBase> process
  186. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  187. public:
  188. static const char* getMethodName()
  189. {
  190. return "aria2.unpause";
  191. }
  192. };
  193. class UnpauseAllRpcMethod:public RpcMethod {
  194. protected:
  195. virtual std::unique_ptr<ValueBase> process
  196. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  197. public:
  198. static const char* getMethodName()
  199. {
  200. return "aria2.unpauseAll";
  201. }
  202. };
  203. #ifdef ENABLE_BITTORRENT
  204. class AddTorrentRpcMethod:public RpcMethod {
  205. protected:
  206. virtual std::unique_ptr<ValueBase> process
  207. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  208. public:
  209. static const char* getMethodName()
  210. {
  211. return "aria2.addTorrent";
  212. }
  213. };
  214. #endif // ENABLE_BITTORRENT
  215. #ifdef ENABLE_METALINK
  216. class AddMetalinkRpcMethod:public RpcMethod {
  217. protected:
  218. virtual std::unique_ptr<ValueBase> process
  219. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  220. public:
  221. static const char* getMethodName()
  222. {
  223. return "aria2.addMetalink";
  224. }
  225. };
  226. #endif // ENABLE_METALINK
  227. class PurgeDownloadResultRpcMethod:public RpcMethod {
  228. protected:
  229. virtual std::unique_ptr<ValueBase> process
  230. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  231. public:
  232. static const char* getMethodName()
  233. {
  234. return "aria2.purgeDownloadResult";
  235. }
  236. };
  237. class RemoveDownloadResultRpcMethod:public RpcMethod {
  238. protected:
  239. virtual std::unique_ptr<ValueBase> process
  240. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  241. public:
  242. static const char* getMethodName()
  243. {
  244. return "aria2.removeDownloadResult";
  245. }
  246. };
  247. class GetUrisRpcMethod:public RpcMethod {
  248. protected:
  249. virtual std::unique_ptr<ValueBase> process
  250. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  251. public:
  252. static const char* getMethodName()
  253. {
  254. return "aria2.getUris";
  255. }
  256. };
  257. class GetFilesRpcMethod:public RpcMethod {
  258. protected:
  259. virtual std::unique_ptr<ValueBase> process
  260. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  261. public:
  262. static const char* getMethodName()
  263. {
  264. return "aria2.getFiles";
  265. }
  266. };
  267. #ifdef ENABLE_BITTORRENT
  268. class GetPeersRpcMethod:public RpcMethod {
  269. protected:
  270. virtual std::unique_ptr<ValueBase> process
  271. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  272. public:
  273. static const char* getMethodName()
  274. {
  275. return "aria2.getPeers";
  276. }
  277. };
  278. #endif // ENABLE_BITTORRENT
  279. class GetServersRpcMethod:public RpcMethod {
  280. protected:
  281. virtual std::unique_ptr<ValueBase> process
  282. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  283. public:
  284. static const char* getMethodName()
  285. {
  286. return "aria2.getServers";
  287. }
  288. };
  289. class TellStatusRpcMethod:public RpcMethod {
  290. protected:
  291. virtual std::unique_ptr<ValueBase> process
  292. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  293. public:
  294. static const char* getMethodName()
  295. {
  296. return "aria2.tellStatus";
  297. }
  298. };
  299. class TellActiveRpcMethod:public RpcMethod {
  300. protected:
  301. virtual std::unique_ptr<ValueBase> process
  302. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  303. public:
  304. static const char* getMethodName()
  305. {
  306. return "aria2.tellActive";
  307. }
  308. };
  309. template<typename T>
  310. class AbstractPaginationRpcMethod:public RpcMethod {
  311. private:
  312. template<typename InputIterator>
  313. std::pair<InputIterator, InputIterator>
  314. getPaginationRange
  315. (int64_t offset, int64_t num, InputIterator first, InputIterator last)
  316. {
  317. if(num <= 0) {
  318. return std::make_pair(last, last);
  319. }
  320. int64_t size = std::distance(first, last);
  321. if(offset < 0) {
  322. int64_t tempoffset = offset+size;
  323. if(tempoffset < 0) {
  324. return std::make_pair(last, last);
  325. }
  326. offset = tempoffset-(num-1);
  327. if(offset < 0) {
  328. offset = 0;
  329. num = tempoffset+1;
  330. }
  331. } else if(size <= offset) {
  332. return std::make_pair(last, last);
  333. }
  334. int64_t lastDistance;
  335. if(size < offset+num) {
  336. lastDistance = size;
  337. } else {
  338. lastDistance = offset+num;
  339. }
  340. last = first;
  341. std::advance(first, offset);
  342. std::advance(last, lastDistance);
  343. return std::make_pair(first, last);
  344. }
  345. protected:
  346. typedef IndexedList<a2_gid_t, std::shared_ptr<T> > ItemListType;
  347. virtual std::unique_ptr<ValueBase> process
  348. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE
  349. {
  350. const Integer* offsetParam = checkRequiredParam<Integer>(req, 0);
  351. const Integer* numParam = checkRequiredInteger(req, 1, IntegerGE(0));
  352. const List* keysParam = checkParam<List>(req, 2);
  353. int64_t offset = offsetParam->i();
  354. int64_t num = numParam->i();
  355. std::vector<std::string> keys;
  356. toStringList(std::back_inserter(keys), keysParam);
  357. const ItemListType& items = getItems(e);
  358. auto range = getPaginationRange(offset, num,
  359. std::begin(items), std::end(items));
  360. auto list = List::g();
  361. for(; range.first != range.second; ++range.first) {
  362. auto entryDict = Dict::g();
  363. createEntry(entryDict.get(), *range.first, e, keys);
  364. list->append(std::move(entryDict));
  365. }
  366. if(offset < 0) {
  367. std::reverse(list->begin(), list->end());
  368. }
  369. return std::move(list);
  370. }
  371. virtual const ItemListType& getItems(DownloadEngine* e) const = 0;
  372. virtual void createEntry
  373. (Dict* entryDict,
  374. const std::shared_ptr<T>& item,
  375. DownloadEngine* e,
  376. const std::vector<std::string>& keys) const = 0;
  377. };
  378. class TellWaitingRpcMethod:
  379. public AbstractPaginationRpcMethod<RequestGroup> {
  380. protected:
  381. virtual const RequestGroupList& getItems(DownloadEngine* e) const
  382. CXX11_OVERRIDE;
  383. virtual void createEntry
  384. (Dict* entryDict,
  385. const std::shared_ptr<RequestGroup>& item,
  386. DownloadEngine* e,
  387. const std::vector<std::string>& keys) const CXX11_OVERRIDE;
  388. public:
  389. static const char* getMethodName()
  390. {
  391. return "aria2.tellWaiting";
  392. }
  393. };
  394. class TellStoppedRpcMethod:
  395. public AbstractPaginationRpcMethod<DownloadResult> {
  396. protected:
  397. virtual const DownloadResultList& getItems(DownloadEngine* e) const
  398. CXX11_OVERRIDE;
  399. virtual void createEntry
  400. (Dict* entryDict,
  401. const std::shared_ptr<DownloadResult>& item,
  402. DownloadEngine* e,
  403. const std::vector<std::string>& keys) const CXX11_OVERRIDE;
  404. public:
  405. static const char* getMethodName()
  406. {
  407. return "aria2.tellStopped";
  408. }
  409. };
  410. class ChangeOptionRpcMethod:public RpcMethod {
  411. protected:
  412. virtual std::unique_ptr<ValueBase> process
  413. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  414. public:
  415. static const char* getMethodName()
  416. {
  417. return "aria2.changeOption";
  418. }
  419. };
  420. class ChangeGlobalOptionRpcMethod:public RpcMethod {
  421. protected:
  422. virtual std::unique_ptr<ValueBase> process
  423. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  424. public:
  425. static const char* getMethodName()
  426. {
  427. return "aria2.changeGlobalOption";
  428. }
  429. };
  430. class GetVersionRpcMethod:public RpcMethod {
  431. protected:
  432. virtual std::unique_ptr<ValueBase> process
  433. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  434. public:
  435. static const char* getMethodName()
  436. {
  437. return "aria2.getVersion";
  438. }
  439. };
  440. class GetOptionRpcMethod:public RpcMethod {
  441. protected:
  442. virtual std::unique_ptr<ValueBase> process
  443. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  444. public:
  445. static const char* getMethodName()
  446. {
  447. return "aria2.getOption";
  448. }
  449. };
  450. class GetGlobalOptionRpcMethod:public RpcMethod {
  451. protected:
  452. virtual std::unique_ptr<ValueBase> process
  453. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  454. public:
  455. static const char* getMethodName()
  456. {
  457. return "aria2.getGlobalOption";
  458. }
  459. };
  460. class ChangePositionRpcMethod:public RpcMethod {
  461. protected:
  462. virtual std::unique_ptr<ValueBase> process
  463. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  464. public:
  465. static const char* getMethodName()
  466. {
  467. return "aria2.changePosition";
  468. }
  469. };
  470. class ChangeUriRpcMethod:public RpcMethod {
  471. protected:
  472. virtual std::unique_ptr<ValueBase> process
  473. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  474. public:
  475. static const char* getMethodName()
  476. {
  477. return "aria2.changeUri";
  478. }
  479. };
  480. class GetSessionInfoRpcMethod:public RpcMethod {
  481. protected:
  482. virtual std::unique_ptr<ValueBase> process
  483. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  484. public:
  485. static const char* getMethodName()
  486. {
  487. return "aria2.getSessionInfo";
  488. }
  489. };
  490. class ShutdownRpcMethod:public RpcMethod {
  491. protected:
  492. virtual std::unique_ptr<ValueBase> process
  493. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  494. public:
  495. static const char* getMethodName()
  496. {
  497. return "aria2.shutdown";
  498. }
  499. };
  500. class GetGlobalStatRpcMethod:public RpcMethod {
  501. protected:
  502. virtual std::unique_ptr<ValueBase> process
  503. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  504. public:
  505. static const char* getMethodName()
  506. {
  507. return "aria2.getGlobalStat";
  508. }
  509. };
  510. class ForceShutdownRpcMethod:public RpcMethod {
  511. protected:
  512. virtual std::unique_ptr<ValueBase> process
  513. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  514. public:
  515. static const char* getMethodName()
  516. {
  517. return "aria2.forceShutdown";
  518. }
  519. };
  520. class SaveSessionRpcMethod:public RpcMethod {
  521. protected:
  522. virtual std::unique_ptr<ValueBase> process
  523. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  524. public:
  525. static const char* getMethodName()
  526. {
  527. return "aria2.saveSession";
  528. }
  529. };
  530. class SystemMulticallRpcMethod:public RpcMethod {
  531. protected:
  532. virtual std::unique_ptr<ValueBase> process
  533. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  534. public:
  535. virtual void authorize(RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE
  536. {
  537. // Batch calls (e.g., system.multicall) authorizes only nested
  538. // methods. This is because XML-RPC system.multicall only accpets
  539. // methods array and there is no room for us to insert token
  540. // parameter.
  541. }
  542. static const char* getMethodName()
  543. {
  544. return "system.multicall";
  545. }
  546. };
  547. class NoSuchMethodRpcMethod:public RpcMethod {
  548. protected:
  549. virtual std::unique_ptr<ValueBase> process
  550. (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
  551. };
  552. // Helper function to store data to entryDict from ds. This function
  553. // is used by tellStatus method.
  554. void gatherStoppedDownload
  555. (Dict* entryDict, const std::shared_ptr<DownloadResult>& ds,
  556. const std::vector<std::string>& keys);
  557. // Helper function to store data to entryDict from group. This
  558. // function is used by tellStatus/tellActive/tellWaiting method
  559. void gatherProgressCommon
  560. (Dict* entryDict, const std::shared_ptr<RequestGroup>& group,
  561. const std::vector<std::string>& keys);
  562. #ifdef ENABLE_BITTORRENT
  563. // Helper function to store BitTorrent metadata from torrentAttrs.
  564. void gatherBitTorrentMetadata(Dict* btDict, TorrentAttribute* torrentAttrs);
  565. #endif // ENABLE_BITTORRENT
  566. } // namespace rpc
  567. bool pauseRequestGroup
  568. (const std::shared_ptr<RequestGroup>& group, bool reserved, bool forcePause);
  569. void changeOption
  570. (const std::shared_ptr<RequestGroup>& group,
  571. const Option& option,
  572. DownloadEngine* e);
  573. void changeGlobalOption(const Option& option, DownloadEngine* e);
  574. } // namespace aria2
  575. #endif // D_RPC_METHOD_IMPL_H