Merge branch 'sonnyp-system.listNotifications'

pull/629/head
Tatsuhiro Tsujikawa 2016-04-15 23:31:17 +09:00
commit 7105ce31f2
8 changed files with 140 additions and 36 deletions

View File

@ -36,5 +36,6 @@ luokar
mozillazg
multisnow
oliviercommelarbre
Sonny Piers
[1] https://gist.github.com/tatsuhiro-t/deaffeb064652104ad11

View File

@ -2262,9 +2262,8 @@ to provide the token as the first parameter as described above.
interface. Therefore it is recommended to prefer Batch or `system.multicall`
requests when appropriate.
`system.listMethods` can be executed without token. Since it just
returns the all available methods, and does not alter anything, it
is safe without secret token.
`system.listMethods` and `system.listNotifications` can be executed without token. Since they just
return available methods/notifications, they do not alter anything, they're safe without secret token.
Methods
~~~~~~~
@ -3478,9 +3477,9 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
.. function:: system.listMethods()
This method returns the all available RPC methods in an array of
This method returns all the available RPC methods in an array of
string. Unlike other methods, this method does not require secret
token. This is safe because this method jsut returns the available
token. This is safe because this method just returns the available
method names.
**JSON-RPC Example**
@ -3506,6 +3505,36 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
>>> s.system.listMethods()
['aria2.addUri', 'aria2.addTorrent', ...
.. function:: system.listNotifications()
This method returns all the available RPC notifications in an array of
string. Unlike other methods, this method does not require secret
token. This is safe because this method just returns the available
notifications names.
**JSON-RPC Example**
::
>>> import urllib2, json
>>> from pprint import pprint
>>> jsonreq = json.dumps({'jsonrpc':'2.0', 'id':'qwer',
... 'method':'system.listNotifications'})
>>> c = urllib2.urlopen('http://localhost:6800/jsonrpc', jsonreq)
>>> pprint(json.loads(c.read()))
{u'id': u'qwer',
u'jsonrpc': u'2.0',
u'result': [u'aria2.onDownloadStart',
u'aria2.onDownloadPause',
...
**XML-RPC Example**
::
>>> import xmlrpclib
>>> s = xmlrpclib.ServerProxy('http://localhost:6800/rpc')
>>> s.system.listNotifications()
['aria2.onDownloadStart', 'aria2.onDownloadPause', ...
Error Handling
~~~~~~~~~~~~~~

View File

@ -623,7 +623,7 @@ void OptimizeConcurrentDownloadsOptionHandler::parseArg(
PrefPtr pref = PREF_OPTIMIZE_CONCURRENT_DOWNLOADS_COEFFA;
std::string* sptr = &coeff_a;
for (;;) {
char *end;
char* end;
errno = 0;
auto dbl = strtod(sptr->c_str(), &end);
if (errno != 0 || sptr->c_str() + sptr->size() != end) {

View File

@ -68,11 +68,28 @@ std::vector<std::string> rpcMethodNames = {
"aria2.removeDownloadResult", "aria2.getVersion", "aria2.getSessionInfo",
"aria2.shutdown", "aria2.forceShutdown", "aria2.getGlobalStat",
"aria2.saveSession", "system.multicall", "system.listMethods",
"system.listNotifications",
};
} // namespace
const std::vector<std::string>& allMethodNames() { return rpcMethodNames; }
namespace {
std::vector<std::string> rpcNotificationsNames = {
"aria2.onDownloadStart", "aria2.onDownloadPause",
"aria2.onDownloadStop", "aria2.onDownloadComplete",
"aria2.onDownloadError",
#ifdef ENABLE_BITTORRENT
"aria2.onBtDownloadComplete",
#endif // ENABLE_BITTORRENT
};
} // namespace
const std::vector<std::string>& allNotificationsNames()
{
return rpcNotificationsNames;
}
namespace {
std::unique_ptr<RpcMethod> createMethod(const std::string& methodName)
{
@ -220,6 +237,10 @@ std::unique_ptr<RpcMethod> createMethod(const std::string& methodName)
return make_unique<SystemListMethodsRpcMethod>();
}
if (methodName == SystemListNotificationsRpcMethod::getMethodName()) {
return make_unique<SystemListNotificationsRpcMethod>();
}
return nullptr;
}
} // namespace

View File

@ -49,6 +49,8 @@ class RpcMethod;
const std::vector<std::string>& allMethodNames();
const std::vector<std::string>& allNotificationsNames();
RpcMethod* getMethod(const std::string& methodName);
} // namespace rpc

View File

@ -1451,6 +1451,26 @@ RpcResponse SystemListMethodsRpcMethod::execute(RpcRequest req,
std::move(req.id));
}
std::unique_ptr<ValueBase>
SystemListNotificationsRpcMethod::process(const RpcRequest& req,
DownloadEngine* e)
{
auto list = List::g();
for (auto& s : allNotificationsNames()) {
list->append(s);
}
return std::move(list);
}
RpcResponse SystemListNotificationsRpcMethod::execute(RpcRequest req,
DownloadEngine* e)
{
auto r = process(req, e);
return RpcResponse(0, RpcResponse::AUTHORIZED, std::move(r),
std::move(req.id));
}
std::unique_ptr<ValueBase> NoSuchMethodRpcMethod::process(const RpcRequest& req,
DownloadEngine* e)
{

View File

@ -537,6 +537,17 @@ public:
static const char* getMethodName() { return "system.listMethods"; }
};
class SystemListNotificationsRpcMethod : public RpcMethod {
protected:
virtual std::unique_ptr<ValueBase> 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<ValueBase> process(const RpcRequest& req,

View File

@ -80,6 +80,7 @@ class RpcMethodTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testSystemMulticall);
CPPUNIT_TEST(testSystemMulticall_fail);
CPPUNIT_TEST(testSystemListMethods);
CPPUNIT_TEST(testSystemListNotifications);
CPPUNIT_TEST_SUITE_END();
private:
@ -146,6 +147,7 @@ public:
void testSystemMulticall();
void testSystemMulticall_fail();
void testSystemListMethods();
void testSystemListNotifications();
};
CPPUNIT_TEST_SUITE_REGISTRATION(RpcMethodTest);
@ -1396,6 +1398,24 @@ void RpcMethodTest::testSystemListMethods()
}
}
void RpcMethodTest::testSystemListNotifications()
{
SystemListNotificationsRpcMethod m;
auto res = m.execute(createReq("system.listNotifications"), e_.get());
CPPUNIT_ASSERT_EQUAL(0, res.code);
const auto resParams = downcast<List>(res.param);
auto& allNames = allNotificationsNames();
CPPUNIT_ASSERT_EQUAL(allNames.size(), resParams->size());
for (size_t i = 0; i < allNames.size(); ++i) {
const auto s = downcast<String>(resParams->get(i));
CPPUNIT_ASSERT(s);
CPPUNIT_ASSERT_EQUAL(allNames[i], s->s());
}
}
} // namespace rpc
} // namespace aria2