BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet 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 
76  typedef websocketpp::log::stub elog_type;
77  typedef websocketpp::log::stub alog_type;
78 
79  typedef base::rng_type rng_type;
80 
81  struct transport_config : public base::transport_config {
88  };
89 
90  typedef websocketpp::transport::asio::endpoint<transport_config> transport_type;
91 
92  // permessage_compress extension
94 #ifdef HAS_ZLIB
95  typedef websocketpp::extensions::permessage_deflate::enabled <permessage_deflate_config>
97 #else
98  typedef websocketpp::extensions::permessage_deflate::disabled <permessage_deflate_config>
100 #endif
101  };
102  struct asio_tls_with_stub_log : public websocketpp::config::asio_tls {
103 
105  typedef asio_tls base;
106 
107  typedef base::concurrency_type concurrency_type;
108 
109  typedef base::request_type request_type;
110  typedef base::response_type response_type;
111 
112  typedef base::message_type message_type;
113  typedef base::con_msg_manager_type con_msg_manager_type;
114  typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
115 
116  typedef websocketpp::log::stub elog_type;
117  typedef websocketpp::log::stub alog_type;
118 
119  typedef base::rng_type rng_type;
120 
121  struct transport_config : public base::transport_config {
128  };
129 
130  typedef websocketpp::transport::asio::endpoint<transport_config> transport_type;
131 
132  // permessage_compress extension
134 #ifdef HAS_ZLIB
135  typedef websocketpp::extensions::permessage_deflate::enabled <permessage_deflate_config>
137 #else
138  typedef websocketpp::extensions::permessage_deflate::disabled <permessage_deflate_config>
140 #endif
141  };
142  struct asio_tls_stub_log : public websocketpp::config::asio_tls {
144  typedef asio_tls base;
145 
146  typedef base::concurrency_type concurrency_type;
147 
148  typedef base::request_type request_type;
149  typedef base::response_type response_type;
150 
151  typedef base::message_type message_type;
152  typedef base::con_msg_manager_type con_msg_manager_type;
153  typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
154 
155  typedef websocketpp::log::stub elog_type;
156  typedef websocketpp::log::stub alog_type;
157 
158  typedef base::rng_type rng_type;
159 
160  struct transport_config : public base::transport_config {
167  };
168 
169  typedef websocketpp::transport::asio::endpoint<transport_config> transport_type;
170 
171  // permessage_compress extension
173 #ifdef HAS_ZLIB
174  typedef websocketpp::extensions::permessage_deflate::enabled <permessage_deflate_config>
176 #else
177  typedef websocketpp::extensions::permessage_deflate::disabled <permessage_deflate_config>
179 #endif
180  };
181 
182  template<typename T>
184  {
185  public:
187  {
188  _remote_endpoint = con->get_remote_endpoint();
189  }
190 
192  {
193  }
194 
195  virtual void send_message( const std::string& message )override
196  {
197  ilog( "[OUT] ${remote_endpoint} ${msg}",
198  ("remote_endpoint",_remote_endpoint) ("msg",message) );
199  auto ec = _ws_connection->send( message );
200  FC_ASSERT( !ec, "websocket send failed: ${msg}", ("msg",ec.message() ) );
201  }
202  virtual void close( int64_t code, const std::string& reason )override
203  {
204  _ws_connection->close(code,reason);
205  }
206 
207  virtual std::string get_request_header(const std::string& key)override
208  {
209  return _ws_connection->get_request_header(key);
210  }
211 
213  };
214 
215  template<typename T>
217  {
218  public:
219  possibly_proxied_websocket_connection( T con, const std::string& forward_header_key )
220  : websocket_connection_impl<T>(con)
221  {
222  // By calling the parent's constructor, _remote_endpoint has been initialized.
223  // Now try to extract remote address from the header, if found, overwrite it
224  if( !forward_header_key.empty() )
225  {
226  const std::string value = this->get_request_header( forward_header_key );
227  if( !value.empty() )
228  this->_remote_endpoint = value;
229  }
230  }
231 
233  {
234  }
235  };
236 
237  typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
238 
239  using websocketpp::connection_hdl;
240 
241  template<typename T>
243  {
244  public:
245  generic_websocket_server_impl( const std::string& forward_header_key )
246  :_server_thread( fc::thread::current() ), _forward_header_key( forward_header_key )
247  {
248  _server.clear_access_channels( websocketpp::log::alevel::all );
249  _server.init_asio( &fc::asio::default_io_service() );
250  _server.set_reuse_addr( true );
251  _server.set_open_handler( [this]( connection_hdl hdl ){
252  _server_thread.async( [this, hdl](){
253  auto new_con = std::make_shared<possibly_proxied_websocket_connection<
254  typename websocketpp::server<T>::connection_ptr>>( _server.get_con_from_hdl(hdl),
256  _on_connection( _connections[hdl] = new_con );
257  }).wait();
258  });
259  _server.set_message_handler( [this]( connection_hdl hdl,
260  typename websocketpp::server<T>::message_ptr msg ){
261  _server_thread.async( [this,hdl,msg](){
262  auto current_con = _connections.find(hdl);
263  if( current_con == _connections.end() )
264  return;
265  auto payload = msg->get_payload();
266  std::shared_ptr<websocket_connection> con = current_con->second;
267  wlog( "[IN] ${remote_endpoint} ${msg}",
268  ("remote_endpoint",con->get_remote_endpoint_string()) ("msg",payload) );
270  auto f = fc::async([this,con,payload](){
271  if( _pending_messages )
273  con->on_message( payload );
274  });
275  if( _pending_messages > 100 )
276  f.wait(); // Note: this is a bit strange, because it forces the server to process all
277  // 100 pending messages (assuming this message is the last one) before
278  // trying to accept a new message.
279  // Ideally the `wait` should be canceled immediately when the number of
280  // pending messages falls below 100. That said, wait on the whole queue,
281  // but not wait on one message.
282  }).wait();
283  });
284 
285  _server.set_socket_init_handler( []( websocketpp::connection_hdl hdl,
286  typename websocketpp::server<T>::connection_type::socket_type& s ) {
287  boost::asio::ip::tcp::no_delay option(true);
288  s.lowest_layer().set_option(option);
289  } );
290 
291  _server.set_http_handler( [this]( connection_hdl hdl ){
292  _server_thread.async( [this,hdl](){
293  auto con = _server.get_con_from_hdl(hdl);
294  auto current_con = std::make_shared<possibly_proxied_websocket_connection<
296  _on_connection( current_con );
297 
298  con->defer_http_response(); // Note: this can tie up resources if send_http_response() is not
299  // called quickly enough
300  std::string remote_endpoint = current_con->get_remote_endpoint_string();
301  std::string request_body = con->get_request_body();
302  wlog( "[HTTP-IN] ${remote_endpoint} ${msg}",
303  ("remote_endpoint",remote_endpoint) ("msg",request_body) );
304 
305  fc::async([current_con, request_body, con, remote_endpoint] {
306  fc::http::reply response = current_con->on_http(request_body);
307  ilog( "[HTTP-OUT] ${remote_endpoint} ${status} ${msg}",
308  ("remote_endpoint",remote_endpoint)
309  ("status",response.status)
310  ("msg",response.body_as_string) );
311  con->set_body( std::move( response.body_as_string ) );
312  con->set_status( websocketpp::http::status_code::value(response.status) );
313  con->send_http_response();
314  current_con->closed();
315  }, "call on_http");
316  }).wait();
317  });
318 
319  _server.set_close_handler( [this]( connection_hdl hdl ){
320  _server_thread.async( [this,hdl](){
321  if( _connections.find(hdl) != _connections.end() )
322  {
323  _connections[hdl]->closed();
324  _connections.erase( hdl );
325  if( _connections.empty() && _all_connections_closed )
327  }
328  else
329  {
330  wlog( "unknown connection closed" );
331  }
332  }).wait();
333  });
334 
335  _server.set_fail_handler( [this]( connection_hdl hdl ){
336  _server_thread.async( [this,hdl](){
337  if( _connections.find(hdl) != _connections.end() )
338  {
339  _connections[hdl]->closed();
340  _connections.erase( hdl );
341  if( _connections.empty() && _all_connections_closed )
343  }
344  else
345  {
346  // if the server is shutting down, assume this hdl is the server socket
349  else
350  wlog( "unknown connection failed" );
351  }
352  }).wait();
353  });
354  }
355 
357  {
358  if( _server.is_listening() )
359  {
360  // _server.stop_listening() may trigger the on_fail callback function (the lambda function set by
361  // _server.set_fail_handler(...) ) for the listening server socket (note: the connection handle
362  // associated with the server socket is not in our connection map),
363  // the on_fail callback function may fire (async) a new task which may run really late
364  // and it will try to access the member variables of this server object,
365  // so we need to wait for it before destructing this object.
367  _server.stop_listening();
368  }
369 
370  // Note: since _connections can be modified by lambda functions in set_*_handler, which are running
371  // in other tasks, perhaps we need to wait for them (especially the one in set_open_handler)
372  // being processed. Otherwise `_all_connections_closed.wait()` may hang.
373  if( !_connections.empty() )
374  {
376 
377  auto cpy_con = _connections;
378  websocketpp::lib::error_code ec;
379  for( auto& item : cpy_con )
380  _server.close( item.first, 0, "server exit", ec );
381 
383  }
384 
387  }
388 
389  typedef std::map<connection_hdl, websocket_connection_ptr, std::owner_less<connection_hdl> > con_map;
390 
391  // Note: std::map is not thread-safe nor task-safe, we may need
392  // to use a mutex or similar to avoid concurrent access.
395  websocketpp::server<T> _server;
399  uint32_t _pending_messages = 0;
400  std::string _forward_header_key;
401  };
402 
403  class websocket_server_impl : public generic_websocket_server_impl<asio_with_stub_log>
404  {
405  public:
406  websocket_server_impl( const std::string& forward_header_key )
407  : generic_websocket_server_impl( forward_header_key )
408  {}
409 
411  };
412 
414  {
415  public:
416  websocket_tls_server_impl( const string& server_pem, const string& ssl_password,
417  const std::string& forward_header_key )
418  : generic_websocket_server_impl( forward_header_key )
419  {
420  _server.set_tls_init_handler( [server_pem,ssl_password]( websocketpp::connection_hdl hdl ) {
421  context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(
422  boost::asio::ssl::context::tlsv12 );
423  try {
424  ctx->set_options( boost::asio::ssl::context::default_workarounds |
425  boost::asio::ssl::context::no_sslv2 |
426  boost::asio::ssl::context::no_sslv3 |
427  boost::asio::ssl::context::no_tlsv1 |
428  boost::asio::ssl::context::no_tlsv1_1 |
429  boost::asio::ssl::context::single_dh_use );
430  ctx->set_password_callback(
431  [ssl_password](std::size_t max_length, boost::asio::ssl::context::password_purpose){
432  return ssl_password;
433  });
434  ctx->use_certificate_chain_file(server_pem);
435  ctx->use_private_key_file(server_pem, boost::asio::ssl::context::pem);
436  } catch (std::exception& e) {
437  std::cout << e.what() << std::endl;
438  }
439  return ctx;
440  });
441  }
442 
444 
445  };
446 
447 
448  template<typename T>
450  {
451  public:
453  :_client_thread( fc::thread::current() )
454  {
455  _client.clear_access_channels( websocketpp::log::alevel::all );
456  _client.set_message_handler( [this]( connection_hdl hdl,
457  typename websocketpp::client<T>::message_ptr msg ){
458  _client_thread.async( [this,msg](){
459  wdump((msg->get_payload()));
460  auto received = msg->get_payload();
461  fc::async( [this,received](){
462  if( _connection )
463  _connection->on_message(received);
464  });
465  }).wait();
466  });
467  _client.set_close_handler( [this]( connection_hdl hdl ){
468  _client_thread.async( [this](){
469  if( _connection ) {
470  _connection->closed();
471  _connection.reset();
472  }
473  } ).wait();
474  if( _closed )
475  _closed->set_value();
476  });
477  _client.set_fail_handler( [this]( connection_hdl hdl ){
478  auto con = _client.get_con_from_hdl(hdl);
479  auto message = con->get_ec().message();
480  if( _connection )
481  {
482  _client_thread.async( [this](){
483  if( _connection ) {
484  _connection->closed();
485  _connection.reset();
486  }
487  } ).wait();
488  }
489  if( _connected && !_connected->ready() )
490  {
492  new FC_EXCEPTION( exception, "${message}", ("message",message)) ) );
493  }
494  if( _closed )
495  _closed->set_value();
496  });
497 
498  _client.init_asio( &fc::asio::default_io_service() );
499  }
500 
502  {
503  if( _connection )
504  {
505  _connection->close(0, "client closed");
506  _connection.reset();
507  }
508  if( _closed )
509  _closed->wait();
510  }
511 
512  websocket_connection_ptr connect( const std::string& uri, const fc::http::headers& headers )
513  {
514  websocketpp::lib::error_code ec;
515 
516  _uri = uri;
517  _connected = promise<void>::create("websocket::connect");
518 
519  _client.set_open_handler( [this]( websocketpp::connection_hdl hdl ){
520  _hdl = hdl;
521  auto con = _client.get_con_from_hdl(hdl);
522  _connection = std::make_shared<websocket_connection_impl<
523  typename websocketpp::client<T>::connection_ptr>>( con );
524  _closed = promise<void>::create("websocket::closed");
526  });
527 
528  auto con = _client.get_connection( uri, ec );
529 
530  for( const fc::http::header& h : headers )
531  {
532  con->append_header( h.key, h.val );
533  }
534 
535  FC_ASSERT( !ec, "error: ${e}", ("e",ec.message()) );
536 
537  _client.connect(con);
538  _connected->wait();
539  return _connection;
540  }
541 
545  websocketpp::client<T> _client;
547  std::string _uri;
549  };
550 
551  class websocket_client_impl : public generic_websocket_client_impl<asio_with_stub_log>
552  {};
553 
555  {
556  public:
557  websocket_tls_client_impl( const std::string& ca_filename )
559  {
560  // ca_filename has special values:
561  // "_none" disables cert checking (potentially insecure!)
562  // "_default" uses default CA's provided by OS
563 
564  //
565  // We need ca_filename to be copied into the closure, as the
566  // referenced object might be destroyed by the caller by the time
567  // tls_init_handler() is called. According to [1], capture-by-value
568  // results in the desired behavior (i.e. creation of
569  // a copy which is stored in the closure) on standards compliant compilers,
570  // but some compilers on some optimization levels
571  // are buggy and are not standards compliant in this situation.
572  // Also, keep in mind this is the opinion of a single forum
573  // poster and might be wrong.
574  //
575  // To be safe, the following line explicitly creates a non-reference string
576  // which is captured by value, which should have the
577  // correct behavior on all compilers.
578  //
579  // [1] http://www.cplusplus.com/forum/general/142165/
580  // [2] http://stackoverflow.com/questions/21443023/capturing-a-reference-by-reference-in-a-c11-lambda
581  //
582 
583  std::string ca_filename_copy = ca_filename;
584 
585  _client.set_tls_init_handler( [this,ca_filename_copy](websocketpp::connection_hdl) {
586  context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(
587  boost::asio::ssl::context::tlsv12);
588  try {
589  ctx->set_options( boost::asio::ssl::context::default_workarounds |
590  boost::asio::ssl::context::no_sslv2 |
591  boost::asio::ssl::context::no_sslv3 |
592  boost::asio::ssl::context::no_tlsv1 |
593  boost::asio::ssl::context::no_tlsv1_1 |
594  boost::asio::ssl::context::single_dh_use );
595 
596  setup_peer_verify( ctx, ca_filename_copy );
597  } catch (std::exception& e) {
598  edump((e.what()));
599  std::cout << e.what() << std::endl;
600  }
601  return ctx;
602  });
603 
604  }
606 
607  std::string get_host()const
608  {
609  return websocketpp::uri( _uri ).get_host();
610  }
611 
612  void setup_peer_verify( context_ptr& ctx, const std::string& ca_filename )
613  {
614  if( ca_filename == "_none" )
615  return;
616  ctx->set_verify_mode( boost::asio::ssl::verify_peer );
617  if( ca_filename == "_default" )
618  {
619 #if WIN32
620  add_windows_root_certs( *ctx );
621 #else
622  ctx->set_default_verify_paths();
623 #endif
624  }
625  else
626  ctx->load_verify_file( ca_filename );
627  ctx->set_verify_depth(10);
628  ctx->set_verify_callback( boost::asio::ssl::rfc2818_verification( get_host() ) );
629  }
630 
631  };
632 
633 
634  } // namespace detail
635 
636  websocket_server::websocket_server( const std::string& forward_header_key )
637  :my( new detail::websocket_server_impl( forward_header_key ) ) {}
639 
641  {
642  my->_on_connection = handler;
643  }
644 
645  void websocket_server::listen( uint16_t port )
646  {
647  my->_server.listen(port);
648  }
650  {
651  my->_server.listen( boost::asio::ip::tcp::endpoint(
652  boost::asio::ip::address_v4(uint32_t(ep.get_address())),ep.port()) );
653  }
654 
656  {
657  websocketpp::lib::asio::error_code ec;
658  return my->_server.get_local_endpoint(ec).port();
659  }
660 
662  my->_server.start_accept();
663  }
664 
666  {
667  my->_server.stop_listening();
668  }
669 
671  {
672  auto cpy_con = my->_connections;
673  websocketpp::lib::error_code ec;
674  for( auto& connection : cpy_con )
675  my->_server.close( connection.first, websocketpp::close::status::normal, "Goodbye", ec );
676  }
677 
678  websocket_tls_server::websocket_tls_server( const string& server_pem, const string& ssl_password,
679  const std::string& forward_header_key )
680  :my( new detail::websocket_tls_server_impl(server_pem, ssl_password, forward_header_key) )
681  {}
682 
684 
686  {
687  my->_on_connection = handler;
688  }
689 
690  void websocket_tls_server::listen( uint16_t port )
691  {
692  my->_server.listen(port);
693  }
695  {
696  my->_server.listen( boost::asio::ip::tcp::endpoint(
697  boost::asio::ip::address_v4(uint32_t(ep.get_address())),ep.port()) );
698  }
699 
701  {
702  websocketpp::lib::asio::error_code ec;
703  return my->_server.get_local_endpoint(ec).port();
704  }
705 
707  my->_server.start_accept();
708  }
709 
711  {
712  my->_server.stop_listening();
713  }
714 
716  {
717  auto cpy_con = my->_connections;
718  websocketpp::lib::error_code ec;
719  for( auto& connection : cpy_con )
720  my->_server.close( connection.first, websocketpp::close::status::normal, "Goodbye", ec );
721  }
722 
723 
724  websocket_client::websocket_client( const std::string& ca_filename )
725  :my( new detail::websocket_client_impl() ),
726  smy(new detail::websocket_tls_client_impl( ca_filename ))
727  {}
728 
730 
732  { try {
733 
734  FC_ASSERT( uri.substr(0,4) == "wss:" || uri.substr(0,3) == "ws:", "Unsupported protocol" );
735 
736  // WSS
737  if( uri.substr(0,4) == "wss:" )
738  return smy->connect( uri, _headers );
739 
740  // WS
741  return my->connect( uri, _headers );
742 
743  } FC_CAPTURE_AND_RETHROW( (uri) ) }
744 
746  {
747  return connect( uri );
748  }
749 
751  {
752  if( my->_hdl )
753  my->_client.close( *my->_hdl, websocketpp::close::status::normal, "Goodbye" );
754  }
755 
757  {
758  close();
759  if( my->_closed )
760  my->_closed->wait();
761  }
762 
763  void websocket_client::append_header(const std::string& key, const std::string& value)
764  {
765  _headers.emplace_back( key, value );
766  }
767 
768 } } // fc::http
fc::http::detail::asio_tls_stub_log::transport_config::concurrency_type
type::concurrency_type concurrency_type
Definition: websocket.cpp:161
fc::http::detail::asio_with_stub_log::response_type
base::response_type response_type
Definition: websocket.cpp:70
fc::promise
Definition: future.hpp:109
fc::http::detail::asio_tls_stub_log::transport_type
websocketpp::transport::asio::endpoint< transport_config > transport_type
Definition: websocket.cpp:169
fc::http::detail::generic_websocket_server_impl::_all_connections_closed
fc::promise< void >::ptr _all_connections_closed
Promise to wait for all connections to be closed.
Definition: websocket.cpp:397
fc::http::detail::asio_tls_with_stub_log::response_type
base::response_type response_type
Definition: websocket.cpp:110
fc::http::detail::asio_tls_with_stub_log::transport_config::concurrency_type
type::concurrency_type concurrency_type
Definition: websocket.cpp:122
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
fc::promise_base::ready
bool ready() const
Definition: future.cpp:37
fc::http::detail::websocket_client_impl
Definition: websocket.cpp:551
fc::http::detail::asio_with_stub_log
Definition: websocket.cpp:62
fc::http::websocket_server::get_listening_port
uint16_t get_listening_port()
Definition: websocket.cpp:655
fc::http::detail::asio_tls_stub_log::elog_type
websocketpp::log::stub elog_type
Definition: websocket.cpp:155
fc::http::detail::asio_tls_with_stub_log::transport_config::request_type
type::request_type request_type
Definition: websocket.cpp:125
fc::http::detail::asio_tls_stub_log::concurrency_type
base::concurrency_type concurrency_type
Definition: websocket.cpp:146
fc::http::detail::asio_tls_with_stub_log
Definition: websocket.cpp:102
FC_EXCEPTION
#define FC_EXCEPTION(EXCEPTION_TYPE, FORMAT,...)
Definition: exception.hpp:371
fc::http::detail::websocket_tls_server_impl::websocket_tls_server_impl
websocket_tls_server_impl(const string &server_pem, const string &ssl_password, const std::string &forward_header_key)
Definition: websocket.cpp:416
wlog
#define wlog(FORMAT,...)
Definition: logger.hpp:123
fc::http::websocket_server::~websocket_server
~websocket_server()
Definition: websocket.cpp:638
fc::http::reply::body_as_string
std::string body_as_string
Definition: connection.hpp:39
fc::exception
Used to generate a useful error report when an exception is thrown.
Definition: exception.hpp:56
variant.hpp
fc::http::detail::asio_tls_stub_log::request_type
base::request_type request_type
Definition: websocket.cpp:148
fc::http::detail::asio_tls_stub_log::alog_type
websocketpp::log::stub alog_type
Definition: websocket.cpp:156
fc::http::detail::asio_tls_stub_log::transport_config::request_type
type::request_type request_type
Definition: websocket.cpp:164
fc::http::websocket_tls_server::on_connection
void on_connection(const on_connection_handler &handler)
Definition: websocket.cpp:685
fc::http::detail::asio_with_stub_log::base
asio base
Definition: websocket.cpp:65
fc::promise< void >::set_value
void set_value()
Definition: future.hpp:181
websocket_api.hpp
fc::http::detail::asio_tls_with_stub_log::type
asio_with_stub_log type
Definition: websocket.cpp:104
fc::http::detail::asio_with_stub_log::transport_config::request_type
type::request_type request_type
Definition: websocket.cpp:85
fc::http::detail::websocket_connection_impl::~websocket_connection_impl
virtual ~websocket_connection_impl()
Definition: websocket.cpp:191
fc::http::websocket_tls_server::close
void close()
Definition: websocket.cpp:715
fc::http::detail::asio_with_stub_log::alog_type
websocketpp::log::stub alog_type
Definition: websocket.cpp:77
fc::http::detail::asio_tls_with_stub_log::permessage_deflate_type
websocketpp::extensions::permessage_deflate::disabled< permessage_deflate_config > permessage_deflate_type
Definition: websocket.cpp:139
fc::http::websocket_connection
Definition: websocket.hpp:20
fc::http::detail::asio_tls_stub_log::transport_config::socket_type
websocketpp::transport::asio::tls_socket::endpoint socket_type
Definition: websocket.cpp:166
fc
Definition: api.hpp:15
fc::http::detail::generic_websocket_server_impl::con_map
std::map< connection_hdl, websocket_connection_ptr, std::owner_less< connection_hdl > > con_map
Definition: websocket.cpp:389
fc::http::detail::asio_with_stub_log::permessage_deflate_type
websocketpp::extensions::permessage_deflate::disabled< permessage_deflate_config > permessage_deflate_type
Definition: websocket.cpp:99
fc::http::detail::websocket_tls_client_impl::get_host
std::string get_host() const
Definition: websocket.cpp:607
fc::http::detail::generic_websocket_client_impl::generic_websocket_client_impl
generic_websocket_client_impl()
Definition: websocket.cpp:452
fc::http::detail::possibly_proxied_websocket_connection
Definition: websocket.cpp:216
fc::http::detail::generic_websocket_client_impl::connect
websocket_connection_ptr connect(const std::string &uri, const fc::http::headers &headers)
Definition: websocket.cpp:512
fc::http::detail::asio_tls_with_stub_log::request_type
base::request_type request_type
Definition: websocket.cpp:109
fc::http::websocket_tls_server::~websocket_tls_server
~websocket_tls_server()
Definition: websocket.cpp:683
fc::http::detail::possibly_proxied_websocket_connection::possibly_proxied_websocket_connection
possibly_proxied_websocket_connection(T con, const std::string &forward_header_key)
Definition: websocket.cpp:219
fc::http::detail::generic_websocket_server_impl::_server
websocketpp::server< T > _server
The server.
Definition: websocket.cpp:395
fc::http::detail::asio_tls_with_stub_log::rng_type
base::rng_type rng_type
Definition: websocket.cpp:119
fc::http::detail::generic_websocket_client_impl::_hdl
fc::optional< connection_hdl > _hdl
Definition: websocket.cpp:548
fc::http::websocket_client::~websocket_client
~websocket_client()
Definition: websocket.cpp:729
fc::http::websocket_connection_ptr
std::shared_ptr< websocket_connection > websocket_connection_ptr
Definition: websocket.hpp:47
fc::http::detail::generic_websocket_client_impl::_connected
fc::promise< void >::ptr _connected
Definition: websocket.cpp:542
fc::http::detail::generic_websocket_client_impl::_uri
std::string _uri
Definition: websocket.cpp:547
fc::http::detail::asio_tls_with_stub_log::base
asio_tls base
Definition: websocket.cpp:105
fc::http::detail::asio_with_stub_log::transport_config::socket_type
websocketpp::transport::asio::basic_socket::endpoint socket_type
Definition: websocket.cpp:87
fc::http::detail::websocket_tls_server_impl
Definition: websocket.cpp:413
fc::http::websocket_client::websocket_client
websocket_client(const std::string &ca_filename="_default")
Definition: websocket.cpp:724
fc::http::detail::asio_with_stub_log::transport_type
websocketpp::transport::asio::endpoint< transport_config > transport_type
Definition: websocket.cpp:90
fc::http::detail::asio_with_stub_log::transport_config
Definition: websocket.cpp:81
fc::http::detail::asio_with_stub_log::message_type
base::message_type message_type
Definition: websocket.cpp:72
fc::promise::create
static ptr create(const char *desc FC_TASK_NAME_DEFAULT_ARG)
Definition: future.hpp:114
fc::http::detail::asio_tls_with_stub_log::transport_config::alog_type
type::alog_type alog_type
Definition: websocket.cpp:123
fc::exception_ptr
std::shared_ptr< exception > exception_ptr
Definition: exception.hpp:131
fc::http::detail::generic_websocket_server_impl::_forward_header_key
std::string _forward_header_key
A header like "X-Forwarded-For" (XFF) with data IP:port.
Definition: websocket.cpp:400
fc::http::detail::asio_tls_stub_log::rng_type
base::rng_type rng_type
Definition: websocket.cpp:158
fc::http::detail::asio_tls_with_stub_log::transport_config::response_type
type::response_type response_type
Definition: websocket.cpp:126
fc::http::detail::asio_tls_with_stub_log::alog_type
websocketpp::log::stub alog_type
Definition: websocket.cpp:117
fc::http::headers
std::vector< header > headers
Definition: connection.hpp:21
fc::http::detail::generic_websocket_client_impl::_closed
fc::promise< void >::ptr _closed
Definition: websocket.cpp:543
fc::http::detail::asio_tls_stub_log::response_type
base::response_type response_type
Definition: websocket.cpp:149
fc::asio::tcp::endpoint
boost::asio::ip::tcp::endpoint endpoint
Definition: asio.hpp:239
fc::ip::endpoint
Definition: ip.hpp:65
fc::cout
cout_t & cout
Definition: iostream.cpp:175
fc::http::detail::websocket_connection_impl::websocket_connection_impl
websocket_connection_impl(T con)
Definition: websocket.cpp:186
fc::http::detail::asio_tls_with_stub_log::endpoint_msg_manager_type
base::endpoint_msg_manager_type endpoint_msg_manager_type
Definition: websocket.cpp:114
fc::http::detail::asio_tls_with_stub_log::message_type
base::message_type message_type
Definition: websocket.cpp:112
fc::wait
T wait(boost::signals2::signal< void(T)> &sig, const microseconds &timeout_us=microseconds::maximum())
Definition: signals.hpp:38
fc::http::detail::asio_tls_with_stub_log::concurrency_type
base::concurrency_type concurrency_type
Definition: websocket.cpp:107
fc::ip::endpoint::get_address
const address & get_address() const
Definition: ip.cpp:79
fc::http::detail::asio_with_stub_log::rng_type
base::rng_type rng_type
Definition: websocket.cpp:79
fc::http::detail::generic_websocket_server_impl::_server_thread
fc::thread & _server_thread
The thread that runs the server.
Definition: websocket.cpp:394
fc::http::detail::asio_with_stub_log::permessage_deflate_config
Definition: websocket.cpp:93
fc::http::detail::websocket_connection_impl::_ws_connection
T _ws_connection
Definition: websocket.cpp:212
fc::http::detail::asio_tls_stub_log::base
asio_tls base
Definition: websocket.cpp:144
asio.hpp
fc::http::websocket_server::start_accept
void start_accept()
Definition: websocket.cpp:661
wdump
#define wdump(SEQ)
Definition: logger.hpp:174
fc::http::detail::asio_with_stub_log::transport_config::response_type
type::response_type response_type
Definition: websocket.cpp:86
ilog
#define ilog(FORMAT,...)
Definition: logger.hpp:117
fc::promise< void >::wait
void wait(const microseconds &timeout=microseconds::maximum())
Definition: future.hpp:174
fc::http::connection_ptr
std::shared_ptr< connection > connection_ptr
Definition: connection.hpp:78
edump
#define edump(SEQ)
Definition: logger.hpp:182
fc::http::detail::asio_with_stub_log::endpoint_msg_manager_type
base::endpoint_msg_manager_type endpoint_msg_manager_type
Definition: websocket.cpp:74
fc::http::websocket_tls_server::stop_listening
void stop_listening()
Definition: websocket.cpp:710
fc::thread
Definition: thread.hpp:39
fc::http::websocket_tls_server::get_listening_port
uint16_t get_listening_port()
Definition: websocket.cpp:700
fc::http::detail::websocket_tls_client_impl::websocket_tls_client_impl
websocket_tls_client_impl(const std::string &ca_filename)
Definition: websocket.cpp:557
fc::http::detail::asio_tls_stub_log::transport_config::alog_type
type::alog_type alog_type
Definition: websocket.cpp:162
fc::http::detail::asio_with_stub_log::transport_config::alog_type
type::alog_type alog_type
Definition: websocket.cpp:83
thread.hpp
fc::http::detail::asio_tls_stub_log::transport_config::elog_type
type::elog_type elog_type
Definition: websocket.cpp:163
fc::http::detail::websocket_tls_client_impl::~websocket_tls_client_impl
virtual ~websocket_tls_client_impl()
Definition: websocket.cpp:605
fc::http::detail::asio_tls_stub_log::con_msg_manager_type
base::con_msg_manager_type con_msg_manager_type
Definition: websocket.cpp:152
fc::http::websocket_client::append_header
void append_header(const std::string &key, const std::string &value)
Definition: websocket.cpp:763
fc::async
auto async(Functor &&f, const char *desc FC_TASK_NAME_DEFAULT_ARG, priority prio=priority()) -> fc::future< decltype(f())>
Definition: thread.hpp:227
fc::http::detail::generic_websocket_server_impl::_connections
con_map _connections
Holds accepted connections.
Definition: websocket.cpp:393
fc::http::detail::asio_tls_with_stub_log::permessage_deflate_config
Definition: websocket.cpp:133
fc::http::detail::generic_websocket_client_impl::_client
websocketpp::client< T > _client
Definition: websocket.cpp:545
fc::http::detail::asio_with_stub_log::elog_type
websocketpp::log::stub elog_type
Definition: websocket.cpp:76
fc::http::websocket_tls_server::start_accept
void start_accept()
Definition: websocket.cpp:706
fc::http::websocket_server::stop_listening
void stop_listening()
Definition: websocket.cpp:665
fc::http::websocket_connection::_remote_endpoint
std::string _remote_endpoint
Definition: websocket.hpp:41
fc::http::detail::generic_websocket_server_impl
Definition: websocket.cpp:242
fc::http::detail::asio_tls_stub_log
Definition: websocket.cpp:142
fc::http::websocket_server::websocket_server
websocket_server(const std::string &forward_header_key)
Definition: websocket.cpp:636
fc::http::detail::asio_with_stub_log::type
asio_with_stub_log type
Definition: websocket.cpp:64
fc::http::websocket_client::connect
websocket_connection_ptr connect(const std::string &uri)
Definition: websocket.cpp:731
fc::http::detail::asio_tls_with_stub_log::elog_type
websocketpp::log::stub elog_type
Definition: websocket.cpp:116
fc::http::reply::status
int status
Definition: connection.hpp:36
fc::http::detail::websocket_tls_server_impl::~websocket_tls_server_impl
virtual ~websocket_tls_server_impl()
Definition: websocket.cpp:443
fc::http::websocket_tls_server::websocket_tls_server
websocket_tls_server(const std::string &server_pem, const std::string &ssl_password, const std::string &forward_header_key)
Definition: websocket.cpp:678
fc::http::detail::websocket_connection_impl::send_message
virtual void send_message(const std::string &message) override
Definition: websocket.cpp:195
json.hpp
websocket.hpp
fc::http::connection
Definition: connection.hpp:59
fc::http::websocket_client::close
void close()
Definition: websocket.cpp:750
fc::http::detail::websocket_connection_impl::get_request_header
virtual std::string get_request_header(const std::string &key) override
Definition: websocket.cpp:207
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
fc::http::detail::asio_tls_stub_log::permessage_deflate_type
websocketpp::extensions::permessage_deflate::disabled< permessage_deflate_config > permessage_deflate_type
Definition: websocket.cpp:178
fc::http::detail::generic_websocket_server_impl::_on_connection
on_connection_handler _on_connection
A handler to be called when a new connection is accepted.
Definition: websocket.cpp:396
fc::http::detail::asio_with_stub_log::request_type
base::request_type request_type
Definition: websocket.cpp:69
fc::http::detail::asio_with_stub_log::transport_config::elog_type
type::elog_type elog_type
Definition: websocket.cpp:84
fc::http::detail::asio_tls_with_stub_log::transport_config
Definition: websocket.cpp:121
fc::http::websocket_server::close
void close()
Definition: websocket.cpp:670
fc::promise_base::set_exception
void set_exception(const fc::exception_ptr &e)
Definition: future.cpp:44
fc::http::detail::websocket_server_impl::~websocket_server_impl
virtual ~websocket_server_impl()
Definition: websocket.cpp:410
fc::http::detail::asio_tls_stub_log::transport_config
Definition: websocket.cpp:160
fc::http::header
Definition: connection.hpp:12
fc::asio::default_io_service
boost::asio::io_service & default_io_service()
Definition: asio.cpp:219
fc::http::detail::asio_tls_stub_log::permessage_deflate_config
Definition: websocket.cpp:172
fc::http::websocket_server::listen
void listen(uint16_t port)
Definition: websocket.cpp:645
fc::http::reply
Definition: connection.hpp:23
fc::http::detail::asio_with_stub_log::concurrency_type
base::concurrency_type concurrency_type
Definition: websocket.cpp:67
fc::http::detail::asio_tls_stub_log::type
asio_tls_stub_log type
Definition: websocket.cpp:143
fc::http::detail::asio_with_stub_log::con_msg_manager_type
base::con_msg_manager_type con_msg_manager_type
Definition: websocket.cpp:73
fc::http::detail::generic_websocket_server_impl::_pending_messages
uint32_t _pending_messages
Number of messages not processed, for rate limiting.
Definition: websocket.cpp:399
variant.hpp
fc::thread::async
auto async(Functor &&f, const char *desc FC_TASK_NAME_DEFAULT_ARG, priority prio=priority()) -> fc::future< decltype(f())>
Definition: thread.hpp:87
fc::http::detail::asio_tls_with_stub_log::transport_config::elog_type
type::elog_type elog_type
Definition: websocket.cpp:124
fc::optional< connection_hdl >
fc::http::detail::context_ptr
websocketpp::lib::shared_ptr< boost::asio::ssl::context > context_ptr
Definition: websocket.cpp:237
fc::ip::endpoint::port
uint16_t port() const
Definition: ip.cpp:78
fc::http::detail::websocket_connection_impl
Definition: websocket.cpp:183
fc::http::websocket_server::on_connection
void on_connection(const on_connection_handler &handler)
Definition: websocket.cpp:640
fc::http::detail::websocket_connection_impl::close
virtual void close(int64_t code, const std::string &reason) override
Definition: websocket.cpp:202
fc::http::detail::asio_tls_stub_log::endpoint_msg_manager_type
base::endpoint_msg_manager_type endpoint_msg_manager_type
Definition: websocket.cpp:153
fc::http::detail::generic_websocket_client_impl::_client_thread
fc::thread & _client_thread
Definition: websocket.cpp:544
fc::http::detail::asio_tls_stub_log::transport_config::response_type
type::response_type response_type
Definition: websocket.cpp:165
fc::http::detail::generic_websocket_server_impl::generic_websocket_server_impl
generic_websocket_server_impl(const std::string &forward_header_key)
Definition: websocket.cpp:245
fc::http::websocket_client::synchronous_close
void synchronous_close()
Definition: websocket.cpp:756
fc::http::detail::asio_tls_with_stub_log::transport_config::socket_type
websocketpp::transport::asio::tls_socket::endpoint socket_type
Definition: websocket.cpp:127
fc::http::on_connection_handler
std::function< void(const websocket_connection_ptr &)> on_connection_handler
Definition: websocket.hpp:49
fc::http::detail::generic_websocket_server_impl::_server_socket_closed
fc::promise< void >::ptr _server_socket_closed
Promise to wait for the server socket to be closed.
Definition: websocket.cpp:398
fc::http::detail::asio_tls_stub_log::message_type
base::message_type message_type
Definition: websocket.cpp:151
fc::http::detail::generic_websocket_client_impl::~generic_websocket_client_impl
virtual ~generic_websocket_client_impl()
Definition: websocket.cpp:501
fc::http::detail::generic_websocket_client_impl::_connection
websocket_connection_ptr _connection
Definition: websocket.cpp:546
fc::http::detail::generic_websocket_server_impl::~generic_websocket_server_impl
virtual ~generic_websocket_server_impl()
Definition: websocket.cpp:356
fc::http::detail::asio_tls_with_stub_log::transport_type
websocketpp::transport::asio::endpoint< transport_config > transport_type
Definition: websocket.cpp:130
fc::http::websocket_tls_server::listen
void listen(uint16_t port)
Definition: websocket.cpp:690
fc::http::detail::asio_with_stub_log::transport_config::concurrency_type
type::concurrency_type concurrency_type
Definition: websocket.cpp:82
fc::http::detail::possibly_proxied_websocket_connection::~possibly_proxied_websocket_connection
virtual ~possibly_proxied_websocket_connection()
Definition: websocket.cpp:232
fc::http::websocket_client::secure_connect
websocket_connection_ptr secure_connect(const std::string &uri)
Definition: websocket.cpp:745
fc::http::detail::websocket_server_impl::websocket_server_impl
websocket_server_impl(const std::string &forward_header_key)
Definition: websocket.cpp:406
fc::http::detail::websocket_tls_client_impl::setup_peer_verify
void setup_peer_verify(context_ptr &ctx, const std::string &ca_filename)
Definition: websocket.cpp:612
fc::http::detail::asio_tls_with_stub_log::con_msg_manager_type
base::con_msg_manager_type con_msg_manager_type
Definition: websocket.cpp:113
fc::http::detail::generic_websocket_client_impl
Definition: websocket.cpp:449
fc::http::detail::websocket_tls_client_impl
Definition: websocket.cpp:554
fc::http::detail::websocket_server_impl
Definition: websocket.cpp:403
optional.hpp