rippled
ServerHandlerImp.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/app/main/Application.h>
21 #include <ripple/app/misc/NetworkOPs.h>
22 #include <ripple/basics/Log.h>
23 #include <ripple/basics/base64.h>
24 #include <ripple/basics/contract.h>
25 #include <ripple/basics/make_SSLContext.h>
26 #include <ripple/beast/net/IPAddressConversion.h>
27 #include <ripple/beast/rfc2616.h>
28 #include <ripple/core/JobQueue.h>
29 #include <ripple/json/json_reader.h>
30 #include <ripple/json/to_string.h>
31 #include <ripple/net/RPCErr.h>
32 #include <ripple/overlay/Overlay.h>
33 #include <ripple/resource/Fees.h>
34 #include <ripple/resource/ResourceManager.h>
35 #include <ripple/rpc/RPCHandler.h>
36 #include <ripple/rpc/Role.h>
37 #include <ripple/rpc/ServerHandler.h>
38 #include <ripple/rpc/impl/RPCHelpers.h>
39 #include <ripple/rpc/impl/ServerHandlerImp.h>
40 #include <ripple/rpc/impl/Tuning.h>
41 #include <ripple/rpc/json_body.h>
42 #include <ripple/server/Server.h>
43 #include <ripple/server/SimpleWriter.h>
44 #include <ripple/server/impl/JSONRPCUtil.h>
45 #include <boost/algorithm/string.hpp>
46 #include <boost/beast/http/fields.hpp>
47 #include <boost/beast/http/string_body.hpp>
48 #include <boost/optional.hpp>
49 #include <boost/regex.hpp>
50 #include <boost/type_traits.hpp>
51 #include <algorithm>
52 #include <stdexcept>
53 
54 namespace ripple {
55 
56 static bool
58 {
59  return request.version() >= 11 && request.target() == "/" &&
60  request.body().size() == 0 &&
61  request.method() == boost::beast::http::verb::get;
62 }
63 
64 static Handoff
66  http_request_type const& request,
67  boost::beast::http::status status)
68 {
69  using namespace boost::beast::http;
70  Handoff handoff;
71  response<string_body> msg;
72  msg.version(request.version());
73  msg.result(status);
74  msg.insert("Server", BuildInfo::getFullVersionString());
75  msg.insert("Content-Type", "text/html");
76  msg.insert("Connection", "close");
77  msg.body() = "Invalid protocol.";
78  msg.prepare_payload();
79  handoff.response = std::make_shared<SimpleWriter>(msg);
80  return handoff;
81 }
82 
83 // VFALCO TODO Rewrite to use boost::beast::http::fields
84 static bool
86 {
87  if (port.user.empty() || port.password.empty())
88  return true;
89 
90  auto const it = h.find("authorization");
91  if ((it == h.end()) || (it->second.substr(0, 6) != "Basic "))
92  return false;
93  std::string strUserPass64 = it->second.substr(6);
94  boost::trim(strUserPass64);
95  std::string strUserPass = base64_decode(strUserPass64);
96  std::string::size_type nColon = strUserPass.find(":");
97  if (nColon == std::string::npos)
98  return false;
99  std::string strUser = strUserPass.substr(0, nColon);
100  std::string strPassword = strUserPass.substr(nColon + 1);
101  return strUser == port.user && strPassword == port.password;
102 }
103 
105  Application& app,
106  Stoppable& parent,
107  boost::asio::io_service& io_service,
108  JobQueue& jobQueue,
109  NetworkOPs& networkOPs,
110  Resource::Manager& resourceManager,
111  CollectorManager& cm)
112  : Stoppable("ServerHandler", parent)
113  , app_(app)
114  , m_resourceManager(resourceManager)
115  , m_journal(app_.journal("Server"))
116  , m_networkOPs(networkOPs)
117  , m_server(make_Server(*this, io_service, app_.journal("Server")))
118  , m_jobQueue(jobQueue)
119 {
120  auto const& group(cm.group("rpc"));
121  rpc_requests_ = group->make_counter("requests");
122  rpc_size_ = group->make_event("size");
123  rpc_time_ = group->make_event("time");
124 }
125 
127 {
128  m_server = nullptr;
129 }
130 
131 void
133 {
134  setup_ = setup;
135  m_server->ports(setup.ports);
136 }
137 
138 //------------------------------------------------------------------------------
139 
140 void
142 {
143  m_server->close();
144 }
145 
146 //------------------------------------------------------------------------------
147 
148 bool
150  Session& session,
151  boost::asio::ip::tcp::endpoint endpoint)
152 {
154 
155  auto const c = ++count_[session.port()];
156 
157  if (session.port().limit && c >= session.port().limit)
158  {
159  JLOG(m_journal.trace())
160  << session.port().name << " is full; dropping " << endpoint;
161  return false;
162  }
163 
164  return true;
165 }
166 
167 Handoff
169  Session& session,
171  http_request_type&& request,
172  boost::asio::ip::tcp::endpoint const& remote_address)
173 {
174  using namespace boost::beast;
175  auto const& p{session.port().protocol};
176  bool const is_ws{
177  p.count("ws") > 0 || p.count("ws2") > 0 || p.count("wss") > 0 ||
178  p.count("wss2") > 0};
179 
180  if (websocket::is_upgrade(request))
181  {
182  if (!is_ws)
183  return statusRequestResponse(request, http::status::unauthorized);
184 
186  try
187  {
188  ws = session.websocketUpgrade();
189  }
190  catch (std::exception const& e)
191  {
192  JLOG(m_journal.error())
193  << "Exception upgrading websocket: " << e.what() << "\n";
194  return statusRequestResponse(
195  request, http::status::internal_server_error);
196  }
197 
198  auto is{std::make_shared<WSInfoSub>(m_networkOPs, ws)};
199  auto const beast_remote_address =
201  is->getConsumer() = requestInboundEndpoint(
203  beast_remote_address,
204  requestRole(
205  Role::GUEST,
206  session.port(),
207  Json::Value(),
208  beast_remote_address,
209  is->user()),
210  is->user(),
211  is->forwarded_for());
212  ws->appDefined = std::move(is);
213  ws->run();
214 
215  Handoff handoff;
216  handoff.moved = true;
217  return handoff;
218  }
219 
220  if (bundle && p.count("peer") > 0)
221  return app_.overlay().onHandoff(
222  std::move(bundle), std::move(request), remote_address);
223 
224  if (is_ws && isStatusRequest(request))
225  return statusResponse(request);
226 
227  // Otherwise pass to legacy onRequest or websocket
228  return {};
229 }
230 
231 static inline Json::Output
233 {
234  return [&](boost::beast::string_view const& b) {
235  session.write(b.data(), b.size());
236  };
237 }
238 
240 build_map(boost::beast::http::fields const& h)
241 {
243  for (auto const& e : h)
244  {
245  auto key(e.name_string().to_string());
246  std::transform(key.begin(), key.end(), key.begin(), [](auto kc) {
247  return std::tolower(static_cast<unsigned char>(kc));
248  });
249  c[key] = e.value().to_string();
250  }
251  return c;
252 }
253 
254 template <class ConstBufferSequence>
255 static std::string
256 buffers_to_string(ConstBufferSequence const& bs)
257 {
258  using boost::asio::buffer_cast;
259  using boost::asio::buffer_size;
260  std::string s;
261  s.reserve(buffer_size(bs));
262  for (auto const& b : bs)
263  s.append(buffer_cast<char const*>(b), buffer_size(b));
264  return s;
265 }
266 
267 void
269 {
270  // Make sure RPC is enabled on the port
271  if (session.port().protocol.count("http") == 0 &&
272  session.port().protocol.count("https") == 0)
273  {
274  HTTPReply(403, "Forbidden", makeOutput(session), app_.journal("RPC"));
275  session.close(true);
276  return;
277  }
278 
279  // Check user/password authorization
280  if (!authorized(session.port(), build_map(session.request())))
281  {
282  HTTPReply(403, "Forbidden", makeOutput(session), app_.journal("RPC"));
283  session.close(true);
284  return;
285  }
286 
287  std::shared_ptr<Session> detachedSession = session.detach();
288  auto const postResult = m_jobQueue.postCoro(
289  jtCLIENT,
290  "RPC-Client",
291  [this, detachedSession](std::shared_ptr<JobQueue::Coro> coro) {
292  processSession(detachedSession, coro);
293  });
294  if (postResult == nullptr)
295  {
296  // The coroutine was rejected, probably because we're shutting down.
297  HTTPReply(
298  503,
299  "Service Unavailable",
300  makeOutput(*detachedSession),
301  app_.journal("RPC"));
302  detachedSession->close(true);
303  return;
304  }
305 }
306 
307 void
311 {
312  Json::Value jv;
313  auto const size = boost::asio::buffer_size(buffers);
314  if (size > RPC::Tuning::maxRequestSize ||
315  !Json::Reader{}.parse(jv, buffers) || !jv.isObject())
316  {
317  Json::Value jvResult(Json::objectValue);
318  jvResult[jss::type] = jss::error;
319  jvResult[jss::error] = "jsonInvalid";
320  jvResult[jss::value] = buffers_to_string(buffers);
321  boost::beast::multi_buffer sb;
322  Json::stream(jvResult, [&sb](auto const p, auto const n) {
323  sb.commit(boost::asio::buffer_copy(
324  sb.prepare(n), boost::asio::buffer(p, n)));
325  });
326  JLOG(m_journal.trace()) << "Websocket sending '" << jvResult << "'";
327  session->send(
328  std::make_shared<StreambufWSMsg<decltype(sb)>>(std::move(sb)));
329  session->complete();
330  return;
331  }
332 
333  JLOG(m_journal.trace()) << "Websocket received '" << jv << "'";
334 
335  auto const postResult = m_jobQueue.postCoro(
336  jtCLIENT,
337  "WS-Client",
338  [this, session, jv = std::move(jv)](
339  std::shared_ptr<JobQueue::Coro> const& coro) {
340  auto const jr = this->processSession(session, coro, jv);
341  auto const s = to_string(jr);
342  auto const n = s.length();
343  boost::beast::multi_buffer sb(n);
344  sb.commit(boost::asio::buffer_copy(
345  sb.prepare(n), boost::asio::buffer(s.c_str(), n)));
346  session->send(
347  std::make_shared<StreambufWSMsg<decltype(sb)>>(std::move(sb)));
348  session->complete();
349  });
350  if (postResult == nullptr)
351  {
352  // The coroutine was rejected, probably because we're shutting down.
353  session->close({boost::beast::websocket::going_away, "Shutting Down"});
354  }
355 }
356 
357 void
358 ServerHandlerImp::onClose(Session& session, boost::system::error_code const&)
359 {
361  --count_[session.port()];
362 }
363 
364 void
366 {
367  stopped();
368 }
369 
370 //------------------------------------------------------------------------------
371 
374  std::shared_ptr<WSSession> const& session,
376  Json::Value const& jv)
377 {
378  auto is = std::static_pointer_cast<WSInfoSub>(session->appDefined);
379  if (is->getConsumer().disconnect())
380  {
381  session->close(
382  {boost::beast::websocket::policy_error, "threshold exceeded"});
383  // FIX: This rpcError is not delivered since the session
384  // was just closed.
385  return rpcError(rpcSLOW_DOWN);
386  }
387 
388  // Requests without "command" are invalid.
391  try
392  {
393  auto apiVersion = RPC::getAPIVersionNumber(jv);
394  if (apiVersion == RPC::APIInvalidVersion ||
395  (!jv.isMember(jss::command) && !jv.isMember(jss::method)) ||
396  (jv.isMember(jss::command) && !jv[jss::command].isString()) ||
397  (jv.isMember(jss::method) && !jv[jss::method].isString()) ||
398  (jv.isMember(jss::command) && jv.isMember(jss::method) &&
399  jv[jss::command].asString() != jv[jss::method].asString()))
400  {
401  jr[jss::type] = jss::response;
402  jr[jss::status] = jss::error;
403  jr[jss::error] = apiVersion == RPC::APIInvalidVersion
404  ? jss::invalid_API_version
405  : jss::missingCommand;
406  jr[jss::request] = jv;
407  if (jv.isMember(jss::id))
408  jr[jss::id] = jv[jss::id];
409  if (jv.isMember(jss::jsonrpc))
410  jr[jss::jsonrpc] = jv[jss::jsonrpc];
411  if (jv.isMember(jss::ripplerpc))
412  jr[jss::ripplerpc] = jv[jss::ripplerpc];
413  if (jv.isMember(jss::api_version))
414  jr[jss::api_version] = jv[jss::api_version];
415 
416  is->getConsumer().charge(Resource::feeInvalidRPC);
417  return jr;
418  }
419 
420  auto required = RPC::roleRequired(
421  apiVersion,
422  jv.isMember(jss::command) ? jv[jss::command].asString()
423  : jv[jss::method].asString());
424  auto role = requestRole(
425  required,
426  session->port(),
427  jv,
428  beast::IP::from_asio(session->remote_endpoint().address()),
429  is->user());
430  if (Role::FORBID == role)
431  {
432  loadType = Resource::feeInvalidRPC;
433  jr[jss::result] = rpcError(rpcFORBIDDEN);
434  }
435  else
436  {
437  RPC::JsonContext context{
438  {app_.journal("RPCHandler"),
439  app_,
440  loadType,
441  app_.getOPs(),
443  is->getConsumer(),
444  role,
445  coro,
446  is,
447  apiVersion},
448  jv,
449  {is->user(), is->forwarded_for()}};
450 
451  RPC::doCommand(context, jr[jss::result]);
452  }
453  }
454  catch (std::exception const& ex)
455  {
456  jr[jss::result] = RPC::make_error(rpcINTERNAL);
457  JLOG(m_journal.error())
458  << "Exception while processing WS: " << ex.what() << "\n"
459  << "Input JSON: " << Json::Compact{Json::Value{jv}};
460  }
461 
462  is->getConsumer().charge(loadType);
463  if (is->getConsumer().warn())
464  jr[jss::warning] = jss::load;
465 
466  // Currently we will simply unwrap errors returned by the RPC
467  // API, in the future maybe we can make the responses
468  // consistent.
469  //
470  // Regularize result. This is duplicate code.
471  if (jr[jss::result].isMember(jss::error))
472  {
473  jr = jr[jss::result];
474  jr[jss::status] = jss::error;
475 
476  auto rq = jv;
477 
478  if (rq.isObject())
479  {
480  if (rq.isMember(jss::passphrase.c_str()))
481  rq[jss::passphrase.c_str()] = "<masked>";
482  if (rq.isMember(jss::secret.c_str()))
483  rq[jss::secret.c_str()] = "<masked>";
484  if (rq.isMember(jss::seed.c_str()))
485  rq[jss::seed.c_str()] = "<masked>";
486  if (rq.isMember(jss::seed_hex.c_str()))
487  rq[jss::seed_hex.c_str()] = "<masked>";
488  }
489 
490  jr[jss::request] = rq;
491  }
492  else
493  {
494  jr[jss::status] = jss::success;
495  }
496 
497  if (jv.isMember(jss::id))
498  jr[jss::id] = jv[jss::id];
499  if (jv.isMember(jss::jsonrpc))
500  jr[jss::jsonrpc] = jv[jss::jsonrpc];
501  if (jv.isMember(jss::ripplerpc))
502  jr[jss::ripplerpc] = jv[jss::ripplerpc];
503  if (jv.isMember(jss::api_version))
504  jr[jss::api_version] = jv[jss::api_version];
505 
506  jr[jss::type] = jss::response;
507  return jr;
508 }
509 
510 // Run as a coroutine.
511 void
513  std::shared_ptr<Session> const& session,
515 {
517  session->port(),
518  buffers_to_string(session->request().body().data()),
519  session->remoteAddress().at_port(0),
520  makeOutput(*session),
521  coro,
522  forwardedFor(session->request()),
523  [&] {
524  auto const iter = session->request().find("X-User");
525  if (iter != session->request().end())
526  return iter->value();
527  return boost::beast::string_view{};
528  }());
529 
530  if (beast::rfc2616::is_keep_alive(session->request()))
531  session->complete();
532  else
533  session->close(true);
534 }
535 
536 static Json::Value
538 {
540  sub["code"] = code;
541  sub["message"] = std::move(message);
543  r["error"] = sub;
544  return r;
545 }
546 
547 Json::Int constexpr method_not_found = -32601;
548 Json::Int constexpr server_overloaded = -32604;
549 Json::Int constexpr forbidden = -32605;
550 Json::Int constexpr wrong_version = -32606;
551 
552 void
554  Port const& port,
555  std::string const& request,
556  beast::IP::Endpoint const& remoteIPAddress,
557  Output&& output,
559  boost::string_view forwardedFor,
560  boost::string_view user)
561 {
562  auto rpcJ = app_.journal("RPC");
563 
564  Json::Value jsonOrig;
565  {
566  Json::Reader reader;
567  if ((request.size() > RPC::Tuning::maxRequestSize) ||
568  !reader.parse(request, jsonOrig) || !jsonOrig ||
569  !jsonOrig.isObject())
570  {
571  HTTPReply(
572  400,
573  "Unable to parse request: " + reader.getFormatedErrorMessages(),
574  output,
575  rpcJ);
576  return;
577  }
578  }
579 
580  bool batch = false;
581  unsigned size = 1;
582  if (jsonOrig.isMember(jss::method) && jsonOrig[jss::method] == "batch")
583  {
584  batch = true;
585  if (!jsonOrig.isMember(jss::params) || !jsonOrig[jss::params].isArray())
586  {
587  HTTPReply(400, "Malformed batch request", output, rpcJ);
588  return;
589  }
590  size = jsonOrig[jss::params].size();
591  }
592 
594  auto const start(std::chrono::high_resolution_clock::now());
595  for (unsigned i = 0; i < size; ++i)
596  {
597  Json::Value const& jsonRPC =
598  batch ? jsonOrig[jss::params][i] : jsonOrig;
599 
600  if (!jsonRPC.isObject())
601  {
603  r[jss::request] = jsonRPC;
604  r[jss::error] =
605  make_json_error(method_not_found, "Method not found");
606  reply.append(r);
607  continue;
608  }
609 
610  auto apiVersion = RPC::APIVersionIfUnspecified;
611  if (jsonRPC.isMember(jss::params) && jsonRPC[jss::params].isArray() &&
612  jsonRPC[jss::params].size() > 0 &&
613  jsonRPC[jss::params][0u].isObject())
614  {
615  apiVersion =
616  RPC::getAPIVersionNumber(jsonRPC[jss::params][Json::UInt(0)]);
617  }
618 
619  if (apiVersion == RPC::APIVersionIfUnspecified && batch)
620  {
621  // for batch request, api_version may be at a different level
622  apiVersion = RPC::getAPIVersionNumber(jsonRPC);
623  }
624 
625  if (apiVersion == RPC::APIInvalidVersion)
626  {
627  if (!batch)
628  {
629  HTTPReply(400, jss::invalid_API_version.c_str(), output, rpcJ);
630  return;
631  }
633  r[jss::request] = jsonRPC;
634  r[jss::error] = make_json_error(
635  wrong_version, jss::invalid_API_version.c_str());
636  reply.append(r);
637  continue;
638  }
639 
640  /* ------------------------------------------------------------------ */
641  auto role = Role::FORBID;
642  auto required = Role::FORBID;
643  if (jsonRPC.isMember(jss::method) && jsonRPC[jss::method].isString())
644  required =
645  RPC::roleRequired(apiVersion, jsonRPC[jss::method].asString());
646 
647  if (jsonRPC.isMember(jss::params) && jsonRPC[jss::params].isArray() &&
648  jsonRPC[jss::params].size() > 0 &&
649  jsonRPC[jss::params][Json::UInt(0)].isObjectOrNull())
650  {
651  role = requestRole(
652  required,
653  port,
654  jsonRPC[jss::params][Json::UInt(0)],
655  remoteIPAddress,
656  user);
657  }
658  else
659  {
660  role = requestRole(
661  required, port, Json::objectValue, remoteIPAddress, user);
662  }
663 
664  Resource::Consumer usage;
665  if (isUnlimited(role))
666  {
667  usage = m_resourceManager.newUnlimitedEndpoint(remoteIPAddress);
668  }
669  else
670  {
672  remoteIPAddress, role == Role::PROXY, forwardedFor);
673  if (usage.disconnect())
674  {
675  if (!batch)
676  {
677  HTTPReply(503, "Server is overloaded", output, rpcJ);
678  return;
679  }
680  Json::Value r = jsonRPC;
681  r[jss::error] =
682  make_json_error(server_overloaded, "Server is overloaded");
683  reply.append(r);
684  continue;
685  }
686  }
687 
688  if (role == Role::FORBID)
689  {
691  if (!batch)
692  {
693  HTTPReply(403, "Forbidden", output, rpcJ);
694  return;
695  }
696  Json::Value r = jsonRPC;
697  r[jss::error] = make_json_error(forbidden, "Forbidden");
698  reply.append(r);
699  continue;
700  }
701 
702  if (!jsonRPC.isMember(jss::method) || jsonRPC[jss::method].isNull())
703  {
705  if (!batch)
706  {
707  HTTPReply(400, "Null method", output, rpcJ);
708  return;
709  }
710  Json::Value r = jsonRPC;
711  r[jss::error] = make_json_error(method_not_found, "Null method");
712  reply.append(r);
713  continue;
714  }
715 
716  Json::Value const& method = jsonRPC[jss::method];
717  if (!method.isString())
718  {
720  if (!batch)
721  {
722  HTTPReply(400, "method is not string", output, rpcJ);
723  return;
724  }
725  Json::Value r = jsonRPC;
726  r[jss::error] =
727  make_json_error(method_not_found, "method is not string");
728  reply.append(r);
729  continue;
730  }
731 
732  std::string strMethod = method.asString();
733  if (strMethod.empty())
734  {
736  if (!batch)
737  {
738  HTTPReply(400, "method is empty", output, rpcJ);
739  return;
740  }
741  Json::Value r = jsonRPC;
742  r[jss::error] =
743  make_json_error(method_not_found, "method is empty");
744  reply.append(r);
745  continue;
746  }
747 
748  // Extract request parameters from the request Json as `params`.
749  //
750  // If the field "params" is empty, `params` is an empty object.
751  //
752  // Otherwise, that field must be an array of length 1 (why?)
753  // and we take that first entry and validate that it's an object.
754  Json::Value params;
755  if (!batch)
756  {
757  params = jsonRPC[jss::params];
758  if (!params)
759  params = Json::Value(Json::objectValue);
760 
761  else if (!params.isArray() || params.size() != 1)
762  {
764  HTTPReply(400, "params unparseable", output, rpcJ);
765  return;
766  }
767  else
768  {
769  params = std::move(params[0u]);
770  if (!params.isObjectOrNull())
771  {
773  HTTPReply(400, "params unparseable", output, rpcJ);
774  return;
775  }
776  }
777  }
778  else // batch
779  {
780  params = jsonRPC;
781  }
782 
783  std::string ripplerpc = "1.0";
784  if (params.isMember(jss::ripplerpc))
785  {
786  if (!params[jss::ripplerpc].isString())
787  {
789  if (!batch)
790  {
791  HTTPReply(400, "ripplerpc is not a string", output, rpcJ);
792  return;
793  }
794 
795  Json::Value r = jsonRPC;
796  r[jss::error] = make_json_error(
797  method_not_found, "ripplerpc is not a string");
798  reply.append(r);
799  continue;
800  }
801  ripplerpc = params[jss::ripplerpc].asString();
802  }
803 
808  if (role != Role::IDENTIFIED && role != Role::PROXY)
809  {
810  forwardedFor.clear();
811  user.clear();
812  }
813 
814  JLOG(m_journal.debug()) << "Query: " << strMethod << params;
815 
816  // Provide the JSON-RPC method as the field "command" in the request.
817  params[jss::command] = strMethod;
818  JLOG(m_journal.trace())
819  << "doRpcCommand:" << strMethod << ":" << params;
820 
822 
823  RPC::JsonContext context{
824  {m_journal,
825  app_,
826  loadType,
827  m_networkOPs,
829  usage,
830  role,
831  coro,
833  apiVersion},
834  params,
835  {user, forwardedFor}};
836  Json::Value result;
837  RPC::doCommand(context, result);
838  usage.charge(loadType);
839  if (usage.warn())
840  result[jss::warning] = jss::load;
841 
843  if (ripplerpc >= "2.0")
844  {
845  if (result.isMember(jss::error))
846  {
847  result[jss::status] = jss::error;
848  result["code"] = result[jss::error_code];
849  result["message"] = result[jss::error_message];
850  result.removeMember(jss::error_message);
851  JLOG(m_journal.debug()) << "rpcError: " << result[jss::error]
852  << ": " << result[jss::error_message];
853  r[jss::error] = std::move(result);
854  }
855  else
856  {
857  result[jss::status] = jss::success;
858  r[jss::result] = std::move(result);
859  }
860  }
861  else
862  {
863  // Always report "status". On an error report the request as
864  // received.
865  if (result.isMember(jss::error))
866  {
867  auto rq = params;
868 
869  if (rq.isObject())
870  { // But mask potentially sensitive information.
871  if (rq.isMember(jss::passphrase.c_str()))
872  rq[jss::passphrase.c_str()] = "<masked>";
873  if (rq.isMember(jss::secret.c_str()))
874  rq[jss::secret.c_str()] = "<masked>";
875  if (rq.isMember(jss::seed.c_str()))
876  rq[jss::seed.c_str()] = "<masked>";
877  if (rq.isMember(jss::seed_hex.c_str()))
878  rq[jss::seed_hex.c_str()] = "<masked>";
879  }
880 
881  result[jss::status] = jss::error;
882  result[jss::request] = rq;
883 
884  JLOG(m_journal.debug()) << "rpcError: " << result[jss::error]
885  << ": " << result[jss::error_message];
886  }
887  else
888  {
889  result[jss::status] = jss::success;
890  }
891  r[jss::result] = std::move(result);
892  }
893 
894  if (params.isMember(jss::jsonrpc))
895  r[jss::jsonrpc] = params[jss::jsonrpc];
896  if (params.isMember(jss::ripplerpc))
897  r[jss::ripplerpc] = params[jss::ripplerpc];
898  if (params.isMember(jss::id))
899  r[jss::id] = params[jss::id];
900  if (batch)
901  reply.append(std::move(r));
902  else
903  reply = std::move(r);
904  }
905  auto response = to_string(reply);
906 
907  rpc_time_.notify(std::chrono::duration_cast<std::chrono::milliseconds>(
909  ++rpc_requests_;
911 
912  response += '\n';
913 
914  if (auto stream = m_journal.debug())
915  {
916  static const int maxSize = 10000;
917  if (response.size() <= maxSize)
918  stream << "Reply: " << response;
919  else
920  stream << "Reply: " << response.substr(0, maxSize);
921  }
922 
923  HTTPReply(200, response, output, rpcJ);
924 }
925 
926 //------------------------------------------------------------------------------
927 
928 /* This response is used with load balancing.
929  If the server is overloaded, status 500 is reported. Otherwise status 200
930  is reported, meaning the server can accept more connections.
931 */
932 Handoff
934 {
935  using namespace boost::beast::http;
936  Handoff handoff;
937  response<string_body> msg;
938  std::string reason;
939  if (app_.serverOkay(reason))
940  {
941  msg.result(boost::beast::http::status::ok);
942  msg.body() = "<!DOCTYPE html><html><head><title>" + systemName() +
943  " Test page for rippled</title></head><body><h1>" + systemName() +
944  " Test</h1><p>This page shows rippled http(s) "
945  "connectivity is working.</p></body></html>";
946  }
947  else
948  {
949  msg.result(boost::beast::http::status::internal_server_error);
950  msg.body() = "<HTML><BODY>Server cannot accept clients: " + reason +
951  "</BODY></HTML>";
952  }
953  msg.version(request.version());
954  msg.insert("Server", BuildInfo::getFullVersionString());
955  msg.insert("Content-Type", "text/html");
956  msg.insert("Connection", "close");
957  msg.prepare_payload();
958  handoff.response = std::make_shared<SimpleWriter>(msg);
959  return handoff;
960 }
961 
962 //------------------------------------------------------------------------------
963 
964 void
966 {
967  for (auto& p : ports)
968  {
969  if (p.secure())
970  {
971  if (p.ssl_key.empty() && p.ssl_cert.empty() && p.ssl_chain.empty())
972  p.context = make_SSLContext(p.ssl_ciphers);
973  else
974  p.context = make_SSLContextAuthed(
975  p.ssl_key, p.ssl_cert, p.ssl_chain, p.ssl_ciphers);
976  }
977  else
978  {
979  p.context = std::make_shared<boost::asio::ssl::context>(
980  boost::asio::ssl::context::sslv23);
981  }
982  }
983 }
984 
985 static Port
986 to_Port(ParsedPort const& parsed, std::ostream& log)
987 {
988  Port p;
989  p.name = parsed.name;
990 
991  if (!parsed.ip)
992  {
993  log << "Missing 'ip' in [" << p.name << "]";
994  Throw<std::exception>();
995  }
996  p.ip = *parsed.ip;
997 
998  if (!parsed.port)
999  {
1000  log << "Missing 'port' in [" << p.name << "]";
1001  Throw<std::exception>();
1002  }
1003  else if (*parsed.port == 0)
1004  {
1005  log << "Port " << *parsed.port << "in [" << p.name << "] is invalid";
1006  Throw<std::exception>();
1007  }
1008  p.port = *parsed.port;
1009  if (parsed.admin_ip)
1010  p.admin_ip = *parsed.admin_ip;
1011  if (parsed.secure_gateway_ip)
1013 
1014  if (parsed.protocol.empty())
1015  {
1016  log << "Missing 'protocol' in [" << p.name << "]";
1017  Throw<std::exception>();
1018  }
1019  p.protocol = parsed.protocol;
1020 
1021  p.user = parsed.user;
1022  p.password = parsed.password;
1023  p.admin_user = parsed.admin_user;
1024  p.admin_password = parsed.admin_password;
1025  p.ssl_key = parsed.ssl_key;
1026  p.ssl_cert = parsed.ssl_cert;
1027  p.ssl_chain = parsed.ssl_chain;
1028  p.ssl_ciphers = parsed.ssl_ciphers;
1029  p.pmd_options = parsed.pmd_options;
1030  p.ws_queue_limit = parsed.ws_queue_limit;
1031  p.limit = parsed.limit;
1032 
1033  return p;
1034 }
1035 
1036 static std::vector<Port>
1037 parse_Ports(Config const& config, std::ostream& log)
1038 {
1039  std::vector<Port> result;
1040 
1041  if (!config.exists("server"))
1042  {
1043  log << "Required section [server] is missing";
1044  Throw<std::exception>();
1045  }
1046 
1047  ParsedPort common;
1048  parse_Port(common, config["server"], log);
1049 
1050  auto const& names = config.section("server").values();
1051  result.reserve(names.size());
1052  for (auto const& name : names)
1053  {
1054  if (!config.exists(name))
1055  {
1056  log << "Missing section: [" << name << "]";
1057  Throw<std::exception>();
1058  }
1059  ParsedPort parsed = common;
1060  parsed.name = name;
1061  parse_Port(parsed, config[name], log);
1062  result.push_back(to_Port(parsed, log));
1063  }
1064 
1065  if (config.standalone())
1066  {
1067  auto it = result.begin();
1068 
1069  while (it != result.end())
1070  {
1071  auto& p = it->protocol;
1072 
1073  // Remove the peer protocol, and if that would
1074  // leave the port empty, remove the port as well
1075  if (p.erase("peer") && p.empty())
1076  it = result.erase(it);
1077  else
1078  ++it;
1079  }
1080  }
1081  else
1082  {
1083  auto const count =
1084  std::count_if(result.cbegin(), result.cend(), [](Port const& p) {
1085  return p.protocol.count("peer") != 0;
1086  });
1087 
1088  if (count > 1)
1089  {
1090  log << "Error: More than one peer protocol configured in [server]";
1091  Throw<std::exception>();
1092  }
1093 
1094  if (count == 0)
1095  log << "Warning: No peer protocol configured";
1096  }
1097 
1098  return result;
1099 }
1100 
1101 // Fill out the client portion of the Setup
1102 static void
1104 {
1105  decltype(setup.ports)::const_iterator iter;
1106  for (iter = setup.ports.cbegin(); iter != setup.ports.cend(); ++iter)
1107  if (iter->protocol.count("http") > 0 ||
1108  iter->protocol.count("https") > 0)
1109  break;
1110  if (iter == setup.ports.cend())
1111  return;
1112  setup.client.secure = iter->protocol.count("https") > 0;
1114  ?
1115  // VFALCO HACK! to make localhost work
1116  (iter->ip.is_v6() ? "::1" : "127.0.0.1")
1117  : iter->ip.to_string();
1118  setup.client.port = iter->port;
1119  setup.client.user = iter->user;
1120  setup.client.password = iter->password;
1121  setup.client.admin_user = iter->admin_user;
1122  setup.client.admin_password = iter->admin_password;
1123 }
1124 
1125 // Fill out the overlay portion of the Setup
1126 static void
1128 {
1129  auto const iter = std::find_if(
1130  setup.ports.cbegin(), setup.ports.cend(), [](Port const& port) {
1131  return port.protocol.count("peer") != 0;
1132  });
1133  if (iter == setup.ports.cend())
1134  {
1135  setup.overlay.port = 0;
1136  return;
1137  }
1138  setup.overlay.ip = iter->ip;
1139  setup.overlay.port = iter->port;
1140 }
1141 
1142 ServerHandler::Setup
1144 {
1146  setup.ports = parse_Ports(config, log);
1147 
1150 
1151  return setup;
1152 }
1153 
1156  Application& app,
1157  Stoppable& parent,
1158  boost::asio::io_service& io_service,
1159  JobQueue& jobQueue,
1160  NetworkOPs& networkOPs,
1161  Resource::Manager& resourceManager,
1162  CollectorManager& cm)
1163 {
1164  return std::make_unique<ServerHandlerImp>(
1165  app, parent, io_service, jobQueue, networkOPs, resourceManager, cm);
1166 }
1167 
1168 } // namespace ripple
ripple::Resource::Manager::newInboundEndpoint
virtual Consumer newInboundEndpoint(beast::IP::Endpoint const &address)=0
Create a new endpoint keyed by inbound IP address or the forwarded IP if proxied.
ripple::NetworkOPs
Provides server functionality for clients.
Definition: NetworkOPs.h:88
ripple::Port::ws_queue_limit
std::uint16_t ws_queue_limit
Definition: Port.h:70
ripple::Application
Definition: Application.h:97
ripple::Port::admin_ip
std::vector< beast::IP::Address > admin_ip
Definition: Port.h:52
ripple::ServerHandlerImp::count_
std::map< std::reference_wrapper< Port const >, int > count_
Definition: ServerHandlerImp.h:102
ripple::RPC::JsonContext
Definition: Context.h:53
ripple::make_Server
std::unique_ptr< Server > make_Server(Handler &handler, boost::asio::io_service &io_service, beast::Journal journal)
Create the HTTP server using the specified handler.
Definition: Server.h:34
ripple::ServerHandlerImp::Setup::client_t::user
std::string user
Definition: ServerHandlerImp.h:63
ripple::Resource::Consumer::warn
bool warn()
Returns true if the consumer should be warned.
Definition: Consumer.cpp:110
ripple::ServerHandlerImp::m_journal
beast::Journal m_journal
Definition: ServerHandlerImp.h:93
ripple::Overlay::onHandoff
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.
ripple::Dir::const_iterator
Definition: Directory.h:49
Json::Value::isObject
bool isObject() const
Definition: json_value.cpp:1027
std::string
STL class.
std::shared_ptr
STL class.
ripple::makeOutput
static Json::Output makeOutput(Session &session)
Definition: ServerHandlerImp.cpp:232
ripple::JobQueue::postCoro
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.
Definition: JobQueue.h:427
Json::Value::isString
bool isString() const
Definition: json_value.cpp:1009
ripple::jtCLIENT
@ jtCLIENT
Definition: Job.h:48
std::exception
STL class.
ripple::Stoppable::stopped
void stopped()
Called by derived classes to indicate that the stoppable has stopped.
Definition: Stoppable.cpp:72
ripple::ServerHandlerImp::m_jobQueue
JobQueue & m_jobQueue
Definition: ServerHandlerImp.h:97
ripple::Session::websocketUpgrade
virtual std::shared_ptr< WSSession > websocketUpgrade()=0
Convert the connection to WebSocket.
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::ServerHandlerImp::setup_
Setup setup_
Definition: ServerHandlerImp.h:96
Json::stream
void stream(Json::Value const &jv, Write const &write)
Stream compact JSON to the specified function.
Definition: json_writer.h:300
ripple::RPC::getAPIVersionNumber
unsigned int getAPIVersionNumber(Json::Value const &jv)
Retrieve the api version number from the json value.
Definition: RPCHelpers.cpp:850
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
ripple::make_json_error
static Json::Value make_json_error(Json::Int code, Json::Value &&message)
Definition: ServerHandlerImp.cpp:537
ripple::http_request_type
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
Definition: Handoff.h:31
ripple::ParsedPort::ssl_ciphers
std::string ssl_ciphers
Definition: Port.h:103
std::string::reserve
T reserve(T... args)
ripple::ServerHandlerImp::Setup::client_t::secure
bool secure
Definition: ServerHandlerImp.h:60
std::make_shared
T make_shared(T... args)
Json::UInt
unsigned int UInt
Definition: json_forwards.h:27
Json::Compact
Decorator for streaming out compact json.
Definition: json_writer.h:316
std::vector
STL class.
ripple::ServerHandlerImp::Setup::client_t::admin_user
std::string admin_user
Definition: ServerHandlerImp.h:65
std::map::find
T find(T... args)
ripple::Port::ssl_key
std::string ssl_key
Definition: Port.h:58
std::string::size
T size(T... args)
ripple::ServerHandlerImp::Setup
Definition: ServerHandlerImp.h:49
ripple::make_SSLContext
std::shared_ptr< boost::asio::ssl::context > make_SSLContext(std::string const &cipherList)
Create a self-signed SSL context that allows anonymous Diffie Hellman.
Definition: make_SSLContext.cpp:450
ripple::requestInboundEndpoint
Resource::Consumer requestInboundEndpoint(Resource::Manager &manager, beast::IP::Endpoint const &remoteAddress, Role const &role, boost::string_view const &user, boost::string_view const &forwardedFor)
Definition: Role.cpp:111
ripple::CollectorManager
Provides the beast::insight::Collector service.
Definition: CollectorManager.h:29
ripple::Port::ip
boost::asio::ip::address ip
Definition: Port.h:49
ripple::method_not_found
constexpr Json::Int method_not_found
Definition: ServerHandlerImp.cpp:547
std::chrono::milliseconds
ripple::ParsedPort::ip
boost::optional< boost::asio::ip::address > ip
Definition: Port.h:108
ripple::ParsedPort::limit
int limit
Definition: Port.h:105
std::lock_guard
STL class.
ripple::server_overloaded
constexpr Json::Int server_overloaded
Definition: ServerHandlerImp.cpp:548
ripple::Resource::feeReferenceRPC
const Charge feeReferenceRPC
ripple::Role::IDENTIFIED
@ IDENTIFIED
ripple::RPC::APIVersionIfUnspecified
constexpr unsigned int APIVersionIfUnspecified
Definition: RPCHelpers.h:212
ripple::HTTPReply
void HTTPReply(int nStatus, std::string const &content, Json::Output const &output, beast::Journal j)
Definition: JSONRPCUtil.cpp:56
Json::Value::isNull
bool isNull() const
isNull() tests to see if this field is null.
Definition: json_value.cpp:967
ripple::ServerHandlerImp::rpc_requests_
beast::insight::Counter rpc_requests_
Definition: ServerHandlerImp.h:98
ripple::Port::admin_user
std::string admin_user
Definition: Port.h:56
ripple::ServerHandlerImp::Setup::client_t::port
std::uint16_t port
Definition: ServerHandlerImp.h:62
std::function
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:42
ripple::parse_Port
void parse_Port(ParsedPort &port, Section const &section, std::ostream &log)
Definition: Port.cpp:139
ripple::Port::name
std::string name
Definition: Port.h:48
Json::Reader
Unserialize a JSON document into a Value.
Definition: json_reader.h:36
ripple::Session
Persistent state information for a connection session.
Definition: Session.h:40
ripple::Session::write
void write(std::string const &s)
Send a copy of data asynchronously.
Definition: Session.h:74
ripple::forbidden
constexpr Json::Int forbidden
Definition: ServerHandlerImp.cpp:549
ripple::ServerHandlerImp::Setup::overlay_t::ip
boost::asio::ip::address ip
Definition: ServerHandlerImp.h:77
ripple::Port::port
std::uint16_t port
Definition: Port.h:50
ripple::ParsedPort
Definition: Port.h:90
ripple::ServerHandlerImp::onRequest
void onRequest(Session &session)
Definition: ServerHandlerImp.cpp:268
ripple::ServerHandlerImp::Setup::makeContexts
void makeContexts()
Definition: ServerHandlerImp.cpp:965
ripple::ServerHandlerImp::statusResponse
Handoff statusResponse(http_request_type const &request) const
Definition: ServerHandlerImp.cpp:933
ripple::Port::protocol
std::set< std::string, boost::beast::iless > protocol
Definition: Port.h:51
algorithm
ripple::isStatusRequest
static bool isStatusRequest(http_request_type const &request)
Definition: ServerHandlerImp.cpp:57
ripple::Application::getOPs
virtual NetworkOPs & getOPs()=0
ripple::ServerHandlerImp::onClose
void onClose(Session &session, boost::system::error_code const &)
Definition: ServerHandlerImp.cpp:358
ripple::ServerHandlerImp::m_networkOPs
NetworkOPs & m_networkOPs
Definition: ServerHandlerImp.h:94
ripple::Section::values
std::vector< std::string > const & values() const
Returns all the values in the section.
Definition: BasicConfig.h:76
ripple::ServerHandlerImp::Setup::client_t::ip
std::string ip
Definition: ServerHandlerImp.h:61
ripple::Port::user
std::string user
Definition: Port.h:54
ripple::Port::ssl_cert
std::string ssl_cert
Definition: Port.h:59
ripple::ServerHandlerImp::ServerHandlerImp
ServerHandlerImp(Application &app, Stoppable &parent, boost::asio::io_service &io_service, JobQueue &jobQueue, NetworkOPs &networkOPs, Resource::Manager &resourceManager, CollectorManager &cm)
Definition: ServerHandlerImp.cpp:104
ripple::make_SSLContextAuthed
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.
Definition: make_SSLContext.cpp:461
std::vector::push_back
T push_back(T... args)
beast::IPAddressConversion::from_asio
static IP::Endpoint from_asio(boost::asio::ip::address const &address)
Definition: IPAddressConversion.h:63
ripple::ServerHandlerImp::rpc_time_
beast::insight::Event rpc_time_
Definition: ServerHandlerImp.h:100
ripple::setup_ServerHandler
ServerHandler::Setup setup_ServerHandler(Config const &config, std::ostream &&log)
Definition: ServerHandlerImp.cpp:1143
stdexcept
ripple::CollectorManager::group
virtual beast::insight::Group::ptr const & group(std::string const &name)=0
beast::rfc2616::is_keep_alive
bool is_keep_alive(boost::beast::http::message< isRequest, Body, Fields > const &m)
Definition: rfc2616.h:475
ripple::RPC::doCommand
Status doCommand(RPC::JsonContext &context, Json::Value &result)
Execute an RPC command and store the results in a Json::Value.
Definition: RPCHandler.cpp:213
ripple::setup_Overlay
Overlay::Setup setup_Overlay(BasicConfig const &config)
Definition: OverlayImpl.cpp:1356
ripple::ServerHandlerImp::Setup::overlay_t::port
std::uint16_t port
Definition: ServerHandlerImp.h:78
Json::Value::append
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:882
ripple::rpcSLOW_DOWN
@ rpcSLOW_DOWN
Definition: ErrorCodes.h:57
ripple::Stoppable
Provides an interface for starting and stopping.
Definition: Stoppable.h:200
ripple::statusRequestResponse
static Handoff statusRequestResponse(http_request_type const &request, boost::beast::http::status status)
Definition: ServerHandlerImp.cpp:65
ripple::Application::serverOkay
virtual bool serverOkay(std::string &reason)=0
ripple::ServerHandlerImp::onStop
void onStop() override
Override called when the stop notification is issued.
Definition: ServerHandlerImp.cpp:141
ripple::ServerHandlerImp::processRequest
void processRequest(Port const &port, std::string const &request, beast::IP::Endpoint const &remoteIPAddress, Output &&, std::shared_ptr< JobQueue::Coro > coro, boost::string_view forwardedFor, boost::string_view user)
Definition: ServerHandlerImp.cpp:553
ripple::InfoSub::pointer
std::shared_ptr< InfoSub > pointer
Definition: InfoSub.h:49
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::authorized
static bool authorized(Port const &port, std::map< std::string, std::string > const &h)
Definition: ServerHandlerImp.cpp:85
ripple::Application::getLedgerMaster
virtual LedgerMaster & getLedgerMaster()=0
ripple::Config
Definition: Config.h:67
ripple::Port::ssl_chain
std::string ssl_chain
Definition: Port.h:60
ripple::ParsedPort::password
std::string password
Definition: Port.h:97
std::ostream
STL class.
ripple::Config::standalone
bool standalone() const
Definition: Config.h:222
ripple::ServerHandlerImp::processSession
Json::Value processSession(std::shared_ptr< WSSession > const &session, std::shared_ptr< JobQueue::Coro > const &coro, Json::Value const &jv)
Definition: ServerHandlerImp.cpp:373
ripple::RPC::Tuning::maxRequestSize
static constexpr int maxRequestSize
Definition: rpc/impl/Tuning.h:60
ripple::ServerHandlerImp::onAccept
bool onAccept(Session &session, boost::asio::ip::tcp::endpoint endpoint)
Definition: ServerHandlerImp.cpp:149
ripple::forwardedFor
boost::string_view forwardedFor(http_request_type const &request)
Definition: Role.cpp:126
ripple::Role::PROXY
@ PROXY
ripple::base64_decode
std::string base64_decode(std::string const &data)
Definition: base64.cpp:245
beast::Journal::error
Stream error() const
Definition: Journal.h:333
ripple::Server
A multi-protocol server.
Definition: ServerImpl.h:44
Json::Value::size
UInt size() const
Number of values in array or object.
Definition: json_value.cpp:706
std::vector::erase
T erase(T... args)
ripple::ParsedPort::admin_user
std::string admin_user
Definition: Port.h:98
ripple::ServerHandlerImp::Setup::client
client_t client
Definition: ServerHandlerImp.h:70
ripple::Port::secure_gateway_ip
std::vector< beast::IP::Address > secure_gateway_ip
Definition: Port.h:53
ripple::Session::request
virtual http_request_type & request()=0
Returns the current HTTP request.
ripple::ServerHandlerImp::rpc_size_
beast::insight::Event rpc_size_
Definition: ServerHandlerImp.h:99
ripple::ParsedPort::secure_gateway_ip
boost::optional< std::vector< beast::IP::Address > > secure_gateway_ip
Definition: Port.h:111
ripple::Role::FORBID
@ FORBID
beast::IP::from_asio
Endpoint from_asio(boost::asio::ip::address const &address)
Convert to Endpoint.
Definition: IPAddressConversion.cpp:26
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::requestRole
Role requestRole(Role const &required, Port const &port, Json::Value const &params, beast::IP::Endpoint const &remoteIp, boost::string_view const &user)
Return the allowed privilege role.
Definition: Role.cpp:67
ripple::Port::ssl_ciphers
std::string ssl_ciphers
Definition: Port.h:61
ripple::Port
Configuration information for a Server listening port.
Definition: Port.h:44
std::map
STL class.
ripple::Session::detach
virtual std::shared_ptr< Session > detach()=0
Detach the session.
ripple::ServerHandlerImp::app_
Application & app_
Definition: ServerHandlerImp.h:91
std::transform
T transform(T... args)
ripple::rpcError
Json::Value rpcError(int iError, Json::Value jvResult)
Definition: RPCErr.cpp:29
ripple::RPC::APIInvalidVersion
constexpr unsigned int APIInvalidVersion
API version numbers used in later API versions.
Definition: RPCHelpers.h:211
ripple::ServerHandlerImp::m_server
std::unique_ptr< Server > m_server
Definition: ServerHandlerImp.h:95
Json::Int
int Int
Definition: json_forwards.h:26
ripple::Resource::feeInvalidRPC
const Charge feeInvalidRPC
ripple::Handoff::moved
bool moved
Definition: Handoff.h:41
ripple::ServerHandlerImp::m_resourceManager
Resource::Manager & m_resourceManager
Definition: ServerHandlerImp.h:92
std::string::append
T append(T... args)
ripple::to_Port
static Port to_Port(ParsedPort const &parsed, std::ostream &log)
Definition: ServerHandlerImp.cpp:986
ripple::StreambufWSMsg
Definition: WSSession.h:72
ripple::Port::pmd_options
boost::beast::websocket::permessage_deflate pmd_options
Definition: Port.h:62
ripple::ParsedPort::ssl_chain
std::string ssl_chain
Definition: Port.h:102
ripple::wrong_version
constexpr Json::Int wrong_version
Definition: ServerHandlerImp.cpp:550
ripple::JobQueue
A pool of threads to perform work.
Definition: JobQueue.h:55
ripple::rpcINTERNAL
@ rpcINTERNAL
Definition: ErrorCodes.h:130
Json::Value::isArray
bool isArray() const
Definition: json_value.cpp:1015
ripple::Port::admin_password
std::string admin_password
Definition: Port.h:57
ripple::isUnlimited
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
Definition: Role.cpp:94
ripple::RPC::roleRequired
Role roleRequired(unsigned int version, std::string const &method)
Definition: RPCHandler.cpp:251
ripple::Resource::Manager
Tracks load and resource consumption.
Definition: ResourceManager.h:36
std::string::substr
T substr(T... args)
ripple::BuildInfo::getFullVersionString
std::string const & getFullVersionString()
Full server version string.
Definition: BuildInfo.cpp:74
ripple::ServerHandlerImp::Setup::client_t::admin_password
std::string admin_password
Definition: ServerHandlerImp.h:66
ripple::ServerHandlerImp::onWSMessage
void onWSMessage(std::shared_ptr< WSSession > session, std::vector< boost::asio::const_buffer > const &buffers)
Definition: ServerHandlerImp.cpp:308
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::ParsedPort::port
boost::optional< std::uint16_t > port
Definition: Port.h:109
ripple::buffers_to_string
static std::string buffers_to_string(ConstBufferSequence const &bs)
Definition: ServerHandlerImp.cpp:256
ripple::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::rpcFORBIDDEN
@ rpcFORBIDDEN
Definition: ErrorCodes.h:48
ripple::Role::GUEST
@ GUEST
Json::Value::removeMember
Value removeMember(const char *key)
Remove and return the named member.
Definition: json_value.cpp:907
ripple::Resource::Manager::newUnlimitedEndpoint
virtual Consumer newUnlimitedEndpoint(beast::IP::Endpoint const &address)=0
Create a new unlimited endpoint keyed by forwarded IP.
ripple::ParsedPort::pmd_options
boost::beast::websocket::permessage_deflate pmd_options
Definition: Port.h:104
std::vector::begin
T begin(T... args)
ripple::ParsedPort::ssl_key
std::string ssl_key
Definition: Port.h:100
ripple::Resource::Consumer::disconnect
bool disconnect()
Returns true if the consumer should be disconnected.
Definition: Consumer.cpp:117
std::string::insert
T insert(T... args)
ripple::ParsedPort::user
std::string user
Definition: Port.h:96
ripple::Port::limit
int limit
Definition: Port.h:67
ripple::ServerHandlerImp::setup
Setup const & setup() const
Definition: ServerHandlerImp.h:122
Json::Reader::parse
bool parse(std::string const &document, Value &root)
Read a Value from a JSON document.
Definition: json_reader.cpp:73
ripple::Resource::Consumer
An endpoint that consumes resources.
Definition: Consumer.h:33
ripple::Resource::Charge
A consumption charge.
Definition: Charge.h:30
ripple::ParsedPort::ws_queue_limit
std::uint16_t ws_queue_limit
Definition: Port.h:106
ripple::setup_Client
static void setup_Client(ServerHandler::Setup &setup)
Definition: ServerHandlerImp.cpp:1103
ripple::Port::password
std::string password
Definition: Port.h:55
Json::Reader::getFormatedErrorMessages
std::string getFormatedErrorMessages() const
Returns a user friendly string that list errors in the parsed document.
Definition: json_reader.cpp:930
ripple::Application::overlay
virtual Overlay & overlay()=0
std::set::count
T count(T... args)
ripple::ServerHandlerImp::Setup::ports
std::vector< Port > ports
Definition: ServerHandlerImp.h:53
ripple::Session::port
virtual Port const & port()=0
Returns the Port settings for this connection.
std::string::empty
T empty(T... args)
ripple::Session::close
virtual void close(bool graceful)=0
Close the session.
ripple::Handoff
Used to indicate the result of a server connection handoff.
Definition: Handoff.h:37
ripple::systemName
static std::string const & systemName()
Definition: SystemParameters.h:34
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::ServerHandlerImp::~ServerHandlerImp
~ServerHandlerImp()
Definition: ServerHandlerImp.cpp:126
beast::IP::Endpoint
A version-independent IP address and port combination.
Definition: IPEndpoint.h:39
std::map::end
T end(T... args)
ripple::Handoff::response
std::shared_ptr< Writer > response
Definition: Handoff.h:47
ripple::ParsedPort::admin_ip
boost::optional< std::vector< beast::IP::Address > > admin_ip
Definition: Port.h:110
ripple::build_map
static std::map< std::string, std::string > build_map(boost::beast::http::fields const &h)
Definition: ServerHandlerImp.cpp:240
ripple::ParsedPort::protocol
std::set< std::string, boost::beast::iless > protocol
Definition: Port.h:95
ripple::ParsedPort::name
std::string name
Definition: Port.h:94
ripple::Resource::Consumer::charge
Disposition charge(Charge const &fee)
Apply a load charge to the consumer.
Definition: Consumer.cpp:99
ripple::ServerHandlerImp::Setup::overlay
overlay_t overlay
Definition: ServerHandlerImp.h:81
ripple::ServerHandlerImp::Setup::client_t::password
std::string password
Definition: ServerHandlerImp.h:64
beast::IP::is_unspecified
bool is_unspecified(Address const &addr)
Returns true if the address is unspecified.
Definition: IPAddress.h:59
std::unique_ptr< stream_type >
ripple::ServerHandlerImp::onStopped
void onStopped(Server &)
Definition: ServerHandlerImp.cpp:365
ripple::ParsedPort::admin_password
std::string admin_password
Definition: Port.h:99
ripple::ParsedPort::ssl_cert
std::string ssl_cert
Definition: Port.h:101
Json::Value::isObjectOrNull
bool isObjectOrNull() const
Definition: json_value.cpp:1033
ripple::RPC::make_error
Json::Value make_error(error_code_i code)
Returns a new json object that reflects the error code.
Definition: ErrorCodes.cpp:203
ripple::make_ServerHandler
std::unique_ptr< ServerHandler > make_ServerHandler(Application &app, Stoppable &parent, boost::asio::io_service &io_service, JobQueue &jobQueue, NetworkOPs &networkOPs, Resource::Manager &resourceManager, CollectorManager &cm)
Definition: ServerHandlerImp.cpp:1155
std::exception::what
T what(T... args)
ripple::ServerHandlerImp::onHandoff
Handoff onHandoff(Session &session, std::unique_ptr< stream_type > &&bundle, http_request_type &&request, boost::asio::ip::tcp::endpoint const &remote_address)
Definition: ServerHandlerImp.cpp:168
ripple::BasicConfig::exists
bool exists(std::string const &name) const
Returns true if a section with the given name exists.
Definition: BasicConfig.cpp:132
Json::Value
Represents a JSON value.
Definition: json_value.h:145
beast::insight::Event::notify
void notify(std::chrono::duration< Rep, Period > const &value) const
Push an event notification.
Definition: Event.h:66
ripple::ServerHandlerImp::countlock_
std::mutex countlock_
Definition: ServerHandlerImp.h:101
ripple::parse_Ports
static std::vector< Port > parse_Ports(Config const &config, std::ostream &log)
Definition: ServerHandlerImp.cpp:1037
ripple::BasicConfig::section
Section & section(std::string const &name)
Returns the section with the given name.
Definition: BasicConfig.cpp:138
Json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:469
std::chrono::high_resolution_clock::now
T now(T... args)