/* */ #ifndef D_RPC_METHOD_IMPL_H #define D_RPC_METHOD_IMPL_H #include "RpcMethod.h" #include #include #include #include "RpcRequest.h" #include "ValueBase.h" #include "TorrentAttribute.h" #include "DlAbortEx.h" #include "fmt.h" #include "IndexedList.h" #include "GroupId.h" #include "RequestGroupMan.h" namespace aria2 { struct DownloadResult; class RequestGroup; class CheckIntegrityEntry; namespace rpc { template const T* checkParam(const RpcRequest& req, size_t index, bool required = false) { const T* p = 0; if (req.params->size() > index) { if ((p = downcast(req.params->get(index))) == 0) { throw DL_ABORT_EX(fmt("The parameter at %lu has wrong type.", static_cast(index))); } } else if (required) { throw DL_ABORT_EX(fmt("The parameter at %lu is required but missing.", static_cast(index))); } return p; } template const T* checkRequiredParam(const RpcRequest& req, size_t index) { return checkParam(req, index, true); } struct IntegerGE { IntegerGE(int32_t min) : min(min) {} bool operator()(const Integer* param, std::string* error) const { if (min <= param->i()) { return true; } else { if (error) { *error = fmt("the value must be greater than or equal to %d.", min); } return false; } } int32_t min; }; template const Integer* checkRequiredInteger(const RpcRequest& req, size_t index, Validator validator) { const Integer* param = checkRequiredParam(req, index); std::string error; if (!validator(param, &error)) { throw DL_ABORT_EX(fmt("The integer parameter at %lu has invalid value: %s", static_cast(index), error.c_str())); } return param; } template void toStringList(OutputIterator out, const List* src) { if (!src) { return; } for (auto& elem : *src) { const String* s = downcast(elem); if (s) { *out++ = s->s(); } } } class AddUriRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.addUri"; } }; class RemoveRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.remove"; } }; class ForceRemoveRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.forceRemove"; } }; class PauseRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.pause"; } }; class ForcePauseRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.forcePause"; } }; class PauseAllRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.pauseAll"; } }; class ForcePauseAllRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.forcePauseAll"; } }; class UnpauseRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.unpause"; } }; class UnpauseAllRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.unpauseAll"; } }; #ifdef ENABLE_BITTORRENT class AddTorrentRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.addTorrent"; } }; #endif // ENABLE_BITTORRENT #ifdef ENABLE_METALINK class AddMetalinkRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.addMetalink"; } }; #endif // ENABLE_METALINK class PurgeDownloadResultRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.purgeDownloadResult"; } }; class RemoveDownloadResultRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.removeDownloadResult"; } }; class GetUrisRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.getUris"; } }; class GetFilesRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.getFiles"; } }; #ifdef ENABLE_BITTORRENT class GetPeersRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.getPeers"; } }; #endif // ENABLE_BITTORRENT class GetServersRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.getServers"; } }; class TellStatusRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.tellStatus"; } }; class TellActiveRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.tellActive"; } }; template class AbstractPaginationRpcMethod : public RpcMethod { private: template std::pair getPaginationRange(int64_t offset, int64_t num, InputIterator first, InputIterator last) { if (num <= 0) { return std::make_pair(last, last); } int64_t size = std::distance(first, last); if (offset < 0) { int64_t tempoffset = offset + size; if (tempoffset < 0) { return std::make_pair(last, last); } offset = tempoffset - (num - 1); if (offset < 0) { offset = 0; num = tempoffset + 1; } } else if (size <= offset) { return std::make_pair(last, last); } int64_t lastDistance; if (size < offset + num) { lastDistance = size; } else { lastDistance = offset + num; } last = first; std::advance(first, offset); std::advance(last, lastDistance); return std::make_pair(first, last); } protected: typedef IndexedList> ItemListType; virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE { const Integer* offsetParam = checkRequiredParam(req, 0); const Integer* numParam = checkRequiredInteger(req, 1, IntegerGE(0)); const List* keysParam = checkParam(req, 2); int64_t offset = offsetParam->i(); int64_t num = numParam->i(); std::vector keys; toStringList(std::back_inserter(keys), keysParam); const ItemListType& items = getItems(e); auto range = getPaginationRange(offset, num, std::begin(items), std::end(items)); auto list = List::g(); for (; range.first != range.second; ++range.first) { auto entryDict = Dict::g(); createEntry(entryDict.get(), *range.first, e, keys); list->append(std::move(entryDict)); } if (offset < 0) { std::reverse(list->begin(), list->end()); } return std::move(list); } virtual const ItemListType& getItems(DownloadEngine* e) const = 0; virtual void createEntry(Dict* entryDict, const std::shared_ptr& item, DownloadEngine* e, const std::vector& keys) const = 0; }; class TellWaitingRpcMethod : public AbstractPaginationRpcMethod { protected: virtual const RequestGroupList& getItems(DownloadEngine* e) const CXX11_OVERRIDE; virtual void createEntry(Dict* entryDict, const std::shared_ptr& item, DownloadEngine* e, const std::vector& keys) const CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.tellWaiting"; } }; class TellStoppedRpcMethod : public AbstractPaginationRpcMethod { protected: virtual const DownloadResultList& getItems(DownloadEngine* e) const CXX11_OVERRIDE; virtual void createEntry(Dict* entryDict, const std::shared_ptr& item, DownloadEngine* e, const std::vector& keys) const CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.tellStopped"; } }; class ChangeOptionRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.changeOption"; } }; class ChangeGlobalOptionRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.changeGlobalOption"; } }; class GetVersionRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.getVersion"; } }; class GetOptionRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.getOption"; } }; class GetGlobalOptionRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.getGlobalOption"; } }; class ChangePositionRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.changePosition"; } }; class ChangeUriRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.changeUri"; } }; class GetSessionInfoRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.getSessionInfo"; } }; class ShutdownRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.shutdown"; } }; class GetGlobalStatRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.getGlobalStat"; } }; class ForceShutdownRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.forceShutdown"; } }; class SaveSessionRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: static const char* getMethodName() { return "aria2.saveSession"; } }; class SystemMulticallRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: virtual RpcResponse execute(RpcRequest req, DownloadEngine* e) CXX11_OVERRIDE; static const char* getMethodName() { return "system.multicall"; } }; class SystemListMethodsRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: virtual RpcResponse execute(RpcRequest req, DownloadEngine* e) CXX11_OVERRIDE; static const char* getMethodName() { return "system.listMethods"; } }; class SystemListNotificationsRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; public: virtual RpcResponse execute(RpcRequest req, DownloadEngine* e) CXX11_OVERRIDE; static const char* getMethodName() { return "system.listNotifications"; } }; class NoSuchMethodRpcMethod : public RpcMethod { protected: virtual std::unique_ptr process(const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE; }; // Helper function to store data to entryDict from ds. This function // is used by tellStatus method. void gatherStoppedDownload(Dict* entryDict, const std::shared_ptr& ds, const std::vector& keys); // Helper function to store data to entryDict from group. This // function is used by tellStatus/tellActive/tellWaiting method void gatherProgressCommon(Dict* entryDict, const std::shared_ptr& group, const std::vector& keys); #ifdef ENABLE_BITTORRENT // Helper function to store BitTorrent metadata from torrentAttrs. void gatherBitTorrentMetadata(Dict* btDict, TorrentAttribute* torrentAttrs); #endif // ENABLE_BITTORRENT } // namespace rpc bool pauseRequestGroup(const std::shared_ptr& group, bool reserved, bool forcePause); void changeOption(const std::shared_ptr& group, const Option& option, DownloadEngine* e); void changeGlobalOption(const Option& option, DownloadEngine* e); } // namespace aria2 #endif // D_RPC_METHOD_IMPL_H