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  if (jr[jss::result].isMember("forwarded") &&
495  jr[jss::result]["forwarded"])
496  jr = jr[jss::result];
497  jr[jss::status] = jss::success;
498  }
499 
500  if (jv.isMember(jss::id))
501  jr[jss::id] = jv[jss::id];
502  if (jv.isMember(jss::jsonrpc))
503  jr[jss::jsonrpc] = jv[jss::jsonrpc];
504  if (jv.isMember(jss::ripplerpc))
505  jr[jss::ripplerpc] = jv[jss::ripplerpc];
506  if (jv.isMember(jss::api_version))
507  jr[jss::api_version] = jv[jss::api_version];
508 
509  jr[jss::type] = jss::response;
510  return jr;
511 }
512 
513 // Run as a coroutine.
514 void
516  std::shared_ptr<Session> const& session,
518 {
520  session->port(),
521  buffers_to_string(session->request().body().data()),
522  session->remoteAddress().at_port(0),
523  makeOutput(*session),
524  coro,
525  forwardedFor(session->request()),
526  [&] {
527  auto const iter = session->request().find("X-User");
528  if (iter != session->request().end())
529  return iter->value();
530  return boost::beast::string_view{};
531  }());
532 
533  if (beast::rfc2616::is_keep_alive(session->request()))
534  session->complete();
535  else
536  session->close(true);
537 }
538 
539 static Json::Value
541 {
543  sub["code"] = code;
544  sub["message"] = std::move(message);
546  r["error"] = sub;
547  return r;
548 }
549 
550 Json::Int constexpr method_not_found = -32601;
551 Json::Int constexpr server_overloaded = -32604;
552 Json::Int constexpr forbidden = -32605;
553 Json::Int constexpr wrong_version = -32606;
554 
555 void
557  Port const& port,
558  std::string const& request,
559  beast::IP::Endpoint const& remoteIPAddress,
560  Output&& output,
562  boost::string_view forwardedFor,
563  boost::string_view user)
564 {
565  auto rpcJ = app_.journal("RPC");
566 
567  Json::Value jsonOrig;
568  {
569  Json::Reader reader;
570  if ((request.size() > RPC::Tuning::maxRequestSize) ||
571  !reader.parse(request, jsonOrig) || !jsonOrig ||
572  !jsonOrig.isObject())
573  {
574  HTTPReply(
575  400,
576  "Unable to parse request: " + reader.getFormatedErrorMessages(),
577  output,
578  rpcJ);
579  return;
580  }
581  }
582 
583  bool batch = false;
584  unsigned size = 1;
585  if (jsonOrig.isMember(jss::method) && jsonOrig[jss::method] == "batch")
586  {
587  batch = true;
588  if (!jsonOrig.isMember(jss::params) || !jsonOrig[jss::params].isArray())
589  {
590  HTTPReply(400, "Malformed batch request", output, rpcJ);
591  return;
592  }
593  size = jsonOrig[jss::params].size();
594  }
595 
597  auto const start(std::chrono::high_resolution_clock::now());
598  for (unsigned i = 0; i < size; ++i)
599  {
600  Json::Value const& jsonRPC =
601  batch ? jsonOrig[jss::params][i] : jsonOrig;
602 
603  if (!jsonRPC.isObject())
604  {
606  r[jss::request] = jsonRPC;
607  r[jss::error] =
608  make_json_error(method_not_found, "Method not found");
609  reply.append(r);
610  continue;
611  }
612 
613  auto apiVersion = RPC::APIVersionIfUnspecified;
614  if (jsonRPC.isMember(jss::params) && jsonRPC[jss::params].isArray() &&
615  jsonRPC[jss::params].size() > 0 &&
616  jsonRPC[jss::params][0u].isObject())
617  {
618  apiVersion =
619  RPC::getAPIVersionNumber(jsonRPC[jss::params][Json::UInt(0)]);
620  }
621 
622  if (apiVersion == RPC::APIVersionIfUnspecified && batch)
623  {
624  // for batch request, api_version may be at a different level
625  apiVersion = RPC::getAPIVersionNumber(jsonRPC);
626  }
627 
628  if (apiVersion == RPC::APIInvalidVersion)
629  {
630  if (!batch)
631  {
632  HTTPReply(400, jss::invalid_API_version.c_str(), output, rpcJ);
633  return;
634  }
636  r[jss::request] = jsonRPC;
637  r[jss::error] = make_json_error(
638  wrong_version, jss::invalid_API_version.c_str());
639  reply.append(r);
640  continue;
641  }
642 
643  /* ------------------------------------------------------------------ */
644  auto role = Role::FORBID;
645  auto required = Role::FORBID;
646  if (jsonRPC.isMember(jss::method) && jsonRPC[jss::method].isString())
647  required =
648  RPC::roleRequired(apiVersion, jsonRPC[jss::method].asString());
649 
650  if (jsonRPC.isMember(jss::params) && jsonRPC[jss::params].isArray() &&
651  jsonRPC[jss::params].size() > 0 &&
652  jsonRPC[jss::params][Json::UInt(0)].isObjectOrNull())
653  {
654  role = requestRole(
655  required,
656  port,
657  jsonRPC[jss::params][Json::UInt(0)],
658  remoteIPAddress,
659  user);
660  }
661  else
662  {
663  role = requestRole(
664  required, port, Json::objectValue, remoteIPAddress, user);
665  }
666 
667  Resource::Consumer usage;
668  if (isUnlimited(role))
669  {
670  usage = m_resourceManager.newUnlimitedEndpoint(remoteIPAddress);
671  }
672  else
673  {
675  remoteIPAddress, role == Role::PROXY, forwardedFor);
676  if (usage.disconnect())
677  {
678  if (!batch)
679  {
680  HTTPReply(503, "Server is overloaded", output, rpcJ);
681  return;
682  }
683  Json::Value r = jsonRPC;
684  r[jss::error] =
685  make_json_error(server_overloaded, "Server is overloaded");
686  reply.append(r);
687  continue;
688  }
689  }
690 
691  if (role == Role::FORBID)
692  {
694  if (!batch)
695  {
696  HTTPReply(403, "Forbidden", output, rpcJ);
697  return;
698  }
699  Json::Value r = jsonRPC;
700  r[jss::error] = make_json_error(forbidden, "Forbidden");
701  reply.append(r);
702  continue;
703  }
704 
705  if (!jsonRPC.isMember(jss::method) || jsonRPC[jss::method].isNull())
706  {
708  if (!batch)
709  {
710  HTTPReply(400, "Null method", output, rpcJ);
711  return;
712  }
713  Json::Value r = jsonRPC;
714  r[jss::error] = make_json_error(method_not_found, "Null method");
715  reply.append(r);
716  continue;
717  }
718 
719  Json::Value const& method = jsonRPC[jss::method];
720  if (!method.isString())
721  {
723  if (!batch)
724  {
725  HTTPReply(400, "method is not string", output, rpcJ);
726  return;
727  }
728  Json::Value r = jsonRPC;
729  r[jss::error] =
730  make_json_error(method_not_found, "method is not string");
731  reply.append(r);
732  continue;
733  }
734 
735  std::string strMethod = method.asString();
736  if (strMethod.empty())
737  {
739  if (!batch)
740  {
741  HTTPReply(400, "method is empty", output, rpcJ);
742  return;
743  }
744  Json::Value r = jsonRPC;
745  r[jss::error] =
746  make_json_error(method_not_found, "method is empty");
747  reply.append(r);
748  continue;
749  }
750 
751  // Extract request parameters from the request Json as `params`.
752  //
753  // If the field "params" is empty, `params` is an empty object.
754  //
755  // Otherwise, that field must be an array of length 1 (why?)
756  // and we take that first entry and validate that it's an object.
757  Json::Value params;
758  if (!batch)
759  {
760  params = jsonRPC[jss::params];
761  if (!params)
762  params = Json::Value(Json::objectValue);
763 
764  else if (!params.isArray() || params.size() != 1)
765  {
767  HTTPReply(400, "params unparseable", output, rpcJ);
768  return;
769  }
770  else
771  {
772  params = std::move(params[0u]);
773  if (!params.isObjectOrNull())
774  {
776  HTTPReply(400, "params unparseable", output, rpcJ);
777  return;
778  }
779  }
780  }
781  else // batch
782  {
783  params = jsonRPC;
784  }
785 
786  std::string ripplerpc = "1.0";
787  if (params.isMember(jss::ripplerpc))
788  {
789  if (!params[jss::ripplerpc].isString())
790  {
792  if (!batch)
793  {
794  HTTPReply(400, "ripplerpc is not a string", output, rpcJ);
795  return;
796  }
797 
798  Json::Value r = jsonRPC;
799  r[jss::error] = make_json_error(
800  method_not_found, "ripplerpc is not a string");
801  reply.append(r);
802  continue;
803  }
804  ripplerpc = params[jss::ripplerpc].asString();
805  }
806 
811  if (role != Role::IDENTIFIED && role != Role::PROXY)
812  {
813  forwardedFor.clear();
814  user.clear();
815  }
816 
817  JLOG(m_journal.debug()) << "Query: " << strMethod << params;
818 
819  // Provide the JSON-RPC method as the field "command" in the request.
820  params[jss::command] = strMethod;
821  JLOG(m_journal.trace())
822  << "doRpcCommand:" << strMethod << ":" << params;
823 
825 
826  RPC::JsonContext context{
827  {m_journal,
828  app_,
829  loadType,
830  m_networkOPs,
832  usage,
833  role,
834  coro,
836  apiVersion},
837  params,
838  {user, forwardedFor}};
839  Json::Value result;
840  RPC::doCommand(context, result);
841  usage.charge(loadType);
842  if (usage.warn())
843  result[jss::warning] = jss::load;
844 
846  if (ripplerpc >= "2.0")
847  {
848  if (result.isMember(jss::error))
849  {
850  result[jss::status] = jss::error;
851  result["code"] = result[jss::error_code];
852  result["message"] = result[jss::error_message];
853  result.removeMember(jss::error_message);
854  JLOG(m_journal.debug()) << "rpcError: " << result[jss::error]
855  << ": " << result[jss::error_message];
856  r[jss::error] = std::move(result);
857  }
858  else
859  {
860  result[jss::status] = jss::success;
861  r[jss::result] = std::move(result);
862  }
863  }
864  else
865  {
866  // Always report "status". On an error report the request as
867  // received.
868  if (result.isMember(jss::error))
869  {
870  auto rq = params;
871 
872  if (rq.isObject())
873  { // But mask potentially sensitive information.
874  if (rq.isMember(jss::passphrase.c_str()))
875  rq[jss::passphrase.c_str()] = "<masked>";
876  if (rq.isMember(jss::secret.c_str()))
877  rq[jss::secret.c_str()] = "<masked>";
878  if (rq.isMember(jss::seed.c_str()))
879  rq[jss::seed.c_str()] = "<masked>";
880  if (rq.isMember(jss::seed_hex.c_str()))
881  rq[jss::seed_hex.c_str()] = "<masked>";
882  }
883 
884  result[jss::status] = jss::error;
885  result[jss::request] = rq;
886 
887  JLOG(m_journal.debug()) << "rpcError: " << result[jss::error]
888  << ": " << result[jss::error_message];
889  }
890  else
891  {
892  result[jss::status] = jss::success;
893  }
894  r[jss::result] = std::move(result);
895  }
896 
897  if (params.isMember(jss::jsonrpc))
898  r[jss::jsonrpc] = params[jss::jsonrpc];
899  if (params.isMember(jss::ripplerpc))
900  r[jss::ripplerpc] = params[jss::ripplerpc];
901  if (params.isMember(jss::id))
902  r[jss::id] = params[jss::id];
903  if (batch)
904  reply.append(std::move(r));
905  else
906  reply = std::move(r);
907  }
908  auto response = to_string(reply);
909 
910  rpc_time_.notify(std::chrono::duration_cast<std::chrono::milliseconds>(
912  ++rpc_requests_;
914 
915  response += '\n';
916 
917  if (auto stream = m_journal.debug())
918  {
919  static const int maxSize = 10000;
920  if (response.size() <= maxSize)
921  stream << "Reply: " << response;
922  else
923  stream << "Reply: " << response.substr(0, maxSize);
924  }
925 
926  HTTPReply(200, response, output, rpcJ);
927 }
928 
929 //------------------------------------------------------------------------------
930 
931 /* This response is used with load balancing.
932  If the server is overloaded, status 500 is reported. Otherwise status 200
933  is reported, meaning the server can accept more connections.
934 */
935 Handoff
937 {
938  using namespace boost::beast::http;
939  Handoff handoff;
940  response<string_body> msg;
941  std::string reason;
942  if (app_.serverOkay(reason))
943  {
944  msg.result(boost::beast::http::status::ok);
945  msg.body() = "<!DOCTYPE html><html><head><title>" + systemName() +
946  " Test page for rippled</title></head><body><h1>" + systemName() +
947  " Test</h1><p>This page shows rippled http(s) "
948  "connectivity is working.</p></body></html>";
949  }
950  else
951  {
952  msg.result(boost::beast::http::status::internal_server_error);
953  msg.body() = "<HTML><BODY>Server cannot accept clients: " + reason +
954  "</BODY></HTML>";
955  }
956  msg.version(request.version());
957  msg.insert("Server", BuildInfo::getFullVersionString());
958  msg.insert("Content-Type", "text/html");
959  msg.insert("Connection", "close");
960  msg.prepare_payload();
961  handoff.response = std::make_shared<SimpleWriter>(msg);
962  return handoff;
963 }
964 
965 //------------------------------------------------------------------------------
966 
967 void
969 {
970  for (auto& p : ports)
971  {
972  if (p.secure())
973  {
974  if (p.ssl_key.empty() && p.ssl_cert.empty() && p.ssl_chain.empty())
975  p.context = make_SSLContext(p.ssl_ciphers);
976  else
977  p.context = make_SSLContextAuthed(
978  p.ssl_key, p.ssl_cert, p.ssl_chain, p.ssl_ciphers);
979  }
980  else
981  {
982  p.context = std::make_shared<boost::asio::ssl::context>(
983  boost::asio::ssl::context::sslv23);
984  }
985  }
986 }
987 
988 static Port
989 to_Port(ParsedPort const& parsed, std::ostream& log)
990 {
991  Port p;
992  p.name = parsed.name;
993 
994  if (!parsed.ip)
995  {
996  log << "Missing 'ip' in [" << p.name << "]";
997  Throw<std::exception>();
998  }
999  p.ip = *parsed.ip;
1000 
1001  if (!parsed.port)
1002  {
1003  log << "Missing 'port' in [" << p.name << "]";
1004  Throw<std::exception>();
1005  }
1006  else if (*parsed.port == 0)
1007  {
1008  log << "Port " << *parsed.port << "in [" << p.name << "] is invalid";
1009  Throw<std::exception>();
1010  }
1011  p.port = *parsed.port;
1012  if (parsed.admin_ip)
1013  p.admin_ip = *parsed.admin_ip;
1014  if (parsed.secure_gateway_ip)
1016 
1017  if (parsed.protocol.empty())
1018  {
1019  log << "Missing 'protocol' in [" << p.name << "]";
1020  Throw<std::exception>();
1021  }
1022  p.protocol = parsed.protocol;
1023 
1024  p.user = parsed.user;
1025  p.password = parsed.password;
1026  p.admin_user = parsed.admin_user;
1027  p.admin_password = parsed.admin_password;
1028  p.ssl_key = parsed.ssl_key;
1029  p.ssl_cert = parsed.ssl_cert;
1030  p.ssl_chain = parsed.ssl_chain;
1031  p.ssl_ciphers = parsed.ssl_ciphers;
1032  p.pmd_options = parsed.pmd_options;
1033  p.ws_queue_limit = parsed.ws_queue_limit;
1034  p.limit = parsed.limit;
1035 
1036  return p;
1037 }
1038 
1039 static std::vector<Port>
1040 parse_Ports(Config const& config, std::ostream& log)
1041 {
1042  std::vector<Port> result;
1043 
1044  if (!config.exists("server"))
1045  {
1046  log << "Required section [server] is missing";
1047  Throw<std::exception>();
1048  }
1049 
1050  ParsedPort common;
1051  parse_Port(common, config["server"], log);
1052 
1053  auto const& names = config.section("server").values();
1054  result.reserve(names.size());
1055  for (auto const& name : names)
1056  {
1057  if (!config.exists(name))
1058  {
1059  log << "Missing section: [" << name << "]";
1060  Throw<std::exception>();
1061  }
1062  ParsedPort parsed = common;
1063  parsed.name = name;
1064  parse_Port(parsed, config[name], log);
1065  result.push_back(to_Port(parsed, log));
1066  }
1067 
1068  if (config.standalone())
1069  {
1070  auto it = result.begin();
1071 
1072  while (it != result.end())
1073  {
1074  auto& p = it->protocol;
1075 
1076  // Remove the peer protocol, and if that would
1077  // leave the port empty, remove the port as well
1078  if (p.erase("peer") && p.empty())
1079  it = result.erase(it);
1080  else
1081  ++it;
1082  }
1083  }
1084  else
1085  {
1086  auto const count =
1087  std::count_if(result.cbegin(), result.cend(), [](Port const& p) {
1088  return p.protocol.count("peer") != 0;
1089  });
1090 
1091  if (count > 1)
1092  {
1093  log << "Error: More than one peer protocol configured in [server]";
1094  Throw<std::exception>();
1095  }
1096 
1097  if (count == 0)
1098  log << "Warning: No peer protocol configured";
1099  }
1100 
1101  return result;
1102 }
1103 
1104 // Fill out the client portion of the Setup
1105 static void
1107 {
1108  decltype(setup.ports)::const_iterator iter;
1109  for (iter = setup.ports.cbegin(); iter != setup.ports.cend(); ++iter)
1110  if (iter->protocol.count("http") > 0 ||
1111  iter->protocol.count("https") > 0)
1112  break;
1113  if (iter == setup.ports.cend())
1114  return;
1115  setup.client.secure = iter->protocol.count("https") > 0;
1117  ?
1118  // VFALCO HACK! to make localhost work
1119  (iter->ip.is_v6() ? "::1" : "127.0.0.1")
1120  : iter->ip.to_string();
1121  setup.client.port = iter->port;
1122  setup.client.user = iter->user;
1123  setup.client.password = iter->password;
1124  setup.client.admin_user = iter->admin_user;
1125  setup.client.admin_password = iter->admin_password;
1126 }
1127 
1128 // Fill out the overlay portion of the Setup
1129 static void
1131 {
1132  auto const iter = std::find_if(
1133  setup.ports.cbegin(), setup.ports.cend(), [](Port const& port) {
1134  return port.protocol.count("peer") != 0;
1135  });
1136  if (iter == setup.ports.cend())
1137  {
1138  setup.overlay.port = 0;
1139  return;
1140  }
1141  setup.overlay.ip = iter->ip;
1142  setup.overlay.port = iter->port;
1143 }
1144 
1145 ServerHandler::Setup
1147 {
1149  setup.ports = parse_Ports(config, log);
1150 
1153 
1154  return setup;
1155 }
1156 
1159  Application& app,
1160  Stoppable& parent,
1161  boost::asio::io_service& io_service,
1162  JobQueue& jobQueue,
1163  NetworkOPs& networkOPs,
1164  Resource::Manager& resourceManager,
1165  CollectorManager& cm)
1166 {
1167  return std::make_unique<ServerHandlerImp>(
1168  app, parent, io_service, jobQueue, networkOPs, resourceManager, cm);
1169 }
1170 
1171 } // 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:101
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:887
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:540
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:550
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:551
ripple::Resource::feeReferenceRPC
const Charge feeReferenceRPC
ripple::Role::IDENTIFIED
@ IDENTIFIED
ripple::RPC::APIVersionIfUnspecified
constexpr unsigned int APIVersionIfUnspecified
Definition: RPCHelpers.h:218
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:45
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:552
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:968
ripple::ServerHandlerImp::statusResponse
Handoff statusResponse(http_request_type const &request) const
Definition: ServerHandlerImp.cpp:936
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:1146
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:386
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:245
ripple::setup_Overlay
Overlay::Setup setup_Overlay(BasicConfig const &config)
Definition: OverlayImpl.cpp:1463
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:201
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:556
ripple::InfoSub::pointer
std::shared_ptr< InfoSub > pointer
Definition: InfoSub.h:43
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:262
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:217
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:989
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:553
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:292
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:74
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:1106
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:931
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
ripple::http_request_type
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
Definition: Handshake.h:47
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:209
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:1158
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:1040
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)