WebSocket++  0.8.2
C++ websocket client/server library
endpoint_impl.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_IMPL_HPP
29 #define WEBSOCKETPP_ENDPOINT_IMPL_HPP
30 
31 #include <string>
32 
33 namespace websocketpp {
34 
35 template <typename connection, typename config>
36 typename endpoint<connection,config>::connection_ptr
37 endpoint<connection,config>::create_connection() {
38  m_alog->write(log::alevel::devel,"create_connection");
39  //scoped_lock_type lock(m_state_lock);
40 
41  /*if (m_state == STOPPING || m_state == STOPPED) {
42  return connection_ptr();
43  }*/
44 
45  //scoped_lock_type guard(m_mutex);
46  // Create a connection on the heap and manage it using a shared pointer
47  connection_ptr con = lib::make_shared<connection_type>(m_is_server,
48  m_user_agent, m_alog, m_elog, lib::ref(m_rng));
49 
50  connection_weak_ptr w(con);
51 
52  // Create a weak pointer on the heap using that shared_ptr.
53  // Cast that weak pointer to void* and manage it using another shared_ptr
54  // connection_hdl hdl(reinterpret_cast<void*>(new connection_weak_ptr(con)));
55 
56  con->set_handle(w);
57 
58  // Copy default handlers from the endpoint
59  con->set_open_handler(m_open_handler);
60  con->set_close_handler(m_close_handler);
61  con->set_fail_handler(m_fail_handler);
62  con->set_ping_handler(m_ping_handler);
63  con->set_pong_handler(m_pong_handler);
64  con->set_pong_timeout_handler(m_pong_timeout_handler);
65  con->set_interrupt_handler(m_interrupt_handler);
66  con->set_http_handler(m_http_handler);
67  con->set_validate_handler(m_validate_handler);
68  con->set_message_handler(m_message_handler);
69 
70  if (m_open_handshake_timeout_dur != config::timeout_open_handshake) {
71  con->set_open_handshake_timeout(m_open_handshake_timeout_dur);
72  }
73  if (m_close_handshake_timeout_dur != config::timeout_close_handshake) {
74  con->set_close_handshake_timeout(m_close_handshake_timeout_dur);
75  }
76  if (m_pong_timeout_dur != config::timeout_pong) {
77  con->set_pong_timeout(m_pong_timeout_dur);
78  }
79  if (m_max_message_size != config::max_message_size) {
80  con->set_max_message_size(m_max_message_size);
81  }
82  con->set_max_http_body_size(m_max_http_body_size);
83 
84  lib::error_code ec;
85 
86  ec = transport_type::init(con);
87  if (ec) {
88  m_elog->write(log::elevel::fatal,ec.message());
89  return connection_ptr();
90  }
91 
92  return con;
93 }
94 
95 template <typename connection, typename config>
96 void endpoint<connection,config>::interrupt(connection_hdl hdl, lib::error_code & ec)
97 {
98  connection_ptr con = get_con_from_hdl(hdl,ec);
99  if (ec) {return;}
100 
101  m_alog->write(log::alevel::devel,"Interrupting connection");
102 
103  ec = con->interrupt();
104 }
105 
106 template <typename connection, typename config>
107 void endpoint<connection,config>::interrupt(connection_hdl hdl) {
108  lib::error_code ec;
109  interrupt(hdl,ec);
110  if (ec) { throw exception(ec); }
111 }
112 
113 template <typename connection, typename config>
114 void endpoint<connection,config>::pause_reading(connection_hdl hdl, lib::error_code & ec)
115 {
116  connection_ptr con = get_con_from_hdl(hdl,ec);
117  if (ec) {return;}
118 
119  ec = con->pause_reading();
120 }
121 
122 template <typename connection, typename config>
123 void endpoint<connection,config>::pause_reading(connection_hdl hdl) {
124  lib::error_code ec;
125  pause_reading(hdl,ec);
126  if (ec) { throw exception(ec); }
127 }
128 
129 template <typename connection, typename config>
130 void endpoint<connection,config>::resume_reading(connection_hdl hdl, lib::error_code & ec)
131 {
132  connection_ptr con = get_con_from_hdl(hdl,ec);
133  if (ec) {return;}
134 
135  ec = con->resume_reading();
136 }
137 
138 template <typename connection, typename config>
139 void endpoint<connection,config>::resume_reading(connection_hdl hdl) {
140  lib::error_code ec;
141  resume_reading(hdl,ec);
142  if (ec) { throw exception(ec); }
143 }
144 
145 template <typename connection, typename config>
146 void endpoint<connection,config>::send_http_response(connection_hdl hdl,
147  lib::error_code & ec)
148 {
149  connection_ptr con = get_con_from_hdl(hdl,ec);
150  if (ec) {return;}
151  con->send_http_response(ec);
152 }
153 
154 template <typename connection, typename config>
155 void endpoint<connection,config>::send_http_response(connection_hdl hdl) {
156  lib::error_code ec;
157  send_http_response(hdl,ec);
158  if (ec) { throw exception(ec); }
159 }
160 
161 template <typename connection, typename config>
162 void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
163  frame::opcode::value op, lib::error_code & ec)
164 {
165  connection_ptr con = get_con_from_hdl(hdl,ec);
166  if (ec) {return;}
167 
168  ec = con->send(payload,op);
169 }
170 
171 template <typename connection, typename config>
172 void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
173  frame::opcode::value op)
174 {
175  lib::error_code ec;
176  send(hdl,payload,op,ec);
177  if (ec) { throw exception(ec); }
178 }
179 
180 template <typename connection, typename config>
181 void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
182  size_t len, frame::opcode::value op, lib::error_code & ec)
183 {
184  connection_ptr con = get_con_from_hdl(hdl,ec);
185  if (ec) {return;}
186  ec = con->send(payload,len,op);
187 }
188 
189 template <typename connection, typename config>
190 void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
191  size_t len, frame::opcode::value op)
192 {
193  lib::error_code ec;
194  send(hdl,payload,len,op,ec);
195  if (ec) { throw exception(ec); }
196 }
197 
198 template <typename connection, typename config>
199 void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg,
200  lib::error_code & ec)
201 {
202  connection_ptr con = get_con_from_hdl(hdl,ec);
203  if (ec) {return;}
204  ec = con->send(msg);
205 }
206 
207 template <typename connection, typename config>
208 void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg) {
209  lib::error_code ec;
210  send(hdl,msg,ec);
211  if (ec) { throw exception(ec); }
212 }
213 
214 template <typename connection, typename config>
215 void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
216  const code, std::string const & reason,
217  lib::error_code & ec)
218 {
219  connection_ptr con = get_con_from_hdl(hdl,ec);
220  if (ec) {return;}
221  con->close(code,reason,ec);
222 }
223 
224 template <typename connection, typename config>
225 void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
226  const code, std::string const & reason)
227 {
228  lib::error_code ec;
229  close(hdl,code,reason,ec);
230  if (ec) { throw exception(ec); }
231 }
232 
233 template <typename connection, typename config>
234 void endpoint<connection,config>::ping(connection_hdl hdl, std::string const &
235  payload, lib::error_code & ec)
236 {
237  connection_ptr con = get_con_from_hdl(hdl,ec);
238  if (ec) {return;}
239  con->ping(payload,ec);
240 }
241 
242 template <typename connection, typename config>
243 void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload)
244 {
245  lib::error_code ec;
246  ping(hdl,payload,ec);
247  if (ec) { throw exception(ec); }
248 }
249 
250 template <typename connection, typename config>
251 void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload,
252  lib::error_code & ec)
253 {
254  connection_ptr con = get_con_from_hdl(hdl,ec);
255  if (ec) {return;}
256  con->pong(payload,ec);
257 }
258 
259 template <typename connection, typename config>
260 void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload)
261 {
262  lib::error_code ec;
263  pong(hdl,payload,ec);
264  if (ec) { throw exception(ec); }
265 }
266 
267 } // namespace websocketpp
268 
269 #endif // WEBSOCKETPP_ENDPOINT_IMPL_HPP