// VFALCO ARGH! returning a single std::string for the entire response?
std::string
ServerHandlerImp::processRequest (std::string const& request,
    beast::IP::Endpoint const& remoteIPAddress)
{
    Json::Value jvRequest;
    {
        Json::Reader reader;
        if ((request.size () > 1000000) ||
            ! reader.parse (request, jvRequest) ||
            jvRequest.isNull () ||
            ! jvRequest.isObject ())
        {
            return createResponse (400, "Unable to parse request");
        }
    }

    auto const role = getConfig ().getAdminRole (jvRequest, remoteIPAddress);

    Resource::Consumer usage;

    if (role == Config::ADMIN)
        usage = m_resourceManager.newAdminEndpoint (remoteIPAddress.to_string());
    else
        usage = m_resourceManager.newInboundEndpoint(remoteIPAddress);

    if (usage.disconnect ())
        return createResponse (503, "Server is overloaded");

    // Parse id now so errors from here on will have the id
    //
    // VFALCO NOTE Except that "id" isn't included in the following errors.
    //
    Json::Value const id = jvRequest ["id"];

    Json::Value const method = jvRequest ["method"];

    if (method.isNull ())
        return createResponse (400, "Null method");

    if (! method.isString ())
        return createResponse (400, "method is not string");

    std::string strMethod = method.asString ();
    if (strMethod.empty())
        return createResponse (400, "method is empty");

    // Parse params
    Json::Value params = jvRequest ["params"];

    if (params.isNull ())
        params = Json::Value (Json::arrayValue);

    else if (!params.isArray ())
        return HTTPReply (400, "params unparseable");

    // VFALCO TODO Shouldn't we handle this earlier?
    //
    if (role == Config::FORBID)
    {
        // VFALCO TODO Needs implementing
        // FIXME Needs implementing
        // XXX This needs rate limiting to prevent brute forcing password.
        return HTTPReply (403, "Forbidden");
    }


    std::string response;
    RPCHandler rpcHandler (m_networkOPs);
    Resource::Charge loadType = Resource::feeReferenceRPC;

    m_journal.debug << "Query: " << strMethod << params;

    Json::Value const result (rpcHandler.doRpcCommand (
        strMethod, params, role, loadType));
    m_journal.debug << "Reply: " << result;

    usage.charge (loadType);

    response = JSONRPCReply (result, Json::Value (), id);

    return createResponse (200, response);
}
Beispiel #2
0
    // Stolen directly from RPCServerHandler
    std::string processRequest (std::string const& request, std::string const& remoteAddress)
    {
        Json::Value jvRequest;
        {
            Json::Reader reader;

            if (! reader.parse (request, jvRequest) ||
                jvRequest.isNull () ||
                ! jvRequest.isObject ())
            {
                return createResponse (400, "Unable to parse request");
            }
        }

        Config::Role const role (getConfig ().getAdminRole (jvRequest, remoteAddress));

        // Parse id now so errors from here on will have the id
        //
        // VFALCO NOTE Except that "id" isn't included in the following errors...
        //
        Json::Value const id = jvRequest ["id"];

        Json::Value const method = jvRequest ["method"];

        if (method.isNull ())
        {
            return createResponse (400, "Null method");
        }
        else if (! method.isString ())
        {
            return createResponse (400, "method is not string");
        }

        std::string strMethod = method.asString ();

        // Parse params
        Json::Value params = jvRequest ["params"];

        if (params.isNull ())
        {
            params = Json::Value (Json::arrayValue);
        }
        else if (!params.isArray ())
        {
            return HTTPReply (400, "params unparseable");
        }

        // VFALCO TODO Shouldn't we handle this earlier?
        //
        if (role == Config::FORBID)
        {
            // VFALCO TODO Needs implementing
            // FIXME Needs implementing
            // XXX This needs rate limiting to prevent brute forcing password.
            return HTTPReply (403, "Forbidden");
        }

        // This code does all the work on the io_service thread and
        // has no rate-limiting based on source IP or anything.
        // This is a temporary safety
        if ((role != Config::ADMIN) && (getApp().getFeeTrack().isLoadedLocal()))
        {
            return HTTPReply (503, "Unable to service at this time");
        }

        std::string response;

        m_journal.debug << "Query: " << strMethod << params;

        RPCHandler rpcHandler (&m_networkOPs);

        LoadType loadType = LT_RPCReference;

        Json::Value const result (rpcHandler.doRpcCommand (
            strMethod, params, role, &loadType));
        // VFALCO NOTE We discard loadType since there is no endpoint to punish

        m_journal.debug << "Reply: " << result;

        response = JSONRPCReply (result, Json::Value (), id);

        return createResponse (200, response);
    }