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