diff --git a/ChangeLog b/ChangeLog index fe08fa48..a1b4559c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2009-05-09 Tatsuhiro Tsujikawa + + Return fault structure for error. FailXmlRpcMethod is renamed as + NoSuchMethodXmlRpcMethod. pieceLength and numPieces are returned + in non-torrent download. Return single param value. + * src/XmlRpcMethod.cc + * src/XmlRpcMethodFactory.cc + * src/XmlRpcMethodImpl.cc + * src/XmlRpcMethodImpl.h + * test/XmlRpcMethodTest.cc + 2009-05-09 Tatsuhiro Tsujikawa Set DownloadResult::IN_PROGRESS for downloads removed by xml-rpc diff --git a/src/XmlRpcMethod.cc b/src/XmlRpcMethod.cc index f626286a..896268cb 100644 --- a/src/XmlRpcMethod.cc +++ b/src/XmlRpcMethod.cc @@ -59,9 +59,9 @@ XmlRpcMethod::XmlRpcMethod(): static BDE createErrorResponse(const Exception& e) { - BDE params = BDE::list(); - params << BDE("ERROR"); - params << BDE(e.what()); + BDE params = BDE::dict(); + params["faultCode"] = BDE(1); + params["faultString"] = BDE(e.what()); return params; } @@ -97,6 +97,8 @@ static void encodeValue(const BDE& value, std::ostream& o) o << ""; if(value.isString()) { o << "" << value.s() << ""; + } else if(value.isInteger()) { + o << "" << value.i() << ""; } else if(value.isList()) { encodeArray(value.listBegin(), value.listEnd(), o); } else if(value.isDict()) { @@ -128,6 +130,23 @@ static std::string encodeXml(const BDE& params) return o.str(); } +static void encodeFault(const BDE& faultValue, std::ostream& o) +{ + o << ""; + encodeValue(faultValue, o); + o << ""; +} + +static std::string encodeErrorXml(const BDE& faultValue) +{ + assert(faultValue.isDict()); + std::stringstream o; + o << "" << ""; + encodeFault(faultValue, o); + o << ""; + return o.str(); +} + std::string XmlRpcMethod::execute(const XmlRpcRequest& req, DownloadEngine* e) { try { @@ -135,7 +154,7 @@ std::string XmlRpcMethod::execute(const XmlRpcRequest& req, DownloadEngine* e) return encodeXml(retparams); } catch(RecoverableException& e) { _logger->debug(EX_EXCEPTION_CAUGHT, e); - return encodeXml(createErrorResponse(e)); + return encodeErrorXml(createErrorResponse(e)); } } diff --git a/src/XmlRpcMethodFactory.cc b/src/XmlRpcMethodFactory.cc index f676170d..3ccc8c47 100644 --- a/src/XmlRpcMethodFactory.cc +++ b/src/XmlRpcMethodFactory.cc @@ -53,7 +53,7 @@ XmlRpcMethodFactory::create(const std::string& methodName) } else if(methodName == "aria2.tellActiveStatus") { return SharedHandle(new TellActiveStatusXmlRpcMethod()); } else { - return SharedHandle(new FailXmlRpcMethod()); + return SharedHandle(new NoSuchMethodXmlRpcMethod()); } } diff --git a/src/XmlRpcMethodImpl.cc b/src/XmlRpcMethodImpl.cc index 278c0d4c..dba68f7a 100644 --- a/src/XmlRpcMethodImpl.cc +++ b/src/XmlRpcMethodImpl.cc @@ -67,7 +67,6 @@ namespace xmlrpc { static BDE createGIDResponse(int32_t gid) { BDE resParams = BDE::list(); - resParams << BDE("OK"); resParams << BDE(Util::itos(gid)); return resParams; } @@ -152,10 +151,7 @@ BDE RemoveXmlRpcMethod::process(const XmlRpcRequest& req, DownloadEngine* e) group->setHaltRequested(true, RequestGroup::USER_REQUEST); - BDE resParams = BDE::list(); - resParams << BDE("OK"); - resParams << BDE(Util::itos(gid)); - return resParams; + return createGIDResponse(gid); } BDE TellActiveStatusXmlRpcMethod::process @@ -192,15 +188,16 @@ BDE TellActiveStatusXmlRpcMethod::process entryDict["files"] = files; } } + + entryDict["pieceLength"] = + BDE(Util::uitos((*i)->getDownloadContext()->getPieceLength())); + entryDict["numPieces"] = + BDE(Util::uitos((*i)->getDownloadContext()->getNumPieces())); SharedHandle btctx = dynamic_pointer_cast((*i)->getDownloadContext()); if(!btctx.isNull()) { entryDict["infoHash"] = BDE(btctx->getInfoHashAsString()); - entryDict["pieceLength"] = - BDE(Util::uitos((*i)->getDownloadContext()->getPieceLength())); - entryDict["numPieces"] = - BDE(Util::uitos((*i)->getDownloadContext()->getNumPieces())); SharedHandle btreg = e->getBtRegistry(); @@ -228,14 +225,17 @@ BDE TellActiveStatusXmlRpcMethod::process res << entryDict; } - return res; + + BDE resParams = BDE::list(); + resParams << res; + return resParams; } -BDE FailXmlRpcMethod::process(const XmlRpcRequest& req, DownloadEngine* e) +BDE NoSuchMethodXmlRpcMethod::process +(const XmlRpcRequest& req, DownloadEngine* e) { throw DlAbortEx - (StringFormat("Method %s was not recognized.", - req._methodName.c_str()).str()); + (StringFormat("No such method: %s", req._methodName.c_str()).str()); } } // namespace xmlrpc diff --git a/src/XmlRpcMethodImpl.h b/src/XmlRpcMethodImpl.h index 200ea509..22718d73 100644 --- a/src/XmlRpcMethodImpl.h +++ b/src/XmlRpcMethodImpl.h @@ -61,7 +61,7 @@ protected: virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e); }; -class FailXmlRpcMethod:public XmlRpcMethod { +class NoSuchMethodXmlRpcMethod:public XmlRpcMethod { protected: virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e); }; diff --git a/test/XmlRpcMethodTest.cc b/test/XmlRpcMethodTest.cc index 8d7afd88..e807619f 100644 --- a/test/XmlRpcMethodTest.cc +++ b/test/XmlRpcMethodTest.cc @@ -22,6 +22,7 @@ class XmlRpcMethodTest:public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(XmlRpcMethodTest); CPPUNIT_TEST(testAddURI); + CPPUNIT_TEST(testNoSuchMethod); CPPUNIT_TEST_SUITE_END(); private: SharedHandle _e; @@ -40,6 +41,7 @@ public: void tearDown() {} void testAddURI(); + void testNoSuchMethod(); }; @@ -57,7 +59,33 @@ void XmlRpcMethodTest::testAddURI() CPPUNIT_ASSERT_EQUAL((size_t)1, rgs.size()); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/"), rgs.front()->getRemainingUris().front()); - CPPUNIT_ASSERT(res.find("OK") != std::string::npos); +} + +void XmlRpcMethodTest::testNoSuchMethod() +{ + NoSuchMethodXmlRpcMethod m; + XmlRpcRequest req("make.hamburger", BDE::none); + std::string res = m.execute(req, 0); + CPPUNIT_ASSERT_EQUAL + (std::string("" + "" + "" + "" + "" + "" + "faultCode1" + "" + "" + "faultString" + "" + "No such method: make.hamburger" + "" + "" + "" + "" + "" + ""), + res); } } // namespace xmlrpc