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