28 #ifndef WEBSOCKETPP_CONNECTION_IMPL_HPP 29 #define WEBSOCKETPP_CONNECTION_IMPL_HPP 50 namespace istate = session::internal_state;
52 template <
typename config>
57 "connection set_termination_handler");
61 m_termination_handler = new_handler;
64 template <
typename config>
67 return m_processor->get_origin(m_request);
70 template <
typename config>
73 return m_send_buffer_size;
76 template <
typename config>
82 template <
typename config>
86 message_ptr msg = m_msg_manager->get_message(op,payload.size());
87 msg->append_payload(payload);
88 msg->set_compressed(
true);
93 template <
typename config>
97 message_ptr msg = m_msg_manager->get_message(op,len);
98 msg->append_payload(payload,len);
103 template <
typename config>
118 bool needs_writing =
false;
120 if (msg->get_prepared()) {
124 write_push(outgoing_msg);
125 needs_writing = !m_write_flag && !m_send_queue.empty();
127 outgoing_msg = m_msg_manager->get_message();
134 lib::error_code ec = m_processor->prepare_data_frame(msg,outgoing_msg);
140 write_push(outgoing_msg);
141 needs_writing = !m_write_flag && !m_send_queue.empty();
145 transport_con_type::dispatch(lib::bind(
151 return lib::error_code();
154 template <
typename config>
163 std::stringstream ss;
164 ss <<
"connection::ping called from invalid state " << m_state;
177 ec = m_processor->prepare_ping(payload,msg);
181 if (m_pong_timeout_handler) {
184 m_ping_timer->cancel();
187 if (m_pong_timeout_dur > 0) {
188 m_ping_timer = transport_con_type::set_timer(
191 &type::handle_pong_timeout,
194 lib::placeholders::_1
202 set but the transport in use does not support timeouts.");
206 bool needs_writing =
false;
210 needs_writing = !m_write_flag && !m_send_queue.empty();
214 transport_con_type::dispatch(lib::bind(
220 ec = lib::error_code();
223 template<
typename config>
232 template<
typename config>
234 lib::error_code
const & ec)
246 if (m_pong_timeout_handler) {
247 m_pong_timeout_handler(m_connection_hdl,payload);
251 template <
typename config>
260 std::stringstream ss;
261 ss <<
"connection::pong called from invalid state " << m_state;
274 ec = m_processor->prepare_pong(payload,msg);
277 bool needs_writing =
false;
281 needs_writing = !m_write_flag && !m_send_queue.empty();
285 transport_con_type::dispatch(lib::bind(
291 ec = lib::error_code();
294 template<
typename config>
303 template <
typename config>
305 std::string
const & reason, lib::error_code & ec)
312 std::string tr(reason,0,std::min<size_t>(reason.size(),
325 template<
typename config>
327 std::string
const & reason)
330 close(code,reason,ec);
340 template <
typename config>
343 return transport_con_type::interrupt(
345 &type::handle_interrupt,
352 template <
typename config>
354 if (m_interrupt_handler) {
355 m_interrupt_handler(m_connection_hdl);
359 template <
typename config>
362 return transport_con_type::dispatch(
364 &type::handle_pause_reading,
371 template <
typename config>
377 template <
typename config>
380 return transport_con_type::dispatch(
382 &type::handle_resume_reading,
389 template <
typename config>
405 template <
typename config>
408 return m_uri->get_secure();
411 template <
typename config>
414 return m_uri->get_host();
417 template <
typename config>
420 return m_uri->get_resource();
423 template <
typename config>
426 return m_uri->get_port();
429 template <
typename config>
435 template <
typename config>
446 template <
typename config>
448 return m_subprotocol;
451 template <
typename config>
452 std::vector<std::string>
const &
454 return m_requested_subprotocols;
457 template <
typename config>
459 lib::error_code & ec)
467 if (value.empty() || std::find_if(value.begin(),value.end(),
474 m_requested_subprotocols.push_back(value);
477 template <
typename config>
480 this->add_subprotocol(value,ec);
487 template <
typename config>
489 lib::error_code & ec)
497 ec = lib::error_code();
503 it = std::find(m_requested_subprotocols.begin(),
504 m_requested_subprotocols.end(),
507 if (it == m_requested_subprotocols.end()) {
512 m_subprotocol =
value;
515 template <
typename config>
518 this->select_subprotocol(value,ec);
525 template <
typename config>
528 return m_request.get_header(key);
531 template <
typename config>
534 return m_request.get_body();
537 template <
typename config>
540 return m_response.get_header(key);
544 template <
typename config>
548 throw exception(
"Call to set_status from invalid state",
551 m_response.set_status(code);
555 template <
typename config>
557 std::string
const & msg)
560 throw exception(
"Call to set_status from invalid state",
564 m_response.set_status(code,msg);
568 template <
typename config>
571 throw exception(
"Call to set_status from invalid state",
575 m_response.set_body(value);
579 template <
typename config>
581 std::string
const & val)
586 m_response.append_header(key,val);
588 throw exception(
"Call to append_header from invalid state",
594 m_request.append_header(key,val);
596 throw exception(
"Call to append_header from invalid state",
603 template <
typename config>
605 std::string
const & val)
610 m_response.replace_header(key,val);
612 throw exception(
"Call to replace_header from invalid state",
618 m_request.replace_header(key,val);
620 throw exception(
"Call to replace_header from invalid state",
627 template <
typename config>
633 m_response.remove_header(key);
635 throw exception(
"Call to remove_header from invalid state",
641 m_request.remove_header(key);
643 throw exception(
"Call to remove_header from invalid state",
660 template <
typename config>
664 if (m_handshake_timer) {
665 m_handshake_timer->cancel();
666 m_handshake_timer.reset();
672 return lib::error_code();
685 template <
typename config>
697 this->write_http_response(lib::error_code());
698 ec = lib::error_code();
701 template <
typename config>
704 this->send_http_response(ec);
715 template <
typename config>
732 &type::handle_transport_init,
734 lib::placeholders::_1
739 template <
typename config>
743 lib::error_code ecm = ec;
747 "handle_transport_init must be called from transport init state");
753 s <<
"handle_transport_init received error: "<< ecm.message();
756 this->terminate(ecm);
763 this->read_handshake(1);
769 this->send_http_request();
773 template <
typename config>
777 if (m_open_handshake_timeout_dur > 0) {
778 m_handshake_timer = transport_con_type::set_timer(
779 m_open_handshake_timeout_dur,
781 &type::handle_open_handshake_timeout,
783 lib::placeholders::_1
788 transport_con_type::async_read_at_least(
793 &type::handle_read_handshake,
795 lib::placeholders::_1,
796 lib::placeholders::_2
803 template <
typename config>
805 size_t bytes_transferred)
809 lib::error_code ecm = ec;
823 "handle_read_handshake invoked after connection was closed");
834 "got (expected) eof/state error from closed con");
839 this->terminate(ecm);
850 size_t bytes_processed = 0;
852 bytes_processed = m_request.consume(m_buf,bytes_transferred);
863 if (bytes_processed > bytes_transferred) {
871 s <<
"bytes_transferred: " << bytes_transferred
872 <<
" bytes, bytes processed: " << bytes_processed <<
" bytes";
876 if (m_request.ready()) {
877 lib::error_code processor_ec = this->initialize_processor();
879 this->write_http_response_error(processor_ec);
883 if (m_processor && m_processor->get_version() == 0) {
886 if (bytes_transferred-bytes_processed >= 8) {
887 m_request.replace_header(
888 "Sec-WebSocket-Key3",
889 std::string(m_buf+bytes_processed,m_buf+bytes_processed+8)
891 bytes_processed += 8;
903 if (!m_request.get_header(
"Sec-WebSocket-Key3").empty()) {
912 std::copy(m_buf+bytes_processed,m_buf+bytes_transferred,m_buf);
913 m_buf_cursor = bytes_transferred-bytes_processed;
919 lib::error_code handshake_ec = this->process_handshake_request();
925 this->write_http_response(handshake_ec);
929 transport_con_type::async_read_at_least(
934 &type::handle_read_handshake,
936 lib::placeholders::_1,
937 lib::placeholders::_2
948 template <
typename config>
952 "write_http_response_error called in invalid state");
959 this->write_http_response(ec);
964 template <
typename config>
966 size_t bytes_transferred)
970 lib::error_code ecm = ec;
989 terminate(lib::error_code());
999 "handle_read_frame: got invalid istate in closed state");
1007 terminate(lib::error_code());
1015 log_err(echannel,
"handle_read_frame", ecm);
1016 this->terminate(ecm);
1030 std::stringstream s;
1031 s <<
"p = " << p <<
" bytes transferred = " << bytes_transferred;
1035 while (p < bytes_transferred) {
1037 std::stringstream s;
1038 s <<
"calling consume with " << bytes_transferred-p <<
" bytes";
1042 lib::error_code consume_ec;
1045 std::stringstream s;
1046 s <<
"Processing Bytes: " <<
utility::to_hex(reinterpret_cast<uint8_t*>(m_buf)+p,bytes_transferred-p);
1050 p += m_processor->consume(
1051 reinterpret_cast<uint8_t*>(m_buf)+p,
1052 bytes_transferred-p,
1057 std::stringstream s;
1058 s <<
"bytes left after consume: " << bytes_transferred-p;
1065 this->terminate(consume_ec);
1068 lib::error_code close_ec;
1071 consume_ec.message(),
1077 this->terminate(close_ec);
1084 if (m_processor->ready()) {
1086 std::stringstream s;
1087 s <<
"Complete message received. Dispatching";
1099 }
else if (m_message_handler) {
1100 m_message_handler(m_connection_hdl, msg);
1103 process_control_frame(msg);
1112 template <
typename config>
1118 transport_con_type::async_read_at_least(
1133 template <
typename config>
1139 return lib::error_code();
1150 m_processor = get_processor(version);
1154 return lib::error_code();
1162 std::stringstream ss;
1164 std::vector<int>::const_iterator it;
1171 m_response.replace_header(
"Sec-WebSocket-Version",ss.str());
1175 template <
typename config>
1186 (transport_con_type::is_secure() ?
"https" :
"http")
1189 if (!m_uri->get_valid()) {
1195 if (m_http_handler) {
1197 m_http_handler(m_connection_hdl);
1207 return lib::error_code();
1210 lib::error_code ec = m_processor->validate_handshake(m_request);
1222 std::pair<lib::error_code,std::string> neg_results;
1223 neg_results = m_processor->negotiate_extensions(m_request);
1225 if (neg_results.first) {
1230 return neg_results.first;
1235 if (neg_results.second.size() > 0) {
1236 m_response.replace_header(
"Sec-WebSocket-Extensions",
1237 neg_results.second);
1242 m_uri = m_processor->get_uri(m_request);
1245 if (!m_uri->get_valid()) {
1252 lib::error_code subp_ec = m_processor->extract_subprotocols(m_request,
1253 m_requested_subprotocols);
1260 if (!m_validate_handler || m_validate_handler(m_connection_hdl)) {
1265 ec = m_processor->process_handshake(m_request,m_subprotocol,m_response);
1268 std::stringstream s;
1269 s <<
"Processing error: " << ec <<
"(" << ec.message() <<
")";
1289 return lib::error_code();
1292 template <
typename config>
1308 m_response.set_version(
"HTTP/1.1");
1311 if (m_response.get_header(
"Server").empty()) {
1312 if (!m_user_agent.empty()) {
1313 m_response.replace_header(
"Server",m_user_agent);
1315 m_response.remove_header(
"Server");
1321 m_handshake_buffer = m_processor->get_raw(m_response);
1324 m_handshake_buffer = m_response.raw();
1329 if (!m_response.get_header(
"Sec-WebSocket-Key3").empty()) {
1336 transport_con_type::async_write(
1337 m_handshake_buffer.data(),
1338 m_handshake_buffer.size(),
1340 &type::handle_write_http_response,
1342 lib::placeholders::_1
1347 template <
typename config>
1351 lib::error_code ecm = ec;
1365 "handle_write_http_response invoked after connection was closed");
1376 "got (expected) eof/state error from closed con");
1381 this->terminate(ecm);
1385 if (m_handshake_timer) {
1386 m_handshake_timer->cancel();
1387 m_handshake_timer.reset();
1397 std::stringstream s;
1398 s <<
"Handshake ended with HTTP error: " 1399 << m_response.get_status_code();
1405 this->log_http_result();
1409 "got to writing HTTP results with m_ec set: "+m_ec.message());
1414 this->terminate(m_ec);
1418 this->log_open_result();
1423 if (m_open_handler) {
1424 m_open_handler(m_connection_hdl);
1427 this->handle_read_frame(lib::error_code(), m_buf_cursor);
1430 template <
typename config>
1440 ec = m_processor->client_handshake_request(m_request,m_uri,
1441 m_requested_subprotocols);
1453 if (m_request.get_header(
"User-Agent").empty()) {
1454 if (!m_user_agent.empty()) {
1455 m_request.replace_header(
"User-Agent",m_user_agent);
1457 m_request.remove_header(
"User-Agent");
1461 m_handshake_buffer = m_request.raw();
1467 if (m_open_handshake_timeout_dur > 0) {
1468 m_handshake_timer = transport_con_type::set_timer(
1469 m_open_handshake_timeout_dur,
1471 &type::handle_open_handshake_timeout,
1473 lib::placeholders::_1
1478 transport_con_type::async_write(
1479 m_handshake_buffer.data(),
1480 m_handshake_buffer.size(),
1482 &type::handle_send_http_request,
1484 lib::placeholders::_1
1489 template <
typename config>
1493 lib::error_code ecm = ec;
1509 "handle_send_http_request invoked after connection was closed");
1520 "got (expected) eof/state error from closed con");
1525 this->terminate(ecm);
1529 transport_con_type::async_read_at_least(
1534 &type::handle_read_http_response,
1536 lib::placeholders::_1,
1537 lib::placeholders::_2
1542 template <
typename config>
1544 size_t bytes_transferred)
1548 lib::error_code ecm = ec;
1562 "handle_read_http_response invoked after connection was closed");
1573 "got (expected) eof/state error from closed con");
1578 this->terminate(ecm);
1582 size_t bytes_processed = 0;
1585 bytes_processed = m_response.consume(m_buf,bytes_transferred);
1588 std::string(
"error in handle_read_http_response: ")+e.
what());
1595 if (m_response.headers_ready()) {
1596 if (m_handshake_timer) {
1597 m_handshake_timer->cancel();
1598 m_handshake_timer.reset();
1601 lib::error_code validate_ec = m_processor->validate_server_handshake_response(
1607 this->terminate(validate_ec);
1613 std::pair<lib::error_code,std::string> neg_results;
1614 neg_results = m_processor->negotiate_extensions(m_response);
1616 if (neg_results.first) {
1625 + neg_results.first.message());
1634 this->log_open_result();
1636 if (m_open_handler) {
1637 m_open_handler(m_connection_hdl);
1643 std::copy(m_buf+bytes_processed,m_buf+bytes_transferred,m_buf);
1644 m_buf_cursor = bytes_transferred-bytes_processed;
1646 this->handle_read_frame(lib::error_code(), m_buf_cursor);
1648 transport_con_type::async_read_at_least(
1653 &type::handle_read_http_response,
1655 lib::placeholders::_1,
1656 lib::placeholders::_2
1662 template <
typename config>
1664 lib::error_code
const & ec)
1670 "open handle_open_handshake_timeout error: "+ec.message());
1678 template <
typename config>
1680 lib::error_code
const & ec)
1686 "asio open handle_close_handshake_timeout error: "+ec.message());
1694 template <
typename config>
1701 if (m_handshake_timer) {
1702 m_handshake_timer->cancel();
1703 m_handshake_timer.reset();
1706 terminate_status tstat =
unknown;
1710 m_local_close_reason = ec.message();
1731 "terminate called on connection that was already terminated");
1737 transport_con_type::async_shutdown(
1739 &type::handle_terminate,
1742 lib::placeholders::_1
1747 template <
typename config>
1749 lib::error_code
const & ec)
1761 if (tstat == failed) {
1763 if (m_fail_handler) {
1764 m_fail_handler(m_connection_hdl);
1767 }
else if (tstat ==
closed) {
1768 if (m_close_handler) {
1769 m_close_handler(m_connection_hdl);
1779 if (m_termination_handler) {
1781 m_termination_handler(type::get_shared());
1782 }
catch (std::exception
const & e) {
1784 std::string(
"termination_handler call failed. Reason was: ")+e.what());
1789 template <
typename config>
1807 while (next_message) {
1808 m_current_msgs.push_back(next_message);
1809 if (!next_message->get_terminal()) {
1810 next_message = write_pop();
1816 if (m_current_msgs.empty()) {
1823 m_write_flag =
true;
1828 for (it = m_current_msgs.begin(); it != m_current_msgs.end(); ++it) {
1829 std::string
const & header = (*it)->get_header();
1830 std::string
const & payload = (*it)->get_payload();
1839 std::stringstream
general,header,payload;
1841 general <<
"Dispatching write containing " << m_current_msgs.size()
1842 <<
" message(s) containing ";
1843 header <<
"Header Bytes: \n";
1844 payload <<
"Payload Bytes: \n";
1849 for (
size_t i = 0; i < m_current_msgs.size(); i++) {
1850 hbytes += m_current_msgs[i]->get_header().size();
1851 pbytes += m_current_msgs[i]->get_payload().size();
1854 header <<
"[" << i <<
"] (" 1855 << m_current_msgs[i]->get_header().size() <<
") " 1860 payload <<
"[" << i <<
"] (" 1861 << m_current_msgs[i]->get_payload().size() <<
") ["<<m_current_msgs[i]->get_opcode()<<
"] " 1863 m_current_msgs[i]->get_payload() :
1871 general << hbytes <<
" header bytes and " << pbytes <<
" payload bytes";
1879 transport_con_type::async_write(
1881 m_write_frame_handler
1885 template <
typename config>
1892 bool terminal = m_current_msgs.back()->get_terminal();
1894 m_send_buffer.clear();
1895 m_current_msgs.clear();
1900 this->terminate(ec);
1905 this->terminate(lib::error_code());
1909 bool needs_writing =
false;
1914 m_write_flag =
false;
1916 needs_writing = !m_send_queue.empty();
1919 if (needs_writing) {
1920 transport_con_type::dispatch(lib::bind(
1927 template <
typename config>
1933 template <
typename config>
1941 std::stringstream s;
1942 s <<
"Control frame received with opcode " << op;
1955 bool should_reply =
true;
1957 if (m_ping_handler) {
1958 should_reply = m_ping_handler(m_connection_hdl, msg->get_payload());
1962 this->
pong(msg->get_payload(),ec);
1968 if (m_pong_handler) {
1969 m_pong_handler(m_connection_hdl, msg->get_payload());
1972 m_ping_timer->cancel();
1982 s <<
"Received invalid close code " << m_remote_close_code
1983 <<
" dropping connection per config.";
1985 this->terminate(ec);
1987 s <<
"Received invalid close code " << m_remote_close_code
1988 <<
" sending acknowledgement and closing";
1991 "Invalid close code");
2003 "Received invalid close reason. Dropping connection per config");
2004 this->terminate(ec);
2007 "Received invalid close reason. Sending acknowledgement and closing");
2009 "Invalid close reason");
2019 s <<
"Received close frame with code " << m_remote_close_code
2020 <<
" and reason " << m_remote_close_reason;
2023 ec = send_close_ack();
2041 terminate(lib::error_code());
2054 template <
typename config>
2056 std::string
const & reason)
2058 return send_close_frame(code,reason,
true,m_is_server);
2061 template <
typename config>
2063 std::string
const & reason,
bool ack,
bool terminal)
2078 m_local_close_reason.clear();
2081 m_local_close_code = code;
2082 m_local_close_reason = reason;
2086 m_local_close_reason.clear();
2089 "acknowledging a no-status close with normal code");
2091 m_local_close_reason.clear();
2094 m_local_close_code = m_remote_close_code;
2095 m_local_close_reason = m_remote_close_reason;
2098 std::stringstream s;
2099 s <<
"Closing with code: " << m_local_close_code <<
", and reason: " 2100 << m_local_close_reason;
2108 lib::error_code ec = m_processor->prepare_close(m_local_close_code,
2109 m_local_close_reason,msg);
2118 msg->set_terminal(
true);
2129 if (m_close_handshake_timeout_dur > 0) {
2130 m_handshake_timer = transport_con_type::set_timer(
2131 m_close_handshake_timeout_dur,
2133 &type::handle_close_handshake_timeout,
2135 lib::placeholders::_1
2140 bool needs_writing =
false;
2144 needs_writing = !m_write_flag && !m_send_queue.empty();
2147 if (needs_writing) {
2148 transport_con_type::dispatch(lib::bind(
2154 return lib::error_code();
2157 template <
typename config>
2166 p = lib::make_shared<processor::hybi00<config> >(
2167 transport_con_type::is_secure(),
2173 p = lib::make_shared<processor::hybi07<config> >(
2174 transport_con_type::is_secure(),
2181 p = lib::make_shared<processor::hybi08<config> >(
2182 transport_con_type::is_secure(),
2189 p = lib::make_shared<processor::hybi13<config> >(
2190 transport_con_type::is_secure(),
2206 template <
typename config>
2213 m_send_buffer_size += msg->get_payload().size();
2214 m_send_queue.push(msg);
2217 std::stringstream s;
2218 s <<
"write_push: message count: " << m_send_queue.size()
2219 <<
" buffer size: " << m_send_buffer_size;
2224 template <
typename config>
2229 if (m_send_queue.empty()) {
2233 msg = m_send_queue.front();
2235 m_send_buffer_size -= msg->get_payload().size();
2239 std::stringstream s;
2240 s <<
"write_pop: message count: " << m_send_queue.size()
2241 <<
" buffer size: " << m_send_buffer_size;
2247 template <
typename config>
2250 std::stringstream s;
2260 s << (version == -1 ?
"HTTP" :
"WebSocket") <<
" Connection ";
2263 s << transport_con_type::get_remote_endpoint() <<
" ";
2266 if (version != -1) {
2267 s <<
"v" << version <<
" ";
2271 std::string ua = m_request.get_header(
"User-Agent");
2280 s << (m_uri ? m_uri->get_resource() :
"NULL") <<
" ";
2283 s << m_response.get_status_code();
2288 template <
typename config>
2291 std::stringstream s;
2294 <<
"close local:[" << m_local_close_code
2295 << (m_local_close_reason.empty() ?
"" :
","+m_local_close_reason)
2296 <<
"] remote:[" << m_remote_close_code
2297 << (m_remote_close_reason.empty() ?
"" :
","+m_remote_close_reason) <<
"]";
2302 template <
typename config>
2305 std::stringstream s;
2310 s <<
"WebSocket Connection ";
2313 s << transport_con_type::get_remote_endpoint();
2321 std::string ua = m_request.get_header(
"User-Agent");
2330 s << (m_uri ? m_uri->get_resource() :
"-");
2333 s <<
" " << m_response.get_status_code();
2336 s <<
" " << m_ec <<
" " << m_ec.message();
2341 template <
typename config>
2343 std::stringstream s;
2351 s << (m_request.get_header(
"host").empty() ?
"-" : m_request.get_header(
"host"))
2352 <<
" " << transport_con_type::get_remote_endpoint()
2353 <<
" \"" << m_request.get_method()
2354 <<
" " << (m_uri ? m_uri->get_resource() :
"-")
2355 <<
" " << m_request.get_version() <<
"\" " << m_response.get_status_code()
2356 <<
" " << m_response.get_body().size();
2359 std::string ua = m_request.get_header(
"User-Agent");
2372 #endif // WEBSOCKETPP_CONNECTION_IMPL_HPP bool is_control(value v)
Check if an opcode is for a control frame.
lib::error_code process_handshake_request()
Perform WebSocket handshake validation of m_request using m_processor.
void add_subprotocol(std::string const &request, lib::error_code &ec)
Adds the given subprotocol string to the request list (exception free)
static level const fatal
Unrecoverable error.
websocketpp::config::asio_tls_client::message_type::ptr message_ptr
void set_termination_handler(termination_handler new_handler)
Sets the handler for a terminating connection.
void read_frame()
Issue a new transport read unless reading is paused.
std::vector< std::string > const & get_requested_subprotocols() const
Gets all of the subprotocols requested by the client.
uint16_t value
The type of a close code value.
lib::error_code make_error_code(error::value e)
static level const control
One line per control frame.
std::string const & get_subprotocol() const
Gets the negotated subprotocol.
bool terminal(value code)
Determine if the code represents an unrecoverable error.
uri_ptr get_uri_from_host(request_type &request, std::string scheme)
Extract a URI ptr from the host header of the request.
lib::error_code pause_reading()
Pause reading of new data.
bool is_websocket_handshake(request_type &r)
Determine whether or not a generic HTTP request is a WebSocket handshake.
Attempted to use a client specific feature on a server endpoint.
void handle_transport_init(lib::error_code const &ec)
status_code::value m_error_code
session::state::value get_state() const
Return the connection state.
lib::function< void(ptr)> termination_handler
static std::vector< int > const versions_supported(helper, helper+4)
Container that stores the list of protocol versions supported.
Selected subprotocol was not requested by the client.
int get_websocket_version(request_type &r)
Extract the version from a WebSocket handshake request.
uri_ptr get_uri() const
Gets the connection URI.
void replace_header(std::string const &key, std::string const &val)
Replace a header.
void ping(std::string const &payload)
Send a ping.
Represents an individual WebSocket connection.
size_t get_buffered_amount() const
Get the size of the outgoing write buffer (in payload bytes)
void handle_read_http_response(lib::error_code const &ec, size_t bytes_transferred)
void terminate(lib::error_code const &ec)
static level const frame_payload
One line per frame, includes the full message payload (warning: chatty)
static value const protocol_error
A protocol error occurred.
static value const normal
Normal closure, meaning that the purpose for which the connection was established has been fulfilled...
static level const devel
Low level debugging information (warning: very chatty)
std::string string_replace_all(std::string subject, std::string const &search, std::string const &replace)
Replace all occurrances of a substring with another.
status::value extract_code(std::string const &payload, lib::error_code &ec)
Extract a close code value from a close payload.
void select_subprotocol(std::string const &value, lib::error_code &ec)
Select a subprotocol to use (exception free)
A fake lock guard implementation that does nothing.
std::string to_hex(std::string const &input)
Convert std::string to ascii printed string of hex digits.
void pong(std::string const &payload)
Send a pong.
void send_http_response()
Send deferred HTTP Response.
bool is_not_token_char(unsigned char c)
Is the character a non-token.
void handle_read_handshake(lib::error_code const &ec, size_t bytes_transferred)
void handle_resume_reading()
Resume reading callback.
static level const frame_header
One line per frame, includes the full frame header.
void handle_open_handshake_timeout(lib::error_code const &ec)
void handle_close_handshake_timeout(lib::error_code const &ec)
lib::error_code initialize_processor()
Set m_processor based on information in m_request.
static level const devel
Development messages (warning: very chatty)
std::string const & get_request_header(std::string const &key) const
Retrieve a request header.
static const int client_version
WebSocket Protocol version to use as a client.
Table::const_iterator iterator
message_type::ptr message_ptr
static level const disconnect
One line for each closed connection. Includes closing codes and reasons.
lib::shared_ptr< message > ptr
lib::error_code resume_reading()
Resume reading of new data.
void start()
Start the connection state machine.
void close(close::status::value const code, std::string const &reason)
Close the connection.
lib::error_code defer_http_response()
Defer HTTP Response until later (Exception free)
Invalid WebSocket protocol version.
void set_status(http::status_code::value code)
Set response status code and message.
void handle_pong_timeout(std::string payload, lib::error_code const &ec)
Utility method that gets called back when the ping timer expires.
close::status::value to_ws(lib::error_code ec)
Converts a processor error_code into a websocket close code.
lib::error_code make_error_code(error::processor_errors e)
Create an error code with the given value and the processor category.
void append_header(std::string const &key, std::string const &val)
Append a header.
lib::error_code send(std::string const &payload, frame::opcode::value op=frame::opcode::text)
Create a message and then add it to the outgoing send queue.
The connection was in the wrong state for this operation.
static level const info
Information about minor configuration problems or additional information about other warnings...
void write_frame()
Checks if there are frames in the send queue and if there are sends one.
void handle_write_frame(lib::error_code const &ec)
Process the results of a frame write operation and start the next write.
static const bool drop_on_protocol_error
Drop connections immediately on protocol error.
Namespace for the WebSocket++ project.
void set_max_message_size(size_t new_value)
Set maximum message size.
Extension negotiation failed.
void close(T *e, websocketpp::connection_hdl hdl)
std::string const & get_origin() const
Return the same origin policy origin value from the opening request.
std::string const & get_response_header(std::string const &key) const
Retrieve a response header.
uint16_t get_port() const
Returns the port component of the connection URI.
lib::shared_ptr< processor_type > processor_ptr
std::string const & get_resource() const
Returns the resource component of the connection URI.
A simple utility buffer class.
void handle_read_frame(lib::error_code const &ec, size_t bytes_transferred)
std::vector< int > const & get_supported_versions() const
Get array of WebSocket protocol versions that this connection supports.
The endpoint is out of outgoing message buffers.
static const size_t connection_read_buffer_size
lib::shared_ptr< uri > uri_ptr
Pointer to a URI.
void handle_interrupt()
Transport inturrupt callback.
static value const no_status
A dummy value to indicate that no status code was received.
void handle_pause_reading()
Pause reading callback.
WebSocket close handshake timed out.
bool get_secure() const
Returns the secure flag from the connection URI.
void handle_terminate(terminate_status tstat, lib::error_code const &ec)
static level const fail
One line for each failed WebSocket connection with details.
static const bool silent_close
Suppresses the return of detailed connection close information.
static value const abnormal_close
A dummy value to indicate that the connection was closed abnormally.
std::string const & get_request_body() const
Retrieve a request body.
static uint8_t const close_reason_size
Maximum size of close frame reason.
read or write after shutdown
void set_uri(uri_ptr uri)
Sets the connection URI.
WebSocket opening handshake timed out.
std::string const & get_host() const
Returns the host component of the connection URI.
uint32_t level
Type of a channel package.
void read_handshake(size_t num_bytes)
Attempted to use a server specific feature on a client endpoint.
lib::error_code interrupt()
Asyncronously invoke handler::on_inturrupt.
std::string extract_reason(std::string const &payload, lib::error_code &ec)
Extract the reason string from a close payload.
virtual const char * what() const
static level const rerror
Recoverable error.
An invalid uri was supplied.
void handle_send_http_request(lib::error_code const &ec)
static level const warn
Information about important problems not severe enough to terminate connections.
void handle_write_http_response(lib::error_code const &ec)
Unsupported WebSocket protocol version.
static value const blank
A blank value for internal use.
static level const connect
Information about new connections.
static level const http
Access related to HTTP requests.
void remove_header(std::string const &key)
Remove a header.
void set_body(std::string const &value)
Set response body content.