websocketpp  0.6.0
C++/Boost Asio based websocket client/server library
endpoint.hpp
1 /*
2  * Copyright (c) 2014, Peter Thorson. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright
7  * notice, this list of conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution.
11  * * Neither the name of the WebSocket++ Project nor the
12  * names of its contributors may be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 
28 #ifndef WEBSOCKETPP_ENDPOINT_HPP
29 #define WEBSOCKETPP_ENDPOINT_HPP
30 
31 #include <websocketpp/connection.hpp>
32 
33 #include <websocketpp/logger/levels.hpp>
34 #include <websocketpp/version.hpp>
35 
36 #include <string>
37 
38 namespace websocketpp {
39 
41 template <typename connection, typename config>
42 class endpoint : public config::transport_type, public config::endpoint_base {
43 public:
44  // Import appropriate types from our helper class
45  // See endpoint_types for more details.
47 
49  typedef typename config::transport_type transport_type;
51  typedef typename config::concurrency_type concurrency_type;
52 
59 
62  typedef typename transport_type::transport_con_type transport_con_type;
65  typedef typename transport_con_type::ptr transport_con_ptr;
66 
68  typedef typename connection_type::message_handler message_handler;
70  typedef typename connection_type::message_ptr message_ptr;
71 
73  typedef typename config::elog_type elog_type;
75  typedef typename config::alog_type alog_type;
76 
78  typedef typename concurrency_type::scoped_lock_type scoped_lock_type;
80  typedef typename concurrency_type::mutex_type mutex_type;
81 
83  typedef typename config::rng_type rng_type;
84 
85  // TODO: organize these
86  typedef typename connection_type::termination_handler termination_handler;
87 
88  explicit endpoint(bool p_is_server)
89  : m_alog(config::alog_level, log::channel_type_hint::access)
90  , m_elog(config::elog_level, log::channel_type_hint::error)
91  , m_user_agent(::websocketpp::user_agent)
92  , m_open_handshake_timeout_dur(config::timeout_open_handshake)
93  , m_close_handshake_timeout_dur(config::timeout_close_handshake)
94  , m_pong_timeout_dur(config::timeout_pong)
95  , m_max_message_size(config::max_message_size)
96  , m_max_http_body_size(config::max_http_body_size)
97  , m_is_server(p_is_server)
98  {
99  m_alog.set_channels(config::alog_level);
100  m_elog.set_channels(config::elog_level);
101 
102  m_alog.write(log::alevel::devel, "endpoint constructor");
103 
104  transport_type::init_logging(&m_alog, &m_elog);
105  }
106 
107 
110 
111  #ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
112  // no copy constructor because endpoints are not copyable
113  endpoint(endpoint &) = delete;
114 
115  // no copy assignment operator because endpoints are not copyable
116  endpoint & operator=(endpoint const &) = delete;
117  #endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
118 
119  #ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
120  endpoint(endpoint && o)
122  : config::transport_type(std::move(o))
123  , config::endpoint_base(std::move(o))
124  , m_alog(std::move(o.m_alog))
125  , m_elog(std::move(o.m_elog))
126  , m_user_agent(std::move(o.m_user_agent))
127  , m_open_handler(std::move(o.m_open_handler))
128 
129  , m_close_handler(std::move(o.m_close_handler))
130  , m_fail_handler(std::move(o.m_fail_handler))
131  , m_ping_handler(std::move(o.m_ping_handler))
132  , m_pong_handler(std::move(o.m_pong_handler))
133  , m_pong_timeout_handler(std::move(o.m_pong_timeout_handler))
134  , m_interrupt_handler(std::move(o.m_interrupt_handler))
135  , m_http_handler(std::move(o.m_http_handler))
136  , m_validate_handler(std::move(o.m_validate_handler))
137  , m_message_handler(std::move(o.m_message_handler))
138 
139  , m_open_handshake_timeout_dur(o.m_open_handshake_timeout_dur)
140  , m_close_handshake_timeout_dur(o.m_close_handshake_timeout_dur)
141  , m_pong_timeout_dur(o.m_pong_timeout_dur)
142  , m_max_message_size(o.m_max_message_size)
143  , m_max_http_body_size(o.m_max_http_body_size)
144 
145  , m_rng(std::move(o.m_rng))
146  , m_is_server(o.m_is_server)
147  {}
148 
149  #ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
150  // no move assignment operator because of const member variables
151  endpoint & operator=(endpoint &&) = delete;
152  #endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
153 
154  #endif // _WEBSOCKETPP_MOVE_SEMANTICS_
155 
156 
158 
166  std::string get_user_agent() const {
167  scoped_lock_type guard(m_mutex);
168  return m_user_agent;
169  }
170 
172 
193  void set_user_agent(std::string const & ua) {
194  scoped_lock_type guard(m_mutex);
195  m_user_agent = ua;
196  }
197 
199 
202  bool is_server() const {
203  return m_is_server;
204  }
205 
206  /********************************/
207  /* Pass-through logging adaptor */
208  /********************************/
209 
211 
217  void set_access_channels(log::level channels) {
218  m_alog.set_channels(channels);
219  }
220 
222 
228  void clear_access_channels(log::level channels) {
229  m_alog.clear_channels(channels);
230  }
231 
233 
239  void set_error_channels(log::level channels) {
240  m_elog.set_channels(channels);
241  }
242 
244 
250  void clear_error_channels(log::level channels) {
251  m_elog.clear_channels(channels);
252  }
253 
255 
258  alog_type & get_alog() {
259  return m_alog;
260  }
261 
263 
266  elog_type & get_elog() {
267  return m_elog;
268  }
269 
270  /*************************/
271  /* Set Handler functions */
272  /*************************/
273 
274  void set_open_handler(open_handler h) {
275  m_alog.write(log::alevel::devel,"set_open_handler");
276  scoped_lock_type guard(m_mutex);
277  m_open_handler = h;
278  }
279  void set_close_handler(close_handler h) {
280  m_alog.write(log::alevel::devel,"set_close_handler");
281  scoped_lock_type guard(m_mutex);
282  m_close_handler = h;
283  }
284  void set_fail_handler(fail_handler h) {
285  m_alog.write(log::alevel::devel,"set_fail_handler");
286  scoped_lock_type guard(m_mutex);
287  m_fail_handler = h;
288  }
289  void set_ping_handler(ping_handler h) {
290  m_alog.write(log::alevel::devel,"set_ping_handler");
291  scoped_lock_type guard(m_mutex);
292  m_ping_handler = h;
293  }
294  void set_pong_handler(pong_handler h) {
295  m_alog.write(log::alevel::devel,"set_pong_handler");
296  scoped_lock_type guard(m_mutex);
297  m_pong_handler = h;
298  }
299  void set_pong_timeout_handler(pong_timeout_handler h) {
300  m_alog.write(log::alevel::devel,"set_pong_timeout_handler");
301  scoped_lock_type guard(m_mutex);
302  m_pong_timeout_handler = h;
303  }
304  void set_interrupt_handler(interrupt_handler h) {
305  m_alog.write(log::alevel::devel,"set_interrupt_handler");
306  scoped_lock_type guard(m_mutex);
307  m_interrupt_handler = h;
308  }
309  void set_http_handler(http_handler h) {
310  m_alog.write(log::alevel::devel,"set_http_handler");
311  scoped_lock_type guard(m_mutex);
312  m_http_handler = h;
313  }
314  void set_validate_handler(validate_handler h) {
315  m_alog.write(log::alevel::devel,"set_validate_handler");
316  scoped_lock_type guard(m_mutex);
317  m_validate_handler = h;
318  }
319  void set_message_handler(message_handler h) {
320  m_alog.write(log::alevel::devel,"set_message_handler");
321  scoped_lock_type guard(m_mutex);
322  m_message_handler = h;
323  }
324 
326  // Connection timeouts and other limits //
328 
330 
349  void set_open_handshake_timeout(long dur) {
350  scoped_lock_type guard(m_mutex);
351  m_open_handshake_timeout_dur = dur;
352  }
353 
355 
375  scoped_lock_type guard(m_mutex);
376  m_close_handshake_timeout_dur = dur;
377  }
378 
380 
396  void set_pong_timeout(long dur) {
397  scoped_lock_type guard(m_mutex);
398  m_pong_timeout_dur = dur;
399  }
400 
402 
412  size_t get_max_message_size() const {
413  return m_max_message_size;
414  }
415 
417 
429  void set_max_message_size(size_t new_value) {
430  m_max_message_size = new_value;
431  }
432 
434 
446  size_t get_max_http_body_size() const {
447  return m_max_http_body_size;
448  }
449 
451 
463  void set_max_http_body_size(size_t new_value) {
464  m_max_http_body_size = new_value;
465  }
466 
467  /*************************************/
468  /* Connection pass through functions */
469  /*************************************/
470 
479  void interrupt(connection_hdl hdl, lib::error_code & ec);
480  void interrupt(connection_hdl hdl);
481 
483 
502  void pause_reading(connection_hdl hdl, lib::error_code & ec);
503 
505  void pause_reading(connection_hdl hdl);
506 
508 
514  void resume_reading(connection_hdl hdl, lib::error_code & ec);
515 
517  void resume_reading(connection_hdl hdl);
518 
520 
532  void send_http_response(connection_hdl hdl, lib::error_code & ec);
533 
535 
547 
549 
557  void send(connection_hdl hdl, std::string const & payload,
558  frame::opcode::value op, lib::error_code & ec);
560 
568  void send(connection_hdl hdl, std::string const & payload,
569  frame::opcode::value op);
570 
571  void send(connection_hdl hdl, void const * payload, size_t len,
572  frame::opcode::value op, lib::error_code & ec);
573  void send(connection_hdl hdl, void const * payload, size_t len,
574  frame::opcode::value op);
575 
576  void send(connection_hdl hdl, message_ptr msg, lib::error_code & ec);
577  void send(connection_hdl hdl, message_ptr msg);
578 
579  void close(connection_hdl hdl, close::status::value const code,
580  std::string const & reason, lib::error_code & ec);
581  void close(connection_hdl hdl, close::status::value const code,
582  std::string const & reason);
583 
585 
592  void ping(connection_hdl hdl, std::string const & payload,
593  lib::error_code & ec);
595 
603  void ping(connection_hdl hdl, std::string const & payload);
604 
606 
613  void pong(connection_hdl hdl, std::string const & payload,
614  lib::error_code & ec);
616 
624  void pong(connection_hdl hdl, std::string const & payload);
625 
627 
640  connection_ptr get_con_from_hdl(connection_hdl hdl, lib::error_code & ec) {
641  connection_ptr con = lib::static_pointer_cast<connection_type>(
642  hdl.lock());
643  if (!con) {
644  ec = error::make_error_code(error::bad_connection);
645  }
646  return con;
647  }
648 
650  connection_ptr get_con_from_hdl(connection_hdl hdl) {
651  lib::error_code ec;
652  connection_ptr con = this->get_con_from_hdl(hdl,ec);
653  if (ec) {
654  throw exception(ec);
655  }
656  return con;
657  }
658 protected:
659  connection_ptr create_connection();
660 
661  alog_type m_alog;
662  elog_type m_elog;
663 private:
664  // dynamic settings
665  std::string m_user_agent;
666 
667  open_handler m_open_handler;
668  close_handler m_close_handler;
669  fail_handler m_fail_handler;
670  ping_handler m_ping_handler;
671  pong_handler m_pong_handler;
672  pong_timeout_handler m_pong_timeout_handler;
673  interrupt_handler m_interrupt_handler;
674  http_handler m_http_handler;
675  validate_handler m_validate_handler;
676  message_handler m_message_handler;
677 
678  long m_open_handshake_timeout_dur;
679  long m_close_handshake_timeout_dur;
680  long m_pong_timeout_dur;
681  size_t m_max_message_size;
682  size_t m_max_http_body_size;
683 
684  rng_type m_rng;
685 
686  // static settings
687  bool const m_is_server;
688 
689  // endpoint state
690  mutable mutex_type m_mutex;
691 };
692 
693 } // namespace websocketpp
694 
695 #include <websocketpp/impl/endpoint_impl.hpp>
696 
697 #endif // WEBSOCKETPP_ENDPOINT_HPP
void send_http_response(connection_hdl hdl, lib::error_code &ec)
Send deferred HTTP Response.
config::concurrency_type concurrency_type
Type of the concurrency component of this endpoint.
Definition: endpoint.hpp:51
uint16_t value
The type of a close code value.
Definition: close.hpp:49
size_t get_max_message_size() const
Get default maximum message size.
Definition: endpoint.hpp:412
bool is_server() const
Returns whether or not this endpoint is a server.
Definition: endpoint.hpp:202
lib::function< void(connection_hdl)> close_handler
The type and function signature of a close handler.
Definition: connection.hpp:69
lib::function< void(connection_hdl)> open_handler
The type and function signature of an open handler.
Definition: connection.hpp:59
void ping(connection_hdl hdl, std::string const &payload, lib::error_code &ec)
Send a ping to a specific connection.
lib::function< void(connection_hdl, std::string)> pong_timeout_handler
The type and function signature of a pong timeout handler.
Definition: connection.hpp:116
lib::function< void(connection_hdl)> interrupt_handler
The type and function signature of an interrupt handler.
Definition: connection.hpp:91
config::rng_type rng_type
Type of RNG.
Definition: endpoint.hpp:83
lib::function< bool(connection_hdl, std::string)> ping_handler
The type and function signature of a ping handler.
Definition: connection.hpp:101
void set_close_handshake_timeout(long dur)
Set close handshake timeout.
Definition: endpoint.hpp:374
lib::weak_ptr< type > weak_ptr
Type of a weak pointer to this connection.
Definition: connection.hpp:245
Represents an individual WebSocket connection.
Definition: connection.hpp:235
connection_type::message_ptr message_ptr
Type of message pointers that this endpoint uses.
Definition: endpoint.hpp:70
void interrupt(connection_hdl hdl, lib::error_code &ec)
connection_type::message_handler message_handler
Type of message_handler.
Definition: endpoint.hpp:68
STL namespace.
void set_open_handshake_timeout(long dur)
Set open handshake timeout.
Definition: endpoint.hpp:349
lib::weak_ptr< void > connection_hdl
A handle to uniquely identify a connection.
transport_con_type::ptr transport_con_ptr
Definition: endpoint.hpp:65
alog_type & get_alog()
Get reference to access logger.
Definition: endpoint.hpp:258
static char const user_agent[]
Default user agent string.
Definition: version.hpp:56
connection_ptr get_con_from_hdl(connection_hdl hdl, lib::error_code &ec)
Retrieves a connection_ptr from a connection_hdl (exception free)
Definition: endpoint.hpp:640
concurrency_type::scoped_lock_type scoped_lock_type
Type of our concurrency policy's scoped lock object.
Definition: endpoint.hpp:78
void pause_reading(connection_hdl hdl, lib::error_code &ec)
Pause reading of new data (exception free)
std::string get_user_agent() const
Returns the user agent string that this endpoint will use.
Definition: endpoint.hpp:166
static level const devel
Development messages (warning: very chatty)
Definition: levels.hpp:141
concurrency_type::mutex_type mutex_type
Type of our concurrency policy's mutex object.
Definition: endpoint.hpp:80
void resume_reading(connection_hdl hdl, lib::error_code &ec)
Resume reading of new data (exception free)
lib::function< bool(connection_hdl)> validate_handler
The type and function signature of a validate handler.
Definition: connection.hpp:129
void set_max_http_body_size(size_t new_value)
Set maximum HTTP message body size.
Definition: endpoint.hpp:463
void set_max_message_size(size_t new_value)
Set default maximum message size.
Definition: endpoint.hpp:429
transport_type::transport_con_type transport_con_type
Definition: endpoint.hpp:62
config::alog_type alog_type
Type of access logger.
Definition: endpoint.hpp:75
size_t get_max_http_body_size() const
Get maximum HTTP message body size.
Definition: endpoint.hpp:446
config::transport_type transport_type
Type of the transport component of this endpoint.
Definition: endpoint.hpp:49
connection_type::ptr connection_ptr
Shared pointer to connection_type.
Definition: endpoint.hpp:56
Stub for user supplied base class.
lib::function< void(connection_hdl)> http_handler
The type and function signature of a http handler.
Definition: connection.hpp:151
void pong(connection_hdl hdl, std::string const &payload, lib::error_code &ec)
Send a pong to a specific connection.
void clear_error_channels(log::level channels)
Clear Error logging channels.
Definition: endpoint.hpp:250
void set_access_channels(log::level channels)
Set Access logging channel.
Definition: endpoint.hpp:217
Namespace for the WebSocket++ project.
Definition: base64.hpp:41
elog_type & get_elog()
Get reference to error logger.
Definition: endpoint.hpp:266
config::elog_type elog_type
Type of error logger.
Definition: endpoint.hpp:73
Creates and manages connections associated with a WebSocket endpoint.
Definition: endpoint.hpp:42
connection_type::weak_ptr connection_weak_ptr
Weak pointer to connection type.
Definition: endpoint.hpp:58
lib::shared_ptr< type > ptr
Type of a shared pointer to this connection.
Definition: connection.hpp:243
connection connection_type
Type of the connections that this endpoint creates.
Definition: endpoint.hpp:54
void clear_access_channels(log::level channels)
Clear Access logging channels.
Definition: endpoint.hpp:228
void set_error_channels(log::level channels)
Set Error logging channel.
Definition: endpoint.hpp:239
void set_pong_timeout(long dur)
Set pong timeout.
Definition: endpoint.hpp:396
lib::function< void(connection_hdl, std::string)> pong_handler
The type and function signature of a pong handler.
Definition: connection.hpp:109
connection_ptr get_con_from_hdl(connection_hdl hdl)
Retrieves a connection_ptr from a connection_hdl (exception version)
Definition: endpoint.hpp:650
void set_user_agent(std::string const &ua)
Sets the user agent string that this endpoint will use.
Definition: endpoint.hpp:193
void send(connection_hdl hdl, std::string const &payload, frame::opcode::value op, lib::error_code &ec)
Create a message and add it to the outgoing send queue (exception free)
lib::function< void(connection_hdl)> fail_handler
The type and function signature of a fail handler.
Definition: connection.hpp:79