BitShares-Core  4.0.0
BitShares blockchain implementation and command-line interface software
websocket.cpp
Go to the documentation of this file.
2 #include <websocketpp/config/asio_client.hpp>
3 #include <websocketpp/config/asio.hpp>
4 #include <websocketpp/server.hpp>
5 #include <websocketpp/config/asio_client.hpp>
6 #include <websocketpp/client.hpp>
7 #include <websocketpp/logger/stub.hpp>
8 
9 #ifdef HAS_ZLIB
10 #include <websocketpp/extensions/permessage_deflate/enabled.hpp>
11 #else
12 #include <websocketpp/extensions/permessage_deflate/disabled.hpp>
13 #endif
14 
15 #include <fc/io/json.hpp>
16 #include <fc/optional.hpp>
17 #include <fc/reflect/variant.hpp>
18 #include <fc/rpc/websocket_api.hpp>
19 #include <fc/variant.hpp>
20 #include <fc/thread/thread.hpp>
21 #include <fc/asio.hpp>
22 
23 #if WIN32
24 #include <wincrypt.h>
25 #endif
26 
27 #ifdef DEFAULT_LOGGER
28 # undef DEFAULT_LOGGER
29 #endif
30 #define DEFAULT_LOGGER "rpc"
31 
32 namespace fc { namespace http {
33 
34  namespace detail {
35 #if WIN32
36  // taken from https://stackoverflow.com/questions/39772878/reliable-way-to-get-root-ca-certificates-on-windows/40710806
37  static void add_windows_root_certs(boost::asio::ssl::context &ctx)
38  {
39  HCERTSTORE hStore = CertOpenSystemStore( 0, "ROOT" );
40  if( hStore == NULL )
41  return;
42 
43  X509_STORE *store = X509_STORE_new();
44  PCCERT_CONTEXT pContext = NULL;
45  while( (pContext = CertEnumCertificatesInStore( hStore, pContext )) != NULL )
46  {
47  X509 *x509 = d2i_X509( NULL, (const unsigned char **)&pContext->pbCertEncoded,
48  pContext->cbCertEncoded);
49  if( x509 != NULL )
50  {
51  X509_STORE_add_cert( store, x509 );
52  X509_free( x509 );
53  }
54  }
55 
56  CertFreeCertificateContext( pContext );
57  CertCloseStore( hStore, 0 );
58 
59  SSL_CTX_set_cert_store( ctx.native_handle(), store );
60  }
61 #endif
62  struct asio_with_stub_log : public websocketpp::config::asio {
63 
65  typedef asio base;
66 
67  typedef base::concurrency_type concurrency_type;
68 
69  typedef base::request_type request_type;
70  typedef base::response_type response_type;
71 
72  typedef base::message_type message_type;
73  typedef base::con_msg_manager_type con_msg_manager_type;
74  typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
75 
77  /*typedef websocketpp::log::syslog<concurrency_type,
78  websocketpp::log::elevel> elog_type;
79  typedef websocketpp::log::syslog<concurrency_type,
80  websocketpp::log::alevel> alog_type;
81  */
82  //typedef base::alog_type alog_type;
83  //typedef base::elog_type elog_type;
84  typedef websocketpp::log::stub elog_type;
85  typedef websocketpp::log::stub alog_type;
86 
87  typedef base::rng_type rng_type;
88 
89  struct transport_config : public base::transport_config {
97  };
98 
99  typedef websocketpp::transport::asio::endpoint<transport_config>
101 
102  static const long timeout_open_handshake = 0;
103 
104  // permessage_compress extension
106 #ifdef HAS_ZLIB
107  typedef websocketpp::extensions::permessage_deflate::enabled <permessage_deflate_config> permessage_deflate_type;
108 #else
109  typedef websocketpp::extensions::permessage_deflate::disabled <permessage_deflate_config> permessage_deflate_type;
110 #endif
111 
112  };
113  struct asio_tls_with_stub_log : public websocketpp::config::asio_tls {
114 
116  typedef asio_tls base;
117 
118  typedef base::concurrency_type concurrency_type;
119 
120  typedef base::request_type request_type;
121  typedef base::response_type response_type;
122 
123  typedef base::message_type message_type;
124  typedef base::con_msg_manager_type con_msg_manager_type;
125  typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
126 
128  /*typedef websocketpp::log::syslog<concurrency_type,
129  websocketpp::log::elevel> elog_type;
130  typedef websocketpp::log::syslog<concurrency_type,
131  websocketpp::log::alevel> alog_type;
132  */
133  //typedef base::alog_type alog_type;
134  //typedef base::elog_type elog_type;
135  typedef websocketpp::log::stub elog_type;
136  typedef websocketpp::log::stub alog_type;
137 
138  typedef base::rng_type rng_type;
139 
140  struct transport_config : public base::transport_config {
147  };
148 
149  typedef websocketpp::transport::asio::endpoint<transport_config>
151 
152  static const long timeout_open_handshake = 0;
153  };
154  struct asio_tls_stub_log : public websocketpp::config::asio_tls {
156  typedef asio_tls base;
157 
158  typedef base::concurrency_type concurrency_type;
159 
160  typedef base::request_type request_type;
161  typedef base::response_type response_type;
162 
163  typedef base::message_type message_type;
164  typedef base::con_msg_manager_type con_msg_manager_type;
165  typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
166 
167  //typedef base::alog_type alog_type;
168  //typedef base::elog_type elog_type;
169  typedef websocketpp::log::stub elog_type;
170  typedef websocketpp::log::stub alog_type;
171 
172  typedef base::rng_type rng_type;
173 
174  struct transport_config : public base::transport_config {
181  };
182 
183  typedef websocketpp::transport::asio::endpoint<transport_config>
185  };
186 
187 
188 
189 
190 
191  using websocketpp::connection_hdl;
192  typedef websocketpp::server<asio_with_stub_log> websocket_server_type;
193  typedef websocketpp::server<asio_tls_stub_log> websocket_tls_server_type;
194 
195  template<typename T>
197  {
198  public:
200  :_ws_connection(con){
201  }
202 
204  {
205  }
206 
207  virtual void send_message( const std::string& message )override
208  {
209  idump((message));
210  //std::cerr<<"send: "<<message<<"\n";
211  auto ec = _ws_connection->send( message );
212  FC_ASSERT( !ec, "websocket send failed: ${msg}", ("msg",ec.message() ) );
213  }
214  virtual void close( int64_t code, const std::string& reason )override
215  {
216  _ws_connection->close(code,reason);
217  }
218 
219  virtual std::string get_request_header(const std::string& key)override
220  {
221  return _ws_connection->get_request_header(key);
222  }
223 
225  };
226 
227  typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
228 
230  {
231  public:
233  :_server_thread( fc::thread::current() )
234  {
235 
236  _server.clear_access_channels( websocketpp::log::alevel::all );
237  _server.init_asio(&fc::asio::default_io_service());
238  _server.set_reuse_addr(true);
239  _server.set_open_handler( [&]( connection_hdl hdl ){
240  _server_thread.async( [&](){
241  auto new_con = std::make_shared<websocket_connection_impl<websocket_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
242  _on_connection( _connections[hdl] = new_con );
243  }).wait();
244  });
245  _server.set_message_handler( [&]( connection_hdl hdl, websocket_server_type::message_ptr msg ){
246  _server_thread.async( [&](){
247  auto current_con = _connections.find(hdl);
248  assert( current_con != _connections.end() );
249  wdump(("server")(msg->get_payload()));
250  auto payload = msg->get_payload();
251  std::shared_ptr<websocket_connection> con = current_con->second;
252  ++_pending_messages;
253  auto f = fc::async([this,con,payload](){ if( _pending_messages ) --_pending_messages; con->on_message( payload ); });
254  if( _pending_messages > 100 )
255  f.wait();
256  }).wait();
257  });
258 
259  _server.set_socket_init_handler( [&](websocketpp::connection_hdl hdl, boost::asio::ip::tcp::socket& s ) {
260  boost::asio::ip::tcp::no_delay option(true);
261  s.lowest_layer().set_option(option);
262  } );
263 
264  _server.set_http_handler( [&]( connection_hdl hdl ){
265  _server_thread.async( [&](){
266  auto current_con = std::make_shared<websocket_connection_impl<websocket_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
267  _on_connection( current_con );
268 
269  auto con = _server.get_con_from_hdl(hdl);
270  con->defer_http_response();
271  std::string request_body = con->get_request_body();
272  wdump(("server")(request_body));
273 
274  fc::async([current_con, request_body, con] {
275  fc::http::reply response = current_con->on_http(request_body);
276  idump( (response) );
277  con->set_body( std::move( response.body_as_string ) );
278  con->set_status( websocketpp::http::status_code::value(response.status) );
279  con->send_http_response();
280  current_con->closed();
281  }, "call on_http");
282  }).wait();
283  });
284 
285  _server.set_close_handler( [&]( connection_hdl hdl ){
286  _server_thread.async( [&](){
287  if( _connections.find(hdl) != _connections.end() )
288  {
289  _connections[hdl]->closed();
290  _connections.erase( hdl );
291  }
292  else
293  {
294  wlog( "unknown connection closed" );
295  }
296  if( _connections.empty() && _closed )
297  _closed->set_value();
298  }).wait();
299  });
300 
301  _server.set_fail_handler( [&]( connection_hdl hdl ){
302  if( _server.is_listening() )
303  {
304  _server_thread.async( [&](){
305  if( _connections.find(hdl) != _connections.end() )
306  {
307  _connections[hdl]->closed();
308  _connections.erase( hdl );
309  }
310  else
311  {
312  wlog( "unknown connection failed" );
313  }
314  if( _connections.empty() && _closed )
315  _closed->set_value();
316  }).wait();
317  }
318  });
319  }
321  {
322  if( _server.is_listening() )
323  _server.stop_listening();
324 
325  if( _connections.size() )
326  _closed = promise<void>::create();
327 
328  auto cpy_con = _connections;
329  for( auto item : cpy_con )
330  _server.close( item.first, 0, "server exit" );
331 
332  if( _closed ) _closed->wait();
333  }
334 
335  typedef std::map<connection_hdl, websocket_connection_ptr,std::owner_less<connection_hdl> > con_map;
336 
337  con_map _connections;
339  websocket_server_type _server;
342  uint32_t _pending_messages = 0;
343  };
344 
346  {
347  public:
348  websocket_tls_server_impl( const string& server_pem, const string& ssl_password )
349  :_server_thread( fc::thread::current() )
350  {
351  //if( server_pem.size() )
352  {
353  _server.set_tls_init_handler( [=]( websocketpp::connection_hdl hdl ) -> context_ptr {
354  context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1);
355  try {
356  ctx->set_options(boost::asio::ssl::context::default_workarounds |
357  boost::asio::ssl::context::no_sslv2 |
358  boost::asio::ssl::context::no_sslv3 |
359  boost::asio::ssl::context::single_dh_use);
360  ctx->set_password_callback([=](std::size_t max_length, boost::asio::ssl::context::password_purpose){ return ssl_password;});
361  ctx->use_certificate_chain_file(server_pem);
362  ctx->use_private_key_file(server_pem, boost::asio::ssl::context::pem);
363  } catch (std::exception& e) {
364  std::cout << e.what() << std::endl;
365  }
366  return ctx;
367  });
368  }
369 
370  _server.clear_access_channels( websocketpp::log::alevel::all );
371  _server.init_asio(&fc::asio::default_io_service());
372  _server.set_reuse_addr(true);
373  _server.set_open_handler( [&]( connection_hdl hdl ){
374  _server_thread.async( [&](){
375  auto new_con = std::make_shared<websocket_connection_impl<websocket_tls_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
376  _on_connection( _connections[hdl] = new_con );
377  }).wait();
378  });
379  _server.set_message_handler( [&]( connection_hdl hdl, websocket_server_type::message_ptr msg ){
380  _server_thread.async( [&](){
381  auto current_con = _connections.find(hdl);
382  assert( current_con != _connections.end() );
383  auto received = msg->get_payload();
384  std::shared_ptr<websocket_connection> con = current_con->second;
385  fc::async([con,received](){ con->on_message( received ); });
386  }).wait();
387  });
388 
389  _server.set_http_handler( [&]( connection_hdl hdl ){
390  _server_thread.async( [&](){
391 
392  auto current_con = std::make_shared<websocket_connection_impl<websocket_tls_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
393  try{
394  _on_connection( current_con );
395 
396  auto con = _server.get_con_from_hdl(hdl);
397  wdump(("server")(con->get_request_body()));
398  auto response = current_con->on_http( con->get_request_body() );
399  idump((response));
400  con->set_body( std::move( response.body_as_string ) );
401  con->set_status( websocketpp::http::status_code::value( response.status ) );
402  } catch ( const fc::exception& e )
403  {
404  edump((e.to_detail_string()));
405  }
406  current_con->closed();
407 
408  }).wait();
409  });
410 
411  _server.set_close_handler( [&]( connection_hdl hdl ){
412  _server_thread.async( [&](){
413  _connections[hdl]->closed();
414  _connections.erase( hdl );
415  }).wait();
416  });
417 
418  _server.set_fail_handler( [&]( connection_hdl hdl ){
419  if( _server.is_listening() )
420  {
421  _server_thread.async( [&](){
422  if( _connections.find(hdl) != _connections.end() )
423  {
424  _connections[hdl]->closed();
425  _connections.erase( hdl );
426  }
427  }).wait();
428  }
429  });
430  }
432  {
433  if( _server.is_listening() )
434  _server.stop_listening();
435  auto cpy_con = _connections;
436  for( auto item : cpy_con )
437  _server.close( item.first, 0, "server exit" );
438  }
439 
440  typedef std::map<connection_hdl, websocket_connection_ptr,std::owner_less<connection_hdl> > con_map;
441 
442  con_map _connections;
444  websocket_tls_server_type _server;
447  };
448 
449 
450 
451 
452 
453 
454 
455 
456 
457 
458 
459 
460 
461  typedef websocketpp::client<asio_with_stub_log> websocket_client_type;
462  typedef websocketpp::client<asio_tls_stub_log> websocket_tls_client_type;
463 
466  using websocketpp::connection_hdl;
467 
468  template<typename T>
470  {
471  public:
473  :_client_thread( fc::thread::current() )
474  {
475  _client.clear_access_channels( websocketpp::log::alevel::all );
476  _client.set_message_handler( [&]( connection_hdl hdl,
477  typename websocketpp::client<T>::message_ptr msg ){
478  _client_thread.async( [&](){
479  wdump((msg->get_payload()));
480  //std::cerr<<"recv: "<<msg->get_payload()<<"\n";
481  auto received = msg->get_payload();
482  fc::async( [=](){
483  if( _connection )
484  _connection->on_message(received);
485  });
486  }).wait();
487  });
488  _client.set_close_handler( [=]( connection_hdl hdl ){
489  _client_thread.async( [&](){ if( _connection ) {_connection->closed(); _connection.reset();} } ).wait();
490  if( _closed ) _closed->set_value();
491  });
492  _client.set_fail_handler( [=]( connection_hdl hdl ){
493  auto con = _client.get_con_from_hdl(hdl);
494  auto message = con->get_ec().message();
495  if( _connection )
496  _client_thread.async( [&](){ if( _connection ) _connection->closed(); _connection.reset(); } ).wait();
497  if( _connected && !_connected->ready() )
498  _connected->set_exception( exception_ptr( new FC_EXCEPTION( exception, "${message}", ("message",message)) ) );
499  if( _closed )
500  _closed->set_value();
501  });
502 
503  _client.init_asio( &fc::asio::default_io_service() );
504  }
506  {
507  if( _connection )
508  {
509  _connection->close(0, "client closed");
510  _connection.reset();
511  }
512  if( _closed )
513  _closed->wait();
514  }
518  websocketpp::client<T> _client;
520  std::string _uri;
522  };
523 
524  class websocket_client_impl : public generic_websocket_client_impl<asio_with_stub_log>
525  {};
526 
528  {
529  public:
530  websocket_tls_client_impl( const std::string& ca_filename )
532  {
533  // ca_filename has special values:
534  // "_none" disables cert checking (potentially insecure!)
535  // "_default" uses default CA's provided by OS
536 
537  //
538  // We need ca_filename to be copied into the closure, as the referenced object might be destroyed by the caller by the time
539  // tls_init_handler() is called. According to [1], capture-by-value results in the desired behavior (i.e. creation of
540  // a copy which is stored in the closure) on standards compliant compilers, but some compilers on some optimization levels
541  // are buggy and are not standards compliant in this situation. Also, keep in mind this is the opinion of a single forum
542  // poster and might be wrong.
543  //
544  // To be safe, the following line explicitly creates a non-reference string which is captured by value, which should have the
545  // correct behavior on all compilers.
546  //
547  // [1] http://www.cplusplus.com/forum/general/142165/
548  // [2] http://stackoverflow.com/questions/21443023/capturing-a-reference-by-reference-in-a-c11-lambda
549  //
550 
551  std::string ca_filename_copy = ca_filename;
552 
553  _client.set_tls_init_handler( [=](websocketpp::connection_hdl) {
554  context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1);
555  try {
556  ctx->set_options(boost::asio::ssl::context::default_workarounds |
557  boost::asio::ssl::context::no_sslv2 |
558  boost::asio::ssl::context::no_sslv3 |
559  boost::asio::ssl::context::single_dh_use);
560 
561  setup_peer_verify( ctx, ca_filename_copy );
562  } catch (std::exception& e) {
563  edump((e.what()));
564  std::cout << e.what() << std::endl;
565  }
566  return ctx;
567  });
568 
569  }
571 
572  std::string get_host()const
573  {
574  return websocketpp::uri( _uri ).get_host();
575  }
576 
577  void setup_peer_verify( context_ptr& ctx, const std::string& ca_filename )
578  {
579  if( ca_filename == "_none" )
580  return;
581  ctx->set_verify_mode( boost::asio::ssl::verify_peer );
582  if( ca_filename == "_default" )
583  {
584 #if WIN32
585  add_windows_root_certs( *ctx );
586 #else
587  ctx->set_default_verify_paths();
588 #endif
589  }
590  else
591  ctx->load_verify_file( ca_filename );
592  ctx->set_verify_depth(10);
593  ctx->set_verify_callback( boost::asio::ssl::rfc2818_verification( get_host() ) );
594  }
595 
596  };
597 
598 
599  } // namespace detail
600 
601  websocket_server::websocket_server():my( new detail::websocket_server_impl() ) {}
603 
605  {
606  my->_on_connection = handler;
607  }
608 
609  void websocket_server::listen( uint16_t port )
610  {
611  my->_server.listen(port);
612  }
614  {
615  my->_server.listen( boost::asio::ip::tcp::endpoint( boost::asio::ip::address_v4(uint32_t(ep.get_address())),ep.port()) );
616  }
617 
619  {
620  websocketpp::lib::asio::error_code ec;
621  return my->_server.get_local_endpoint(ec).port();
622  }
623 
625  my->_server.start_accept();
626  }
627 
629  {
630  my->_server.stop_listening();
631  }
632 
634  {
635  for (auto& connection : my->_connections)
636  my->_server.close(connection.first, websocketpp::close::status::normal, "Goodbye");
637  }
638 
639 
640 
641  websocket_tls_server::websocket_tls_server( const string& server_pem, const string& ssl_password ):my( new detail::websocket_tls_server_impl(server_pem, ssl_password) ) {}
643 
645  {
646  my->_on_connection = handler;
647  }
648 
649  void websocket_tls_server::listen( uint16_t port )
650  {
651  my->_server.listen(port);
652  }
654  {
655  my->_server.listen( boost::asio::ip::tcp::endpoint( boost::asio::ip::address_v4(uint32_t(ep.get_address())),ep.port()) );
656  }
657 
659  my->_server.start_accept();
660  }
661 
662 
663  websocket_tls_client::websocket_tls_client( const std::string& ca_filename ):my( new detail::websocket_tls_client_impl( ca_filename ) ) {}
665 
666 
667 
668  websocket_client::websocket_client( const std::string& ca_filename ):my( new detail::websocket_client_impl() ),smy(new detail::websocket_tls_client_impl( ca_filename )) {}
670 
672  { try {
673  if( uri.substr(0,4) == "wss:" )
674  return secure_connect(uri);
675  FC_ASSERT( uri.substr(0,3) == "ws:" );
676 
677  // wlog( "connecting to ${uri}", ("uri",uri));
678  websocketpp::lib::error_code ec;
679 
680  my->_uri = uri;
681  my->_connected = promise<void>::create("websocket::connect");
682 
683  my->_client.set_open_handler( [=]( websocketpp::connection_hdl hdl ){
684  my->_hdl = hdl;
685  auto con = my->_client.get_con_from_hdl(hdl);
686  my->_connection = std::make_shared<detail::websocket_connection_impl<detail::websocket_client_connection_type>>( con );
687  my->_closed = promise<void>::create("websocket::closed");
688  my->_connected->set_value();
689  });
690 
691  auto con = my->_client.get_connection( uri, ec );
692 
693  if( ec ) FC_ASSERT( !ec, "error: ${e}", ("e",ec.message()) );
694 
695  my->_client.connect(con);
696  my->_connected->wait();
697  return my->_connection;
698  } FC_CAPTURE_AND_RETHROW( (uri) ) }
699 
701  { try {
702  if( uri.substr(0,3) == "ws:" )
703  return connect(uri);
704  FC_ASSERT( uri.substr(0,4) == "wss:" );
705  // wlog( "connecting to ${uri}", ("uri",uri));
706  websocketpp::lib::error_code ec;
707 
708  smy->_uri = uri;
709  smy->_connected = promise<void>::create("websocket::connect");
710 
711  smy->_client.set_open_handler( [=]( websocketpp::connection_hdl hdl ){
712  auto con = smy->_client.get_con_from_hdl(hdl);
713  smy->_connection = std::make_shared<detail::websocket_connection_impl<detail::websocket_tls_client_connection_type>>( con );
714  smy->_closed = promise<void>::create("websocket::closed");
715  smy->_connected->set_value();
716  });
717 
718  auto con = smy->_client.get_connection( uri, ec );
719  if( ec )
720  FC_ASSERT( !ec, "error: ${e}", ("e",ec.message()) );
721  smy->_client.connect(con);
722  smy->_connected->wait();
723  return smy->_connection;
724  } FC_CAPTURE_AND_RETHROW( (uri) ) }
725 
727  {
728  if (my->_hdl)
729  my->_client.close(*my->_hdl, websocketpp::close::status::normal, "Goodbye");
730  }
731 
733  {
734  close();
735  if (my->_closed)
736  my->_closed->wait();
737  }
738 
740  { try {
741  // wlog( "connecting to ${uri}", ("uri",uri));
742  websocketpp::lib::error_code ec;
743 
744  my->_connected = promise<void>::create("websocket::connect");
745 
746  my->_client.set_open_handler( [=]( websocketpp::connection_hdl hdl ){
747  auto con = my->_client.get_con_from_hdl(hdl);
748  my->_connection = std::make_shared<detail::websocket_connection_impl<detail::websocket_tls_client_connection_type>>( con );
749  my->_closed = promise<void>::create("websocket::closed");
750  my->_connected->set_value();
751  });
752 
753  auto con = my->_client.get_connection( uri, ec );
754  if( ec )
755  {
756  FC_ASSERT( !ec, "error: ${e}", ("e",ec.message()) );
757  }
758  my->_client.connect(con);
759  my->_connected->wait();
760  return my->_connection;
761  } FC_CAPTURE_AND_RETHROW( (uri) ) }
762 
763 } } // fc::http
base::con_msg_manager_type con_msg_manager_type
Definition: websocket.cpp:124
virtual void send_message(const std::string &message) override
Definition: websocket.cpp:207
websocketpp::server< asio_with_stub_log > websocket_server_type
Definition: websocket.cpp:192
auto async(Functor &&f, const char *desc FC_TASK_NAME_DEFAULT_ARG, priority prio=priority()) -> fc::future< decltype(f())>
Definition: thread.hpp:227
std::map< connection_hdl, websocket_connection_ptr, std::owner_less< connection_hdl > > con_map
Definition: websocket.cpp:335
base::concurrency_type concurrency_type
Definition: websocket.cpp:67
static ptr create(const char *desc FC_TASK_NAME_DEFAULT_ARG)
Definition: future.hpp:114
on_connection_handler _on_connection
Definition: websocket.cpp:340
base::response_type response_type
Definition: websocket.cpp:161
fc::optional< connection_hdl > _hdl
Definition: websocket.cpp:521
websocketpp::transport::asio::endpoint< transport_config > transport_type
Definition: websocket.cpp:150
const auto response
websocketpp::server< asio_tls_stub_log > websocket_tls_server_type
Definition: websocket.cpp:193
base::concurrency_type concurrency_type
Definition: websocket.cpp:158
websocketpp::transport::asio::tls_socket::endpoint socket_type
Definition: websocket.cpp:146
static const long timeout_open_handshake
Definition: websocket.cpp:102
T wait(boost::signals2::signal< void(T)> &sig, const microseconds &timeout_us=microseconds::maximum())
Definition: signals.hpp:38
void listen(uint16_t port)
Definition: websocket.cpp:649
base::concurrency_type concurrency_type
Definition: websocket.cpp:118
websocket_tls_client_type::connection_ptr websocket_tls_client_connection_type
Definition: websocket.cpp:465
websocketpp::lib::shared_ptr< boost::asio::ssl::context > context_ptr
Definition: websocket.cpp:227
websocket_client_type::connection_ptr websocket_client_connection_type
Definition: websocket.cpp:464
websocketpp::extensions::permessage_deflate::disabled< permessage_deflate_config > permessage_deflate_type
Definition: websocket.cpp:109
websocket_connection_ptr connect(const std::string &uri)
Definition: websocket.cpp:739
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
Definition: exception.hpp:56
std::string to_detail_string(log_level ll=log_level::all) const
Definition: exception.cpp:183
std::shared_ptr< connection > connection_ptr
Definition: connection.hpp:78
std::map< connection_hdl, websocket_connection_ptr, std::owner_less< connection_hdl > > con_map
Definition: websocket.cpp:440
void on_connection(const on_connection_handler &handler)
Definition: websocket.cpp:644
cout_t & cout
Definition: iostream.cpp:175
#define wlog(FORMAT,...)
Definition: logger.hpp:123
websocket_tls_server(const std::string &server_pem=std::string(), const std::string &ssl_password=std::string())
Definition: websocket.cpp:641
void on_connection(const on_connection_handler &handler)
Definition: websocket.cpp:604
std::shared_ptr< websocket_connection > websocket_connection_ptr
Definition: websocket.hpp:41
void setup_peer_verify(context_ptr &ctx, const std::string &ca_filename)
Definition: websocket.cpp:577
fc::promise< void >::ptr _closed
Definition: websocket.cpp:341
const address & get_address() const
Definition: ip.cpp:72
websocketpp::log::stub elog_type
Custom Logging policies.
Definition: websocket.cpp:84
std::shared_ptr< exception > exception_ptr
Definition: exception.hpp:131
websocket_connection_ptr secure_connect(const std::string &uri)
Definition: websocket.cpp:700
websocket_tls_client(const std::string &ca_filename="_default")
Definition: websocket.cpp:663
#define wdump(SEQ)
Definition: logger.hpp:174
base::endpoint_msg_manager_type endpoint_msg_manager_type
Definition: websocket.cpp:74
const T & wait(const microseconds &timeout=microseconds::maximum())
Definition: future.hpp:127
#define edump(SEQ)
Definition: logger.hpp:182
uint16_t port() const
Definition: ip.cpp:71
websocketpp::transport::asio::endpoint< transport_config > transport_type
Definition: websocket.cpp:184
websocket_tls_server_impl(const string &server_pem, const string &ssl_password)
Definition: websocket.cpp:348
std::function< void(const websocket_connection_ptr &)> on_connection_handler
Definition: websocket.hpp:43
websocketpp::log::stub alog_type
Definition: websocket.cpp:85
virtual std::string get_request_header(const std::string &key) override
Definition: websocket.cpp:219
#define idump(SEQ)
Definition: logger.hpp:166
websocket_connection_ptr connect(const std::string &uri)
Definition: websocket.cpp:671
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:478
websocketpp::transport::asio::tls_socket::endpoint socket_type
Definition: websocket.cpp:180
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
boost::asio::ip::tcp::endpoint endpoint
Definition: asio.hpp:240
websocketpp::log::stub alog_type
Definition: websocket.cpp:170
base::endpoint_msg_manager_type endpoint_msg_manager_type
Definition: websocket.cpp:165
base::endpoint_msg_manager_type endpoint_msg_manager_type
Definition: websocket.cpp:125
websocketpp::transport::asio::basic_socket::endpoint socket_type
Definition: websocket.cpp:96
boost::asio::io_service & default_io_service()
Definition: asio.cpp:182
Definition: api.hpp:15
websocketpp::client< asio_tls_stub_log > websocket_tls_client_type
Definition: websocket.cpp:462
base::con_msg_manager_type con_msg_manager_type
Definition: websocket.cpp:164
std::string body_as_string
Definition: connection.hpp:39
void listen(uint16_t port)
Definition: websocket.cpp:609
websocket_tls_client_impl(const std::string &ca_filename)
Definition: websocket.cpp:530
base::con_msg_manager_type con_msg_manager_type
Definition: websocket.cpp:73
websocketpp::log::stub elog_type
Custom Logging policies.
Definition: websocket.cpp:135
virtual void close(int64_t code, const std::string &reason) override
Definition: websocket.cpp:214
websocketpp::transport::asio::endpoint< transport_config > transport_type
Definition: websocket.cpp:100
#define FC_EXCEPTION(EXCEPTION_TYPE, FORMAT,...)
Definition: exception.hpp:371
websocket_client(const std::string &ca_filename="_default")
Definition: websocket.cpp:668
websocketpp::log::stub elog_type
Definition: websocket.cpp:169
base::response_type response_type
Definition: websocket.cpp:70
websocketpp::client< asio_with_stub_log > websocket_client_type
Definition: websocket.cpp:461