From fed1250218e2d6c683975e081df5f4c9eb8d4d4e Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 2 Dec 2012 16:05:45 -0800 Subject: [PATCH] Regularize RPC handling. --- src/cpp/ripple/RPCHandler.cpp | 40 ++++++++++++++++++++++----------- src/cpp/ripple/RPCHandler.h | 3 ++- src/cpp/ripple/RPCServer.cpp | 2 +- src/cpp/ripple/WSConnection.cpp | 26 ++++++++++++++++----- 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index e2a5d1c951..2474ee5373 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -317,9 +317,6 @@ Json::Value RPCHandler::doAccountInfo(Json::Value params) return ret; } - - - Json::Value RPCHandler::doConnect(Json::Value params) { if (theConfig.RUN_STANDALONE) @@ -458,7 +455,6 @@ Json::Value RPCHandler::doOwnerInfo(Json::Value params) return ret; } - Json::Value RPCHandler::doPeers(Json::Value params) { Json::Value obj(Json::objectValue); @@ -2140,14 +2136,31 @@ Json::Value RPCHandler::doUnsubscribe(Json::Value jvRequest) return jvResult; } -Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& params, int role) +Json::Value RPCHandler::doRpcCommand(const std::string& strCommand, Json::Value& jvParams, int iRole) { - cLog(lsTRACE) << "RPC:" << command; - cLog(lsTRACE) << "RPC params:" << params; + if (!jvParams.isArray() || jvParams.size() > 1) + return rpcError(rpcINVALID_PARAMS); + + Json::Value jvRequest = jvParams[0u]; + + jvRequest["command"] = strCommand; + + return doCommand(jvRequest, iRole); +} + +Json::Value RPCHandler::doCommand(Json::Value& jvParams, int iRole) +{ + if (!jvParams.isMember("command")) + return rpcError(rpcINVALID_PARAMS); + + std::string strCommand = jvParams["command"].asString(); + + cLog(lsTRACE) << "COMMAND:" << strCommand; + cLog(lsTRACE) << "REQUEST:" << jvParams; LoadEvent::autoptr le(theApp->getJobQueue().getLoadEventAP(jtRPC)); - mRole = role; + mRole = iRole; static struct { const char* pCommand; @@ -2213,7 +2226,7 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param int i = NUMBER(commandsA); - while (i-- && command != commandsA[i].pCommand) + while (i-- && strCommand != commandsA[i].pCommand) ; if (i < 0) @@ -2230,11 +2243,12 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param } else if (commandsA[i].iMinParams >= 0 ? commandsA[i].iMaxParams - ? (params.size() < commandsA[i].iMinParams - || (commandsA[i].iMaxParams >= 0 && params.size() > commandsA[i].iMaxParams)) + ? (jvParams.size() < commandsA[i].iMinParams + || (commandsA[i].iMaxParams >= 0 && jvParams.size() > commandsA[i].iMaxParams)) : false - : params.isArray()) + : jvParams.isArray()) { +cLog(lsDEBUG) << "params.size: " << jvParams.size() << " array: " << jvParams.isArray(); return rpcError(rpcINVALID_PARAMS); } else if ((commandsA[i].iOptions & optNetwork) && !mNetOps->available()) @@ -2255,7 +2269,7 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param else { try { - return (this->*(commandsA[i].dfpFunc))(params); + return (this->*(commandsA[i].dfpFunc))(jvParams); } catch (std::exception& e) { diff --git a/src/cpp/ripple/RPCHandler.h b/src/cpp/ripple/RPCHandler.h index 17671d5b31..4867955a7f 100644 --- a/src/cpp/ripple/RPCHandler.h +++ b/src/cpp/ripple/RPCHandler.h @@ -106,7 +106,8 @@ public: RPCHandler(NetworkOPs* netOps); RPCHandler(NetworkOPs* netOps, InfoSub* infoSub); - Json::Value doCommand(const std::string& command, Json::Value& params, int role); + Json::Value doCommand(Json::Value& jvRequest, int role); + Json::Value doRpcCommand(const std::string& strCommand, Json::Value& jvParams, int iRole); Json::Value handleJSONSubmit(Json::Value jvRequest); }; diff --git a/src/cpp/ripple/RPCServer.cpp b/src/cpp/ripple/RPCServer.cpp index 16daa4abc2..98e7e0399e 100644 --- a/src/cpp/ripple/RPCServer.cpp +++ b/src/cpp/ripple/RPCServer.cpp @@ -145,7 +145,7 @@ std::string RPCServer::handleRequest(const std::string& requestStr) RPCHandler mRPCHandler(mNetOps); cLog(lsTRACE) << valParams; - Json::Value result = mRPCHandler.doCommand(strMethod, valParams, mRole); + Json::Value result = mRPCHandler.doRpcCommand(strMethod, valParams, mRole); cLog(lsTRACE) << result; std::string strReply = JSONRPCReply(result, Json::Value(), id); diff --git a/src/cpp/ripple/WSConnection.cpp b/src/cpp/ripple/WSConnection.cpp index 875b18942f..59bb17751e 100644 --- a/src/cpp/ripple/WSConnection.cpp +++ b/src/cpp/ripple/WSConnection.cpp @@ -6,6 +6,7 @@ SETUP_LOG(); +#include "CallRPC.h" // XXX Remove this, don't provide support for RPC syntax. #include "WSConnection.h" #include "WSHandler.h" @@ -48,13 +49,28 @@ Json::Value WSConnection::invokeCommand(Json::Value& jvRequest) RPCHandler mRPCHandler(&mNetwork, this); Json::Value jvResult(Json::objectValue); - // Regular RPC command + // XXX Temporarily support RPC style commands over websocket. Remove this. + if (jvRequest.isMember("params")) + { + RPCParser rpParser; + + Json::Value jvRpcRequest = rpParser.parseCommand(jvRequest["command"].asString(), jvRequest["params"]); + + if (jvRpcRequest.isMember("error")) + { + jvResult = jvRpcRequest; + } + else + { + jvResult["result"] = mRPCHandler.doCommand( + jvRpcRequest, + mHandler->getPublic() ? RPCHandler::GUEST : RPCHandler::ADMIN); + } + } + else { jvResult["result"] = mRPCHandler.doCommand( - jvRequest["command"].asString(), - jvRequest.isMember("params") - ? jvRequest["params"] - : jvRequest, + jvRequest, mHandler->getPublic() ? RPCHandler::GUEST : RPCHandler::ADMIN); }