28 #ifndef WEBSOCKETPP_CONNECTION_HPP
29 #define WEBSOCKETPP_CONNECTION_HPP
31 #include <websocketpp/close.hpp>
32 #include <websocketpp/error.hpp>
33 #include <websocketpp/frame.hpp>
35 #include <websocketpp/logger/levels.hpp>
36 #include <websocketpp/processors/processor.hpp>
37 #include <websocketpp/transport/base/connection.hpp>
38 #include <websocketpp/http/constants.hpp>
40 #include <websocketpp/common/connection_hdl.hpp>
41 #include <websocketpp/common/cpp11.hpp>
42 #include <websocketpp/common/functional.hpp>
49 namespace websocketpp {
59 typedef lib::function<
void(connection_hdl)> open_handler;
69 typedef lib::function<
void(connection_hdl)> close_handler;
79 typedef lib::function<
void(connection_hdl)> fail_handler;
91 typedef lib::function<
void(connection_hdl)> interrupt_handler;
101 typedef lib::function<
bool(connection_hdl,std::string)> ping_handler;
109 typedef lib::function<
void(connection_hdl,std::string)> pong_handler;
116 typedef lib::function<
void(connection_hdl,std::string)> pong_timeout_handler;
129 typedef lib::function<
bool(connection_hdl)> validate_handler;
151 typedef lib::function<
void(connection_hdl)> http_handler;
154 typedef lib::function<
void(lib::error_code
const & ec, size_t bytes_transferred)> read_handler;
155 typedef lib::function<
void(lib::error_code
const & ec)> write_frame_handler;
158 #ifdef _WEBSOCKETPP_INITIALIZER_LISTS_
164 static std::vector<
int>
const versions_supported = {0,7,8,13};
167 static int const helper[] = {0,7,8,13};
173 static std::vector<
int>
const versions_supported(helper,helper+4);
201 namespace internal_state {
209 READ_HTTP_REQUEST = 2,
210 WRITE_HTTP_REQUEST = 3,
211 READ_HTTP_RESPONSE = 4,
212 WRITE_HTTP_RESPONSE = 5,
213 PROCESS_HTTP_REQUEST = 6,
214 PROCESS_CONNECTION = 7
219 namespace http_state {
234 template <
typename config>
236 :
public config::transport_type::transport_con_type
237 ,
public config::connection_base
241 typedef connection<config> type;
243 typedef lib::shared_ptr<type> ptr;
245 typedef lib::weak_ptr<type> weak_ptr;
248 typedef typename config::concurrency_type concurrency_type;
250 typedef typename config::alog_type alog_type;
252 typedef typename config::elog_type elog_type;
255 typedef typename config::transport_type::transport_con_type
258 typedef typename transport_con_type::ptr transport_con_ptr;
260 typedef lib::function<
void(ptr)> termination_handler;
262 typedef typename concurrency_type::scoped_lock_type scoped_lock_type;
263 typedef typename concurrency_type::mutex_type mutex_type;
265 typedef typename config::request_type request_type;
266 typedef typename config::response_type response_type;
268 typedef typename config::message_type message_type;
269 typedef typename message_type::ptr message_ptr;
271 typedef typename config::con_msg_manager_type con_msg_manager_type;
272 typedef typename con_msg_manager_type::ptr con_msg_manager_ptr;
275 typedef typename config::rng_type rng_type;
277 typedef processor::processor<config> processor_type;
278 typedef lib::shared_ptr<processor_type> processor_ptr;
281 typedef lib::function<
void(connection_hdl,message_ptr)> message_handler;
284 typedef typename transport_con_type::timer_ptr timer_ptr;
287 typedef session::internal_state::value istate_type;
290 enum terminate_status {
297 explicit connection(
bool p_is_server, std::string
const & ua,
const lib::shared_ptr<alog_type>& alog,
298 const lib::shared_ptr<elog_type>& elog, rng_type & rng)
299 : transport_con_type(p_is_server, alog, elog)
300 , m_handle_read_frame(lib::bind(
301 &type::handle_read_frame,
303 lib::placeholders::_1,
304 lib::placeholders::_2
306 , m_write_frame_handler(lib::bind(
307 &type::handle_write_frame,
309 lib::placeholders::_1
312 , m_open_handshake_timeout_dur(config::timeout_open_handshake)
313 , m_close_handshake_timeout_dur(config::timeout_close_handshake)
314 , m_pong_timeout_dur(config::timeout_pong)
315 , m_max_message_size(config::max_message_size)
316 , m_state(session::state::connecting)
317 , m_internal_state(session::internal_state::USER_INIT)
318 , m_msg_manager(
new con_msg_manager_type())
319 , m_send_buffer_size(0)
320 , m_write_flag(
false)
322 , m_is_server(p_is_server)
326 , m_local_close_code(close::status::abnormal_close)
327 , m_remote_close_code(close::status::abnormal_close)
329 , m_http_state(session::http_state::init)
332 m_alog->write(log::alevel::devel,
"connection constructor");
337 return lib::static_pointer_cast<type>(transport_con_type::get_shared());
351 void set_open_handler(open_handler h) {
361 void set_close_handler(close_handler h) {
372 void set_fail_handler(fail_handler h) {
387 void set_ping_handler(ping_handler h) {
398 void set_pong_handler(pong_handler h) {
421 void set_pong_timeout_handler(pong_timeout_handler h) {
422 m_pong_timeout_handler = h;
432 void set_interrupt_handler(interrupt_handler h) {
433 m_interrupt_handler = h;
447 void set_http_handler(http_handler h) {
463 void set_validate_handler(validate_handler h) {
464 m_validate_handler = h;
473 void set_message_handler(message_handler h) {
474 m_message_handler = h;
501 void set_open_handshake_timeout(
long dur) {
502 m_open_handshake_timeout_dur = dur;
525 void set_close_handshake_timeout(
long dur) {
526 m_close_handshake_timeout_dur = dur;
546 void set_pong_timeout(
long dur) {
547 m_pong_timeout_dur = dur;
559 size_t get_max_message_size()
const {
560 return m_max_message_size;
575 void set_max_message_size(size_t new_value) {
576 m_max_message_size = new_value;
578 m_processor->set_max_message_size(new_value);
594 size_t get_max_http_body_size()
const {
595 return m_request.get_max_body_size();
610 void set_max_http_body_size(size_t new_value) {
611 m_request.set_max_body_size(new_value);
629 size_t get_buffered_amount()
const;
635 size_t buffered_amount()
const {
636 return get_buffered_amount();
655 lib::error_code send(std::string
const & payload, frame::opcode::value op =
656 frame::opcode::text);
672 lib::error_code send(
void const * payload, size_t len, frame::opcode::value
673 op = frame::opcode::binary);
688 lib::error_code send(message_ptr msg);
703 lib::error_code interrupt();
706 void handle_interrupt();
728 lib::error_code pause_reading();
731 void handle_pause_reading();
740 lib::error_code resume_reading();
743 void handle_resume_reading();
757 void ping(std::string
const & payload);
760 void ping(std::string
const & payload, lib::error_code & ec);
763 void handle_pong_timeout(std::string payload, lib::error_code
const & ec);
775 void pong(std::string
const & payload);
778 void pong(std::string
const & payload, lib::error_code & ec);
800 void close(close::status::value
const code, std::string
const & reason);
803 void close(close::status::value
const code, std::string
const & reason,
804 lib::error_code & ec);
817 bool get_secure()
const;
826 std::string
const & get_host()
const;
835 std::string
const & get_resource()
const;
844 uint16_t get_port()
const;
853 uri_ptr get_uri()
const;
862 void set_uri(uri_ptr uri);
875 std::string
const & get_subprotocol()
const;
884 std::vector<std::string>
const & get_requested_subprotocols()
const;
899 void add_subprotocol(std::string
const & request, lib::error_code & ec);
912 void add_subprotocol(std::string
const & request);
927 void select_subprotocol(std::string
const & value, lib::error_code & ec);
940 void select_subprotocol(std::string
const & value);
953 std::string
const & get_request_header(std::string
const & key)
const;
964 std::string
const & get_request_body()
const;
973 std::string
const & get_response_header(std::string
const & key)
const;
983 http::status_code::value get_response_code()
const {
984 return m_response.get_status_code();
995 std::string
const & get_response_msg()
const {
996 return m_response.get_status_msg();
1013 void set_status(http::status_code::value code);
1028 void set_status(http::status_code::value code, std::string
const & msg);
1043 void set_body(std::string
const & value);
1059 void append_header(std::string
const & key, std::string
const & val);
1074 void replace_header(std::string
const & key, std::string
const & val);
1086 void remove_header(std::string
const & key);
1102 request_type
const & get_request()
const {
1121 response_type
const & get_response()
const {
1138 lib::error_code defer_http_response();
1150 void send_http_response(lib::error_code & ec);
1153 void send_http_response();
1183 connection_hdl get_handle()
const {
1184 return m_connection_hdl;
1191 bool is_server()
const {
1202 std::string
const & get_origin()
const;
1210 session::state::value get_state()
const;
1217 close::status::value get_local_close_code()
const {
1218 return m_local_close_code;
1225 std::string
const & get_local_close_reason()
const {
1226 return m_local_close_reason;
1233 close::status::value get_remote_close_code()
const {
1234 return m_remote_close_code;
1241 std::string
const & get_remote_close_reason()
const {
1242 return m_remote_close_reason;
1254 lib::error_code get_ec()
const {
1277 message_ptr get_message(websocketpp::frame::opcode::value op, size_t size)
1280 return m_msg_manager->get_message(op, size);
1291 void read_handshake(size_t num_bytes);
1293 void handle_read_handshake(lib::error_code
const & ec,
1294 size_t bytes_transferred);
1295 void handle_read_http_response(lib::error_code
const & ec,
1296 size_t bytes_transferred);
1299 void handle_write_http_response(lib::error_code
const & ec);
1300 void handle_send_http_request(lib::error_code
const & ec);
1302 void handle_open_handshake_timeout(lib::error_code
const & ec);
1303 void handle_close_handshake_timeout(lib::error_code
const & ec);
1305 void handle_read_frame(lib::error_code
const & ec, size_t bytes_transferred);
1309 std::vector<
int>
const & get_supported_versions()
const;
1313 void set_termination_handler(termination_handler new_handler);
1315 void terminate(lib::error_code
const & ec);
1316 void handle_terminate(terminate_status tstat, lib::error_code
const & ec);
1338 void handle_write_frame(lib::error_code
const & ec);
1356 void set_handle(connection_hdl hdl) {
1357 m_connection_hdl = hdl;
1358 transport_con_type::set_handle(hdl);
1361 void handle_transport_init(lib::error_code
const & ec);
1365 lib::error_code initialize_processor();
1369 lib::error_code process_handshake_request();
1374 void write_http_response(lib::error_code
const & ec);
1377 void send_http_request();
1380 void write_http_response_error(lib::error_code
const & ec);
1386 void process_control_frame(message_ptr msg);
1399 lib::error_code send_close_ack(close::status::value code =
1400 close::status::blank, std::string
const & reason = std::string());
1417 lib::error_code send_close_frame(close::status::value code =
1418 close::status::blank, std::string
const & reason = std::string(),
bool ack =
false,
1419 bool terminal =
false);
1431 processor_ptr get_processor(
int version)
const;
1443 void write_push(message_ptr msg);
1456 message_ptr write_pop();
1464 void log_open_result();
1470 void log_close_result();
1476 void log_fail_result();
1482 void log_http_result();
1485 template <
typename error_type>
1486 void log_err(log::level l,
char const * msg, error_type
const & ec) {
1487 std::stringstream s;
1488 s << msg <<
" error: " << ec <<
" (" << ec.message() <<
")";
1489 m_elog->write(l, s.str());
1493 read_handler m_handle_read_frame;
1494 write_frame_handler m_write_frame_handler;
1497 std::string
const m_user_agent;
1500 connection_hdl m_connection_hdl;
1503 open_handler m_open_handler;
1504 close_handler m_close_handler;
1505 fail_handler m_fail_handler;
1506 ping_handler m_ping_handler;
1507 pong_handler m_pong_handler;
1508 pong_timeout_handler m_pong_timeout_handler;
1509 interrupt_handler m_interrupt_handler;
1510 http_handler m_http_handler;
1511 validate_handler m_validate_handler;
1512 message_handler m_message_handler;
1515 long m_open_handshake_timeout_dur;
1516 long m_close_handshake_timeout_dur;
1517 long m_pong_timeout_dur;
1518 size_t m_max_message_size;
1524 session::state::value m_state;
1530 istate_type m_internal_state;
1532 mutable mutex_type m_connection_state_lock;
1539 mutex_type m_write_lock;
1542 char m_buf[config::connection_read_buffer_size];
1543 size_t m_buf_cursor;
1544 termination_handler m_termination_handler;
1545 con_msg_manager_ptr m_msg_manager;
1546 timer_ptr m_handshake_timer;
1547 timer_ptr m_ping_timer;
1551 std::string m_handshake_buffer;
1562 processor_ptr m_processor;
1568 std::queue<message_ptr> m_send_queue;
1574 size_t m_send_buffer_size;
1580 std::vector<transport::buffer> m_send_buffer;
1584 std::vector<message_ptr> m_current_msgs;
1596 request_type m_request;
1597 response_type m_response;
1599 std::string m_subprotocol;
1603 std::vector<std::string> m_requested_subprotocols;
1605 bool const m_is_server;
1606 const lib::shared_ptr<alog_type> m_alog;
1607 const lib::shared_ptr<elog_type> m_elog;
1613 close::status::value m_local_close_code;
1616 std::string m_local_close_reason;
1619 close::status::value m_remote_close_code;
1622 std::string m_remote_close_reason;
1625 lib::error_code m_ec;
1633 session::http_state::value m_http_state;
1640 #include <websocketpp/impl/connection_impl.hpp>