13#include <boost/asio.hpp> 
   14#include <boost/optional.hpp> 
   41   using boost::optional;
 
   42   using boost::asio::ip::tcp;
 
   43   using boost::asio::ip::address_v4;
 
   44   using boost::asio::ip::address_v6;
 
   45   using std::shared_ptr;
 
   53   static http_plugin_defaults current_http_plugin_defaults;
 
   56      current_http_plugin_defaults = 
config;
 
 
  152      static size_t in_flight_sizeof( 
const string& 
s ) {
 
  163      static size_t in_flight_sizeof( 
const fc::variant& v ) {
 
 
  174   using ssl_context_ptr =  websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context>;
 
  177   static bool verbose_http_errors = 
false;
 
  219         bool host_port_is_valid( 
const std::string& header_host_port, 
const string& endpoint_local_host_port ) {
 
 
  223         bool host_is_valid( 
const std::string& host, 
const string& endpoint_local_host_port, 
bool secure) {
 
  229            static auto has_port_expr = regex(
"[^:]:[0-9]+$"); 
 
  230            if (std::regex_search(host, has_port_expr)) {
 
  234               return host_port_is_valid( host + 
":" + std::to_string(secure ? websocketpp::uri_default_secure_port : websocketpp::uri_default_port ), endpoint_local_host_port);
 
 
  239            ssl_context_ptr ctx = websocketpp::lib::make_shared<websocketpp::lib::asio::ssl::context>(asio::ssl::context::sslv23_server);
 
  242               ctx->set_options(asio::ssl::context::default_workarounds |
 
  243                                asio::ssl::context::no_sslv2 |
 
  244                                asio::ssl::context::no_sslv3 |
 
  245                                asio::ssl::context::no_tlsv1 |
 
  246                                asio::ssl::context::no_tlsv1_1 |
 
  247                                asio::ssl::context::single_dh_use);
 
  250               ctx->use_private_key_file(
https_key, asio::ssl::context::pem);
 
  256                  SYS_THROW(chain::http_exception, 
"Failed to set NID_secp384r1");
 
  257               if(SSL_CTX_set_tmp_ecdh(ctx->native_handle(), (EC_KEY*)ecdh) != 1)
 
  258                  SYS_THROW(chain::http_exception, 
"Failed to set ECDH PFS");
 
  260               if(SSL_CTX_set_cipher_list(ctx->native_handle(), \
 
  261                  "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:AES256:" \
 
  262                  "!DHE:!RSA:!AES128:!RC4:!DES:!3DES:!DSS:!SRP:!PSK:!EXP:!MD5:!LOW:!aNULL:!eNULL") != 1)
 
  263                  SYS_THROW(chain::http_exception, 
"Failed to set HTTPS cipher list");
 
  266            } 
catch(std::exception& e) {
 
 
  275            string err = 
"Internal Service error, http: ";
 
  287               } 
catch (
const std::exception& e) {
 
  291                                        "Internal Service Error",
 
  293                                                                   verbose_http_errors )};
 
  296                  err += 
"Unknown Exception";
 
  298                                        "Internal Service Error",
 
  301                                              verbose_http_errors )};
 
  304            } 
catch (fc::timeout_exception& e) {
 
  305               con->set_body( R
"xxx({"message": "Internal Server Error"})xxx" ); 
  306               fc_elog( logger, "Timeout exception ${te} attempting to handle exception: ${e}", (
"te", e.to_detail_string())(
"e", err) );
 
  308               con->set_body( R
"xxx({"message": "Internal Server Error"})xxx" ); 
  309               fc_elog( logger, "Exception attempting to handle exception: ${e}", (
"e", err) );
 
  311            con->send_http_response();
 
 
  316            bool is_secure = con->get_uri()->get_secure();
 
  317            const auto& local_endpoint = con->get_socket().lowest_layer().local_endpoint();
 
  318            auto local_socket_host_port = local_endpoint.address().to_string() + 
":" + std::to_string(local_endpoint.port());
 
  320            const auto& host_str = req.get_header(
"Host");
 
  321            if (host_str.empty() || !
host_is_valid(host_str, local_socket_host_port, is_secure)) {
 
 
  332               fc_dlog( 
logger, 
"429 - too many bytes in flight: ${bytes}", (
"bytes", bytes_in_flight_size) );
 
  336               ei.
what = 
"Too many bytes in flight: " + std::to_string( bytes_in_flight_size );
 
  340               con->send_http_response();
 
 
  377               _conn->set_body(std::move(body));
 
  379               _conn->send_http_response();
 
 
 
  395            return std::make_shared<abstract_conn_impl<T>>(std::move(conn), std::move(impl));
 
 
  433               _object = std::move(from._object);
 
  435               _impl = std::move(from._impl);
 
 
 
  465            return std::make_shared<in_flight<T>>(std::forward<T>(
object), std::move(impl));
 
 
  479            auto next_ptr = std::make_shared<url_handler>(std::move(next));
 
  480            return [my=std::move(my), 
priority, next_ptr=std::move(next_ptr)]
 
  483               if (!conn->verify_max_bytes_in_flight()) {
 
  488                  then(code, std::move(resp));
 
  493               app().
post( 
priority, [next_ptr, conn=std::move(conn), 
r=std::move(
r), tracked_b, wrapped_then=std::move(wrapped_then)]() 
mutable {
 
  496                     (*next_ptr)( std::move( 
r ), std::move(*(*tracked_b)), std::move(wrapped_then)) ;
 
  498                     conn->handle_exception();
 
 
  514                  next(std::move(
r), std::move(b), std::move(then));
 
  516                  conn->handle_exception();
 
 
  530            return [my=shared_from_this(), abstract_conn_ptr]( 
int code, 
fc::variant response ) {
 
  532               if (!abstract_conn_ptr->verify_max_bytes_in_flight()) {
 
  537               boost::asio::post( my->thread_pool->get_executor(),
 
  538                                  [my, abstract_conn_ptr, code, tracked_response=std::move(tracked_response)]() {
 
  540                     std::string json = fc::json::to_string( *(*tracked_response), fc::time_point::now() + my->max_response_time );
 
  541                     auto tracked_json = make_in_flight(std::move(json), my);
 
  542                     abstract_conn_ptr->send_response(std::move(*(*tracked_json)), code);
 
  544                     abstract_conn_ptr->handle_exception();
 
 
  553               auto& req = con->get_request();
 
  555               if(!allow_host<T>(req, con))
 
  558               if( !access_control_allow_origin.empty()) {
 
  559                  con->append_header( 
"Access-Control-Allow-Origin", access_control_allow_origin );
 
  561               if( !access_control_allow_headers.empty()) {
 
  562                  con->append_header( 
"Access-Control-Allow-Headers", access_control_allow_headers );
 
  564               if( !access_control_max_age.empty()) {
 
  565                  con->append_header( 
"Access-Control-Max-Age", access_control_max_age );
 
  567               if( access_control_allow_credentials ) {
 
  568                  con->append_header( 
"Access-Control-Allow-Credentials", 
"true" );
 
  571               if(req.get_method() == 
"OPTIONS") {
 
  576               con->append_header( 
"Content-type", 
"application/json" );
 
  577               con->defer_http_response();
 
  579               auto abstract_conn_ptr = make_abstract_conn_ptr<T>(con, shared_from_this());
 
  580               if( !verify_max_bytes_in_flight( con )) 
return;
 
  582               std::string resource = con->get_uri()->get_resource();
 
  583               auto handler_itr = url_handlers.find( resource );
 
  584               if( handler_itr != url_handlers.end()) {
 
  585                  std::string body = con->get_request_body();
 
  586                  handler_itr->second( abstract_conn_ptr, std::move( resource ), std::move( body ), make_http_response_handler<T>(abstract_conn_ptr) );
 
  588                  fc_dlog( 
logger, 
"404 - not found: ${ep}", (
"ep", resource) );
 
  593                  con->send_http_response();
 
  596               handle_exception<T>( con );
 
 
  604               ws.init_asio( &thread_pool->get_executor() );
 
  605               ws.set_reuse_addr(
true);
 
  606               ws.set_max_http_body_size(max_body_size);
 
  609                  handle_http_request<detail::asio_with_stub_log<T>>(
ws.get_con_from_hdl(hdl));
 
  613            } 
catch ( 
const std::exception& e ){
 
 
  621            auto resolved_port_str = std::to_string(ep.port());
 
  622            valid_hosts.emplace(host + 
":" + port);
 
  623            valid_hosts.emplace(host + 
":" + resolved_port_str);
 
 
 
  641             "The filename (relative to data-dir) to create a unix socket for HTTP RPC; set blank to disable.");
 
  644            (
"unix-socket-path", bpo::value<string>(),
 
  645             "The filename (relative to data-dir) to create a unix socket for HTTP RPC; set blank to disable.");
 
  649            (
"http-server-address", bpo::value<string>()->default_value(
"127.0.0.1:" + std::to_string(current_http_plugin_defaults.
default_http_port)),
 
  650             "The local IP and port to listen for incoming http connections; set blank to disable.");
 
  653            (
"http-server-address", bpo::value<string>(),
 
  654             "The local IP and port to listen for incoming http connections; leave blank to disable.");
 
  657            (
"https-server-address", bpo::value<string>(),
 
  658             "The local IP and port to listen for incoming https connections; leave blank to disable.")
 
  660            (
"https-certificate-chain-file", bpo::value<string>(),
 
  661             "Filename with the certificate chain to present on https connections. PEM format. Required for https.")
 
  663            (
"https-private-key-file", bpo::value<string>(),
 
  664             "Filename with https private key in PEM format. Required for https")
 
  666            (
"https-ecdh-curve", bpo::value<https_ecdh_curve_t>()->notifier([
this](
https_ecdh_curve_t c) {
 
  667               my->https_ecdh_curve = c;
 
  669            "Configure https ECDH curve to use: secp384r1 or prime256v1")
 
  671            (
"access-control-allow-origin", bpo::value<string>()->notifier([
this](
const string& v) {
 
  672                my->access_control_allow_origin = v;
 
  673                fc_ilog( 
logger, 
"configured http with Access-Control-Allow-Origin: ${o}",
 
  674                         (
"o", my->access_control_allow_origin) );
 
  676             "Specify the Access-Control-Allow-Origin to be returned on each request.")
 
  678            (
"access-control-allow-headers", bpo::value<string>()->notifier([
this](
const string& v) {
 
  679                my->access_control_allow_headers = v;
 
  680                fc_ilog( 
logger, 
"configured http with Access-Control-Allow-Headers : ${o}",
 
  681                         (
"o", my->access_control_allow_headers) );
 
  683             "Specify the Access-Control-Allow-Headers to be returned on each request.")
 
  685            (
"access-control-max-age", bpo::value<string>()->notifier([
this](
const string& v) {
 
  686                my->access_control_max_age = v;
 
  687                fc_ilog( 
logger, 
"configured http with Access-Control-Max-Age : ${o}",
 
  688                         (
"o", my->access_control_max_age) );
 
  690             "Specify the Access-Control-Max-Age to be returned on each request.")
 
  692            (
"access-control-allow-credentials",
 
  693             bpo::bool_switch()->notifier([
this](
bool v) {
 
  694                my->access_control_allow_credentials = v;
 
  695                if( v ) 
fc_ilog( 
logger, 
"configured http with Access-Control-Allow-Credentials: true" );
 
  696             })->default_value(
false),
 
  697             "Specify if Access-Control-Allow-Credentials: true should be returned on each request.")
 
  698            (
"max-body-size", bpo::value<uint32_t>()->default_value(my->max_body_size),
 
  699             "The maximum body size in bytes allowed for incoming RPC requests")
 
  700            (
"http-max-bytes-in-flight-mb", bpo::value<int64_t>()->default_value(500),
 
  701             "Maximum size in megabytes http_plugin should use for processing http requests. -1 for unlimited. 429 error response when exceeded." )
 
  702            (
"http-max-response-time-ms", bpo::value<uint32_t>()->default_value(30),
 
  703             "Maximum time for processing a request.")
 
  704            (
"verbose-http-errors", bpo::bool_switch()->default_value(
false),
 
  705             "Append the error log to HTTP responses")
 
  706            (
"http-validate-host", boost::program_options::value<bool>()->default_value(
true),
 
  707             "If set to false, then any incoming \"Host\" header is considered valid")
 
  708            (
"http-alias", bpo::value<std::vector<string>>()->composing(),
 
  709             "Additionaly acceptable values for the \"Host\" header of incoming HTTP requests, can be specified multiple times.  Includes http/s_server_address by default.")
 
  710            (
"http-threads", bpo::value<uint16_t>()->default_value( my->thread_pool_size ),
 
  711             "Number of worker threads in http thread pool")
 
 
  717         my->max_body_size = options.at( 
"max-body-size" ).as<
uint32_t>();
 
  718         verbose_http_errors = options.at( 
"verbose-http-errors" ).as<
bool>();
 
  720         my->thread_pool_size = options.at( 
"http-threads" ).as<
uint16_t>();
 
  721         SYS_ASSERT( my->thread_pool_size > 0, chain::plugin_config_exception,
 
  722                     "http-threads ${num} must be greater than 0", (
"num", my->thread_pool_size));
 
  724         auto max_bytes_mb = options.at( 
"http-max-bytes-in-flight-mb" ).as<
int64_t>();
 
  725         SYS_ASSERT( (max_bytes_mb >= -1 && max_bytes_mb < std::numeric_limits<int64_t>::max() / (1024 * 1024)), chain::plugin_config_exception,
 
  726                     "http-max-bytes-in-flight-mb (${max_bytes_mb}) must be equal to or greater than -1 and less than ${max}", (
"max_bytes_mb", max_bytes_mb) (
"max", std::numeric_limits<int64_t>::max() / (1024 * 1024)) );
 
  727         if ( max_bytes_mb == -1 ) {
 
  728            my->max_bytes_in_flight = std::numeric_limits<size_t>::max();
 
  730            my->max_bytes_in_flight = max_bytes_mb * 1024 * 1024;
 
  734         my->validate_host = options.at(
"http-validate-host").as<
bool>();
 
  735         if( options.count( 
"http-alias" )) {
 
  737            my->valid_hosts.insert(aliases.begin(), aliases.end());
 
  740         tcp::resolver resolver( 
app().get_io_service());
 
  741         if( options.count( 
"http-server-address" ) && options.at( 
"http-server-address" ).as<
string>().length()) {
 
  742            string lipstr = options.at( 
"http-server-address" ).as<
string>();
 
  743            string host = lipstr.substr( 0, lipstr.find( 
':' ));
 
  744            string port = lipstr.substr( host.size() + 1, lipstr.size());
 
  745            tcp::resolver::query query( tcp::v4(), host.c_str(), port.c_str());
 
  747               my->listen_endpoint = *resolver.resolve( query );
 
  748               ilog( 
"configured http to listen on ${h}:${p}", (
"h", host)( 
"p", port ));
 
  749            } 
catch ( 
const boost::system::system_error& ec ) {
 
  750               elog( 
"failed to configure http to listen on ${h}:${p} (${m})",
 
  751                     (
"h", host)( 
"p", port )( 
"m", ec.what()));
 
  755            if (my->listen_endpoint) {
 
  756               my->add_aliases_for_endpoint(*my->listen_endpoint, host, port);
 
  760         if( options.count( 
"unix-socket-path" ) && !options.at( 
"unix-socket-path" ).as<
string>().empty()) {
 
  761            boost::filesystem::path sock_path = options.at(
"unix-socket-path").as<
string>();
 
  762            if (sock_path.is_relative())
 
  764            my->unix_endpoint = asio::local::stream_protocol::endpoint(sock_path.string());
 
  767         if( options.count( 
"https-server-address" ) && options.at( 
"https-server-address" ).as<
string>().length()) {
 
  768            if( !options.count( 
"https-certificate-chain-file" ) ||
 
  769                options.at( 
"https-certificate-chain-file" ).as<
string>().empty()) {
 
  770               elog( 
"https-certificate-chain-file is required for HTTPS" );
 
  773            if( !options.count( 
"https-private-key-file" ) ||
 
  774                options.at( 
"https-private-key-file" ).as<
string>().empty()) {
 
  775               elog( 
"https-private-key-file is required for HTTPS" );
 
  779            string lipstr = options.at( 
"https-server-address" ).as<
string>();
 
  780            string host = lipstr.substr( 0, lipstr.find( 
':' ));
 
  781            string port = lipstr.substr( host.size() + 1, lipstr.size());
 
  782            tcp::resolver::query query( tcp::v4(), host.c_str(), port.c_str());
 
  784               my->https_listen_endpoint = *resolver.resolve( query );
 
  785               ilog( 
"configured https to listen on ${h}:${p} (TLS configuration will be validated momentarily)",
 
  786                     (
"h", host)( 
"p", port ));
 
  787               my->https_cert_chain = options.at( 
"https-certificate-chain-file" ).as<
string>();
 
  788               my->https_key = options.at( 
"https-private-key-file" ).as<
string>();
 
  789            } 
catch ( 
const boost::system::system_error& ec ) {
 
  790               elog( 
"failed to configure https to listen on ${h}:${p} (${m})",
 
  791                     (
"h", host)( 
"p", port )( 
"m", ec.what()));
 
  795            if (my->https_listen_endpoint) {
 
  796               my->add_aliases_for_endpoint(*my->https_listen_endpoint, host, port);
 
 
  810            my->thread_pool.emplace( 
"http", my->thread_pool_size );
 
  811            if(my->listen_endpoint) {
 
  813                  my->create_server_for_endpoint(*my->listen_endpoint, my->server);
 
  816                  my->server.listen(*my->listen_endpoint);
 
  817                  my->server.start_accept();
 
  821               } 
catch ( 
const std::exception& e ){
 
  830            if(my->unix_endpoint) {
 
  833                  my->unix_server.init_asio( &my->thread_pool->get_executor() );
 
  834                  my->unix_server.set_max_http_body_size(my->max_body_size);
 
  835                  my->unix_server.listen(*my->unix_endpoint);
 
  840                  my->unix_server.start_accept();
 
  844               } 
catch ( 
const std::exception& e ){
 
  845                  fc_elog( 
logger, 
"unix socket service (${path}) failed to start: ${e}", (
"e", e.
what())(
"path",my->unix_endpoint->path()) );
 
  848                  fc_elog( 
logger, 
"error thrown from unix socket (${path}) io service", (
"path",my->unix_endpoint->path()) );
 
  853            if(my->https_listen_endpoint) {
 
  855                  my->create_server_for_endpoint(*my->https_listen_endpoint, my->https_server);
 
  857                     return my->on_tls_init(hdl);
 
  861                  my->https_server.listen(*my->https_listen_endpoint);
 
  862                  my->https_server.start_accept();
 
  866               } 
catch ( 
const std::exception& e ){
 
  876               std::string(
"/v1/node/get_supported_apis"),
 
  879                     if (body.empty()) body = 
"{}";
 
  880                     auto result = (*this).get_supported_apis();
 
 
  899      if(my->server.is_listening())
 
  900         my->server.stop_listening();
 
  901      if(my->https_server.is_listening())
 
  902         my->https_server.stop_listening();
 
  903      if(my->unix_server.is_listening())
 
  904         my->unix_server.stop_listening();
 
  906      if( my->thread_pool ) {
 
  907         my->thread_pool->stop();
 
  908         my->thread_pool.reset();
 
  912      my->url_handlers.clear();
 
  914      app().
post( 0, [me = my](){} ); 
 
 
  920      my->url_handlers[
url] = my->make_app_thread_url_handler(
priority, handler, my);
 
 
  925      my->url_handlers[
url] = my->make_http_thread_url_handler(handler);
 
 
  932         } 
catch (chain::unknown_block_exception& e) {
 
  935         } 
catch (chain::invalid_http_request& e) {
 
  938         } 
catch (chain::unsatisfied_authorization& e) {
 
  941         } 
catch (chain::tx_duplicate& e) {
 
  944         } 
catch (fc::eof_exception& e) {
 
  947            fc_elog( 
logger, 
"Unable to parse arguments to ${api}.${call}", (
"api", api_name)( 
"call", call_name ) );
 
  952            fc_dlog( 
logger, 
"Exception while processing ${api}.${call}: ${e}",
 
  953                     (
"api", api_name)( 
"call", call_name )(
"e", e.to_detail_string()) );
 
  954         } 
catch (std::exception& e) {
 
  957            fc_elog( 
logger, 
"STD Exception encountered while processing ${api}.${call}",
 
  958                     (
"api", api_name)( 
"call", call_name ) );
 
  959            fc_dlog( 
logger, 
"Exception Details: ${e}", (
"e", e.what()) );
 
  964            fc_elog( 
logger, 
"Unknown Exception encountered while processing ${api}.${call}",
 
  965                     (
"api", api_name)( 
"call", call_name ) );
 
  968         std::cerr << 
"Exception attempting to handle exception for " << api_name << 
"." << call_name << std::endl;
 
 
  973      return (!my->listen_endpoint || my->listen_endpoint->address().is_loopback()) && (!my->https_listen_endpoint || my->https_listen_endpoint->address().is_loopback());
 
 
  977      return (!my->listen_endpoint || my->listen_endpoint->address().is_loopback());
 
 
  981      return verbose_http_errors;
 
 
  987      for (
const auto& handler : my->url_handlers) {
 
  988         if (handler.first != 
"/v1/node/get_supported_apis")
 
  989            result.apis.emplace_back(handler.first);
 
 
  996      return my->max_response_time;
 
 
 1002      if (
s == 
"secp384r1")
 
 1004      else if (
s == 
"prime256v1")
 
 1007         in.setstate(std::ios_base::failbit);
 
 
 1015         osm << 
"prime256v1";
 
 
std::string ws(int const level)
 
#define SYS_THROW(exc_type, FORMAT,...)
 
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
 
bfs::path data_dir() const
Get data directory.
 
auto post(int priority, Func &&func)
 
void register_config_type()
 
Used to generate a useful error report when an exception is thrown.
 
static constexpr fc::microseconds format_time_limit
 
std::string to_detail_string(log_level ll=log_level::all) const
 
const char * what() const noexcept override
 
static string to_string(const variant &v, const yield_function_t &yield, const output_formatting format=output_formatting::stringify_large_ints_and_doubles)
 
static void update(const fc::string &name, logger &log)
 
static constexpr time_point maximum()
 
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
 
string access_control_allow_headers
 
http_plugin_impl & operator=(const http_plugin_impl &)=delete
 
set< string > valid_hosts
 
ssl_context_ptr on_tls_init(websocketpp::connection_hdl hdl)
 
websocket_server_tls_type https_server
 
http_plugin_impl(http_plugin_impl &&)=delete
 
string access_control_allow_origin
 
void add_aliases_for_endpoint(const tcp::endpoint &ep, string host, string port)
 
std::optional< asio::local::stream_protocol::endpoint > unix_endpoint
 
uint16_t thread_pool_size
 
http_plugin_impl(const http_plugin_impl &)=delete
 
bool host_is_valid(const std::string &host, const string &endpoint_local_host_port, bool secure)
 
void create_server_for_endpoint(const tcp::endpoint &ep, websocketpp::server< detail::asio_with_stub_log< T > > &ws)
 
fc::microseconds max_response_time
 
websocket_server_type server
 
static void handle_exception(detail::connection_ptr< T > con)
 
static detail::abstract_conn_ptr make_abstract_conn_ptr(detail::connection_ptr< T > conn, http_plugin_impl_ptr impl)
 
bool access_control_allow_credentials
 
static detail::internal_url_handler make_app_thread_url_handler(int priority, url_handler next, http_plugin_impl_ptr my)
 
std::optional< sysio::chain::named_thread_pool > thread_pool
 
auto make_http_response_handler(detail::abstract_conn_ptr abstract_conn_ptr)
 
std::atomic< size_t > bytes_in_flight
 
static auto make_in_flight(T &&object, http_plugin_impl_ptr impl)
 
std::optional< tcp::endpoint > https_listen_endpoint
 
static detail::internal_url_handler make_http_thread_url_handler(url_handler next)
 
http_plugin_impl()=default
 
websocket_local_server_type unix_server
 
bool host_port_is_valid(const std::string &header_host_port, const string &endpoint_local_host_port)
 
string access_control_max_age
 
map< string, detail::internal_url_handler > url_handlers
 
std::optional< tcp::endpoint > listen_endpoint
 
void handle_http_request(detail::connection_ptr< T > con)
 
http_plugin_impl & operator=(http_plugin_impl &&)=delete
 
https_ecdh_curve_t https_ecdh_curve
 
size_t max_bytes_in_flight
 
bool allow_host(const typename T::request_type &req, detail::connection_ptr< T > con)
 
bool verify_max_bytes_in_flight(const T &con)
 
void add_api(const api_description &api, int priority=appbase::priority::medium_low)
 
void add_handler(const string &url, const url_handler &, int priority=appbase::priority::medium_low)
 
void add_async_handler(const string &url, const url_handler &handler)
 
virtual void set_program_options(options_description &, options_description &cfg) override
 
bool verbose_errors() const
 
get_supported_apis_result get_supported_apis() const
 
fc::microseconds get_max_response_time() const
 
bool is_on_loopback() const
 
static void set_defaults(const http_plugin_defaults config)
 
void plugin_initialize(const variables_map &options)
 
static void handle_exception(const char *api_name, const char *call_name, const string &body, url_response_callback cb)
 
void handle_sighup() override
 
Stub logger that ignores all input.
 
connection_type::ptr connection_ptr
 
Asio based endpoint transport component.
 
Asio based endpoint transport component.
 
#define FC_LOG_AND_RETHROW()
 
const fc::string logger_name("http_plugin")
 
#define FC_LOG_MESSAGE(LOG_LEVEL, FORMAT,...)
A helper method for generating log messages.
 
#define fc_ilog(LOGGER, FORMAT,...)
 
#define fc_elog(LOGGER, FORMAT,...)
 
#define fc_dlog(LOGGER, FORMAT,...)
 
size_t pack_size(const T &v)
 
datastream< ST > & operator<<(datastream< ST > &s, const sysio::chain::may_not_exist< T > &v)
 
datastream< ST > & operator>>(datastream< ST > &s, sysio::chain::may_not_exist< T > &v)
 
std::function< void(abstract_conn_ptr, string, string, url_response_callback)> internal_url_handler
 
std::shared_ptr< abstract_conn > abstract_conn_ptr
 
typename websocketpp::server< T >::connection_ptr connection_ptr
 
websocketpp::lib::shared_ptr< websocketpp::lib::asio::ssl::context > ssl_context_ptr
 
std::function< void(string, string, url_response_callback)> url_handler
Callback type for a URL handler.
 
std::function< void(int, fc::variant)> url_response_callback
A callback function provided to a URL handler to allow it to specify the HTTP response code and body.
 
const fc::string logger_name("net_plugin_impl")
 
std::shared_ptr< class http_plugin_impl > http_plugin_impl_ptr
 
lib::weak_ptr< void > connection_hdl
A handle to uniquely identify a connection.
 
#define T(meth, val, expected)
 
static constexpr int high
 
virtual bool verify_max_bytes_in_flight()=0
 
virtual void handle_exception()=0
 
virtual void send_response(std::string, int)=0
 
type::request_type request_type
 
websocketpp::transport::asio::basic_socket::local_endpoint socket_type
 
type::alog_type alog_type
 
type::elog_type elog_type
 
type::concurrency_type concurrency_type
 
type::response_type response_type
 
base::message_type message_type
 
static const long timeout_open_handshake
 
base::con_msg_manager_type con_msg_manager_type
 
asio_local_with_stub_log type
 
base::concurrency_type concurrency_type
 
base::response_type response_type
 
websocketpp::log::stub elog_type
 
websocketpp::transport::asio::local_endpoint< transport_config > transport_type
 
base::endpoint_msg_manager_type endpoint_msg_manager_type
 
base::request_type request_type
 
websocketpp::log::stub alog_type
 
type::elog_type elog_type
 
type::concurrency_type concurrency_type
 
type::response_type response_type
 
type::alog_type alog_type
 
type::request_type request_type
 
base::con_msg_manager_type con_msg_manager_type
 
base::message_type message_type
 
base::request_type request_type
 
websocketpp::log::stub alog_type
 
websocketpp::transport::asio::endpoint< transport_config > transport_type
 
base::endpoint_msg_manager_type endpoint_msg_manager_type
 
websocketpp::log::stub elog_type
 
base::response_type response_type
 
base::concurrency_type concurrency_type
 
static const long timeout_open_handshake
 
Structure used to create JSON error responses.
 
string default_unix_socket_path
 
uint16_t default_http_port
 
abstract_conn_impl(abstract_conn_impl &&)=delete
 
abstract_conn_impl(const abstract_conn_impl &)=delete
 
void send_response(std::string body, int code) override
 
bool verify_max_bytes_in_flight() override
 
abstract_conn_impl(detail::connection_ptr< T > conn, http_plugin_impl_ptr impl)
 
http_plugin_impl_ptr _impl
 
detail::connection_ptr< T > _conn
 
abstract_conn_impl & operator=(abstract_conn_impl &&) noexcept=default
 
void handle_exception() override
 
abstract_conn_impl & operator=(const abstract_conn_impl &)=delete
 
in_flight(in_flight &&from)
 
in_flight & operator=(const in_flight &)=delete
 
in_flight(const in_flight &)=delete
 
in_flight & operator=(in_flight &&from)
 
http_plugin_impl_ptr _impl
 
in_flight(T &&object, http_plugin_impl_ptr impl)
 
const T & operator*() const
 
Server config with asio transport and TLS disabled.
 
static level const all
Special aggregate value representing "all levels".
 
yh_object_descriptor object