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
create_connection()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, lib::ref(m_alog), lib::ref(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>
interrupt(connection_hdl hdl,lib::error_code & ec)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>
interrupt(connection_hdl hdl)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>
pause_reading(connection_hdl hdl,lib::error_code & ec)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>
pause_reading(connection_hdl hdl)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>
resume_reading(connection_hdl hdl,lib::error_code & ec)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>
resume_reading(connection_hdl hdl)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 
146 
147 template <typename connection, typename config>
send(connection_hdl hdl,std::string const & payload,frame::opcode::value op,lib::error_code & ec)148 void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
149     frame::opcode::value op, lib::error_code & ec)
150 {
151     connection_ptr con = get_con_from_hdl(hdl,ec);
152     if (ec) {return;}
153 
154     ec = con->send(payload,op);
155 }
156 
157 template <typename connection, typename config>
send(connection_hdl hdl,std::string const & payload,frame::opcode::value op)158 void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
159     frame::opcode::value op)
160 {
161     lib::error_code ec;
162     send(hdl,payload,op,ec);
163     if (ec) { throw exception(ec); }
164 }
165 
166 template <typename connection, typename config>
send(connection_hdl hdl,void const * payload,size_t len,frame::opcode::value op,lib::error_code & ec)167 void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
168     size_t len, frame::opcode::value op, lib::error_code & ec)
169 {
170     connection_ptr con = get_con_from_hdl(hdl,ec);
171     if (ec) {return;}
172     ec = con->send(payload,len,op);
173 }
174 
175 template <typename connection, typename config>
send(connection_hdl hdl,void const * payload,size_t len,frame::opcode::value op)176 void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
177     size_t len, frame::opcode::value op)
178 {
179     lib::error_code ec;
180     send(hdl,payload,len,op,ec);
181     if (ec) { throw exception(ec); }
182 }
183 
184 template <typename connection, typename config>
send(connection_hdl hdl,message_ptr msg,lib::error_code & ec)185 void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg,
186     lib::error_code & ec)
187 {
188     connection_ptr con = get_con_from_hdl(hdl,ec);
189     if (ec) {return;}
190     ec = con->send(msg);
191 }
192 
193 template <typename connection, typename config>
send(connection_hdl hdl,message_ptr msg)194 void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg) {
195     lib::error_code ec;
196     send(hdl,msg,ec);
197     if (ec) { throw exception(ec); }
198 }
199 
200 template <typename connection, typename config>
close(connection_hdl hdl,close::status::value const code,std::string const & reason,lib::error_code & ec)201 void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
202     const code, std::string const & reason,
203     lib::error_code & ec)
204 {
205     connection_ptr con = get_con_from_hdl(hdl,ec);
206     if (ec) {return;}
207     con->close(code,reason,ec);
208 }
209 
210 template <typename connection, typename config>
close(connection_hdl hdl,close::status::value const code,std::string const & reason)211 void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
212     const code, std::string const & reason)
213 {
214     lib::error_code ec;
215     close(hdl,code,reason,ec);
216     if (ec) { throw exception(ec); }
217 }
218 
219 template <typename connection, typename config>
ping(connection_hdl hdl,std::string const & payload,lib::error_code & ec)220 void endpoint<connection,config>::ping(connection_hdl hdl, std::string const &
221     payload, lib::error_code & ec)
222 {
223     connection_ptr con = get_con_from_hdl(hdl,ec);
224     if (ec) {return;}
225     con->ping(payload,ec);
226 }
227 
228 template <typename connection, typename config>
ping(connection_hdl hdl,std::string const & payload)229 void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload)
230 {
231     lib::error_code ec;
232     ping(hdl,payload,ec);
233     if (ec) { throw exception(ec); }
234 }
235 
236 template <typename connection, typename config>
pong(connection_hdl hdl,std::string const & payload,lib::error_code & ec)237 void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload,
238     lib::error_code & ec)
239 {
240     connection_ptr con = get_con_from_hdl(hdl,ec);
241     if (ec) {return;}
242     con->pong(payload,ec);
243 }
244 
245 template <typename connection, typename config>
pong(connection_hdl hdl,std::string const & payload)246 void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload)
247 {
248     lib::error_code ec;
249     pong(hdl,payload,ec);
250     if (ec) { throw exception(ec); }
251 }
252 
253 } // namespace websocketpp
254 
255 #endif // WEBSOCKETPP_ENDPOINT_IMPL_HPP
256