diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 1f498a047..e9737daa5 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -53,7 +53,23 @@ std::string EncodeBase64(const std::string& s) Json::Value RPCParser::parseAsIs(const Json::Value& jvParams) { - return Json::Value(Json::objectValue); + Json::Value v(Json::objectValue); + if (jvParams.isArray() && (jvParams.size() > 0)) + v["params"] = jvParams; + return v; +} + +Json::Value RPCParser::parseInternal(const Json::Value& jvParams) +{ + Json::Value v(Json::objectValue); + v["internal_command"] = jvParams[0u]; + + Json::Value params(Json::arrayValue); + for (unsigned i = 1; i < jvParams.size(); ++i) + params.append(jvParams[i]); + v["params"] = params; + + return v; } // account_info || @@ -481,6 +497,8 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) { "wallet_propose", &RPCParser::parseWalletPropose, 0, 1 }, { "wallet_seed", &RPCParser::parseWalletSeed, 0, 1 }, + { "internal", &RPCParser::parseInternal, 1, -1 }, + #if ENABLE_INSECURE // XXX Unnecessary commands which should be removed. { "login", &RPCParser::parseLogin, 2, 2 }, diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 4c893256c..47f0537ff 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -23,6 +23,7 @@ protected: Json::Value parseEvented(const Json::Value& jvParams); Json::Value parseGetCounts(const Json::Value& jvParams); Json::Value parseLedger(const Json::Value& jvParams); + Json::Value parseInternal(const Json::Value& jvParams); #if ENABLE_INSECURE Json::Value parseLogin(const Json::Value& jvParams); #endif diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 3791bf946..938642fde 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -2432,6 +2432,13 @@ Json::Value RPCHandler::doRpcCommand(const std::string& strMethod, Json::Value& return jvResult; } +Json::Value RPCHandler::doInternal(Json::Value jvRequest) +{ // Used for debug or special-purpose RPC commands + if (!jvRequest.isMember("internal_command")) + return rpcError(rpcINVALID_PARAMS); + return RPCInternalHandler::runHandler(jvRequest["internal_command"].asString(), jvRequest["params"]); +} + Json::Value RPCHandler::doCommand(Json::Value& jvRequest, int iRole) { if (!jvRequest.isMember("command")) @@ -2460,6 +2467,7 @@ Json::Value RPCHandler::doCommand(Json::Value& jvRequest, int iRole) { "account_tx", &RPCHandler::doAccountTransactions, false, optNetwork }, { "connect", &RPCHandler::doConnect, true, optNone }, { "get_counts", &RPCHandler::doGetCounts, true, optNone }, + { "internal", &RPCHandler::doInternal, true, optNone }, { "ledger", &RPCHandler::doLedger, false, optNetwork }, { "ledger_accept", &RPCHandler::doLedgerAccept, true, optCurrent }, { "ledger_closed", &RPCHandler::doLedgerClosed, false, optClosed }, @@ -2571,4 +2579,29 @@ Json::Value RPCHandler::doCommand(Json::Value& jvRequest, int iRole) } } +RPCInternalHandler* RPCInternalHandler::sHeadHandler = NULL; + +RPCInternalHandler::RPCInternalHandler(const std::string& name, handler_t Handler) : mName(name), mHandler(Handler) +{ + mNextHandler = sHeadHandler; + sHeadHandler = this; +} + +Json::Value RPCInternalHandler::runHandler(const std::string& name, const Json::Value& params) +{ + RPCInternalHandler* h = sHeadHandler; + while (h != NULL) + { + if (name == h->mName) + { + cLog(lsWARNING) << "Internal command " << name << ": " << params; + Json::Value ret = h->mHandler(params); + cLog(lsWARNING) << "Internal command returns: " << ret; + return ret; + } + h = h->mNextHandler; + } + return rpcError(rpcBAD_SYNTAX); +} + // vim:ts=4 diff --git a/src/cpp/ripple/RPCHandler.h b/src/cpp/ripple/RPCHandler.h index bfd99ba1a..d5c2d6e69 100644 --- a/src/cpp/ripple/RPCHandler.h +++ b/src/cpp/ripple/RPCHandler.h @@ -1,8 +1,17 @@ #ifndef __RPCHANDLER__ #define __RPCHANDLER__ +#include + +#include "../json/value.h" + +#include "RippleAddress.h" +#include "SerializedTypes.h" +#include "Ledger.h" + // used by the RPCServer or WSDoor to carry out these RPC commands class NetworkOPs; +class InfoSub; class RPCHandler { @@ -46,6 +55,7 @@ class RPCHandler Json::Value doDataStore(Json::Value params); #endif Json::Value doGetCounts(Json::Value params); + Json::Value doInternal(Json::Value params); Json::Value doLedger(Json::Value params); Json::Value doLogLevel(Json::Value params); Json::Value doLogRotate(Json::Value params); @@ -106,5 +116,22 @@ public: Json::Value doRpcCommand(const std::string& strCommand, Json::Value& jvParams, int iRole); }; +class RPCInternalHandler +{ +public: + typedef Json::Value (*handler_t)(const Json::Value&); + +protected: + static RPCInternalHandler* sHeadHandler; + + RPCInternalHandler* mNextHandler; + std::string mName; + handler_t mHandler; + +public: + RPCInternalHandler(const std::string& name, handler_t handler); + static Json::Value runHandler(const std::string& name, const Json::Value& params); +}; + #endif // vim:ts=4