mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-28 23:15:52 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
@@ -8,7 +8,8 @@
|
||||
"dependencies": {
|
||||
"async": "~0.1.22",
|
||||
"ws": "~0.4.22",
|
||||
"extend": "~1.1.1"
|
||||
"extend": "~1.1.1",
|
||||
"simple-jsonrpc": "~0.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"buster": "~0.6.2",
|
||||
|
||||
@@ -537,6 +537,7 @@ int commandLineRPC(const std::vector<std::string>& vCmd)
|
||||
theConfig.RPC_PORT,
|
||||
theConfig.RPC_USER,
|
||||
theConfig.RPC_PASSWORD,
|
||||
"",
|
||||
jvRequest.isMember("method") // Allow parser to rewrite method.
|
||||
? jvRequest["method"].asString()
|
||||
: vCmd[0],
|
||||
@@ -597,11 +598,11 @@ int commandLineRPC(const std::vector<std::string>& vCmd)
|
||||
return nRet;
|
||||
}
|
||||
|
||||
Json::Value callRPC(const std::string& strIp, const int iPort, const std::string& strUsername, const std::string& strPassword, const std::string& strMethod, const Json::Value& params)
|
||||
Json::Value callRPC(const std::string& strIp, const int iPort, const std::string& strUsername, const std::string& strPassword, const std::string& strPath, const std::string& strMethod, const Json::Value& params)
|
||||
{
|
||||
// Connect to localhost
|
||||
if (!theConfig.QUIET)
|
||||
std::cerr << "Connecting to: " << theConfig.RPC_IP << ":" << theConfig.RPC_PORT << std::endl;
|
||||
std::cerr << "Connecting to: " << strIp << ":" << iPort << std::endl;
|
||||
|
||||
boost::asio::ip::tcp::endpoint
|
||||
endpoint(boost::asio::ip::address::from_string(strIp), iPort);
|
||||
@@ -618,7 +619,7 @@ Json::Value callRPC(const std::string& strIp, const int iPort, const std::string
|
||||
// Send request
|
||||
std::string strRequest = JSONRPCRequest(strMethod, params, Json::Value(1));
|
||||
cLog(lsDEBUG) << "send request " << strMethod << " : " << strRequest << std::endl;
|
||||
std::string strPost = createHTTPPost(strRequest, mapRequestHeaders);
|
||||
std::string strPost = createHTTPPost(strPath, strRequest, mapRequestHeaders);
|
||||
stream << strPost << std::flush;
|
||||
|
||||
// std::cerr << "post " << strPost << std::endl;
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
};
|
||||
|
||||
extern int commandLineRPC(const std::vector<std::string>& vCmd);
|
||||
extern Json::Value callRPC(const std::string& strIp, const int iPort, const std::string& strUsername, const std::string& strPassword, const std::string& strMethod, const Json::Value& params);
|
||||
extern Json::Value callRPC(const std::string& strIp, const int iPort, const std::string& strUsername, const std::string& strPassword, const std::string& strPath, const std::string& strMethod, const Json::Value& params);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ enum http_status_type
|
||||
extern std::string JSONRPCRequest(const std::string& strMethod, const Json::Value& params,
|
||||
const Json::Value& id);
|
||||
|
||||
extern std::string createHTTPPost(const std::string& strMsg,
|
||||
extern std::string createHTTPPost(const std::string& strPath, const std::string& strMsg,
|
||||
const std::map<std::string, std::string>& mapRequestHeaders);
|
||||
|
||||
extern int ReadHTTP(std::basic_istream<char>& stream,
|
||||
|
||||
@@ -2370,12 +2370,12 @@ Json::Value RPCHandler::doUnsubscribe(Json::Value jvRequest)
|
||||
// command is the method. The request object is supplied as the first element of the params.
|
||||
Json::Value RPCHandler::doRpcCommand(const std::string& strMethod, Json::Value& jvParams, int iRole)
|
||||
{
|
||||
// cLog(lsTRACE) << "doRpcCommand:" << strMethod << ":" << jvParams;
|
||||
cLog(lsTRACE) << "doRpcCommand:" << strMethod << ":" << jvParams;
|
||||
|
||||
if (!jvParams.isArray() || jvParams.size() != 1)
|
||||
if (!jvParams.isArray() || jvParams.size() > 1)
|
||||
return rpcError(rpcINVALID_PARAMS);
|
||||
|
||||
Json::Value jvRequest = jvParams[0u];
|
||||
Json::Value jvRequest = jvParams.size() ? jvParams[0u] : Json::Value(Json::objectValue);
|
||||
|
||||
if (!jvRequest.isObject())
|
||||
return rpcError(rpcINVALID_PARAMS);
|
||||
|
||||
@@ -4,10 +4,23 @@
|
||||
|
||||
#include "CallRPC.h"
|
||||
|
||||
SETUP_LOG();
|
||||
|
||||
RPCSub::RPCSub(const std::string& strUrl, const std::string& strUsername, const std::string& strPassword)
|
||||
: mUrl(strUrl), mUsername(strUsername), mPassword(strPassword)
|
||||
{
|
||||
mId = 1;
|
||||
std::string strScheme;
|
||||
|
||||
if (!parseUrl(strUrl, strScheme, mIp, mPort, mPath))
|
||||
{
|
||||
throw std::runtime_error("Failed to parse url.");
|
||||
}
|
||||
else if (strScheme != "http")
|
||||
{
|
||||
throw std::runtime_error("Only http is supported.");
|
||||
}
|
||||
|
||||
mSeq = 1;
|
||||
}
|
||||
|
||||
void RPCSub::sendThread()
|
||||
@@ -33,7 +46,7 @@ void RPCSub::sendThread()
|
||||
mDeque.pop_front();
|
||||
|
||||
jvEvent = pEvent.second;
|
||||
jvEvent["id"] = pEvent.first;
|
||||
jvEvent["seq"] = pEvent.first;
|
||||
|
||||
bSend = true;
|
||||
}
|
||||
@@ -43,9 +56,14 @@ void RPCSub::sendThread()
|
||||
if (bSend)
|
||||
{
|
||||
// Drop result.
|
||||
(void) callRPC(mIp, mPort, mUsername, mPassword, "event", jvEvent);
|
||||
|
||||
sendThread();
|
||||
try
|
||||
{
|
||||
(void) callRPC(mIp, mPort, mUsername, mPassword, mPath, "event", jvEvent);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
cLog(lsDEBUG) << boost::str(boost::format("callRPC exception: %s") % e.what());
|
||||
}
|
||||
}
|
||||
} while (bSend);
|
||||
}
|
||||
@@ -61,7 +79,7 @@ void RPCSub::send(const Json::Value& jvObj)
|
||||
mDeque.pop_back();
|
||||
}
|
||||
|
||||
mDeque.push_back(std::make_pair(mId++, jvObj));
|
||||
mDeque.push_back(std::make_pair(mSeq++, jvObj));
|
||||
|
||||
if (!mSending)
|
||||
{
|
||||
|
||||
@@ -17,8 +17,9 @@ class RPCSub : public InfoSub
|
||||
int mPort;
|
||||
std::string mUsername;
|
||||
std::string mPassword;
|
||||
std::string mPath;
|
||||
|
||||
int mId; // Next id to allocate.
|
||||
int mSeq; // Next id to allocate.
|
||||
|
||||
bool mSending; // Sending threead is active.
|
||||
|
||||
|
||||
@@ -39,11 +39,13 @@ Json::Value JSONRPCError(int code, const std::string& message)
|
||||
// and to be compatible with other JSON-RPC implementations.
|
||||
//
|
||||
|
||||
std::string createHTTPPost(const std::string& strMsg, const std::map<std::string, std::string>& mapRequestHeaders)
|
||||
std::string createHTTPPost(const std::string& strPath, const std::string& strMsg, const std::map<std::string, std::string>& mapRequestHeaders)
|
||||
{
|
||||
std::ostringstream s;
|
||||
|
||||
s << "POST / HTTP/1.1\r\n"
|
||||
s << "POST "
|
||||
<< (strPath.empty() ? "/" : strPath)
|
||||
<< " HTTP/1.1\r\n"
|
||||
<< "User-Agent: " SYSTEM_NAME "-json-rpc/" << FormatFullVersion() << "\r\n"
|
||||
<< "Host: 127.0.0.1\r\n"
|
||||
<< "Content-Type: application/json\r\n"
|
||||
|
||||
@@ -35,4 +35,12 @@ exports.servers = {
|
||||
}
|
||||
};
|
||||
|
||||
exports.http_servers = {
|
||||
// A local test server
|
||||
"alpha-http" : {
|
||||
"ip" : "127.0.0.1",
|
||||
"port" : 8088,
|
||||
}
|
||||
};
|
||||
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
194
test/jsonrpc-test.js
Normal file
194
test/jsonrpc-test.js
Normal file
@@ -0,0 +1,194 @@
|
||||
var async = require("async");
|
||||
var buster = require("buster");
|
||||
var http = require("http");
|
||||
var jsonrpc = require("simple-jsonrpc");
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
|
||||
var Amount = require("../src/js/amount.js").Amount;
|
||||
var Remote = require("../src/js/remote.js").Remote;
|
||||
var Server = require("./server.js").Server;
|
||||
|
||||
var testutils = require("./testutils.js");
|
||||
|
||||
var config = require("./config.js");
|
||||
|
||||
require("../src/js/amount.js").config = require("./config.js");
|
||||
require("../src/js/remote.js").config = require("./config.js");
|
||||
|
||||
// How long to wait for server to start.
|
||||
var serverDelay = 1500;
|
||||
|
||||
buster.testRunner.timeout = 5000;
|
||||
|
||||
var HttpServer = function () {
|
||||
};
|
||||
|
||||
var server;
|
||||
var server_events;
|
||||
|
||||
var build_setup = function (options) {
|
||||
var setup = testutils.build_setup(options);
|
||||
|
||||
return function (done) {
|
||||
var self = this;
|
||||
|
||||
var http_config = config.http_servers["zed"];
|
||||
|
||||
server_events = new EventEmitter;
|
||||
server = http.createServer(function (req, res) {
|
||||
// console.log("REQUEST");
|
||||
var input = "";
|
||||
|
||||
req.setEncoding();
|
||||
|
||||
req.on('data', function (buffer) {
|
||||
// console.log("DATA: %s", buffer);
|
||||
|
||||
input = input + buffer;
|
||||
});
|
||||
|
||||
req.on('end', function () {
|
||||
// console.log("END");
|
||||
var request = JSON.parse(input);
|
||||
|
||||
// console.log("REQ: %s", JSON.stringify(request, undefined, 2));
|
||||
|
||||
server_events.emit('request', request, res);
|
||||
});
|
||||
|
||||
req.on('close', function () {
|
||||
// console.log("CLOSE");
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(http_config.port, http_config.ip, undefined,
|
||||
function () {
|
||||
// console.log("server up: %s %d", http_config.ip, http_config.port);
|
||||
|
||||
setup.call(self, done);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var build_teardown = function () {
|
||||
var teardown = testutils.build_teardown();
|
||||
|
||||
return function (done) {
|
||||
var self = this;
|
||||
|
||||
server.close(function () {
|
||||
// console.log("server closed");
|
||||
|
||||
teardown.call(self, done);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
buster.testCase("JSON-RPC", {
|
||||
setUp : build_setup(),
|
||||
// setUp : build_setup({ verbose: true }),
|
||||
// setUp : build_setup({verbose: true , no_server: true}),
|
||||
tearDown : build_teardown(),
|
||||
|
||||
"server_info" :
|
||||
function (done) {
|
||||
var rippled_config = config.servers.alpha;
|
||||
var client = jsonrpc.client("http://" + rippled_config.rpc_ip + ":" + rippled_config.rpc_port);
|
||||
|
||||
client.call('server_info', [], function (result) {
|
||||
// console.log(JSON.stringify(result, undefined, 2));
|
||||
buster.assert('info' in result);
|
||||
|
||||
done();
|
||||
});
|
||||
},
|
||||
|
||||
"subscribe server" :
|
||||
function (done) {
|
||||
var rippled_config = config.servers.alpha;
|
||||
var client = jsonrpc.client("http://" + rippled_config.rpc_ip + ":" + rippled_config.rpc_port);
|
||||
var http_config = config.http_servers["zed"];
|
||||
|
||||
client.call('subscribe', [{
|
||||
'url' : "http://" + http_config.ip + ":" + http_config.port,
|
||||
'streams' : [ 'server' ],
|
||||
}], function (result) {
|
||||
// console.log(JSON.stringify(result, undefined, 2));
|
||||
|
||||
buster.assert('random' in result);
|
||||
|
||||
done();
|
||||
});
|
||||
},
|
||||
|
||||
"subscribe ledger" :
|
||||
function (done) {
|
||||
var self = this;
|
||||
|
||||
var rippled_config = config.servers.alpha;
|
||||
var client = jsonrpc.client("http://" + rippled_config.rpc_ip + ":" + rippled_config.rpc_port);
|
||||
var http_config = config.http_servers["zed"];
|
||||
|
||||
async.waterfall([
|
||||
function (callback) {
|
||||
self.what = "Subscribe.";
|
||||
|
||||
client.call('subscribe', [{
|
||||
'url' : "http://" + http_config.ip + ":" + http_config.port,
|
||||
'streams' : [ 'ledger' ],
|
||||
}], function (result) {
|
||||
//console.log(JSON.stringify(result, undefined, 2));
|
||||
|
||||
buster.assert('ledger_index' in result);
|
||||
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Accept a ledger.";
|
||||
|
||||
server_events.once('request', function (request, response) {
|
||||
// console.log("GOT: %s", JSON.stringify(request, undefined, 2));
|
||||
|
||||
buster.assert.equals(1, request.params.seq);
|
||||
buster.assert.equals(3, request.params.ledger_index);
|
||||
|
||||
response.statusCode = 200;
|
||||
response.end(JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
result: {},
|
||||
id: request.id
|
||||
}));
|
||||
|
||||
callback();
|
||||
});
|
||||
|
||||
self.remote.ledger_accept();
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Accept another ledger.";
|
||||
|
||||
server_events.once('request', function (request, response) {
|
||||
// console.log("GOT: %s", JSON.stringify(request, undefined, 2));
|
||||
|
||||
buster.assert.equals(2, request.params.seq);
|
||||
buster.assert.equals(4, request.params.ledger_index);
|
||||
|
||||
response.statusCode = 200;
|
||||
response.end(JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
result: {},
|
||||
id: request.id
|
||||
}));
|
||||
|
||||
callback();
|
||||
});
|
||||
|
||||
self.remote.ledger_accept();
|
||||
},
|
||||
], function (error) {
|
||||
buster.refute(error, self.what);
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -107,8 +107,6 @@ var build_setup = function (opts, host) {
|
||||
var build_teardown = function (host) {
|
||||
|
||||
return function (done) {
|
||||
|
||||
|
||||
host = host || config.server_default;
|
||||
|
||||
var data = this.store[host];
|
||||
|
||||
Reference in New Issue
Block a user