RESTinio
ws_connection.hpp
Go to the documentation of this file.
1 /*
2  restinio
3 */
4 
9 #pragma once
10 
11 #include <queue>
12 
14 
15 #include <http_parser.h>
16 
18 
19 #include <restinio/all.hpp>
25 
27 
29 
30 namespace restinio
31 {
32 
33 namespace websocket
34 {
35 
36 namespace basic
37 {
38 
39 namespace impl
40 {
41 
42 using write_groups_queue_t = std::queue< write_group_t >;
43 
45 constexpr size_t
47 {
48  return 14;
49 }
50 
51 //
52 // ws_outgoing_data_t
53 //
54 
57 {
58  public:
60  void
62  {
63  m_awaiting_write_groups.emplace( std::move( wg ) );
64  }
65 
68  {
70 
71  if( !m_awaiting_write_groups.empty() )
72  {
73  result = std::move( m_awaiting_write_groups.front() );
75  }
76 
77  return result;
78  }
79 
80  private:
83 };
84 
85 //
86 // connection_input_t
87 //
88 
91 {
92  connection_input_t( std::size_t buffer_size )
93  : m_buf{ buffer_size }
94  {}
95 
98 
101 
103  std::string m_payload;
104 
106  void
108  {
109  m_parser.reset();
110  m_payload.clear();
111  }
112 };
113 
114 //
115 // ws_connection_t
116 //
117 
119 template <
120  typename Traits,
121  typename WS_Message_Handler >
122 class ws_connection_t final
123  : public ws_connection_base_t
124  , public restinio::impl::executor_wrapper_t< typename Traits::strand_t >
125 {
127 
128  public:
129  using message_handler_t = WS_Message_Handler;
130 
131  using timer_manager_t = typename Traits::timer_manager_t;
132  using timer_manager_handle_t = std::shared_ptr< timer_manager_t >;
133  using timer_guard_t = typename timer_manager_t::timer_guard_t;
134  using logger_t = typename Traits::logger_t;
135  using strand_t = typename Traits::strand_t;
136  using stream_socket_t = typename Traits::stream_socket_t;
139 
140  using ws_weak_handle_t = std::weak_ptr< ws_t >;
141 
144  connection_id_t conn_id,
148  stream_socket_t socket,
149  lifetime_monitor_t lifetime_monitor,
151  message_handler_t msg_handler )
152  : ws_connection_base_t{ conn_id }
153  , executor_wrapper_base_t{ socket.get_executor() }
154  , m_settings{ std::move( settings ) }
155  , m_socket{ std::move( socket ) }
156  , m_lifetime_monitor{ std::move( lifetime_monitor ) }
157  , m_timer_guard{ m_settings->create_timer_guard() }
159  , m_msg_handler{ std::move( msg_handler ) }
160  , m_logger{ *( m_settings->m_logger ) }
161  {
162  // Notify of a new connection instance.
163  m_logger.trace( [&]{
164  return fmt::format(
165  "[connection:{}] move socket to [ws_connection:{}]",
166  connection_id(),
167  connection_id() );
168  } );
169 
170  m_logger.trace( [&]{
171  return fmt::format(
172  "[ws_connection:{}] start connection with {}",
173  connection_id(),
174  m_socket.remote_endpoint() );
175  } );
176 
177  // Inform state listener if it used.
178  m_settings->call_state_listener( [this]() noexcept {
179  return connection_state::notice_t {
180  connection_id(),
181  m_socket.remote_endpoint(),
182  connection_state::upgraded_to_websocket_t{}
183  };
184  } );
185  }
186 
187  ws_connection_t( const ws_connection_t & ) = delete;
191 
192  ~ws_connection_t() override
193  {
194  try
195  {
196  // Notify of a new connection instance.
197  m_logger.trace( [&]{
198  return fmt::format(
199  "[ws_connection:{}] destructor called",
200  connection_id() );
201  } );
202  }
203  catch( ... )
204  {}
205  }
206 
208  virtual void
209  shutdown() override
210  {
211  asio_ns::dispatch(
212  this->get_executor(),
213  [ this, ctx = shared_from_this() ]
214  // NOTE: this lambda is noexcept since v.0.6.0.
215  () noexcept {
216  try
217  {
218  // An exception from logger shouldn't prevent
219  // main shutdown actions.
221  [&]{
222  return fmt::format(
223  "[ws_connection:{}] shutdown",
224  connection_id() );
225  } );
226 
228  graceful_close();
229  }
230  catch( const std::exception & ex )
231  {
233  [&]{
234  return fmt::format(
235  "[ws_connection:{}] shutdown operation error: {}",
236  connection_id(),
237  ex.what() );
238  } );
239  }
240  } );
241  }
242 
244  virtual void
245  kill() override
246  {
247  asio_ns::dispatch(
248  this->get_executor(),
249  [ this, ctx = shared_from_this() ]
250  // NOTE: this lambda is noexcept since v.0.6.0.
251  () noexcept
252  {
253  try
254  {
255  // An exception from logger shouldn't prevent
256  // main kill actions.
258  [&]{
259  return fmt::format(
260  "[ws_connection:{}] kill",
261  connection_id() );
262  } );
263 
266 
267  close_impl();
268  }
269  catch( const std::exception & ex )
270  {
272  [&]{
273  return fmt::format(
274  "[ws_connection:{}] kill operation error: {}",
275  connection_id(),
276  ex.what() );
277  } );
278  }
279  } );
280  }
281 
283  void
284  init_read( ws_handle_t wsh ) override
285  {
286  ws_weak_handle_t wswh{ wsh };
287 
288  // Run write message on io_context loop (direct invocation if possible).
289  asio_ns::dispatch(
290  this->get_executor(),
291  [ this, ctx = shared_from_this(), wswh = std::move( wswh ) ]
292  // NOTE: this lambda is noexcept since v.0.6.0.
293  () noexcept
294  {
295  try
296  {
297  // Start timeout checking.
298  m_prepared_weak_ctx = shared_from_this();
300 
304  }
305  catch( const std::exception & ex )
306  {
309  [&]{
310  return fmt::format(
311  "[ws_connection:{}] unable to init read: {}",
312  connection_id(),
313  ex.what() );
314  } );
315  }
316  } );
317  }
318 
320  virtual void
322  write_group_t wg,
323  bool is_close_frame ) override
324  {
326  asio_ns::dispatch(
327  this->get_executor(),
328  [ this,
329  actual_wg = std::move( wg ),
330  ctx = shared_from_this(),
331  is_close_frame ]
332  // NOTE: this lambda is noexcept since v.0.6.0.
333  () mutable noexcept
334  {
335  try
336  {
339  std::move( actual_wg ),
340  is_close_frame );
341  else
342  {
343  m_logger.warn( [&]{
344  return fmt::format(
345  "[ws_connection:{}] cannot write to websocket: "
346  "write operations disabled",
347  connection_id() );
348  } );
349  }
350  }
351  catch( const std::exception & ex )
352  {
355  [&]{
356  return fmt::format(
357  "[ws_connection:{}] unable to write data: {}",
358  connection_id(),
359  ex.what() );
360  } );
361  }
362  } );
363  }
364  private:
366 
370  void
371  close_impl() noexcept
372  {
374  [&]() noexcept {
376  [&]{
377  return fmt::format(
378  "[ws_connection:{}] close socket",
379  connection_id() );
380  } );
381 
382  // This actions can throw and because of that we have
383  // to wrap them...
385  m_logger,
386  "ws_connection.close_impl.socket.shutdown",
387  [&] {
388  asio_ns::error_code ignored_ec;
389  m_socket.shutdown(
390  asio_ns::ip::tcp::socket::shutdown_both,
391  ignored_ec );
392  } );
393 
395  m_logger,
396  "ws_connection.close_impl.socket.close",
397  [&] {
398  m_socket.close();
399  } );
400  } );
401  }
402 
404  void
406  {
409  }
410 
412  void
414  {
416  [&]{
417  send_close_frame_to_peer( status_code_t::normal_closure );
419  } );
420  }
421 
423  void
424  send_close_frame_to_peer( std::string payload )
425  {
427  bufs.reserve( 2 );
428 
429  bufs.emplace_back(
431  final_frame,
432  opcode_t::connection_close_frame,
433  payload.size() ) );
434 
435  bufs.emplace_back( std::move( payload ) );
437 
439 
440  // No more data must be written.
442  }
443 
445  void
448  std::string desc = std::string{} )
449  {
450  send_close_frame_to_peer( std::string{ status_code_to_bin( code ) + desc } );
451  }
452 
454 
462  template< typename MSG_BUILDER >
463  void
465  status_code_t status,
466  MSG_BUILDER msg_builder ) noexcept
467  {
468  // An exception in logger shouldn't prevent the main actions.
470  m_logger, std::move( msg_builder ) );
471 
472  // This can throw but we have to suppress any exceptions.
474  m_logger, "ws_connection.call_close_handler_if_necessary",
475  [this, status] {
477  } );
478 
480  }
481 
482 
484  void
486  {
487  m_logger.trace( [&]{
488  return fmt::format(
489  "[ws_connection:{}] start reading header",
490  connection_id() );
491  } );
492 
493  // Prepare parser for consuming new message.
495 
496  if( 0 == m_input.m_buf.length() )
497  {
499  }
500  else
501  {
502  // Has something to read from m_input.m_buf.
505  }
506  }
507 
509  void
511  {
512  m_logger.trace( [&]{
513  return fmt::format(
514  "[ws_connection:{}] continue reading message",
515  connection_id() );
516  } );
517 
518  m_socket.async_read_some(
520  asio_ns::bind_executor(
521  this->get_executor(),
522  [ this, ctx = shared_from_this() ]
523  // NOTE: this lambda is noexcept since v.0.6.0.
524  ( const asio_ns::error_code & ec, std::size_t length ) noexcept
525  {
526  try
527  {
528  after_read_header( ec, length );
529  }
530  catch( const std::exception & ex )
531  {
534  [&]{
535  return fmt::format(
536  "[ws_connection:{}] after read header callback error: {}",
537  connection_id(),
538  ex.what() );
539  } );
540  }
541  } ) );
542  }
543 
545  void
546  handle_read_error( const char * desc, const asio_ns::error_code & ec )
547  {
548  // Assume that connection is lost.
550  status_code_t::connection_lost,
551  [&]{
552  return fmt::format(
553  "[ws_connection:{}] {}: {}",
554  connection_id(),
555  desc,
556  ec.message() );
557  } );
558  }
559 
561  void
563  const asio_ns::error_code & ec,
564  std::size_t length )
565  {
566  if( !ec )
567  {
568  m_logger.trace( [&]{
569  return fmt::format(
570  "[ws_connection:{}] received {} bytes",
571  this->connection_id(),
572  length );
573  } );
574 
575  m_input.m_buf.obtained_bytes( length );
577  }
578  else
579  {
580  handle_read_error( "reading message header error", ec );
581  }
582  }
583 
585  void
586  consume_header_from_buffer( const char * data, std::size_t length )
587  {
588  const auto nparsed = m_input.m_parser.parser_execute( data, length );
589 
590  m_input.m_buf.consumed_bytes( nparsed );
591 
593  {
595  }
596  else
597  {
598  assert( nparsed == length );
600  }
601  }
602 
604  void
606  {
607  m_logger.trace( [&]{
608  return fmt::format(
609  "[ws_connection:{}] start handling {} ({:#x})",
610  connection_id(),
612  static_cast<std::uint16_t>(md.m_opcode) );
613  } );
614 
615  const auto validation_result =
617 
618  if( validation_state_t::frame_header_is_valid != validation_result )
619  {
620  m_logger.error( [&]{
621  return fmt::format(
622  "[ws_connection:{}] invalid header",
623  connection_id() );
624  } );
625 
627  {
629  [&]{
630  send_close_frame_to_peer( status_code_t::protocol_error );
631  // Do not wait anything in return, because
632  // protocol is violated.
633  } );
634 
635  call_close_handler_if_necessary( status_code_t::protocol_error );
636  }
638  {
639  // Wait for close frame cannot be done.
640  close_impl();
641  }
642 
643  return;
644  }
645 
647  }
648 
650  void
652  {
653  const auto payload_length =
655 
656  m_input.m_payload.resize( payload_length );
657 
658  if( payload_length == 0 )
659  {
660  // Callback for message with 0-size payload.
662  }
663  else
664  {
665  const auto payload_part_size =
666  std::min( m_input.m_buf.length(), payload_length );
667 
668  std::memcpy(
669  &m_input.m_payload.front(),
670  m_input.m_buf.bytes(),
671  payload_part_size );
672 
673  m_input.m_buf.consumed_bytes( payload_part_size );
674 
675  const std::size_t length_remaining =
676  payload_length - payload_part_size;
677 
679  &m_input.m_payload.front(),
680  payload_part_size,
681  length_remaining ) )
682  {
683  if( 0 == length_remaining )
684  {
685  // All message is obtained.
687  }
688  else
689  {
690  // Read the rest of payload:
692  &m_input.m_payload.front() + payload_part_size,
693  length_remaining );
694  }
695  }
696  // Else payload is invalid and validate_payload_part()
697  // has handled the case so do nothing.
698  }
699  }
700 
702  void
705  char * payload_data,
707  std::size_t length_remaining,
709  bool do_validate_payload_and_call_msg_handler = true )
710  {
711  m_socket.async_read_some(
712  asio_ns::buffer( payload_data, length_remaining ),
713  asio_ns::bind_executor(
714  this->get_executor(),
715  [ this,
716  ctx = shared_from_this(),
717  payload_data,
718  length_remaining,
719  do_validate_payload_and_call_msg_handler ]
720  // NOTE: this lambda is noexcept since v.0.6.0.
721  ( const asio_ns::error_code & ec, std::size_t length ) noexcept
722  {
723  try
724  {
726  payload_data,
727  length_remaining,
728  ec,
729  length,
730  do_validate_payload_and_call_msg_handler );
731  }
732  catch( const std::exception & ex )
733  {
736  [&]{
737  return fmt::format(
738  "[ws_connection:{}] after read payload callback error: {}",
739  connection_id(),
740  ex.what() );
741  } );
742  }
743  } ) );
744  }
745 
747  void
749  char * payload_data,
750  std::size_t length_remaining,
751  const asio_ns::error_code & ec,
752  std::size_t length,
753  bool do_validate_payload_and_call_msg_handler = true )
754  {
755  if( !ec )
756  {
757  m_logger.trace( [&]{
758  return fmt::format(
759  "[ws_connection:{}] received {} bytes",
760  this->connection_id(),
761  length );
762  } );
763 
764  assert( length <= length_remaining );
765 
766  const std::size_t next_length_remaining =
767  length_remaining - length;
768 
769  if( do_validate_payload_and_call_msg_handler )
770  {
771  if( validate_payload_part( payload_data, length, next_length_remaining ) )
772  {
773  if( 0 == next_length_remaining )
774  {
775  // Here: all the payload is ready.
776 
777  // All message is obtained.
779  }
780  else
781  {
782  //Here: not all payload is obtained,
783  // so inintiate read once again:
785  payload_data + length,
786  next_length_remaining,
787  do_validate_payload_and_call_msg_handler );
788  }
789  }
790  // Else payload is invalid and validate_payload_part()
791  // has handled the case so do nothing.
792  }
793  else
794  {
795  if( 0 == next_length_remaining )
796  {
798  }
799  else
800  {
802  payload_data + length,
803  length_remaining - length,
804  do_validate_payload_and_call_msg_handler );
805  }
806  }
807  }
808  else
809  {
810  handle_read_error( "reading message payload error", ec );
811  }
812  }
813 
815  void
817  {
818  if( auto wsh = m_websocket_weak_handle.lock() )
819  {
820  try
821  {
823  std::move( wsh ),
824  std::move( close_frame ) );
825  }
826  catch( const std::exception & ex )
827  {
828  m_logger.error( [&]{
829  return fmt::format(
830  "[ws_connection:{}] execute handler error: {}",
831  connection_id(),
832  ex.what() );
833  } );
834  }
835  }
836  }
837 
839  bool
841  char * payload_data,
842  std::size_t length,
843  std::size_t next_length_remaining )
844  {
845  const auto validation_result =
847 
848  if( validation_state_t::payload_part_is_valid != validation_result )
849  {
850  handle_invalid_payload( validation_result );
851 
852  if( validation_state_t::incorrect_utf8_data == validation_result )
853  {
854  // Can skip this payload because it was not a bad close frame.
855 
856  // It is the case we are expecting close frame
857  // so validator must be ready to receive more headers
858  // and payloads after this frame.
860 
861  if( 0 == next_length_remaining )
862  {
864  }
865  else
866  {
867  // Skip checking payload for this frame:
868  const bool do_validate_payload_and_call_msg_handler = false;
870  payload_data + length,
871  next_length_remaining,
872  do_validate_payload_and_call_msg_handler );
873  }
874  }
875  return false;
876  }
877 
878  return true;
879  }
880 
882  void
884  {
885  m_logger.error( [&]{
886  return fmt::format(
887  "[ws_connection:{}] invalid paload",
888  connection_id() );
889  } );
890 
891  if( validation_state_t::invalid_close_code == validation_result )
892  {
893  // A corner case: invalid payload in close frame.
894 
896  {
897  // Case: close frame was not expected.
898 
899  // This actually must be executed:
901  [&]{
902  send_close_frame_to_peer( status_code_t::protocol_error );
903  // Do not wait anything in return, because
904  // protocol is violated.
905  } );
906 
907  // Notify user of a close but use a correct close code.
908  call_close_handler_if_necessary( status_code_t::protocol_error );
909  }
911  {
912  // Case: close frame was expected.
913 
914  // We got a close frame but it is incorrect,
915  // so just close (there is not too much we can do).
916  close_impl();
917  }
918  }
919  else
920  {
922  {
924  [&]{
925  send_close_frame_to_peer( status_code_t::invalid_message_data );
927  } );
928 
929  call_close_handler_if_necessary( status_code_t::invalid_message_data );
930  }
931  }
932  }
933 
934  void
936  {
937  auto & md = m_input.m_parser.current_message();
938 
939  const auto validation_result = m_protocol_validator.finish_frame();
940  if( validation_state_t::frame_is_valid == validation_result )
941  {
943  {
944  if( opcode_t::connection_close_frame == md.m_opcode )
945  {
946  m_logger.trace( [&]{
947  return fmt::format(
948  "[ws_connection:{}] got close frame from peer, status: {}",
949  connection_id(),
950  static_cast<std::uint16_t>(
952  } );
953 
956  [&]{
958  } );
959 
961  }
962 
964  std::make_shared< message_t >(
965  md.m_final_flag ? final_frame : not_final_frame,
966  md.m_opcode,
967  std::move( m_input.m_payload ) ) );
968 
971  }
972  else
973  {
975 
976  if( opcode_t::connection_close_frame == md.m_opcode )
977  {
978  // Got it!
979  m_timer_guard.cancel();
980 
981  close_impl();
982 
983  m_logger.trace( [&]{
984  return fmt::format(
985  "[ws_connection:{}] expected close frame came",
986  connection_id() );
987  } );
988  }
989  else
990  {
991  // Wait for next frame.
993  }
994  }
995  }
996  else
997  {
998  handle_invalid_payload( validation_result );
999  }
1000  }
1001 
1002  void
1004  {
1006  [&]{
1008  std::make_shared< message_t >(
1009  final_frame,
1010  opcode_t::connection_close_frame,
1011  status_code_to_bin( status ) ) );
1012  } );
1013  }
1014 
1016  void
1017  write_data_impl( write_group_t wg, bool is_close_frame )
1018  {
1019  if( m_socket.is_open() )
1020  {
1021  if( is_close_frame )
1022  {
1023  m_logger.trace( [&]{
1024  return fmt::format(
1025  "[ws_connection:{}] user sends close frame",
1026  connection_id() );
1027  } );
1028 
1029  m_close_frame_to_peer.disable(); // It is formed and sent by user
1030  m_close_frame_to_user.disable(); // And user knows that websocket is closed.
1031  // No more writes.
1033 
1034  // Start waiting only close-frame.
1036  }
1037 
1038  // Push write_group to queue.
1039  m_outgoing_data.append( std::move( wg ) );
1040 
1042  }
1043  else
1044  {
1045  m_logger.warn( [&]{
1046  return fmt::format(
1047  "[ws_connection:{}] try to write while socket is closed",
1048  connection_id() );
1049  } );
1050 
1051  try
1052  {
1055  asio_convertible_error_t::write_was_not_executed ) );
1056  }
1057  catch( ... )
1058  {}
1059  }
1060  }
1061 
1064  void
1066  {
1068  {
1069  init_write();
1070  }
1071  }
1072 
1074  void
1076  {
1077  // Here: not writing anything to socket, so
1078  // write operation can be initiated.
1079  auto next_write_group = m_outgoing_data.pop_ready_buffers();
1080 
1081  if( next_write_group )
1082  {
1083  m_logger.trace( [&]{
1084  return fmt::format(
1085  "[ws_connection:{}] start next write group, "
1086  "size: {}",
1087  this->connection_id(),
1088  next_write_group->items_count() );
1089  } );
1090 
1091  // Initialize write context with a new write group.
1093  std::move( next_write_group ) );
1094 
1095  // Start the loop of sending data from current write group.
1097  }
1098  }
1099 
1100  // Use aliases for shorter names.
1104 
1105  void
1107  {
1108  try
1109  {
1111 
1112  if( holds_alternative< trivial_write_operation_t >( wo ) )
1113  {
1114  handle_trivial_write_operation( get< trivial_write_operation_t >( wo ) );
1115  }
1116  else if( holds_alternative< none_write_operation_t >( wo ) )
1117  {
1119  }
1120  else
1121  {
1122  assert( holds_alternative< file_write_operation_t >( wo ) );
1123  throw exception_t{ "sendfile write operation not implemented" };
1124  }
1125  }
1126  catch( const std::exception & ex )
1127  {
1130  [&]{
1131  return fmt::format(
1132  "[ws_connection:{}] handle_current_write_ctx failed: {}",
1133  connection_id(),
1134  ex.what() );
1135  } );
1136  }
1137  }
1138 
1139  void
1141  {
1142  // Asio buffers (param for async write):
1143  auto & bufs = op.get_trivial_bufs();
1144 
1145  m_logger.trace( [&]{
1146  return fmt::format(
1147  "[ws_connection:{}] sending data with "
1148  "buf count: {}, "
1149  "total size: {}",
1150  connection_id(),
1151  bufs.size(),
1152  op.size() ); } );
1153 
1155 
1156  // There is somethig to write.
1157  asio_ns::async_write(
1158  m_socket,
1159  bufs,
1160  asio_ns::bind_executor(
1161  this->get_executor(),
1162  [ this,
1163  ctx = shared_from_this() ]
1164  // NOTE: this lambda is noexcept since v.0.6.0.
1165  ( const asio_ns::error_code & ec, std::size_t written ) noexcept
1166  {
1167  try
1168  {
1169  if( !ec )
1170  {
1171  m_logger.trace( [&]{
1172  return fmt::format(
1173  "[ws_connection:{}] outgoing data was sent: {} bytes",
1174  connection_id(),
1175  written );
1176  } );
1177  }
1178 
1179  after_write( ec );
1180  }
1181  catch( const std::exception & ex )
1182  {
1185  [&]{
1186  return fmt::format(
1187  "[ws_connection:{}] after write callback error: {}",
1188  connection_id(),
1189  ex.what() );
1190  } );
1191  }
1192  } ) );
1193  }
1194 
1196  void
1198  {
1199  // Finishing writing this group.
1200  m_logger.trace( [&]{
1201  return fmt::format(
1202  "[ws_connection:{}] finishing current write group",
1203  this->connection_id() );
1204  } );
1205 
1206  // Group notificators are called from here (if exist):
1208 
1209  // Start another write opertion
1210  // if there is something to send.
1212  }
1213 
1215  void
1216  after_write( const asio_ns::error_code & ec )
1217  {
1218  if( !ec )
1219  {
1221  }
1222  else
1223  {
1225  status_code_t::connection_lost,
1226  [&]{
1227  return fmt::format(
1228  "[ws_connection:{}] unable to write: {}",
1229  connection_id(),
1230  ec.message() );
1231  } );
1232 
1233  try
1234  {
1236  }
1237  catch( const std::exception & ex )
1238  {
1239  m_logger.error( [&]{
1240  return fmt::format(
1241  "[ws_connection:{}] notificator error: {}",
1242  connection_id(),
1243  ex.what() );
1244  } );
1245  }
1246  }
1247  }
1248 
1251 
1254 
1261 
1264  static ws_connection_t &
1266  {
1267  return static_cast< ws_connection_t & >( base );
1268  }
1269 
1270  virtual void
1272  {
1273  asio_ns::dispatch(
1274  this->get_executor(),
1275  [ ctx = std::move( self ) ]
1276  // NOTE: this lambda is noexcept since v.0.6.0.
1277  () noexcept
1278  {
1279  auto & conn_object = cast_to_self( *ctx );
1280  // If an exception will be thrown we can only
1281  // close the connection.
1282  try
1283  {
1284  conn_object.check_timeout_impl();
1285  }
1286  catch( const std::exception & x )
1287  {
1288  conn_object.trigger_error_and_close(
1290  [&] {
1291  return fmt::format( "[connection: {}] unexpected "
1292  "error during timeout handling: {}",
1293  conn_object.connection_id(),
1294  x.what() );
1295  } );
1296  }
1297  } );
1298  }
1299 
1300  std::chrono::steady_clock::time_point m_write_operation_timeout_after;
1301  std::chrono::steady_clock::time_point m_close_frame_from_peer_timeout_after =
1302  std::chrono::steady_clock::time_point::max();
1305 
1306  void
1308  {
1309  const auto now = std::chrono::steady_clock::now();
1311  {
1312  m_logger.trace( [&]{
1313  return fmt::format(
1314  "[wd_connection:{}] write operation timed out",
1315  connection_id() );
1316  } );
1319  close_impl();
1320  }
1321  else if( now > m_close_frame_from_peer_timeout_after )
1322  {
1323  m_logger.trace( [&]{
1324  return fmt::format(
1325  "[wd_connection:{}] waiting for close-frame from peer timed out",
1326  connection_id() );
1327  } );
1328  close_impl();
1329  }
1330  else
1331  {
1333  }
1334  }
1335 
1337  void
1339  {
1340  m_timer_guard.schedule( m_prepared_weak_ctx );
1341  }
1342 
1344  void
1346  {
1348  std::chrono::steady_clock::now() + m_settings->m_write_http_response_timelimit;
1349  }
1350 
1351  void
1353  {
1355  std::chrono::steady_clock::now() + m_settings->m_read_next_http_message_timelimit;
1356  }
1358 
1361 
1364 
1367 
1370 
1373 
1376 
1379 
1381  enum class write_state_t
1382  {
1384  write_enabled,
1387  };
1388 
1391 
1393  enum class read_state_t
1394  {
1400  read_nothing
1401  };
1402 
1405 
1409  {
1410  public:
1411  template < typename Action >
1412  void
1413  run_if_first( Action && action ) noexcept(noexcept(action()))
1414  {
1415  if( m_not_executed_yet )
1416  {
1417  m_not_executed_yet = false;
1418  action();
1419  }
1420  }
1421 
1423  void
1425  {
1426  m_not_executed_yet = false;
1427  }
1428 
1429  private:
1430  bool m_not_executed_yet{ true };
1431  };
1432 
1436 };
1437 
1438 } /* namespace impl */
1439 
1440 } /* namespace basic */
1441 
1442 } /* namespace websocket */
1443 
1444 } /* namespace restinio */
restinio::websocket::basic::impl::ws_connection_t::handle_trivial_write_operation
void handle_trivial_write_operation(const trivial_write_operation_t &op)
Definition: ws_connection.hpp:1140
restinio::websocket::basic::impl::connection_input_t::connection_input_t
connection_input_t(std::size_t buffer_size)
Definition: ws_connection.hpp:92
restinio::tcp_connection_ctx_base_t::connection_id
connection_id_t connection_id() const noexcept
Get connection id.
Definition: tcp_connection_ctx_base.hpp:38
restinio::make_asio_compaible_error
asio_ns::error_code make_asio_compaible_error(asio_convertible_error_t err) noexcept
Make restinio error_code compatible with asio_ns::error_code.
Definition: asio_include.hpp:210
restinio::exception_t
Exception class for all exceptions thrown by RESTinio.
Definition: exception.hpp:26
restinio::websocket::basic::impl::ws_connection_t::send_close_frame_to_peer
void send_close_frame_to_peer(std::string payload)
Send close frame to peer.
Definition: ws_connection.hpp:424
restinio::impl::fixed_buffer_t::length
std::size_t length() const noexcept
How many unconsumed bytes are there in buffer.
Definition: fixed_buffer.hpp:63
restinio::websocket::basic::impl::ws_connection_t::write_data_impl
void write_data_impl(write_group_t wg, bool is_close_frame)
Implementation of writing data performed on the asio_ns::io_context.
Definition: ws_connection.hpp:1017
restinio::impl::fixed_buffer_t
Helper class for reading bytes and feeding them to parser.
Definition: fixed_buffer.hpp:27
restinio::websocket::basic::message_handle_t
std::shared_ptr< message_t > message_handle_t
Request handler, that is the type for calling request handlers.
Definition: message.hpp:227
restinio::websocket::basic::impl::ws_connection_t::start_read_header
void start_read_header()
Start the process of reading ws messages from socket.
Definition: ws_connection.hpp:485
restinio::impl::write_group_output_ctx_t::trivial_write_operation_t
Trivial write operaton.
Definition: write_group_output_ctx.hpp:106
restinio::impl::executor_wrapper_t< Traits::strand_t >::get_executor
Traits::strand_t & get_executor() noexcept
An executor for callbacks on async operations.
Definition: executor_wrapper.hpp:35
restinio::websocket::basic::impl::ws_connection_t::m_settings
restinio::impl::connection_settings_handle_t< Traits > m_settings
Common paramaters of a connection.
Definition: ws_connection.hpp:1250
restinio::websocket::basic::impl::ws_connection_t::message_handler_t
WS_Message_Handler message_handler_t
Definition: ws_connection.hpp:129
restinio::websocket::basic::impl::ws_connection_t::init_next_timeout_checking
void init_next_timeout_checking()
schedule next timeout checking.
Definition: ws_connection.hpp:1338
restinio::websocket::basic::impl::ws_connection_t::cast_to_self
static ws_connection_t & cast_to_self(tcp_connection_ctx_base_t &base)
Timers.
Definition: ws_connection.hpp:1265
restinio::websocket::basic::impl::ws_connection_t::one_shot_action_t::disable
void disable()
Disable ation: action will not be executed even on a first shot.
Definition: ws_connection.hpp:1424
restinio::websocket::basic::impl::ws_connection_t::m_timer_guard
timer_guard_t m_timer_guard
Definition: ws_connection.hpp:1304
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:421
restinio::impl::write_group_output_ctx_t::transmitting
bool transmitting() const noexcept
Check if data is trunsmitting now.
Definition: write_group_output_ctx.hpp:235
restinio::websocket::basic::opcode_to_string
const char * opcode_to_string(opcode_t opcode)
Helper sunction to get method string name.
Definition: message.hpp:46
restinio::impl::write_group_output_ctx_t
Helper class for writting response data.
Definition: write_group_output_ctx.hpp:80
restinio::impl::write_group_output_ctx_t::extract_next_write_operation
solid_write_operation_variant_t extract_next_write_operation()
et an object with next write operation to perform.
Definition: write_group_output_ctx.hpp:253
message.hpp
restinio::websocket::basic::impl::ws_connection_t::m_write_state
write_state_t m_write_state
A state of a websocket output.
Definition: ws_connection.hpp:1390
restinio::connection_count_limits::connection_lifetime_monitor_t
Helper type for controlling the lifetime of the connection.
Definition: connection_count_limiter.hpp:375
asio_include.hpp
restinio::impl::write_group_output_ctx_t::fail_write_group
void fail_write_group(const asio_ns::error_code &ec)
Handle current group write process failed.
Definition: write_group_output_ctx.hpp:283
restinio::websocket::basic::impl::ws_connection_t::m_outgoing_data
ws_outgoing_data_t m_outgoing_data
Output buffers queue.
Definition: ws_connection.hpp:1375
restinio::websocket::basic::impl::ws_parser_t
Websocket parser.
Definition: ws_parser.hpp:260
restinio::websocket::basic::impl::ws_parser_t::current_message
const message_details_t & current_message() const
Get current mesasge details.
Definition: ws_parser.hpp:303
restinio::websocket::basic::impl::ws_connection_t::after_read_payload
void after_read_payload(char *payload_data, std::size_t length_remaining, const asio_ns::error_code &ec, std::size_t length, bool do_validate_payload_and_call_msg_handler=true)
Handle read operation result, when reading payload.
Definition: ws_connection.hpp:748
ws_protocol_validator.hpp
restinio::websocket::basic::not_final_frame
constexpr final_frame_flag_t not_final_frame
Definition: message.hpp:136
restinio::websocket::basic::impl::ws_connection_t::m_protocol_validator
ws_protocol_validator_t m_protocol_validator
Helper for validating protocol.
Definition: ws_connection.hpp:1363
restinio::impl::executor_wrapper_t
Wrapper for an executor (strand) used by connections.
Definition: executor_wrapper.hpp:25
restinio::websocket::basic::impl::ws_connection_t::write_state_t::write_enabled
@ write_enabled
Able to append outgoing data.
restinio::websocket::basic::impl::ws_connection_t::m_input
connection_input_t m_input
Input routine.
Definition: ws_connection.hpp:1360
restinio::websocket::basic::impl::ws_connection_t::call_handler_on_current_message
void call_handler_on_current_message()
Definition: ws_connection.hpp:935
restinio::impl::write_group_output_ctx_t::start_next_write_group
void start_next_write_group(optional_t< write_group_t > next_wg) noexcept
Start handlong next write group.
Definition: write_group_output_ctx.hpp:239
restinio::websocket::basic::impl::ws_connection_t::consume_header_from_buffer
void consume_header_from_buffer(const char *data, std::size_t length)
Parse header from internal buffer.
Definition: ws_connection.hpp:586
restinio::websocket::basic::impl::ws_connection_t::init_read
void init_read(ws_handle_t wsh) override
Start reading ws-messages.
Definition: ws_connection.hpp:284
restinio::websocket::basic::impl::ws_connection_t::handle_parsed_and_valid_header
void handle_parsed_and_valid_header(const message_details_t &md)
Handle parsed and valid header.
Definition: ws_connection.hpp:651
restinio::impl::fixed_buffer_t::consumed_bytes
void consumed_bytes(std::size_t length) noexcept
Mark how many bytes were obtained.
Definition: fixed_buffer.hpp:56
restinio::connection_id_t
std::uint64_t connection_id_t
Type for ID of connection.
Definition: common_types.hpp:155
restinio::websocket::basic::impl::ws_connection_t::init_write_if_necessary
void init_write_if_necessary()
Checks if there is something to write, and if so starts write operation.
Definition: ws_connection.hpp:1065
restinio::websocket::basic::impl::ws_connection_t::handle_invalid_payload
void handle_invalid_payload(validation_state_t validation_result)
Handle payload errors.
Definition: ws_connection.hpp:883
restinio::websocket::basic::impl::ws_connection_t::write_data
virtual void write_data(write_group_t wg, bool is_close_frame) override
Write pieces of outgoing data.
Definition: ws_connection.hpp:321
restinio::websocket::basic::impl::ws_connection_t::m_write_output_ctx
restinio::impl::write_group_output_ctx_t m_write_output_ctx
Write to socket operation context.
Definition: ws_connection.hpp:1372
restinio::websocket::basic::impl::ws_connection_t::guard_write_operation
void guard_write_operation()
Start guard write operation if necessary.
Definition: ws_connection.hpp:1345
restinio::websocket::basic::impl::ws_outgoing_data_t::pop_ready_buffers
optional_t< write_group_t > pop_ready_buffers()
Definition: ws_connection.hpp:67
RESTINIO_ENSURE_NOEXCEPT_CALL
#define RESTINIO_ENSURE_NOEXCEPT_CALL(expr)
A wrapper around static_assert for checking that an expression is noexcept and execution of that expr...
Definition: compiler_features.hpp:60
restinio::websocket::basic::impl::message_details_t
Websocket message class with more detailed protocol information.
Definition: ws_parser.hpp:63
restinio::websocket::basic::impl::ws_connection_t::check_timeout
virtual void check_timeout(tcp_connection_ctx_handle_t &self) override
Definition: ws_connection.hpp:1271
restinio::websocket::basic::impl::ws_connection_t::start_read_payload
void start_read_payload(char *payload_data, std::size_t length_remaining, bool do_validate_payload_and_call_msg_handler=true)
Start reading message payload.
Definition: ws_connection.hpp:703
restinio::websocket::basic::impl::ws_connection_t::ws_weak_handle_t
std::weak_ptr< ws_t > ws_weak_handle_t
Definition: ws_connection.hpp:140
restinio::impl::fixed_buffer_t::obtained_bytes
void obtained_bytes(std::size_t length) noexcept
Mark how many bytes were obtained.
Definition: fixed_buffer.hpp:48
restinio::websocket::basic::impl::ws_connection_t::handle_current_write_ctx
void handle_current_write_ctx()
Definition: ws_connection.hpp:1106
restinio::websocket::basic::impl::ws_protocol_validator_t::process_and_unmask_next_payload_part
validation_state_t process_and_unmask_next_payload_part(char *data, size_t size)
Validate next part of current frame and reset source part to unmasked data.
Definition: ws_protocol_validator.hpp:278
restinio::websocket::basic::impl::ws_connection_t::one_shot_action_t
A helper class for running exclusive action. Only a first action will run.
Definition: ws_connection.hpp:1409
restinio::websocket::basic::impl::ws_connection_t::shutdown
virtual void shutdown() override
Shutdown websocket.
Definition: ws_connection.hpp:209
restinio::websocket::basic::impl::ws_connection_t
Context for handling websocket connections.
Definition: ws_connection.hpp:125
restinio::utils::log_error_noexcept
void log_error_noexcept(Logger &&logger, Message_Builder &&builder) noexcept
Definition: suppress_exceptions.hpp:71
ws_parser.hpp
restinio::websocket::basic::impl::ws_connection_t::read_state_t::read_nothing
@ read_nothing
Do not read anything (before activation).
restinio::impl::write_group_output_ctx_t::none_write_operation_t
None write operation.
Definition: write_group_output_ctx.hpp:232
restinio::websocket::basic::impl::ws_connection_t::timer_manager_t
typename Traits::timer_manager_t timer_manager_t
Definition: ws_connection.hpp:131
restinio::write_group_t::invoke_after_write_notificator_if_exists
void invoke_after_write_notificator_if_exists(const asio_ns::error_code &ec)
Get after write notificator.
Definition: buffers.hpp:815
restinio::websocket::basic::impl::ws_parser_t::parser_execute
size_t parser_execute(const char *data, size_t size)
Parse piece of data from buffer.
Definition: ws_parser.hpp:265
restinio::websocket::basic::impl::ws_outgoing_data_t::append
void append(write_group_t wg)
Add buffers to queue.
Definition: ws_connection.hpp:61
restinio::websocket::basic::impl::ws_connection_t::graceful_close
void graceful_close()
Close WebSocket connection in a graceful manner.
Definition: ws_connection.hpp:413
restinio::impl::connection_settings_handle_t
std::shared_ptr< connection_settings_t< Traits > > connection_settings_handle_t
Definition: connection_settings.hpp:199
restinio::websocket::basic::impl::ws_connection_t::m_prepared_weak_ctx
tcp_connection_ctx_weak_handle_t m_prepared_weak_ctx
Definition: ws_connection.hpp:1303
restinio::websocket::basic::impl::ws_connection_t::handle_parsed_header
void handle_parsed_header(const message_details_t &md)
Handle parsed header.
Definition: ws_connection.hpp:605
restinio::utils::impl::uint64_to_size_t
std::size_t uint64_to_size_t(std::uint64_t v)
Helper function for truncating uint64 to std::size_t with exception if that truncation will lead to d...
Definition: safe_uint_truncate.hpp:59
restinio::websocket::basic::impl::write_groups_queue_t
std::queue< write_group_t > write_groups_queue_t
Definition: ws_connection.hpp:42
restinio::impl::fixed_buffer_t::make_asio_buffer
auto make_asio_buffer() noexcept
Make asio buffer for reading bytes from socket.
Definition: fixed_buffer.hpp:41
executor_wrapper.hpp
restinio::websocket::basic::impl::ws_connection_t::timer_guard_t
typename timer_manager_t::timer_guard_t timer_guard_t
Definition: ws_connection.hpp:133
restinio::websocket::basic::ws_handle_t
std::shared_ptr< ws_t > ws_handle_t
Alias for ws_t handle.
Definition: ws_connection_base.hpp:27
restinio::utils::log_trace_noexcept
void log_trace_noexcept(Logger &&logger, Message_Builder &&builder) noexcept
Definition: suppress_exceptions.hpp:32
restinio::websocket::basic::impl::ws_connection_t::ws_connection_t
ws_connection_t(const ws_connection_t &)=delete
restinio::websocket::basic::impl::ws_connection_t::m_logger
logger_t & m_logger
Logger for operation.
Definition: ws_connection.hpp:1369
restinio::websocket::basic::impl::ws_connection_t::timer_manager_handle_t
std::shared_ptr< timer_manager_t > timer_manager_handle_t
Definition: ws_connection.hpp:132
restinio::websocket::basic::impl::ws_connection_t::logger_t
typename Traits::logger_t logger_t
Definition: ws_connection.hpp:134
write_group_output_ctx.hpp
nonstd::optional_lite::optional
class optional
Definition: optional.hpp:839
restinio::websocket::basic::impl::write_message_details
raw_data_t write_message_details(const message_details_t &message)
Serialize websocket message details into bytes buffer.
Definition: ws_parser.hpp:515
restinio::websocket::basic::impl::ws_connection_t::one_shot_action_t::run_if_first
void run_if_first(Action &&action) noexcept(noexcept(action()))
Definition: ws_connection.hpp:1413
restinio::websocket::basic::impl::connection_input_t
Websocket input stuff.
Definition: ws_connection.hpp:91
restinio::websocket::basic::impl::ws_connection_t::write_state_t
write_state_t
Websocket output states.
Definition: ws_connection.hpp:1382
restinio::websocket::basic::impl::ws_connection_t::m_websocket_weak_handle
ws_weak_handle_t m_websocket_weak_handle
A waek handler for owning ws_t to use it when call message handler.
Definition: ws_connection.hpp:1378
restinio::utils::suppress_exceptions
void suppress_exceptions(Logger &&logger, const char *block_description, Lambda &&lambda) noexcept
Helper function for execution a block of code with suppression of any exceptions raised inside that b...
Definition: suppress_exceptions.hpp:94
restinio::websocket::basic::impl::ws_protocol_validator_t::reset
void reset()
Reset to initial state.
Definition: ws_protocol_validator.hpp:341
include_fmtlib.hpp
A special wrapper around fmtlib include files.
restinio::tcp_connection_ctx_base_t
TCP connection base.
Definition: tcp_connection_ctx_base.hpp:29
restinio::websocket::basic::final_frame
constexpr final_frame_flag_t final_frame
Definition: message.hpp:135
restinio::websocket::basic::impl::ws_connection_t::stream_socket_t
typename Traits::stream_socket_t stream_socket_t
Definition: ws_connection.hpp:136
restinio::websocket::basic::impl::ws_connection_t::~ws_connection_t
~ws_connection_t() override
Definition: ws_connection.hpp:192
restinio::websocket::basic::impl::ws_connection_t::m_close_impl
one_shot_action_t m_close_impl
Definition: ws_connection.hpp:1435
restinio::websocket::basic::impl::ws_connection_t::strand_t
typename Traits::strand_t strand_t
Definition: ws_connection.hpp:135
restinio::websocket::basic::impl::ws_protocol_validator_t
Class for websocket protocol validations.
Definition: ws_protocol_validator.hpp:195
restinio::websocket::basic::impl::ws_connection_t::operator=
ws_connection_t & operator=(const ws_connection_t &)=delete
restinio::websocket::basic::impl::ws_connection_t::m_lifetime_monitor
lifetime_monitor_t m_lifetime_monitor
Monitor of the connection lifetime.
Definition: ws_connection.hpp:1260
restinio::websocket::basic::impl::ws_protocol_validator_t::finish_frame
validation_state_t finish_frame()
Make final checks of payload if it is necessary and reset state.
Definition: ws_protocol_validator.hpp:303
restinio::websocket::basic::impl::ws_connection_t::init_write
void init_write()
Initiate write operation.
Definition: ws_connection.hpp:1075
restinio::websocket::basic::impl::ws_connection_t::read_state_t::read_any_frame
@ read_any_frame
Reads any type of frame and serve it to user.
restinio::websocket::basic::impl::ws_connection_t::after_read_header
void after_read_header(const asio_ns::error_code &ec, std::size_t length)
Handle read operation result, when reading header.
Definition: ws_connection.hpp:562
restinio::websocket::basic::impl::connection_input_t::reset_parser_and_payload
void reset_parser_and_payload()
Prepare parser for reading new http-message.
Definition: ws_connection.hpp:107
restinio::websocket::basic::impl::ws_connection_t::m_close_frame_to_peer
one_shot_action_t m_close_frame_to_peer
Definition: ws_connection.hpp:1434
restinio::websocket::basic::impl::ws_protocol_validator_t::process_new_frame
validation_state_t process_new_frame(const message_details_t &frame)
Start work with new frame.
Definition: ws_protocol_validator.hpp:211
restinio::websocket::basic::impl::ws_connection_t::call_message_handler
void call_message_handler(message_handle_t close_frame)
Call user message handler with current message.
Definition: ws_connection.hpp:816
restinio::write_group_t
Group of writable items transported to the context of underlying connection as one solid piece.
Definition: buffers.hpp:692
restinio::websocket::basic::impl::ws_connection_t::start_waiting_close_frame_only
void start_waiting_close_frame_only()
Start waiting for close-frame.
Definition: ws_connection.hpp:405
restinio::websocket::basic::impl::connection_input_t::m_parser
ws_parser_t m_parser
websocket parser.
Definition: ws_connection.hpp:97
restinio::websocket::basic::impl::ws_connection_t::validate_payload_part
bool validate_payload_part(char *payload_data, std::size_t length, std::size_t next_length_remaining)
Validates a part of received payload.
Definition: ws_connection.hpp:840
restinio::websocket::basic::impl::ws_connection_t::m_msg_handler
message_handler_t m_msg_handler
Websocket message handler provided by user.
Definition: ws_connection.hpp:1366
restinio
Definition: asio_include.hpp:21
restinio::websocket::basic::impl::ws_connection_t::ws_connection_t
ws_connection_t(ws_connection_t &&)=delete
restinio::websocket::basic::impl::websocket_header_max_size
constexpr size_t websocket_header_max_size()
Max possible size of websocket frame header (a part before payload).
Definition: ws_connection.hpp:46
restinio::websocket::basic::impl::ws_parser_t::reset
void reset()
Reset internal state.
Definition: ws_parser.hpp:294
restinio::websocket::basic::impl::ws_connection_t::read_state_t::read_only_close_frame
@ read_only_close_frame
Reads only close frame: skip all frames until close-frame.
restinio::websocket::basic::impl::ws_connection_t::m_close_frame_to_user
one_shot_action_t m_close_frame_to_user
Definition: ws_connection.hpp:1433
restinio::impl::write_group_output_ctx_t::finish_write_group
void finish_write_group()
Finish writing group normally.
Definition: write_group_output_ctx.hpp:294
restinio::impl::write_group_output_ctx_t::trivial_write_operation_t::get_trivial_bufs
const std::vector< asio_ns::const_buffer > & get_trivial_bufs() const noexcept
Get buffer "iovec" for performing gather write.
Definition: write_group_output_ctx.hpp:127
restinio::websocket::basic::impl::ws_connection_t::m_read_state
read_state_t m_read_state
A state of a websocket input.
Definition: ws_connection.hpp:1404
restinio::websocket::basic::impl::ws_connection_base_t
WebSocket connection base.
Definition: ws_connection_base.hpp:39
restinio::impl::write_group_output_ctx_t::trivial_write_operation_t::size
auto size() const noexcept
The size of data within this operation.
Definition: write_group_output_ctx.hpp:133
restinio::websocket::basic::impl::ws_connection_t::executor_wrapper_base_t
restinio::impl::executor_wrapper_t< typename Traits::strand_t > executor_wrapper_base_t
Definition: ws_connection.hpp:126
restinio::websocket::basic::impl::ws_connection_t::kill
virtual void kill() override
Kill websocket.
Definition: ws_connection.hpp:245
restinio::websocket::basic::impl::connection_input_t::m_buf
restinio::impl::fixed_buffer_t m_buf
Input buffer.
Definition: ws_connection.hpp:100
restinio::websocket::basic::impl::ws_connection_t::send_close_frame_to_peer
void send_close_frame_to_peer(status_code_t code, std::string desc=std::string{})
Send close frame to peer.
Definition: ws_connection.hpp:446
restinio::websocket::basic::status_code_from_bin
status_code_t status_code_from_bin(string_view_t data)
Definition: message.hpp:112
restinio::websocket::basic::impl::message_details_t::m_opcode
opcode_t m_opcode
Opcode.
Definition: ws_parser.hpp:117
restinio::websocket::basic::impl::validation_state_t
validation_state_t
States of validated frame.
Definition: ws_protocol_validator.hpp:29
restinio::tcp_connection_ctx_handle_t
std::shared_ptr< tcp_connection_ctx_base_t > tcp_connection_ctx_handle_t
Alias for http connection handle.
Definition: tcp_connection_ctx_base.hpp:62
restinio::websocket::basic::impl::ws_connection_t::one_shot_action_t::m_not_executed_yet
bool m_not_executed_yet
Definition: ws_connection.hpp:1430
restinio::websocket::basic::impl::ws_connection_t::read_state_t
read_state_t
Websocket input states.
Definition: ws_connection.hpp:1394
restinio::websocket::basic::impl::ws_connection_t::finish_handling_current_write_ctx
void finish_handling_current_write_ctx()
Do post write actions for current write group.
Definition: ws_connection.hpp:1197
restinio::websocket::basic::impl::message_details_t::payload_len
std::uint64_t payload_len() const
Get payload len.
Definition: ws_parser.hpp:92
compiler_features.hpp
Detection of compiler version and absence of various features.
restinio::websocket::basic::impl::ws_connection_t::write_state_t::write_disabled
@ write_disabled
No more outgoing data can be added (e.g. close-frame was sent).
restinio::tcp_connection_ctx_weak_handle_t
std::weak_ptr< tcp_connection_ctx_base_t > tcp_connection_ctx_weak_handle_t
Alias for http connection weak handle.
Definition: tcp_connection_ctx_base.hpp:65
restinio::websocket::basic::impl::ws_connection_t::m_write_operation_timeout_after
std::chrono::steady_clock::time_point m_write_operation_timeout_after
Definition: ws_connection.hpp:1300
restinio::websocket::basic::impl::ws_connection_t::handle_read_error
void handle_read_error(const char *desc, const asio_ns::error_code &ec)
Handle read error (reading header or payload)
Definition: ws_connection.hpp:546
restinio::websocket::basic::impl::ws_connection_t::after_write
void after_write(const asio_ns::error_code &ec)
Handle write response finished.
Definition: ws_connection.hpp:1216
restinio::websocket::basic::status_code_t
status_code_t
Definition: message.hpp:86
restinio::impl::fixed_buffer_t::bytes
const char * bytes() const noexcept
Get pointer to unconsumed bytes.
Definition: fixed_buffer.hpp:69
restinio::websocket::basic::impl::ws_connection_t::guard_close_frame_from_peer_operation
void guard_close_frame_from_peer_operation()
Definition: ws_connection.hpp:1352
restinio::websocket::basic::impl::ws_connection_t::check_timeout_impl
void check_timeout_impl()
Definition: ws_connection.hpp:1307
safe_uint_truncate.hpp
Helpers for safe truncation of unsigned integers.
restinio::websocket::basic::impl::ws_connection_t::trigger_error_and_close
void trigger_error_and_close(status_code_t status, MSG_BUILDER msg_builder) noexcept
Trigger an error.
Definition: ws_connection.hpp:464
restinio::websocket::basic::impl::ws_outgoing_data_t
A queue for outgoing buffers.
Definition: ws_connection.hpp:57
code
Definition: inftrees.h:24
restinio::websocket::basic::impl::validation_state_t::initial_state
@ initial_state
restinio::websocket::basic::impl::connection_input_t::m_payload
std::string m_payload
Current payload.
Definition: ws_connection.hpp:103
restinio::websocket::basic::status_code_t::normal_closure
@ normal_closure
restinio::websocket::basic::impl::ws_connection_t::m_close_frame_from_peer_timeout_after
std::chrono::steady_clock::time_point m_close_frame_from_peer_timeout_after
Definition: ws_connection.hpp:1301
restinio::websocket::basic::status_code_to_bin
std::string status_code_to_bin(status_code_t code)
Definition: message.hpp:101
restinio::websocket::basic::impl::ws_connection_t::call_close_handler_if_necessary
void call_close_handler_if_necessary(status_code_t status)
Definition: ws_connection.hpp:1003
restinio::websocket::basic::impl::ws_connection_t::consume_header_from_socket
void consume_header_from_socket()
Initiate read operation on socket to receive bytes for header.
Definition: ws_connection.hpp:510
restinio::writable_items_container_t
std::vector< writable_item_t > writable_items_container_t
Definition: buffers.hpp:668
all.hpp
restinio::websocket::basic::impl::ws_parser_t::header_parsed
bool header_parsed() const
Check header of current websocket message is parsed.
Definition: ws_parser.hpp:284
restinio::websocket::basic::impl::ws_connection_t::close_impl
void close_impl() noexcept
Standard close routine.
Definition: ws_connection.hpp:371
restinio::websocket::basic::impl::ws_connection_t::m_socket
stream_socket_t m_socket
Connection.
Definition: ws_connection.hpp:1253
restinio::websocket::basic::impl::ws_connection_t::lifetime_monitor_t
typename connection_count_limit_types< Traits >::lifetime_monitor_t lifetime_monitor_t
Definition: ws_connection.hpp:138
restinio::websocket::basic::impl::ws_outgoing_data_t::m_awaiting_write_groups
write_groups_queue_t m_awaiting_write_groups
A queue of buffers.
Definition: ws_connection.hpp:82
restinio::impl::write_group_output_ctx_t::file_write_operation_t
Write operaton using sendfile.
Definition: write_group_output_ctx.hpp:142