Moved jsonRpc flag from RpcMethod to RpcRequest.

Now RpcMethod is stateless, so we can cache and reuse them.
pull/1/head
Tatsuhiro Tsujikawa 2011-06-15 00:19:07 +09:00
parent ba9673be1d
commit 2d92571cf9
6 changed files with 24 additions and 32 deletions

View File

@ -179,6 +179,7 @@ HttpServerBodyCommand::processJsonRpcRequest(const Dict* jsondict)
return createJsonRpcErrorResponse(-32602, "Invalid params.", id); return createJsonRpcErrorResponse(-32602, "Invalid params.", id);
} }
rpc::RpcRequest req(methodName->s(), params, id); rpc::RpcRequest req(methodName->s(), params, id);
req.jsonRpc = true;
SharedHandle<rpc::RpcMethod> method; SharedHandle<rpc::RpcMethod> method;
try { try {
method = rpc::RpcMethodFactory::create(req.methodName); method = rpc::RpcMethodFactory::create(req.methodName);
@ -186,7 +187,6 @@ HttpServerBodyCommand::processJsonRpcRequest(const Dict* jsondict)
A2_LOG_INFO_EX(EX_EXCEPTION_CAUGHT, e); A2_LOG_INFO_EX(EX_EXCEPTION_CAUGHT, e);
return createJsonRpcErrorResponse(-32601, "Method not found.", id); return createJsonRpcErrorResponse(-32601, "Method not found.", id);
} }
method->setJsonRpc(true);
A2_LOG_INFO(fmt("Executing RPC method %s", req.methodName.c_str())); A2_LOG_INFO(fmt("Executing RPC method %s", req.methodName.c_str()));
rpc::RpcResponse res = method->execute(req, e_); rpc::RpcResponse res = method->execute(req, e_);
return res; return res;

View File

@ -53,18 +53,17 @@ namespace aria2 {
namespace rpc { namespace rpc {
RpcMethod::RpcMethod() RpcMethod::RpcMethod()
: optionParser_(OptionParser::getInstance()), : optionParser_(OptionParser::getInstance())
jsonRpc_(false)
{} {}
RpcMethod::~RpcMethod() {} RpcMethod::~RpcMethod() {}
SharedHandle<ValueBase> RpcMethod::createErrorResponse SharedHandle<ValueBase> RpcMethod::createErrorResponse
(const Exception& e) (const Exception& e, const RpcRequest& req)
{ {
SharedHandle<Dict> params = Dict::g(); SharedHandle<Dict> params = Dict::g();
params->put((jsonRpc_ ? "code" : "faultCode"), Integer::g(1)); params->put((req.jsonRpc ? "code" : "faultCode"), Integer::g(1));
params->put((jsonRpc_ ? "message" : "faultString"), std::string(e.what())); params->put((req.jsonRpc ? "message" : "faultString"), std::string(e.what()));
return params; return params;
} }
@ -73,9 +72,9 @@ RpcResponse RpcMethod::execute
{ {
try { try {
return RpcResponse(0, process(req, e), req.id); return RpcResponse(0, process(req, e), req.id);
} catch(RecoverableException& e) { } catch(RecoverableException& ex) {
A2_LOG_DEBUG_EX(EX_EXCEPTION_CAUGHT, e); A2_LOG_DEBUG_EX(EX_EXCEPTION_CAUGHT, ex);
return RpcResponse(1, createErrorResponse(e), req.id); return RpcResponse(1, createErrorResponse(ex, req), req.id);
} }
} }

View File

@ -56,7 +56,8 @@ struct RpcResponse;
// This class offers abstract implementation of processing RPC // This class offers abstract implementation of processing RPC
// request. You have to inherit this class and implement process() // request. You have to inherit this class and implement process()
// method to add new RPC API. // method to add new RPC API. The derived class must be stateless
// since we reuse the instances.
// //
// There is RpcMethodFactory class which instantiates RpcMethod // There is RpcMethodFactory class which instantiates RpcMethod
// subclass. If you add new RpcMethod subclass, don't forget to add it // subclass. If you add new RpcMethod subclass, don't forget to add it
@ -64,7 +65,6 @@ struct RpcResponse;
class RpcMethod { class RpcMethod {
private: private:
SharedHandle<OptionParser> optionParser_; SharedHandle<OptionParser> optionParser_;
bool jsonRpc_;
protected: protected:
// Subclass must implement this function to fulfil RpcRequest req. // Subclass must implement this function to fulfil RpcRequest req.
// The return value of this method is used as a return value of RPC // The return value of this method is used as a return value of RPC
@ -89,7 +89,8 @@ protected:
// command to dest. // command to dest.
void applyChangeableGlobalOption(Option* dest, Option* src) const; void applyChangeableGlobalOption(Option* dest, Option* src) const;
SharedHandle<ValueBase> createErrorResponse(const Exception& e); SharedHandle<ValueBase> createErrorResponse
(const Exception& e, const RpcRequest& req);
const SharedHandle<OptionParser>& getOptionParser() const const SharedHandle<OptionParser>& getOptionParser() const
{ {
@ -103,15 +104,6 @@ public:
// Do work to fulfill RpcRequest req and returns its result as // Do work to fulfill RpcRequest req and returns its result as
// RpcResponse. This method delegates to process() method. // RpcResponse. This method delegates to process() method.
RpcResponse execute(const RpcRequest& req, DownloadEngine* e); RpcResponse execute(const RpcRequest& req, DownloadEngine* e);
// Set whether JSON-RPC style parameter handling.
void setJsonRpc(bool f)
{
jsonRpc_ = f;
}
bool getJsonRpc() const
{
return jsonRpc_;
}
}; };
} // namespace rpc } // namespace rpc

View File

@ -270,7 +270,7 @@ SharedHandle<ValueBase> AddTorrentRpcMethod::process
throw DL_ABORT_EX("Torrent data is not provided."); throw DL_ABORT_EX("Torrent data is not provided.");
} }
SharedHandle<String> tempTorrentParam; SharedHandle<String> tempTorrentParam;
if(getJsonRpc()) { if(req.jsonRpc) {
tempTorrentParam = String::g(Base64::decode(torrentParam->s())); tempTorrentParam = String::g(Base64::decode(torrentParam->s()));
torrentParam = tempTorrentParam.get(); torrentParam = tempTorrentParam.get();
} }
@ -317,7 +317,7 @@ SharedHandle<ValueBase> AddMetalinkRpcMethod::process
throw DL_ABORT_EX("Metalink data is not provided."); throw DL_ABORT_EX("Metalink data is not provided.");
} }
SharedHandle<String> tempMetalinkParam; SharedHandle<String> tempMetalinkParam;
if(getJsonRpc()) { if(req.jsonRpc) {
tempMetalinkParam = String::g(Base64::decode(metalinkParam->s())); tempMetalinkParam = String::g(Base64::decode(metalinkParam->s()));
metalinkParam = tempMetalinkParam.get(); metalinkParam = tempMetalinkParam.get();
} }
@ -1376,7 +1376,7 @@ SharedHandle<ValueBase> SystemMulticallRpcMethod::process
const Dict* methodDict = asDict(*i); const Dict* methodDict = asDict(*i);
if(!methodDict) { if(!methodDict) {
list->append(createErrorResponse list->append(createErrorResponse
(DL_ABORT_EX("system.multicall expected struct."))); (DL_ABORT_EX("system.multicall expected struct."), req));
continue; continue;
} }
const String* methodName = asString(methodDict->get(KEY_METHOD_NAME)); const String* methodName = asString(methodDict->get(KEY_METHOD_NAME));
@ -1384,18 +1384,18 @@ SharedHandle<ValueBase> SystemMulticallRpcMethod::process
if(!methodName || !paramsList) { if(!methodName || !paramsList) {
list->append(createErrorResponse list->append(createErrorResponse
(DL_ABORT_EX("Missing methodName or params."))); (DL_ABORT_EX("Missing methodName or params."), req));
continue; continue;
} }
if(methodName->s() == getMethodName()) { if(methodName->s() == getMethodName()) {
list->append(createErrorResponse list->append(createErrorResponse
(DL_ABORT_EX("Recursive system.multicall forbidden."))); (DL_ABORT_EX("Recursive system.multicall forbidden."), req));
continue; continue;
} }
SharedHandle<RpcMethod> method = RpcMethodFactory::create(methodName->s()); SharedHandle<RpcMethod> method = RpcMethodFactory::create(methodName->s());
method->setJsonRpc(getJsonRpc());
RpcRequest innerReq RpcRequest innerReq
(methodName->s(), static_pointer_cast<List>(methodDict->get(KEY_PARAMS))); (methodName->s(), static_pointer_cast<List>(methodDict->get(KEY_PARAMS)));
innerReq.jsonRpc = req.jsonRpc;
RpcResponse res = method->execute(innerReq, e); RpcResponse res = method->execute(innerReq, e);
if(res.code == 0) { if(res.code == 0) {
SharedHandle<List> l = List::g(); SharedHandle<List> l = List::g();

View File

@ -40,13 +40,13 @@ namespace rpc {
RpcRequest::RpcRequest(const std::string& methodName, RpcRequest::RpcRequest(const std::string& methodName,
const SharedHandle<List>& params) const SharedHandle<List>& params)
: methodName(methodName), params(params) : methodName(methodName), params(params), jsonRpc(false)
{} {}
RpcRequest::RpcRequest(const std::string& methodName, RpcRequest::RpcRequest(const std::string& methodName,
const SharedHandle<List>& params, const SharedHandle<List>& params,
const SharedHandle<ValueBase>& id) const SharedHandle<ValueBase>& id)
: methodName(methodName), params(params), id(id) : methodName(methodName), params(params), id(id), jsonRpc(false)
{} {}
RpcRequest::RpcRequest(const RpcRequest& c) RpcRequest::RpcRequest(const RpcRequest& c)

View File

@ -49,13 +49,14 @@ struct RpcRequest {
std::string methodName; std::string methodName;
SharedHandle<List> params; SharedHandle<List> params;
SharedHandle<ValueBase> id; SharedHandle<ValueBase> id;
bool jsonRpc;
RpcRequest(const std::string& methodName, RpcRequest(const std::string& methodName,
const SharedHandle<List>& params); const SharedHandle<List>& params);
RpcRequest(const std::string& methodName, RpcRequest(const std::string& methodName,
const SharedHandle<List>& params, const SharedHandle<List>& params,
const SharedHandle<ValueBase>& id); const SharedHandle<ValueBase>& id);
~RpcRequest(); ~RpcRequest();