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

View File

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

View File

@ -56,7 +56,8 @@ struct RpcResponse;
// This class offers abstract implementation of processing RPC
// 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
// subclass. If you add new RpcMethod subclass, don't forget to add it
@ -64,7 +65,6 @@ struct RpcResponse;
class RpcMethod {
private:
SharedHandle<OptionParser> optionParser_;
bool jsonRpc_;
protected:
// Subclass must implement this function to fulfil RpcRequest req.
// The return value of this method is used as a return value of RPC
@ -89,7 +89,8 @@ protected:
// command to dest.
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
{
@ -103,15 +104,6 @@ public:
// Do work to fulfill RpcRequest req and returns its result as
// RpcResponse. This method delegates to process() method.
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

View File

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

View File

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

View File

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