mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-21 19:45:53 +00:00
Send output incrementally in ServerHandlerImp.
This commit is contained in:
committed by
Vinnie Falco
parent
167f4666e2
commit
fc9a23d6d4
@@ -1762,6 +1762,8 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerTiming.h">
|
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerTiming.h">
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerToJson.h">
|
||||||
|
</ClInclude>
|
||||||
<ClCompile Include="..\..\src\ripple\app\ledger\OrderBookDB.cpp">
|
<ClCompile Include="..\..\src\ripple\app\ledger\OrderBookDB.cpp">
|
||||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@@ -2628,6 +2628,9 @@
|
|||||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerTiming.h">
|
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerTiming.h">
|
||||||
<Filter>ripple\app\ledger</Filter>
|
<Filter>ripple\app\ledger</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerToJson.h">
|
||||||
|
<Filter>ripple\app\ledger</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClCompile Include="..\..\src\ripple\app\ledger\OrderBookDB.cpp">
|
<ClCompile Include="..\..\src\ripple\app\ledger\OrderBookDB.cpp">
|
||||||
<Filter>ripple\app\ledger</Filter>
|
<Filter>ripple\app\ledger</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@@ -29,16 +29,6 @@ namespace ripple {
|
|||||||
|
|
||||||
unsigned int const gMaxHTTPHeaderSize = 0x02000000;
|
unsigned int const gMaxHTTPHeaderSize = 0x02000000;
|
||||||
|
|
||||||
Json::Value JSONRPCError (int code, std::string const& message)
|
|
||||||
{
|
|
||||||
Json::Value error (Json::objectValue);
|
|
||||||
|
|
||||||
error[jss::code] = Json::Value (code);
|
|
||||||
error[jss::message] = Json::Value (message);
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getHTTPHeaderTimestamp ()
|
std::string getHTTPHeaderTimestamp ()
|
||||||
{
|
{
|
||||||
// CHECKME This is probably called often enough that optimizing it makes
|
// CHECKME This is probably called often enough that optimizing it makes
|
||||||
@@ -54,160 +44,74 @@ std::string getHTTPHeaderTimestamp ()
|
|||||||
return std::string (buffer);
|
return std::string (buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HTTPReply (int nStatus, std::string const& strMsg)
|
void HTTPReply (int nStatus, std::string const& content, RPC::Output output)
|
||||||
{
|
{
|
||||||
if (ShouldLog (lsTRACE, RPC))
|
if (ShouldLog (lsTRACE, RPC))
|
||||||
{
|
{
|
||||||
WriteLog (lsTRACE, RPC) << "HTTP Reply " << nStatus << " " << strMsg;
|
WriteLog (lsTRACE, RPC) << "HTTP Reply " << nStatus << " " << content;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ret;
|
|
||||||
|
|
||||||
if (nStatus == 401)
|
if (nStatus == 401)
|
||||||
{
|
{
|
||||||
ret.reserve (512);
|
output ("HTTP/1.0 401 Authorization Required\r\n");
|
||||||
|
output (getHTTPHeaderTimestamp ());
|
||||||
ret.append ("HTTP/1.0 401 Authorization Required\r\n");
|
|
||||||
ret.append (getHTTPHeaderTimestamp ());
|
|
||||||
|
|
||||||
// CHECKME this returns a different version than the replies below. Is
|
// CHECKME this returns a different version than the replies below. Is
|
||||||
// this by design or an accident or should it be using
|
// this by design or an accident or should it be using
|
||||||
// BuildInfo::getFullVersionString () as well?
|
// BuildInfo::getFullVersionString () as well?
|
||||||
ret.append ("Server: " + systemName () + "-json-rpc/v1");
|
output ("Server: " + systemName () + "-json-rpc/v1");
|
||||||
ret.append ("\r\n");
|
output ("\r\n");
|
||||||
|
|
||||||
// Be careful in modifying this! If you change the contents you MUST
|
// Be careful in modifying this! If you change the contents you MUST
|
||||||
// update the Content-Length header as well to indicate the correct
|
// update the Content-Length header as well to indicate the correct
|
||||||
// size of the data.
|
// size of the data.
|
||||||
ret.append ("WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
|
output ("WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
|
||||||
"Content-Type: text/html\r\n"
|
"Content-Type: text/html\r\n"
|
||||||
"Content-Length: 296\r\n"
|
"Content-Length: 296\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
|
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 "
|
||||||
"\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
|
"Transitional//EN\"\r\n"
|
||||||
|
"\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd"
|
||||||
|
"\">\r\n"
|
||||||
"<HTML>\r\n"
|
"<HTML>\r\n"
|
||||||
"<HEAD>\r\n"
|
"<HEAD>\r\n"
|
||||||
"<TITLE>Error</TITLE>\r\n"
|
"<TITLE>Error</TITLE>\r\n"
|
||||||
"<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
|
"<META HTTP-EQUIV='Content-Type' "
|
||||||
|
"CONTENT='text/html; charset=ISO-8859-1'>\r\n"
|
||||||
"</HEAD>\r\n"
|
"</HEAD>\r\n"
|
||||||
"<BODY><H1>401 Unauthorized.</H1></BODY>\r\n");
|
"<BODY><H1>401 Unauthorized.</H1></BODY>\r\n");
|
||||||
|
|
||||||
return ret;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.reserve(256 + strMsg.length());
|
|
||||||
|
|
||||||
switch (nStatus)
|
switch (nStatus)
|
||||||
{
|
{
|
||||||
case 200: ret.append ("HTTP/1.1 200 OK\r\n"); break;
|
case 200: output ("HTTP/1.1 200 OK\r\n"); break;
|
||||||
case 400: ret.append ("HTTP/1.1 400 Bad Request\r\n"); break;
|
case 400: output ("HTTP/1.1 400 Bad Request\r\n"); break;
|
||||||
case 403: ret.append ("HTTP/1.1 403 Forbidden\r\n"); break;
|
case 403: output ("HTTP/1.1 403 Forbidden\r\n"); break;
|
||||||
case 404: ret.append ("HTTP/1.1 404 Not Found\r\n"); break;
|
case 404: output ("HTTP/1.1 404 Not Found\r\n"); break;
|
||||||
case 500: ret.append ("HTTP/1.1 500 Internal Server Error\r\n"); break;
|
case 500: output ("HTTP/1.1 500 Internal Server Error\r\n"); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.append (getHTTPHeaderTimestamp ());
|
output (getHTTPHeaderTimestamp ());
|
||||||
|
|
||||||
ret.append ("Connection: Keep-Alive\r\n");
|
output ("Connection: Keep-Alive\r\n"
|
||||||
|
"Content-Length: ");
|
||||||
|
|
||||||
// VFALCO TODO Determine if/when this header should be added
|
// VFALCO TODO Determine if/when this header should be added
|
||||||
//if (getConfig ().RPC_ALLOW_REMOTE)
|
//if (getConfig ().RPC_ALLOW_REMOTE)
|
||||||
// ret.append ("Access-Control-Allow-Origin: *\r\n");
|
// output ("Access-Control-Allow-Origin: *\r\n");
|
||||||
|
|
||||||
ret.append ("Content-Length: ");
|
output (std::to_string(content.size () + 2));
|
||||||
ret.append (std::to_string(strMsg.size () + 2));
|
output ("\r\n"
|
||||||
ret.append ("\r\n");
|
"Content-Type: application/json; charset=UTF-8\r\n");
|
||||||
|
|
||||||
ret.append ("Content-Type: application/json; charset=UTF-8\r\n");
|
output ("Server: " + systemName () + "-json-rpc/");
|
||||||
|
output (BuildInfo::getFullVersionString ());
|
||||||
ret.append ("Server: " + systemName () + "-json-rpc/");
|
output ("\r\n"
|
||||||
ret.append (BuildInfo::getFullVersionString ());
|
"\r\n");
|
||||||
ret.append ("\r\n");
|
output (content);
|
||||||
|
output ("\r\n");
|
||||||
ret.append ("\r\n");
|
|
||||||
ret.append (strMsg);
|
|
||||||
ret.append ("\r\n");
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ReadHTTPStatus (std::basic_istream<char>& stream)
|
|
||||||
{
|
|
||||||
std::string str;
|
|
||||||
getline (stream, str);
|
|
||||||
std::vector<std::string> vWords;
|
|
||||||
boost::split (vWords, str, boost::is_any_of (" "));
|
|
||||||
|
|
||||||
if (vWords.size () < 2)
|
|
||||||
return 500;
|
|
||||||
|
|
||||||
return atoi (vWords[1].c_str ());
|
|
||||||
}
|
|
||||||
|
|
||||||
int ReadHTTPHeader (std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet)
|
|
||||||
{
|
|
||||||
int nLen = 0;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
std::string str;
|
|
||||||
std::getline (stream, str);
|
|
||||||
|
|
||||||
if (str.empty () || str == "\r")
|
|
||||||
break;
|
|
||||||
|
|
||||||
std::string::size_type nColon = str.find (":");
|
|
||||||
|
|
||||||
if (nColon != std::string::npos)
|
|
||||||
{
|
|
||||||
std::string strHeader = str.substr (0, nColon);
|
|
||||||
boost::trim (strHeader);
|
|
||||||
boost::to_lower (strHeader);
|
|
||||||
std::string strValue = str.substr (nColon + 1);
|
|
||||||
boost::trim (strValue);
|
|
||||||
mapHeadersRet[strHeader] = strValue;
|
|
||||||
|
|
||||||
if (strHeader == "content-length")
|
|
||||||
nLen = atoi (strValue.c_str ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ReadHTTP (std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet,
|
|
||||||
std::string& strMessageRet)
|
|
||||||
{
|
|
||||||
mapHeadersRet.clear ();
|
|
||||||
strMessageRet = "";
|
|
||||||
|
|
||||||
// Read status
|
|
||||||
int nStatus = ReadHTTPStatus (stream);
|
|
||||||
|
|
||||||
// Read header
|
|
||||||
int nLen = ReadHTTPHeader (stream, mapHeadersRet);
|
|
||||||
|
|
||||||
if (nLen < 0 || nLen > gMaxHTTPHeaderSize)
|
|
||||||
return 500;
|
|
||||||
|
|
||||||
// Read message
|
|
||||||
if (nLen > 0)
|
|
||||||
{
|
|
||||||
std::vector<char> vch (nLen);
|
|
||||||
stream.read (&vch[0], nLen);
|
|
||||||
strMessageRet = std::string (vch.begin (), vch.end ());
|
|
||||||
}
|
|
||||||
|
|
||||||
return nStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string JSONRPCReply (Json::Value const& result, Json::Value const& error, Json::Value const& id)
|
|
||||||
{
|
|
||||||
Json::Value reply (Json::objectValue);
|
|
||||||
reply[jss::result] = result;
|
|
||||||
//reply["error"]=error;
|
|
||||||
//reply["id"]=id;
|
|
||||||
return to_string (reply) + "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|||||||
@@ -21,22 +21,11 @@
|
|||||||
#define RIPPLE_SERVER_JSONRPCUTIL_H_INCLUDED
|
#define RIPPLE_SERVER_JSONRPCUTIL_H_INCLUDED
|
||||||
|
|
||||||
#include <ripple/json/json_value.h>
|
#include <ripple/json/json_value.h>
|
||||||
|
#include <ripple/rpc/Output.h>
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
// VFALCO These functions are all deprecated they are inefficient and have poor signatures.
|
void HTTPReply (int nStatus, std::string const& strMsg, RPC::Output);
|
||||||
|
|
||||||
extern std::string JSONRPCReply (Json::Value const& result, Json::Value const& error, Json::Value const& id);
|
|
||||||
|
|
||||||
extern Json::Value JSONRPCError (int code, std::string const& message);
|
|
||||||
|
|
||||||
// VFALCO This needs to be rewritten to use beast::http::message
|
|
||||||
extern std::string HTTPReply (int nStatus, std::string const& strMsg);
|
|
||||||
|
|
||||||
// VFALCO NOTE This one looks like it does some sort of stream i/o
|
|
||||||
extern int ReadHTTP (std::basic_istream<char>& stream,
|
|
||||||
std::map<std::string, std::string>& mapHeadersRet,
|
|
||||||
std::string& strMessageRet);
|
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|
||||||
|
|||||||
@@ -28,10 +28,12 @@
|
|||||||
#include <ripple/overlay/Overlay.h>
|
#include <ripple/overlay/Overlay.h>
|
||||||
#include <ripple/resource/Manager.h>
|
#include <ripple/resource/Manager.h>
|
||||||
#include <ripple/resource/Fees.h>
|
#include <ripple/resource/Fees.h>
|
||||||
|
#include <ripple/rpc/Coroutine.h>
|
||||||
#include <beast/crypto/base64.h>
|
#include <beast/crypto/base64.h>
|
||||||
#include <beast/cxx14/algorithm.h> // <algorithm>
|
#include <beast/cxx14/algorithm.h> // <algorithm>
|
||||||
#include <beast/http/rfc2616.h>
|
#include <beast/http/rfc2616.h>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <boost/type_traits.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/regex.hpp>
|
#include <boost/regex.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -146,6 +148,36 @@ ServerHandlerImp::onHandoff (HTTP::Session& session,
|
|||||||
return Handoff{};
|
return Handoff{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
RPC::Output makeOutput (HTTP::Session& session)
|
||||||
|
{
|
||||||
|
return [&](boost::string_ref const& b)
|
||||||
|
{
|
||||||
|
session.write (b.data(), b.size());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void runCoroutine (RPC::Coroutine coroutine, JobQueue& jobQueue)
|
||||||
|
{
|
||||||
|
if (!coroutine)
|
||||||
|
return;
|
||||||
|
coroutine();
|
||||||
|
if (!coroutine)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Reschedule the job on the job queue.
|
||||||
|
jobQueue.addJob (
|
||||||
|
jtCLIENT, "RPC-Coroutine",
|
||||||
|
[coroutine, &jobQueue] (Job&)
|
||||||
|
{
|
||||||
|
runCoroutine (coroutine, jobQueue);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void
|
void
|
||||||
ServerHandlerImp::onRequest (HTTP::Session& session)
|
ServerHandlerImp::onRequest (HTTP::Session& session)
|
||||||
{
|
{
|
||||||
@@ -153,14 +185,17 @@ ServerHandlerImp::onRequest (HTTP::Session& session)
|
|||||||
if (! authorized (session.port(),
|
if (! authorized (session.port(),
|
||||||
build_map(session.request().headers)))
|
build_map(session.request().headers)))
|
||||||
{
|
{
|
||||||
session.write (HTTPReply (403, "Forbidden"));
|
HTTPReply (403, "Forbidden", makeOutput (session));
|
||||||
session.close (true);
|
session.close (true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_jobQueue.addJob (jtCLIENT, "RPC-Client", std::bind (
|
auto detach = session.detach();
|
||||||
&ServerHandlerImp::processSession, this, std::placeholders::_1,
|
|
||||||
session.detach()));
|
RPC::Coroutine::YieldFunction yieldFunction =
|
||||||
|
[this, detach] (Yield const& y) { processSession (detach, y); };
|
||||||
|
RPC::Coroutine coroutine (yieldFunction);
|
||||||
|
runCoroutine (std::move(coroutine), m_jobQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -177,36 +212,44 @@ ServerHandlerImp::onStopped (HTTP::Server&)
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ServerHandlerImp will yield after emitting serverOutputChunkSize bytes.
|
||||||
|
// If this value is 0, it means "yield after each output"
|
||||||
|
// A negative value means "never yield"
|
||||||
|
// TODO(tom): negotiate a spot for this in Configs.
|
||||||
|
const int serverOutputChunkSize = -1;
|
||||||
|
|
||||||
// Dispatched on the job queue
|
// Dispatched on the job queue
|
||||||
void
|
void
|
||||||
ServerHandlerImp::processSession (Job& job,
|
ServerHandlerImp::processSession (
|
||||||
std::shared_ptr<HTTP::Session> const& session)
|
std::shared_ptr<HTTP::Session> const& session, Yield const& yield)
|
||||||
{
|
{
|
||||||
session->write (processRequest (session->port(),
|
auto output = makeOutput (*session);
|
||||||
to_string(session->body()), session->remoteAddress().at_port(0)));
|
if (serverOutputChunkSize >= 0)
|
||||||
|
{
|
||||||
|
output = RPC::chunkedYieldingOutput (
|
||||||
|
output, yield, serverOutputChunkSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
processRequest (
|
||||||
|
session->port(),
|
||||||
|
to_string (session->body()),
|
||||||
|
session->remoteAddress().at_port (0),
|
||||||
|
output,
|
||||||
|
yield);
|
||||||
|
|
||||||
if (session->request().keep_alive())
|
if (session->request().keep_alive())
|
||||||
{
|
|
||||||
session->complete();
|
session->complete();
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
session->close (true);
|
session->close (true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
void
|
||||||
ServerHandlerImp::createResponse (
|
ServerHandlerImp::processRequest (
|
||||||
int statusCode,
|
HTTP::Port const& port,
|
||||||
std::string const& description)
|
std::string const& request,
|
||||||
{
|
beast::IP::Endpoint const& remoteIPAddress,
|
||||||
return HTTPReply (statusCode, description);
|
Output output,
|
||||||
}
|
Yield yield)
|
||||||
|
|
||||||
// VFALCO ARGH! returning a single std::string for the entire response?
|
|
||||||
std::string
|
|
||||||
ServerHandlerImp::processRequest (HTTP::Port const& port,
|
|
||||||
std::string const& request, beast::IP::Endpoint const& remoteIPAddress)
|
|
||||||
{
|
{
|
||||||
Json::Value jsonRPC;
|
Json::Value jsonRPC;
|
||||||
{
|
{
|
||||||
@@ -216,7 +259,8 @@ ServerHandlerImp::processRequest (HTTP::Port const& port,
|
|||||||
jsonRPC.isNull () ||
|
jsonRPC.isNull () ||
|
||||||
! jsonRPC.isObject ())
|
! jsonRPC.isObject ())
|
||||||
{
|
{
|
||||||
return createResponse (400, "Unable to parse request");
|
HTTPReply (400, "Unable to parse request", output);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,25 +283,36 @@ ServerHandlerImp::processRequest (HTTP::Port const& port,
|
|||||||
usage = m_resourceManager.newInboundEndpoint(remoteIPAddress);
|
usage = m_resourceManager.newInboundEndpoint(remoteIPAddress);
|
||||||
|
|
||||||
if (usage.disconnect ())
|
if (usage.disconnect ())
|
||||||
return createResponse (503, "Server is overloaded");
|
{
|
||||||
|
HTTPReply (503, "Server is overloaded", output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Parse id now so errors from here on will have the id
|
// Parse id now so errors from here on will have the id
|
||||||
//
|
//
|
||||||
// VFALCO NOTE Except that "id" isn't included in the following errors.
|
// VFALCO NOTE Except that "id" isn't included in the following errors.
|
||||||
//
|
//
|
||||||
Json::Value const id = jsonRPC ["id"];
|
Json::Value const id = jsonRPC ["id"];
|
||||||
|
|
||||||
Json::Value const method = jsonRPC ["method"];
|
Json::Value const method = jsonRPC ["method"];
|
||||||
|
|
||||||
if (method.isNull ())
|
if (method.isNull ())
|
||||||
return createResponse (400, "Null method");
|
{
|
||||||
|
HTTPReply (400, "Null method", output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (! method.isString ())
|
if (! method.isString ())
|
||||||
return createResponse (400, "method is not string");
|
{
|
||||||
|
HTTPReply (400, "method is not string", output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::string strMethod = method.asString ();
|
std::string strMethod = method.asString ();
|
||||||
if (strMethod.empty())
|
if (strMethod.empty())
|
||||||
return createResponse (400, "method is empty");
|
{
|
||||||
|
HTTPReply (400, "method is empty", output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Parse params
|
// Parse params
|
||||||
Json::Value params = jsonRPC ["params"];
|
Json::Value params = jsonRPC ["params"];
|
||||||
@@ -266,7 +321,10 @@ ServerHandlerImp::processRequest (HTTP::Port const& port,
|
|||||||
params = Json::Value (Json::arrayValue);
|
params = Json::Value (Json::arrayValue);
|
||||||
|
|
||||||
else if (!params.isArray ())
|
else if (!params.isArray ())
|
||||||
return HTTPReply (400, "params unparseable");
|
{
|
||||||
|
HTTPReply (400, "params unparseable", output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// VFALCO TODO Shouldn't we handle this earlier?
|
// VFALCO TODO Shouldn't we handle this earlier?
|
||||||
//
|
//
|
||||||
@@ -275,25 +333,28 @@ ServerHandlerImp::processRequest (HTTP::Port const& port,
|
|||||||
// VFALCO TODO Needs implementing
|
// VFALCO TODO Needs implementing
|
||||||
// FIXME Needs implementing
|
// FIXME Needs implementing
|
||||||
// XXX This needs rate limiting to prevent brute forcing password.
|
// XXX This needs rate limiting to prevent brute forcing password.
|
||||||
return HTTPReply (403, "Forbidden");
|
HTTPReply (403, "Forbidden", output);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string response;
|
|
||||||
RPCHandler rpcHandler (m_networkOPs);
|
RPCHandler rpcHandler (m_networkOPs);
|
||||||
Resource::Charge loadType = Resource::feeReferenceRPC;
|
Resource::Charge loadType = Resource::feeReferenceRPC;
|
||||||
|
|
||||||
m_journal.debug << "Query: " << strMethod << params;
|
m_journal.debug << "Query: " << strMethod << params;
|
||||||
|
|
||||||
Json::Value const result (rpcHandler.doRpcCommand (
|
auto result = rpcHandler.doRpcCommand (
|
||||||
strMethod, params, role, loadType));
|
strMethod, params, role, loadType, yield);
|
||||||
m_journal.debug << "Reply: " << result;
|
m_journal.debug << "Reply: " << result;
|
||||||
|
|
||||||
usage.charge (loadType);
|
usage.charge (loadType);
|
||||||
|
|
||||||
response = JSONRPCReply (result, Json::Value (), id);
|
Json::Value reply (Json::objectValue);
|
||||||
|
reply[jss::result] = std::move (result);
|
||||||
|
auto response = to_string (reply);
|
||||||
|
response += '\n';
|
||||||
|
|
||||||
return createResponse (200, response);
|
HTTPReply (200, response, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <ripple/core/Job.h>
|
#include <ripple/core/Job.h>
|
||||||
#include <ripple/server/ServerHandler.h>
|
#include <ripple/server/ServerHandler.h>
|
||||||
#include <ripple/server/Session.h>
|
#include <ripple/server/Session.h>
|
||||||
|
#include <ripple/rpc/Output.h>
|
||||||
#include <ripple/rpc/RPCHandler.h>
|
#include <ripple/rpc/RPCHandler.h>
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
@@ -49,6 +50,9 @@ public:
|
|||||||
~ServerHandlerImp();
|
~ServerHandlerImp();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using Output = RPC::Output;
|
||||||
|
using Yield = RPC::Yield;
|
||||||
|
|
||||||
void
|
void
|
||||||
setup (Setup const& setup, beast::Journal journal) override;
|
setup (Setup const& setup, beast::Journal journal) override;
|
||||||
|
|
||||||
@@ -104,15 +108,11 @@ private:
|
|||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
void
|
void
|
||||||
processSession (Job& job,
|
processSession (std::shared_ptr<HTTP::Session> const&, Yield const&);
|
||||||
std::shared_ptr<HTTP::Session> const& session);
|
|
||||||
|
|
||||||
std::string
|
void
|
||||||
createResponse (int statusCode, std::string const& description);
|
|
||||||
|
|
||||||
std::string
|
|
||||||
processRequest (HTTP::Port const& port, std::string const& request,
|
processRequest (HTTP::Port const& port, std::string const& request,
|
||||||
beast::IP::Endpoint const& remoteIPAddress);
|
beast::IP::Endpoint const& remoteIPAddress, Output, Yield);
|
||||||
|
|
||||||
//
|
//
|
||||||
// PropertyStream
|
// PropertyStream
|
||||||
|
|||||||
Reference in New Issue
Block a user