20#include <xrpld/app/main/Application.h> 
   21#include <xrpld/app/misc/NetworkOPs.h> 
   22#include <xrpld/core/ConfigSections.h> 
   23#include <xrpld/core/JobQueue.h> 
   24#include <xrpld/overlay/Overlay.h> 
   25#include <xrpld/rpc/RPCHandler.h> 
   26#include <xrpld/rpc/Role.h> 
   27#include <xrpld/rpc/ServerHandler.h> 
   28#include <xrpld/rpc/detail/Tuning.h> 
   29#include <xrpld/rpc/json_body.h> 
   31#include <xrpl/basics/Log.h> 
   32#include <xrpl/basics/base64.h> 
   33#include <xrpl/basics/contract.h> 
   34#include <xrpl/basics/make_SSLContext.h> 
   35#include <xrpl/beast/net/IPAddressConversion.h> 
   36#include <xrpl/beast/rfc2616.h> 
   37#include <xrpl/json/json_reader.h> 
   38#include <xrpl/json/to_string.h> 
   39#include <xrpl/protocol/ApiVersion.h> 
   40#include <xrpl/protocol/ErrorCodes.h> 
   41#include <xrpl/protocol/RPCErr.h> 
   42#include <xrpl/resource/Fees.h> 
   43#include <xrpl/resource/ResourceManager.h> 
   44#include <xrpl/server/Server.h> 
   45#include <xrpl/server/SimpleWriter.h> 
   46#include <xrpl/server/detail/JSONRPCUtil.h> 
   48#include <boost/algorithm/string.hpp> 
   49#include <boost/beast/http/fields.hpp> 
   50#include <boost/beast/http/string_body.hpp> 
   60    return request.version() >= 11 && request.target() == 
"/" &&
 
   61        request.body().size() == 0 &&
 
   62        request.method() == boost::beast::http::verb::get;
 
 
   68    boost::beast::http::status status)
 
   70    using namespace boost::beast::http;
 
   72    response<string_body> msg;
 
   73    msg.version(request.version());
 
   76    msg.insert(
"Content-Type", 
"text/html");
 
   77    msg.insert(
"Connection", 
"close");
 
   78    msg.body() = 
"Invalid protocol.";
 
   79    msg.prepare_payload();
 
 
   91    auto const it = h.
find(
"authorization");
 
   92    if ((it == h.
end()) || (it->second.substr(0, 6) != 
"Basic "))
 
   95    boost::trim(strUserPass64);
 
   97    std::string::size_type nColon = strUserPass.
find(
":");
 
   98    if (nColon == std::string::npos)
 
  102    return strUser == port.
user && strPassword == port.
password;
 
 
  108    boost::asio::io_context& io_context,
 
  114    , m_resourceManager(resourceManager)
 
  115    , m_journal(app_.journal(
"Server"))
 
  116    , m_networkOPs(networkOPs)
 
  117    , m_server(
make_Server(*this, io_context, app_.journal(
"Server")))
 
  118    , m_jobQueue(jobQueue)
 
  120    auto const& group(cm.
group(
"rpc"));
 
 
  142            auto const endpointPort = it->second.port();
 
  144                port.port = endpointPort;
 
  147                (port.protocol.count(
"http") > 0 ||
 
  148                 port.protocol.count(
"https") > 0))
 
  151            if (!
setup_.
overlay.port() && (port.protocol.count(
"peer") > 0))
 
 
  174    boost::asio::ip::tcp::endpoint endpoint)
 
  176    auto const& port = session.
port();
 
  178    auto const c = [
this, &port]() {
 
  183    if (port.limit && c >= port.limit)
 
  186            << port.name << 
" is full; dropping " << endpoint;
 
 
  198    boost::asio::ip::tcp::endpoint 
const& remote_address)
 
  200    using namespace boost::beast;
 
  203        p.
count(
"ws") > 0 || p.count(
"ws2") > 0 || p.count(
"wss") > 0 ||
 
  204        p.count(
"wss2") > 0};
 
  206    if (websocket::is_upgrade(request))
 
  219                << 
"Exception upgrading websocket: " << e.
what() << 
"\n";
 
  221                request, http::status::internal_server_error);
 
  225        auto const beast_remote_address =
 
  229            beast_remote_address,
 
  234                beast_remote_address,
 
  237            is->forwarded_for());
 
  238        ws->appDefined = std::move(is);
 
  242        handoff.
moved = 
true;
 
  246    if (bundle && p.count(
"peer") > 0)
 
  248            std::move(bundle), std::move(request), remote_address);
 
 
  260    return [&](boost::beast::string_view 
const& b) {
 
  261        session.
write(b.data(), b.size());
 
 
  269    for (
auto const& e : h)
 
  275            return std::tolower(static_cast<unsigned char>(kc));
 
 
  282template <
class ConstBufferSequence>
 
  286    using boost::asio::buffer_size;
 
  292        s.
append(
static_cast<char const*
>(b.data()), buffer_size(b));
 
 
  323    if (postResult == 
nullptr)
 
  328            "Service Unavailable",
 
  331        detachedSession->close(
true);
 
 
  342    auto const size = boost::asio::buffer_size(buffers);
 
  347        jvResult[jss::type] = jss::error;
 
  348        jvResult[jss::error] = 
"jsonInvalid";
 
  350        boost::beast::multi_buffer sb;
 
  351        Json::stream(jvResult, [&sb](
auto const p, 
auto const n) {
 
  352            sb.commit(boost::asio::buffer_copy(
 
  353                sb.prepare(n), boost::asio::buffer(p, n)));
 
  355        JLOG(
m_journal.
trace()) << 
"Websocket sending '" << jvResult << 
"'";
 
  367        [
this, session, jv = std::move(jv)](
 
  371            auto const n = s.length();
 
  372            boost::beast::multi_buffer sb(n);
 
  373            sb.commit(boost::asio::buffer_copy(
 
  374                sb.prepare(n), boost::asio::buffer(s.c_str(), n)));
 
  379    if (postResult == 
nullptr)
 
  382        session->close({boost::beast::websocket::going_away, 
"Shutting Down"});
 
 
  410    using namespace std::chrono_literals;
 
  411    auto const level = (duration >= 10s) ? journal.
error()
 
  412        : (duration >= 1s)               ? journal.
warn()
 
  415    JLOG(level) << 
"RPC request processing duration = " 
  416                << std::chrono::duration_cast<std::chrono::microseconds>(
 
  419                << 
" microseconds. request = " << request;
 
 
  429    if (is->getConsumer().disconnect(
m_journal))
 
  432            {boost::beast::websocket::policy_error, 
"threshold exceeded"});
 
  452            jr[jss::type] = jss::response;
 
  453            jr[jss::status] = jss::error;
 
  455                ? jss::invalid_API_version
 
  456                : jss::missingCommand;
 
  457            jr[jss::request] = jv;
 
  459                jr[jss::id] = jv[jss::id];
 
  461                jr[jss::jsonrpc] = jv[jss::jsonrpc];
 
  463                jr[jss::ripplerpc] = jv[jss::ripplerpc];
 
  465                jr[jss::api_version] = jv[jss::api_version];
 
  501                {is->user(), is->forwarded_for()}};
 
  514            << 
"Exception while processing WS: " << ex.
what() << 
"\n" 
  519    is->getConsumer().charge(loadType);
 
  520    if (is->getConsumer().warn())
 
  521        jr[jss::warning] = jss::load;
 
  528    if (jr[jss::result].isMember(jss::error))
 
  530        jr = jr[jss::result];
 
  531        jr[jss::status] = jss::error;
 
  537            if (rq.isMember(jss::passphrase.c_str()))
 
  538                rq[jss::passphrase.c_str()] = 
"<masked>";
 
  539            if (rq.isMember(jss::secret.c_str()))
 
  540                rq[jss::secret.c_str()] = 
"<masked>";
 
  541            if (rq.isMember(jss::seed.c_str()))
 
  542                rq[jss::seed.c_str()] = 
"<masked>";
 
  543            if (rq.isMember(jss::seed_hex.c_str()))
 
  544                rq[jss::seed_hex.c_str()] = 
"<masked>";
 
  547        jr[jss::request] = rq;
 
  551        if (jr[jss::result].isMember(
"forwarded") &&
 
  552            jr[jss::result][
"forwarded"])
 
  553            jr = jr[jss::result];
 
  554        jr[jss::status] = jss::success;
 
  558        jr[jss::id] = jv[jss::id];
 
  560        jr[jss::jsonrpc] = jv[jss::jsonrpc];
 
  562        jr[jss::ripplerpc] = jv[jss::ripplerpc];
 
  564        jr[jss::api_version] = jv[jss::api_version];
 
  566    jr[jss::type] = jss::response;
 
 
  579        session->remoteAddress().at_port(0),
 
  584            auto const iter = session->request().find(
"X-User");
 
  585            if (iter != session->request().end())
 
  586                return iter->value();
 
  587            return boost::beast::string_view{};
 
  593        session->close(
true);
 
 
  601    sub[
"message"] = std::move(message);
 
 
  613ServerHandler::processRequest(
 
  622    auto rpcJ = app_.journal(
"RPC");
 
  627        if ((request.
size() > RPC::Tuning::maxRequestSize) ||
 
  628            !reader.
parse(request, jsonOrig) || !jsonOrig ||
 
  642    if (jsonOrig.
isMember(jss::method) && jsonOrig[jss::method] == 
"batch")
 
  645        if (!jsonOrig.
isMember(jss::params) || !jsonOrig[jss::params].
isArray())
 
  647            HTTPReply(400, 
"Malformed batch request", output, rpcJ);
 
  650        size = jsonOrig[jss::params].
size();
 
  655    for (
unsigned i = 0; i < size; ++i)
 
  658            batch ? jsonOrig[jss::params][i] : jsonOrig;
 
  663            r[jss::request] = jsonRPC;
 
  670        unsigned apiVersion = RPC::apiVersionIfUnspecified;
 
  672            jsonRPC[jss::params].
size() > 0 &&
 
  673            jsonRPC[jss::params][0u].
isObject())
 
  675            apiVersion = RPC::getAPIVersionNumber(
 
  677                app_.config().BETA_RPC_API);
 
  680        if (apiVersion == RPC::apiVersionIfUnspecified && 
batch)
 
  684                RPC::getAPIVersionNumber(jsonRPC, app_.config().BETA_RPC_API);
 
  687        if (apiVersion == RPC::apiInvalidVersion)
 
  691                HTTPReply(400, jss::invalid_API_version.c_str(), output, rpcJ);
 
  695            r[jss::request] = jsonRPC;
 
  703        auto role = Role::FORBID;
 
  704        auto required = Role::FORBID;
 
  706            required = RPC::roleRequired(
 
  708                app_.config().BETA_RPC_API,
 
  712            jsonRPC[jss::params].
size() > 0 &&
 
  731            usage = m_resourceManager.newUnlimitedEndpoint(remoteIPAddress);
 
  735            usage = m_resourceManager.newInboundEndpoint(
 
  741                    HTTPReply(503, 
"Server is overloaded", output, rpcJ);
 
  752        if (role == Role::FORBID)
 
  754            usage.
charge(Resource::feeMalformedRPC);
 
  757                HTTPReply(403, 
"Forbidden", output, rpcJ);
 
  766        if (!jsonRPC.
isMember(jss::method) || jsonRPC[jss::method].
isNull())
 
  768            usage.
charge(Resource::feeMalformedRPC);
 
  771                HTTPReply(400, 
"Null method", output, rpcJ);
 
  783            usage.
charge(Resource::feeMalformedRPC);
 
  786                HTTPReply(400, 
"method is not string", output, rpcJ);
 
  797        if (strMethod.
empty())
 
  799            usage.
charge(Resource::feeMalformedRPC);
 
  802                HTTPReply(400, 
"method is empty", output, rpcJ);
 
  821            params = jsonRPC[jss::params];
 
  827                usage.
charge(Resource::feeMalformedRPC);
 
  828                HTTPReply(400, 
"params unparseable", output, rpcJ);
 
  833                params = std::move(params[0u]);
 
  836                    usage.
charge(Resource::feeMalformedRPC);
 
  837                    HTTPReply(400, 
"params unparseable", output, rpcJ);
 
  848        if (params.
isMember(jss::ripplerpc))
 
  850            if (!params[jss::ripplerpc].isString())
 
  852                usage.
charge(Resource::feeMalformedRPC);
 
  855                    HTTPReply(400, 
"ripplerpc is not a string", output, rpcJ);
 
  865            ripplerpc = params[jss::ripplerpc].
asString();
 
  872        if (role != Role::IDENTIFIED && role != Role::PROXY)
 
  878        JLOG(m_journal.debug()) << 
"Query: " << strMethod << params;
 
  881        params[jss::command] = strMethod;
 
  882        JLOG(m_journal.trace())
 
  883            << 
"doRpcCommand:" << strMethod << 
":" << params;
 
  892             app_.getLedgerMaster(),
 
  906            RPC::doCommand(context, result);
 
  912            JLOG(m_journal.error()) << 
"Internal error : " << ex.
what()
 
  913                                    << 
" when processing request: " 
  924            result[jss::warning] = jss::load;
 
  927        if (ripplerpc >= 
"2.0")
 
  931                result[jss::status] = jss::error;
 
  932                result[
"code"] = result[jss::error_code];
 
  933                result[
"message"] = result[jss::error_message];
 
  935                JLOG(m_journal.debug()) << 
"rpcError: " << result[jss::error]
 
  936                                        << 
": " << result[jss::error_message];
 
  937                r[jss::error] = std::move(result);
 
  941                result[jss::status] = jss::success;
 
  942                r[jss::result] = std::move(result);
 
  955                    if (rq.isMember(jss::passphrase.c_str()))
 
  956                        rq[jss::passphrase.c_str()] = 
"<masked>";
 
  957                    if (rq.isMember(jss::secret.c_str()))
 
  958                        rq[jss::secret.c_str()] = 
"<masked>";
 
  959                    if (rq.isMember(jss::seed.c_str()))
 
  960                        rq[jss::seed.c_str()] = 
"<masked>";
 
  961                    if (rq.isMember(jss::seed_hex.c_str()))
 
  962                        rq[jss::seed_hex.c_str()] = 
"<masked>";
 
  965                result[jss::status] = jss::error;
 
  966                result[jss::request] = rq;
 
  968                JLOG(m_journal.debug()) << 
"rpcError: " << result[jss::error]
 
  969                                        << 
": " << result[jss::error_message];
 
  973                result[jss::status] = jss::success;
 
  975            r[jss::result] = std::move(result);
 
  979            r[jss::jsonrpc] = params[jss::jsonrpc];
 
  980        if (params.
isMember(jss::ripplerpc))
 
  981            r[jss::ripplerpc] = params[jss::ripplerpc];
 
  983            r[jss::id] = params[jss::id];
 
  985            reply.
append(std::move(r));
 
  987            reply = std::move(r);
 
  990            reply[jss::result].
isMember(jss::result))
 
  992            reply = reply[jss::result];
 
  995                reply[jss::result][jss::status] = reply[jss::status];
 
 1002    int const httpStatus = [&reply]() {
 
 1005        if (reply.
isMember(jss::ripplerpc) &&
 
 1006            reply[jss::ripplerpc].
isString() &&
 
 1007            reply[jss::ripplerpc].
asString() >= 
"3.0")
 
 1011                reply[jss::error].
isMember(jss::error_code) &&
 
 1012                reply[jss::error][jss::error_code].
isInt())
 
 1014                int const errCode = reply[jss::error][jss::error_code].
asInt();
 
 1015                return RPC::error_code_http_status(
 
 1023    auto response = to_string(reply);
 
 1025    rpc_time_.notify(std::chrono::duration_cast<std::chrono::milliseconds>(
 
 1032    if (
auto stream = m_journal.debug())
 
 1034        static int const maxSize = 10000;
 
 1035        if (response.size() <= maxSize)
 
 1036            stream << 
"Reply: " << response;
 
 1038            stream << 
"Reply: " << response.substr(0, maxSize);
 
 1041    HTTPReply(httpStatus, response, output, rpcJ);
 
 
 1053    using namespace boost::beast::http;
 
 1055    response<string_body> msg;
 
 1057    if (app_.serverOkay(reason))
 
 1059        msg.result(boost::beast::http::status::ok);
 
 1060        msg.body() = 
"<!DOCTYPE html><html><head><title>" + systemName() +
 
 1061            " Test page for rippled</title></head><body><h1>" + systemName() +
 
 1062            " Test</h1><p>This page shows rippled http(s) " 
 1063            "connectivity is working.</p></body></html>";
 
 1067        msg.result(boost::beast::http::status::internal_server_error);
 
 1068        msg.body() = 
"<HTML><BODY>Server cannot accept clients: " + reason +
 
 1071    msg.version(request.version());
 
 1072    msg.
insert(
"Server", BuildInfo::getFullVersionString());
 
 1073    msg.insert(
"Content-Type", 
"text/html");
 
 1074    msg.insert(
"Connection", 
"close");
 
 1075    msg.prepare_payload();
 
 
 1083ServerHandler::Setup::makeContexts()
 
 1085    for (
auto& p : ports)
 
 1089            if (p.ssl_key.empty() && p.ssl_cert.empty() && p.ssl_chain.empty())
 
 1093                    p.ssl_key, p.ssl_cert, p.ssl_chain, p.ssl_ciphers);
 
 1098                boost::asio::ssl::context::sslv23);
 
 
 1111        log << 
"Missing 'ip' in [" << p.
name << 
"]";
 
 1112        Throw<std::exception>();
 
 1118        log << 
"Missing 'port' in [" << p.
name << 
"]";
 
 1119        Throw<std::exception>();
 
 1125        log << 
"Missing 'protocol' in [" << p.
name << 
"]";
 
 1126        Throw<std::exception>();
 
 
 1154    if (!config.
exists(
"server"))
 
 1156        log << 
"Required section [server] is missing";
 
 1157        Throw<std::exception>();
 
 1165    for (
auto const& name : names)
 
 1167        if (!config.
exists(name))
 
 1169            log << 
"Missing section: [" << name << 
"]";
 
 1170            Throw<std::exception>();
 
 1175        if (name == SECTION_PORT_GRPC)
 
 1185        auto it = result.
begin();
 
 1187        while (it != result.
end())
 
 1189            auto& p = it->protocol;
 
 1193            if (p.erase(
"peer") && p.empty())
 
 1194                it = result.
erase(it);
 
 1203                return p.protocol.count(
"peer") != 0;
 
 1208            log << 
"Error: More than one peer protocol configured in [server]";
 
 1209            Throw<std::exception>();
 
 1213            log << 
"Warning: No peer protocol configured";
 
 
 1223    decltype(setup.
ports)::const_iterator iter;
 
 1224    for (iter = setup.
ports.cbegin(); iter != setup.
ports.cend(); ++iter)
 
 1225        if (iter->protocol.count(
"http") > 0 ||
 
 1226            iter->protocol.count(
"https") > 0)
 
 1228    if (iter == setup.
ports.cend())
 
 1230    setup.
client.
secure = iter->protocol.count(
"https") > 0;
 
 1234        (iter->ip.is_v6() ? 
"::1" : 
"127.0.0.1")
 
 1235        : iter->ip.to_string();
 
 
 1249            return port.protocol.count(
"peer") != 0;
 
 1251    if (iter == setup.
ports.cend())
 
 1256    setup.
overlay = {iter->ip, iter->port};
 
 
 1274    boost::asio::io_context& io_context,
 
 
Decorator for streaming out compact json.
 
Unserialize a JSON document into a Value.
 
std::string getFormatedErrorMessages() const
Returns a user friendly string that list errors in the parsed document.
 
bool parse(std::string const &document, Value &root)
Read a Value from a JSON document.
 
Value & append(Value const &value)
Append value to array at the end.
 
UInt size() const
Number of values in array or object.
 
bool isObjectOrNull() const
 
Value removeMember(char const *key)
Remove and return the named member.
 
std::string asString() const
Returns the unquoted string value.
 
bool isNull() const
isNull() tests to see if this field is null.
 
bool isMember(char const *key) const
Return true if the object has a member named key.
 
A version-independent IP address and port combination.
 
A generic endpoint for log messages.
 
Stream trace() const
Severity stream access functions.
 
virtual Config & config()=0
 
virtual Overlay & overlay()=0
 
virtual beast::Journal journal(std::string const &name)=0
 
virtual NetworkOPs & getOPs()=0
 
virtual LedgerMaster & getLedgerMaster()=0
 
bool exists(std::string const &name) const
Returns true if a section with the given name exists.
 
Section & section(std::string const &name)
Returns the section with the given name.
 
Provides the beast::insight::Collector service.
 
virtual beast::insight::Group::ptr const & group(std::string const &name)=0
 
A pool of threads to perform work.
 
std::shared_ptr< Coro > postCoro(JobType t, std::string const &name, F &&f)
Creates a coroutine and adds a job to the queue which will run it.
 
Provides server functionality for clients.
 
virtual Handoff onHandoff(std::unique_ptr< stream_type > &&bundle, http_request_type &&request, boost::asio::ip::tcp::endpoint remote_address)=0
Conditionally accept an incoming HTTP request.
 
An endpoint that consumes resources.
 
bool warn()
Returns true if the consumer should be warned.
 
bool disconnect(beast::Journal const &j)
Returns true if the consumer should be disconnected.
 
Disposition charge(Charge const &fee, std::string const &context={})
Apply a load charge to the consumer.
 
Tracks load and resource consumption.
 
std::vector< std::string > const & values() const
Returns all the values in the section.
 
Resource::Manager & m_resourceManager
 
std::condition_variable condition_
 
Json::Value processSession(std::shared_ptr< WSSession > const &session, std::shared_ptr< JobQueue::Coro > const &coro, Json::Value const &jv)
 
void onWSMessage(std::shared_ptr< WSSession > session, std::vector< boost::asio::const_buffer > const &buffers)
 
std::unique_ptr< Server > m_server
 
ServerHandler(ServerHandlerCreator const &, Application &app, boost::asio::io_context &io_context, JobQueue &jobQueue, NetworkOPs &networkOPs, Resource::Manager &resourceManager, CollectorManager &cm)
 
beast::insight::Event rpc_size_
 
Setup const & setup() const
 
beast::insight::Counter rpc_requests_
 
void onClose(Session &session, boost::system::error_code const &)
 
Handoff statusResponse(http_request_type const &request) const
 
NetworkOPs & m_networkOPs
 
beast::insight::Event rpc_time_
 
bool onAccept(Session &session, boost::asio::ip::tcp::endpoint endpoint)
 
std::map< std::reference_wrapper< Port const  >, int > count_
 
void onRequest(Session &session)
 
void processRequest(Port const &port, std::string const &request, beast::IP::Endpoint const &remoteIPAddress, Output &&, std::shared_ptr< JobQueue::Coro > coro, std::string_view forwardedFor, std::string_view user)
 
Handoff onHandoff(Session &session, std::unique_ptr< stream_type > &&bundle, http_request_type &&request, boost::asio::ip::tcp::endpoint const &remote_address)
 
Persistent state information for a connection session.
 
virtual std::shared_ptr< WSSession > websocketUpgrade()=0
Convert the connection to WebSocket.
 
virtual Port const & port()=0
Returns the Port settings for this connection.
 
virtual std::shared_ptr< Session > detach()=0
Detach the session.
 
virtual void close(bool graceful)=0
Close the session.
 
virtual http_request_type & request()=0
Returns the current HTTP request.
 
void write(std::string const &s)
Send a copy of data asynchronously.
 
void stream(Json::Value const &jv, Write const &write)
Stream compact JSON to the specified function.
 
@ arrayValue
array value (ordered list)
 
@ objectValue
object value (collection of name/value pairs).
 
Endpoint from_asio(boost::asio::ip::address const &address)
Convert to Endpoint.
 
bool is_unspecified(Address const &addr)
Returns true if the address is unspecified.
 
bool is_keep_alive(boost::beast::http::message< isRequest, Body, Fields > const &m)
 
std::string const & getFullVersionString()
Full server version string.
 
static int constexpr maxRequestSize
 
Json::Value make_error(error_code_i code)
Returns a new json object that reflects the error code.
 
Role roleRequired(unsigned int version, bool betaEnabled, std::string const &method)
 
Status doCommand(RPC::JsonContext &context, Json::Value &result)
Execute an RPC command and store the results in a Json::Value.
 
static constexpr auto apiInvalidVersion
 
unsigned int getAPIVersionNumber(Json::Value const &jv, bool betaEnabled)
Retrieve the api version number from the json value.
 
Charge const feeReferenceRPC
 
Charge const feeMalformedRPC
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
void HTTPReply(int nStatus, std::string const &strMsg, Json::Output const &, beast::Journal j)
 
static std::vector< Port > parse_Ports(Config const &config, std::ostream &log)
 
static Port to_Port(ParsedPort const &parsed, std::ostream &log)
 
static Json::Output makeOutput(Session &session)
 
std::unique_ptr< Server > make_Server(Handler &handler, boost::asio::io_context &io_context, beast::Journal journal)
Create the HTTP server using the specified handler.
 
Resource::Consumer requestInboundEndpoint(Resource::Manager &manager, beast::IP::Endpoint const &remoteAddress, Role const &role, std::string_view user, std::string_view forwardedFor)
 
Json::Int constexpr wrong_version
 
static Json::Value make_json_error(Json::Int code, Json::Value &&message)
 
std::string base64_decode(std::string_view data)
 
void parse_Port(ParsedPort &port, Section const §ion, std::ostream &log)
 
Json::Value rpcError(int iError)
 
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
 
std::shared_ptr< boost::asio::ssl::context > make_SSLContext(std::string const &cipherList)
Create a self-signed SSL context that allows anonymous Diffie Hellman.
 
Json::Int constexpr method_not_found
 
Json::Int constexpr forbidden
 
ServerHandler::Setup setup_ServerHandler(Config const &config, std::ostream &&log)
 
void logDuration(Json::Value const &request, T const &duration, beast::Journal &journal)
 
std::string_view forwardedFor(http_request_type const &request)
 
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
 
std::unique_ptr< ServerHandler > make_ServerHandler(Application &app, boost::asio::io_context &io_context, JobQueue &jobQueue, NetworkOPs &networkOPs, Resource::Manager &resourceManager, CollectorManager &cm)
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
static Handoff statusRequestResponse(http_request_type const &request, boost::beast::http::status status)
 
static std::string buffers_to_string(ConstBufferSequence const &bs)
 
static void setup_Client(ServerHandler::Setup &setup)
 
std::shared_ptr< boost::asio::ssl::context > make_SSLContextAuthed(std::string const &keyFile, std::string const &certFile, std::string const &chainFile, std::string const &cipherList)
Create an authenticated SSL context using the specified files.
 
Overlay::Setup setup_Overlay(BasicConfig const &config)
 
Role requestRole(Role const &required, Port const &port, Json::Value const ¶ms, beast::IP::Endpoint const &remoteIp, std::string_view user)
Return the allowed privilege role.
 
static std::map< std::string, std::string > build_map(boost::beast::http::fields const &h)
 
static bool isStatusRequest(http_request_type const &request)
 
static bool authorized(Port const &port, std::map< std::string, std::string > const &h)
 
Json::Int constexpr server_overloaded
 
T remove_suffix(T... args)
 
static IP::Endpoint from_asio(boost::asio::ip::address const &address)
 
Used to indicate the result of a server connection handoff.
 
std::shared_ptr< Writer > response
 
boost::beast::websocket::permessage_deflate pmd_options
 
std::optional< std::uint16_t > port
 
std::vector< boost::asio::ip::network_v4 > admin_nets_v4
 
std::uint16_t ws_queue_limit
 
std::vector< boost::asio::ip::network_v6 > secure_gateway_nets_v6
 
std::set< std::string, boost::beast::iless > protocol
 
std::string admin_password
 
std::vector< boost::asio::ip::network_v6 > admin_nets_v6
 
std::optional< boost::asio::ip::address > ip
 
std::vector< boost::asio::ip::network_v4 > secure_gateway_nets_v4
 
Configuration information for a Server listening port.
 
std::vector< boost::asio::ip::network_v6 > admin_nets_v6
 
std::set< std::string, boost::beast::iless > protocol
 
std::vector< boost::asio::ip::network_v6 > secure_gateway_nets_v6
 
std::vector< boost::asio::ip::network_v4 > secure_gateway_nets_v4
 
boost::asio::ip::address ip
 
std::uint16_t ws_queue_limit
 
std::string admin_password
 
std::vector< boost::asio::ip::network_v4 > admin_nets_v4
 
boost::beast::websocket::permessage_deflate pmd_options
 
std::string admin_password
 
boost::asio::ip::tcp::endpoint overlay
 
std::vector< Port > ports