2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
28#ifndef WEBSOCKETPP_CONNECTION_IMPL_HPP
29#define WEBSOCKETPP_CONNECTION_IMPL_HPP
31#include <websocketpp/processors/hybi00.hpp>
32#include <websocketpp/processors/hybi07.hpp>
33#include <websocketpp/processors/hybi08.hpp>
34#include <websocketpp/processors/hybi13.hpp>
36#include <websocketpp/processors/processor.hpp>
38#include <websocketpp/common/platforms.hpp>
39#include <websocketpp/common/system_error.hpp>
50namespace istate = session::internal_state;
52template <
typename config>
54 termination_handler new_handler)
57 "connection set_termination_handler");
61 m_termination_handler = new_handler;
64template <
typename config>
67 return m_processor->get_origin(m_request);
70template <
typename config>
73 return m_send_buffer_size;
76template <
typename config>
82template <
typename config>
86 message_ptr msg = m_msg_manager->get_message(op,payload.size());
87 msg->append_payload(payload);
88 msg->set_compressed(
true);
93template <
typename config>
97 message_ptr msg = m_msg_manager->get_message(op,len);
98 msg->append_payload(payload,len);
103template <
typename config>
111 scoped_lock_type lock(m_connection_state_lock);
112 if (m_state != session::state::open) {
117 message_ptr outgoing_msg;
118 bool needs_writing =
false;
120 if (msg->get_prepared()) {
123 scoped_lock_type lock(m_write_lock);
124 write_push(outgoing_msg);
125 needs_writing = !m_write_flag && !m_send_queue.empty();
127 outgoing_msg = m_msg_manager->get_message();
133 scoped_lock_type lock(m_write_lock);
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();
151 return lib::error_code();
154template <
typename config>
155void connection<config>::
ping(std::string
const& payload, lib::error_code& ec) {
161 scoped_lock_type lock(m_connection_state_lock);
162 if (m_state != session::state::open) {
163 std::stringstream ss;
164 ss <<
"connection::ping called from invalid state " << m_state;
171 message_ptr msg = m_msg_manager->get_message();
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) {
194 lib::placeholders::_1
201 m_elog->write(log
::elevel::warn,
"Warning: a pong_timeout_handler is \
202 set but the transport in use does not support timeouts.");
206 bool needs_writing =
false;
208 scoped_lock_type lock(m_write_lock);
210 needs_writing = !m_write_flag && !m_send_queue.empty();
220 ec = lib::error_code();
223template<
typename config>
232template<
typename config>
234 lib::error_code
const & ec)
246 if (m_pong_timeout_handler) {
247 m_pong_timeout_handler(m_connection_hdl,payload);
251template <
typename config>
252void connection<config>::
pong(std::string
const& payload, lib::error_code& ec) {
258 scoped_lock_type lock(m_connection_state_lock);
259 if (m_state != session::state::open) {
260 std::stringstream ss;
261 ss <<
"connection::pong called from invalid state " << m_state;
268 message_ptr msg = m_msg_manager->get_message();
274 ec = m_processor->prepare_pong(payload,msg);
277 bool needs_writing =
false;
279 scoped_lock_type lock(m_write_lock);
281 needs_writing = !m_write_flag && !m_send_queue.empty();
291 ec = lib::error_code();
294template<
typename config>
303template <
typename config>
305 std::string
const & reason, lib::error_code & ec)
312 std::string tr(reason,0,std::min<size_t>(reason.size(),
313 frame::limits::close_reason_size));
315 scoped_lock_type lock(m_connection_state_lock);
317 if (m_state != session::state::open) {
322 ec =
this->send_close_frame(code,tr,
false,close::status::terminal(code));
325template<
typename config>
327 std::string
const & reason)
330 close(code,reason,ec);
338
339
340template <
typename config>
352template <
typename config>
354 if (m_interrupt_handler) {
355 m_interrupt_handler(m_connection_hdl);
359template <
typename config>
361 m_alog->write(log
::alevel::devel,
"connection connection::pause_reading");
371template <
typename config>
373 m_alog->write(log
::alevel::devel,
"connection connection::handle_pause_reading");
377template <
typename config>
379 m_alog->write(log
::alevel::devel,
"connection connection::resume_reading");
389template <
typename config>
405template <
typename config>
408 return m_uri->get_secure();
411template <
typename config>
414 return m_uri->get_host();
417template <
typename config>
420 return m_uri->get_resource();
423template <
typename config>
426 return m_uri->get_port();
429template <
typename config>
435template <
typename config>
446template <
typename config>
448 return m_subprotocol;
451template <
typename config>
454 return m_requested_subprotocols;
457template <
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);
477template <
typename config>
480 this->add_subprotocol(value,ec);
487template <
typename config>
489 lib::error_code & ec)
497 ec = lib::error_code();
501 std::vector<std::string>::iterator it;
503 it = std::find(m_requested_subprotocols.begin(),
504 m_requested_subprotocols.end(),
507 if (it == m_requested_subprotocols.end()) {
512 m_subprotocol = value;
515template <
typename config>
518 this->select_subprotocol(value,ec);
525template <
typename config>
528 return m_request.get_header(key);
531template <
typename config>
534 return m_request.get_body();
537template <
typename config>
540 return m_response.get_header(key);
544template <
typename config>
547 if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
548 throw exception(
"Call to set_status from invalid state",
551 m_response.set_status(code);
555template <
typename config>
557 std::string
const & msg)
559 if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
560 throw exception(
"Call to set_status from invalid state",
564 m_response.set_status(code,msg);
568template <
typename config>
570 if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
571 throw exception(
"Call to set_status from invalid state",
575 m_response.set_body(value);
579template <
typename config>
581 std::string
const & val)
584 if (m_internal_state == istate::PROCESS_HTTP_REQUEST) {
586 m_response.append_header(key,val);
588 throw exception(
"Call to append_header from invalid state",
592 if (m_internal_state == istate::USER_INIT) {
594 m_request.append_header(key,val);
596 throw exception(
"Call to append_header from invalid state",
603template <
typename config>
605 std::string
const & val)
608 if (m_internal_state == istate::PROCESS_HTTP_REQUEST) {
610 m_response.replace_header(key,val);
612 throw exception(
"Call to replace_header from invalid state",
616 if (m_internal_state == istate::USER_INIT) {
618 m_request.replace_header(key,val);
620 throw exception(
"Call to replace_header from invalid state",
627template <
typename config>
631 if (m_internal_state == istate::PROCESS_HTTP_REQUEST) {
633 m_response.remove_header(key);
635 throw exception(
"Call to remove_header from invalid state",
639 if (m_internal_state == istate::USER_INIT) {
641 m_request.remove_header(key);
643 throw exception(
"Call to remove_header from invalid state",
651
652
653
654
655
656
657
658
659
660template <
typename config>
664 if (m_handshake_timer) {
665 m_handshake_timer->cancel();
666 m_handshake_timer.reset();
670 m_http_state = session::http_state::deferred;
672 return lib::error_code();
677
678
679
680
681
682
683
684
685template <
typename config>
688 scoped_lock_type lock(m_connection_state_lock);
689 if (m_http_state != session::http_state::deferred) {
694 m_http_state = session::http_state::body_written;
697 this->write_http_response(lib::error_code());
698 ec = lib::error_code();
701template <
typename config>
704 this->send_http_response(ec);
715template <
typename config>
719 if (m_internal_state != istate::USER_INIT) {
725 m_internal_state = istate::TRANSPORT_INIT;
732 &
type::handle_transport_init,
734 lib::placeholders::_1
739template <
typename config>
740void connection<config>::handle_transport_init(lib::error_code
const & ec) {
743 lib::error_code ecm = ec;
745 if (m_internal_state != istate::TRANSPORT_INIT) {
747 "handle_transport_init must be called from transport init state");
753 s <<
"handle_transport_init received error: "<< ecm.message();
756 this->terminate(ecm);
762 m_internal_state = istate::READ_HTTP_REQUEST;
763 this->read_handshake(1);
767 m_internal_state = istate::WRITE_HTTP_REQUEST;
768 m_processor = get_processor(config::client_version);
769 this->send_http_request();
773template <
typename config>
774void connection<config>::read_handshake(size_t num_bytes) {
777 if (m_open_handshake_timeout_dur > 0) {
779 m_open_handshake_timeout_dur,
781 &
type::handle_open_handshake_timeout,
783 lib::placeholders::_1
788 transport_con_type::async_read_at_least(
791 config::connection_read_buffer_size,
793 &type::handle_read_handshake,
795 lib::placeholders::_1,
796 lib::placeholders::_2
803template <
typename config>
804void connection<config>::handle_read_handshake(lib::error_code
const & ec,
805 size_t bytes_transferred)
809 lib::error_code ecm = ec;
812 scoped_lock_type lock(m_connection_state_lock);
814 if (m_state == session::state::connecting) {
815 if (m_internal_state != istate::READ_HTTP_REQUEST) {
818 }
else if (m_state == session::state::closed) {
823 "handle_read_handshake invoked after connection was closed");
834 "got (expected) eof/state error from closed con");
839 this->terminate(ecm);
844 if (bytes_transferred > config::connection_read_buffer_size) {
850 size_t bytes_processed = 0;
852 bytes_processed = m_request.consume(m_buf,bytes_transferred);
856 m_response.set_status(e.m_error_code,e.m_error_msg);
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()) {
904 m_alog->write(log::alevel::devel,
905 utility::to_hex(m_request.get_header(
"Sec-WebSocket-Key3")));
912 std::copy(m_buf+bytes_processed,m_buf+bytes_transferred,m_buf);
913 m_buf_cursor = bytes_transferred-bytes_processed;
916 m_internal_state = istate::PROCESS_HTTP_REQUEST;
919 lib::error_code handshake_ec =
this->process_handshake_request();
924 if (!m_is_http || m_http_state == session::http_state::init) {
925 this->write_http_response(handshake_ec);
929 transport_con_type::async_read_at_least(
932 config::connection_read_buffer_size,
934 &type::handle_read_handshake,
936 lib::placeholders::_1,
937 lib::placeholders::_2
948template <
typename config>
949void connection<config>::write_http_response_error(lib::error_code
const & ec) {
950 if (m_internal_state != istate::READ_HTTP_REQUEST) {
952 "write_http_response_error called in invalid state");
957 m_internal_state = istate::PROCESS_HTTP_REQUEST;
959 this->write_http_response(ec);
964template <
typename config>
965void connection<config>::handle_read_frame(lib::error_code
const & ec,
966 size_t bytes_transferred)
970 lib::error_code ecm = ec;
972 if (!ecm && m_internal_state != istate::PROCESS_CONNECTION) {
980 if (m_state == session::state::closed) {
985 }
else if (m_state == session::state::closing && !m_is_server) {
989 terminate(lib::error_code());
997 if (m_state == session::state::closed) {
999 "handle_read_frame: got invalid istate in closed state");
1012 log_err(echannel,
"handle_read_frame", ecm);
1013 this->terminate(ecm);
1019
1020
1021
1022
1027 std::stringstream s;
1028 s <<
"p = " << p <<
" bytes transferred = " << bytes_transferred;
1032 while (p < bytes_transferred) {
1034 std::stringstream s;
1035 s <<
"calling consume with " << bytes_transferred-p <<
" bytes";
1039 lib::error_code consume_ec;
1042 std::stringstream s;
1043 s <<
"Processing Bytes: " << utility::to_hex(
reinterpret_cast<uint8_t*>(m_buf)+p,bytes_transferred-p);
1047 p += m_processor->consume(
1048 reinterpret_cast<uint8_t*>(m_buf)+p,
1049 bytes_transferred-p,
1054 std::stringstream s;
1055 s <<
"bytes left after consume: " << bytes_transferred-p;
1061 if (config::drop_on_protocol_error) {
1062 this->terminate(consume_ec);
1065 lib::error_code close_ec;
1068 consume_ec.message(),
1074 this->terminate(close_ec);
1081 if (m_processor->ready()) {
1083 std::stringstream s;
1084 s <<
"Complete message received. Dispatching";
1088 message_ptr msg = m_processor->get_message();
1092 }
else if (!is_control(msg->get_opcode())) {
1094 if (m_state != session::state::open) {
1095 m_elog->write(log
::elevel::warn,
"got non-close frame while closing");
1096 }
else if (m_message_handler) {
1097 m_message_handler(m_connection_hdl, msg);
1100 process_control_frame(msg);
1109template <
typename config>
1115 transport_con_type::async_read_at_least(
1122
1125 config::connection_read_buffer_size,
1130template <
typename config>
1135 if (!
processor::is_websocket_handshake(m_request)) {
1136 return lib::error_code();
1139 int version =
processor::get_websocket_version(m_request);
1142 m_alog->write(log
::alevel::devel,
"BAD REQUEST: can't determine version");
1147 m_processor = get_processor(version);
1151 return lib::error_code();
1156 m_alog->write(log
::alevel::devel,
"BAD REQUEST: no processor for version");
1159 std::stringstream ss;
1161 std::vector<
int>::const_iterator it;
1162 for (it = versions_supported.begin(); it != versions_supported.end(); it++)
1168 m_response.replace_header(
"Sec-WebSocket-Version",ss.str());
1172template <
typename config>
1176 if (!
processor::is_websocket_handshake(m_request)) {
1181 m_uri = processor::get_uri_from_host(
1183 (transport_con_type::is_secure() ?
"https" :
"http")
1186 if (!m_uri->get_valid()) {
1187 m_alog->write(log
::alevel::devel,
"Bad request: failed to parse uri");
1192 if (m_http_handler) {
1194 m_http_handler(m_connection_hdl);
1196 if (m_state == session::state::closed) {
1204 return lib::error_code();
1207 lib::error_code ec = m_processor->validate_handshake(m_request);
1219 std::pair<lib::error_code,std::string> neg_results;
1220 neg_results = m_processor->negotiate_extensions(m_request);
1222 if (neg_results.first == processor::error::make_error_code(processor::error::extension_parse_error)) {
1225 m_elog->write(log::elevel::info,
"Bad request: " + neg_results.first.message());
1227 return neg_results.first;
1228 }
else if (neg_results.first) {
1232 m_elog->write(log::elevel::info,
1233 "Extension negotiation failed: " + neg_results.first.message());
1238 if (neg_results.second.size() > 0) {
1239 m_response.replace_header(
"Sec-WebSocket-Extensions",
1240 neg_results.second);
1245 m_uri = m_processor->get_uri(m_request);
1248 if (!m_uri->get_valid()) {
1249 m_alog->write(log
::alevel::devel,
"Bad request: failed to parse uri");
1255 lib::error_code subp_ec = m_processor->extract_subprotocols(m_request,
1256 m_requested_subprotocols);
1263 if (!m_validate_handler || m_validate_handler(m_connection_hdl)) {
1268 ec = m_processor->process_handshake(m_request,m_subprotocol,m_response);
1271 std::stringstream s;
1272 s <<
"Processing error: " << ec <<
"(" << ec.message() <<
")";
1285 if (m_response.get_status_code() ==
http::
status_code::uninitialized) {
1292 return lib::error_code();
1295template <
typename config>
1296void connection<config>::write_http_response(lib::error_code
const & ec) {
1300 m_alog->write(log
::alevel::http,
"An HTTP handler took over the connection.");
1304 if (m_response.get_status_code() ==
http::
status_code::uninitialized) {
1311 m_response.set_version(
"HTTP/1.1");
1314 if (m_response.get_header(
"Server").empty()) {
1315 if (!m_user_agent.empty()) {
1316 m_response.replace_header(
"Server",m_user_agent);
1318 m_response.remove_header(
"Server");
1324 m_handshake_buffer = m_processor->get_raw(m_response);
1327 m_handshake_buffer = m_response.raw();
1331 m_alog->write(log::alevel::devel,
"Raw Handshake response:\n"+m_handshake_buffer);
1332 if (!m_response.get_header(
"Sec-WebSocket-Key3").empty()) {
1333 m_alog->write(log::alevel::devel,
1334 utility::to_hex(m_response.get_header(
"Sec-WebSocket-Key3")));
1339 transport_con_type::async_write(
1340 m_handshake_buffer.data(),
1341 m_handshake_buffer.size(),
1343 &type::handle_write_http_response,
1345 lib::placeholders::_1
1350template <
typename config>
1351void connection<config>::handle_write_http_response(lib::error_code
const & ec) {
1354 lib::error_code ecm = ec;
1357 scoped_lock_type lock(m_connection_state_lock);
1359 if (m_state == session::state::connecting) {
1360 if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
1363 }
else if (m_state == session::state::closed) {
1368 "handle_write_http_response invoked after connection was closed");
1379 "got (expected) eof/state error from closed con");
1384 this->terminate(ecm);
1388 if (m_handshake_timer) {
1389 m_handshake_timer->cancel();
1390 m_handshake_timer.reset();
1393 if (m_response.get_status_code() !=
http::
status_code::switching_protocols)
1396
1397
1398
1400 std::stringstream s;
1401 s <<
"Handshake ended with HTTP error: "
1402 << m_response.get_status_code();
1408 this->log_http_result();
1412 "got to writing HTTP results with m_ec set: "+m_ec.message());
1417 this->terminate(m_ec);
1421 this->log_open_result();
1423 m_internal_state = istate::PROCESS_CONNECTION;
1424 m_state = session::state::open;
1426 if (m_open_handler) {
1427 m_open_handler(m_connection_hdl);
1430 this->handle_read_frame(lib::error_code(), m_buf_cursor);
1433template <
typename config>
1434void connection<config>::send_http_request() {
1443 ec = m_processor->client_handshake_request(m_request,m_uri,
1444 m_requested_subprotocols);
1451 m_elog->write(log
::elevel::fatal,
"Internal library error: missing processor");
1456 if (m_request.get_header(
"User-Agent").empty()) {
1457 if (!m_user_agent.empty()) {
1458 m_request.replace_header(
"User-Agent",m_user_agent);
1460 m_request.remove_header(
"User-Agent");
1464 m_handshake_buffer = m_request.raw();
1467 m_alog->write(log::alevel::devel,
"Raw Handshake request:\n"+m_handshake_buffer);
1470 if (m_open_handshake_timeout_dur > 0) {
1472 m_open_handshake_timeout_dur,
1474 &
type::handle_open_handshake_timeout,
1476 lib::placeholders::_1
1481 transport_con_type::async_write(
1482 m_handshake_buffer.data(),
1483 m_handshake_buffer.size(),
1485 &type::handle_send_http_request,
1487 lib::placeholders::_1
1492template <
typename config>
1493void connection<config>::handle_send_http_request(lib::error_code
const & ec) {
1496 lib::error_code ecm = ec;
1499 scoped_lock_type lock(m_connection_state_lock);
1501 if (m_state == session::state::connecting) {
1502 if (m_internal_state != istate::WRITE_HTTP_REQUEST) {
1505 m_internal_state = istate::READ_HTTP_RESPONSE;
1507 }
else if (m_state == session::state::closed) {
1512 "handle_send_http_request invoked after connection was closed");
1523 "got (expected) eof/state error from closed con");
1528 this->terminate(ecm);
1532 transport_con_type::async_read_at_least(
1535 config::connection_read_buffer_size,
1537 &type::handle_read_http_response,
1539 lib::placeholders::_1,
1540 lib::placeholders::_2
1545template <
typename config>
1546void connection<config>::handle_read_http_response(lib::error_code
const & ec,
1547 size_t bytes_transferred)
1551 lib::error_code ecm = ec;
1554 scoped_lock_type lock(m_connection_state_lock);
1556 if (m_state == session::state::connecting) {
1557 if (m_internal_state != istate::READ_HTTP_RESPONSE) {
1560 }
else if (m_state == session::state::closed) {
1565 "handle_read_http_response invoked after connection was closed");
1576 "got (expected) eof/state error from closed con");
1581 this->terminate(ecm);
1585 size_t bytes_processed = 0;
1588 bytes_processed = m_response.consume(m_buf,bytes_transferred);
1591 std::string(
"error in handle_read_http_response: ")+e.what());
1596 m_alog->write(log
::alevel::devel,std::string(
"Raw response: ")+m_response.raw());
1598 if (m_response.headers_ready()) {
1599 if (m_handshake_timer) {
1600 m_handshake_timer->cancel();
1601 m_handshake_timer.reset();
1604 lib::error_code validate_ec = m_processor->validate_server_handshake_response(
1610 this->terminate(validate_ec);
1616 std::pair<lib::error_code,std::string> neg_results;
1617 neg_results = m_processor->negotiate_extensions(m_response);
1619 if (neg_results.first) {
1627 m_alog->write(log::alevel::devel,
"Extension negotiation failed: "
1628 + neg_results.first.message());
1634 m_internal_state = istate::PROCESS_CONNECTION;
1635 m_state = session::state::open;
1637 this->log_open_result();
1639 if (m_open_handler) {
1640 m_open_handler(m_connection_hdl);
1646 std::copy(m_buf+bytes_processed,m_buf+bytes_transferred,m_buf);
1647 m_buf_cursor = bytes_transferred-bytes_processed;
1649 this->handle_read_frame(lib::error_code(), m_buf_cursor);
1651 transport_con_type::async_read_at_least(
1654 config::connection_read_buffer_size,
1656 &type::handle_read_http_response,
1658 lib::placeholders::_1,
1659 lib::placeholders::_2
1665template <
typename config>
1666void connection<config>::handle_open_handshake_timeout(
1667 lib::error_code
const & ec)
1673 "open handle_open_handshake_timeout error: "+ec.message());
1681template <
typename config>
1682void connection<config>::handle_close_handshake_timeout(
1683 lib::error_code
const & ec)
1686 m_alog->write(log
::alevel::devel,
"asio close handshake timer cancelled");
1689 "asio open handle_close_handshake_timeout error: "+ec.message());
1692 m_alog->write(log
::alevel::devel,
"asio close handshake timer expired");
1697template <
typename config>
1698void connection<config>::terminate(lib::error_code
const & ec) {
1704 if (m_handshake_timer) {
1705 m_handshake_timer->cancel();
1706 m_handshake_timer.reset();
1709 terminate_status tstat = unknown;
1713 m_local_close_reason = ec.message();
1718 m_http_state = session::http_state::closed;
1720 if (m_state == session::state::connecting) {
1721 m_state = session::state::closed;
1729 }
else if (m_state != session::state::closed) {
1730 m_state = session::state::closed;
1734 "terminate called on connection that was already terminated");
1742 &
type::handle_terminate,
1745 lib::placeholders::_1
1750template <
typename config>
1751void connection<config>::handle_terminate(terminate_status tstat,
1752 lib::error_code
const & ec)
1764 if (tstat == failed) {
1766 if (m_fail_handler) {
1767 m_fail_handler(m_connection_hdl);
1770 }
else if (tstat == closed) {
1771 if (m_close_handler) {
1772 m_close_handler(m_connection_hdl);
1782 if (m_termination_handler) {
1785 }
catch (std::exception
const & e) {
1787 std::string(
"termination_handler call failed. Reason was: ")+e.what());
1792template <
typename config>
1797 scoped_lock_type lock(m_write_lock);
1809 message_ptr next_message = write_pop();
1810 while (next_message) {
1811 m_current_msgs.push_back(next_message);
1812 if (!next_message->get_terminal()) {
1813 next_message = write_pop();
1815 next_message = message_ptr();
1819 if (m_current_msgs.empty()) {
1826 m_write_flag =
true;
1830 typename std::vector<message_ptr>::iterator it;
1831 for (it = m_current_msgs.begin(); it != m_current_msgs.end(); ++it) {
1832 std::string
const & header = (*it)->get_header();
1833 std::string
const & payload = (*it)->get_payload();
1835 m_send_buffer.push_back(transport::buffer(header.c_str(),header.size()));
1836 m_send_buffer.push_back(transport::buffer(payload.c_str(),payload.size()));
1842 std::stringstream general,header,payload;
1844 general <<
"Dispatching write containing " << m_current_msgs.size()
1845 <<
" message(s) containing ";
1846 header <<
"Header Bytes: \n";
1847 payload <<
"Payload Bytes: \n";
1852 for (size_t i = 0; i < m_current_msgs.size(); i++) {
1853 hbytes += m_current_msgs[i]->get_header().size();
1854 pbytes += m_current_msgs[i]->get_payload().size();
1857 header <<
"[" << i <<
"] ("
1858 << m_current_msgs[i]->get_header().size() <<
") "
1859 << utility::to_hex(m_current_msgs[i]->get_header()) <<
"\n";
1861 if (m_alog->static_test(log::alevel::frame_payload)) {
1862 if (m_alog->dynamic_test(log::alevel::frame_payload)) {
1863 payload <<
"[" << i <<
"] ("
1864 << m_current_msgs[i]->get_payload().size() <<
") ["<<m_current_msgs[i]->get_opcode()<<
"] "
1865 << (m_current_msgs[i]->get_opcode() == frame::opcode::text ?
1866 m_current_msgs[i]->get_payload() :
1867 utility::to_hex(m_current_msgs[i]->get_payload())
1874 general << hbytes <<
" header bytes and " << pbytes <<
" payload bytes";
1882 transport_con_type::async_write(
1884 m_write_frame_handler
1888template <
typename config>
1895 bool terminal = m_current_msgs.back()->get_terminal();
1897 m_send_buffer.clear();
1898 m_current_msgs.clear();
1903 this->terminate(ec);
1908 this->terminate(lib::error_code());
1912 bool needs_writing =
false;
1914 scoped_lock_type lock(m_write_lock);
1917 m_write_flag =
false;
1919 needs_writing = !m_send_queue.empty();
1922 if (needs_writing) {
1930template <
typename config>
1933 return versions_supported;
1936template <
typename config>
1937void connection<config>::process_control_frame(
typename config::message_type::ptr msg)
1944 std::stringstream s;
1945 s <<
"Control frame received with opcode " << op;
1948 if (m_state == session::state::closed) {
1952 if (op !=
frame::
opcode::CLOSE && m_state != session::state::open) {
1953 m_elog->write(log
::elevel::warn,
"got non-close frame in state closing");
1958 bool should_reply =
true;
1960 if (m_ping_handler) {
1961 should_reply = m_ping_handler(m_connection_hdl, msg->get_payload());
1965 this->pong(msg->get_payload(),ec);
1971 if (m_pong_handler) {
1972 m_pong_handler(m_connection_hdl, msg->get_payload());
1975 m_ping_timer->cancel();
1984 if (config::drop_on_protocol_error) {
1985 s <<
"Received invalid close code " << m_remote_close_code
1986 <<
" dropping connection per config.";
1988 this->terminate(ec);
1990 s <<
"Received invalid close code " << m_remote_close_code
1991 <<
" sending acknowledgement and closing";
1994 "Invalid close code");
2002 m_remote_close_reason = close::extract_reason(msg->get_payload(),ec);
2004 if (config::drop_on_protocol_error) {
2006 "Received invalid close reason. Dropping connection per config");
2007 this->terminate(ec);
2010 "Received invalid close reason. Sending acknowledgement and closing");
2012 "Invalid close reason");
2020 if (m_state == session::state::open) {
2022 s <<
"Received close frame with code " << m_remote_close_code
2023 <<
" and reason " << m_remote_close_reason;
2026 ec = send_close_ack();
2030 }
else if (m_state == session::state::closing && !m_was_clean) {
2044 terminate(lib::error_code());
2052 m_elog->write(log
::elevel::devel,
"Got control frame with invalid opcode");
2057template <
typename config>
2059 std::string
const & reason)
2061 return send_close_frame(code,reason,
true,m_is_server);
2064template <
typename config>
2066 std::string
const & reason,
bool ack,
bool terminal)
2078 if (config::silent_close) {
2081 m_local_close_reason.clear();
2084 m_local_close_code = code;
2085 m_local_close_reason = reason;
2089 m_local_close_reason.clear();
2092 "acknowledging a no-status close with normal code");
2094 m_local_close_reason.clear();
2097 m_local_close_code = m_remote_close_code;
2098 m_local_close_reason = m_remote_close_reason;
2101 std::stringstream s;
2102 s <<
"Closing with code: " << m_local_close_code <<
", and reason: "
2103 << m_local_close_reason;
2106 message_ptr msg = m_msg_manager->get_message();
2111 lib::error_code ec = m_processor->prepare_close(m_local_close_code,
2112 m_local_close_reason,msg);
2121 msg->set_terminal(
true);
2124 m_state = session::state::closing;
2132 if (m_close_handshake_timeout_dur > 0) {
2134 m_close_handshake_timeout_dur,
2136 &
type::handle_close_handshake_timeout,
2138 lib::placeholders::_1
2143 bool needs_writing =
false;
2145 scoped_lock_type lock(m_write_lock);
2147 needs_writing = !m_write_flag && !m_send_queue.empty();
2150 if (needs_writing) {
2157 return lib::error_code();
2160template <
typename config>
2162connection<config>::get_processor(
int version)
const {
2204 p->set_max_message_size(m_max_message_size);
2209template <
typename config>
2210void connection<config>::write_push(
typename config::message_type::ptr msg)
2216 m_send_buffer_size += msg->get_payload().size();
2217 m_send_queue.push(msg);
2220 std::stringstream s;
2221 s <<
"write_push: message count: " << m_send_queue.size()
2222 <<
" buffer size: " << m_send_buffer_size;
2227template <
typename config>
2228typename config::message_type::ptr
connection<config>::write_pop()
2232 if (m_send_queue.empty()) {
2236 msg = m_send_queue.front();
2238 m_send_buffer_size -= msg->get_payload().size();
2242 std::stringstream s;
2243 s <<
"write_pop: message count: " << m_send_queue.size()
2244 <<
" buffer size: " << m_send_buffer_size;
2250template <
typename config>
2253 std::stringstream s;
2256 if (!
processor::is_websocket_handshake(m_request)) {
2259 version =
processor::get_websocket_version(m_request);
2263 s << (version == -1 ?
"HTTP" :
"WebSocket") <<
" Connection ";
2269 if (version != -1) {
2270 s <<
"v" << version <<
" ";
2274 std::string ua = m_request.get_header(
"User-Agent");
2279 s <<
"\"" << utility::string_replace_all(ua,
"\"",
"\\\"") <<
"\" ";
2283 s << (m_uri ? m_uri->get_resource() :
"NULL") <<
" ";
2286 s << m_response.get_status_code();
2291template <
typename config>
2294 std::stringstream s;
2297 <<
"close local:[" << m_local_close_code
2298 << (m_local_close_reason.empty() ?
"" :
","+m_local_close_reason)
2299 <<
"] remote:[" << m_remote_close_code
2300 << (m_remote_close_reason.empty() ?
"" :
","+m_remote_close_reason) <<
"]";
2305template <
typename config>
2308 std::stringstream s;
2310 int version =
processor::get_websocket_version(m_request);
2313 s <<
"WebSocket Connection ";
2320 s <<
" v" << version;
2324 std::string ua = m_request.get_header(
"User-Agent");
2329 s <<
" \"" << utility::string_replace_all(ua,
"\"",
"\\\"") <<
"\" ";
2333 s << (m_uri ? m_uri->get_resource() :
"-");
2336 s <<
" " << m_response.get_status_code();
2339 s <<
" " << m_ec <<
" " << m_ec.message();
2344template <
typename config>
2346 std::stringstream s;
2348 if (
processor::is_websocket_handshake(m_request)) {
2349 m_alog->write(log
::alevel::devel,
"Call to log_http_result for WebSocket");
2354 s << (m_request.get_header(
"host").empty() ?
"-" : m_request.get_header(
"host"))
2355 <<
" " << transport_con_type::get_remote_endpoint()
2356 <<
" \"" << m_request.get_method()
2357 <<
" " << (m_uri ? m_uri->get_resource() :
"-")
2358 <<
" " << m_request.get_version() <<
"\" " << m_response.get_status_code()
2359 <<
" " << m_response.get_body().size();
2362 std::string ua = m_request.get_header(
"User-Agent");
2367 s <<
" \"" << utility::string_replace_all(ua,
"\"",
"\\\"") <<
"\" ";
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
#define _WEBSOCKETPP_CPP11_THREAD_
#define _WEBSOCKETPP_CPP11_MEMORY_
#define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
#define _WEBSOCKETPP_INITIALIZER_LISTS_
Concurrency policy that uses std::mutex / boost::mutex.
Stub for user supplied base class.
Represents an individual WebSocket connection.
ptr get_shared()
Get a shared pointer to this component.
void handle_interrupt()
Transport inturrupt callback.
void set_message_handler(message_handler h)
Set message handler.
lib::error_code interrupt()
Asyncronously invoke handler::on_inturrupt.
void start()
Start the connection state machine.
std::string const & get_request_body() const
Retrieve a request body.
config::transport_type::transport_con_type transport_con_type
Type of the transport component of this connection.
void ping(std::string const &payload)
Send a ping.
void set_close_handler(close_handler h)
Set close handler.
void set_pong_handler(pong_handler h)
Set pong handler.
lib::error_code send(message_ptr msg)
Add a message to the outgoing send queue.
config::alog_type alog_type
Type of the access logging policy.
http::status_code::value get_response_code() const
Get response HTTP status code.
lib::error_code defer_http_response()
Defer HTTP Response until later (Exception free)
lib::error_code resume_reading()
Resume reading of new data.
void add_subprotocol(std::string const &request, lib::error_code &ec)
Adds the given subprotocol string to the request list (exception free)
void add_subprotocol(std::string const &request)
Adds the given subprotocol string to the request list.
bool get_secure() const
Returns the secure flag from the connection URI.
void set_close_handshake_timeout(long dur)
Set close handshake timeout.
void set_body(std::string const &value)
Set response body content.
size_t get_buffered_amount() const
Get the size of the outgoing write buffer (in payload bytes)
std::string const & get_origin() const
Return the same origin policy origin value from the opening request.
void close(close::status::value const code, std::string const &reason, lib::error_code &ec)
exception free variant of close
std::string const & get_host() const
Returns the host component of the connection URI.
response_type const & get_response() const
Get response object.
void set_max_message_size(size_t new_value)
Set maximum message size.
std::string const & get_resource() const
Returns the resource component of the connection URI.
void select_subprotocol(std::string const &value, lib::error_code &ec)
Select a subprotocol to use (exception free)
std::string const & get_request_header(std::string const &key) const
Retrieve a request header.
lib::error_code process_handshake_request()
void handle_pause_reading()
Pause reading callback.
std::vector< int > const & get_supported_versions() const
Get array of WebSocket protocol versions that this connection supports.
lib::error_code send(void const *payload, size_t len, frame::opcode::value op=frame::opcode::binary)
Send a message (raw array overload)
void remove_header(std::string const &key)
Remove a header.
uri_ptr get_uri() const
Gets the connection URI.
void ping(std::string const &payload, lib::error_code &ec)
exception free variant of ping
connection_hdl get_handle() const
Get Connection Handle.
void set_pong_timeout_handler(pong_timeout_handler h)
Set pong timeout handler.
void send_http_response(lib::error_code &ec)
Send deferred HTTP Response (exception free)
connection< config > type
Type of this connection.
void set_ping_handler(ping_handler h)
Set ping handler.
std::string const & get_response_header(std::string const &key) const
Retrieve a response header.
void set_http_handler(http_handler h)
Set http handler.
std::string const & get_response_msg() const
Get response HTTP status message.
config::elog_type elog_type
Type of the error logging policy.
void pong(std::string const &payload, lib::error_code &ec)
exception free variant of pong
message_ptr get_message(websocketpp::frame::opcode::value op, size_t size) const
Get a message buffer.
void handle_write_frame(lib::error_code const &ec)
Process the results of a frame write operation and start the next write.
close::status::value get_local_close_code() const
Get the WebSocket close code sent by this endpoint.
lib::error_code get_ec() const
Get the internal error code for a closed/failed connection.
void set_fail_handler(fail_handler h)
Set fail handler.
void write_frame()
Checks if there are frames in the send queue and if there are sends one.
session::state::value get_state() const
Return the connection state.
void select_subprotocol(std::string const &value)
Select a subprotocol to use.
void set_status(http::status_code::value code)
Set response status code and message.
void replace_header(std::string const &key, std::string const &val)
Replace a header.
void set_status(http::status_code::value code, std::string const &msg)
Set response status code and message.
size_t get_max_http_body_size() const
Get maximum HTTP message body size.
config::concurrency_type concurrency_type
Type of the concurrency component of this connection.
transport_con_type::timer_ptr timer_ptr
Type of a pointer to a transport timer handle.
void set_validate_handler(validate_handler h)
Set validate handler.
void pong(std::string const &payload)
Send a pong.
void set_interrupt_handler(interrupt_handler h)
Set interrupt handler.
size_t buffered_amount() const
Get the size of the outgoing write buffer (in payload bytes)
void send_http_response()
Send deferred HTTP Response.
close::status::value get_remote_close_code() const
Get the WebSocket close code sent by the remote endpoint.
void set_open_handler(open_handler h)
Set open handler.
bool is_server() const
Get whether or not this connection is part of a server or client.
lib::shared_ptr< type > ptr
Type of a shared pointer to this connection.
std::string const & get_remote_close_reason() const
Get the WebSocket close reason sent by the remote endpoint.
void set_pong_timeout(long dur)
Set pong timeout.
lib::error_code initialize_processor()
void set_uri(uri_ptr uri)
Sets the connection URI.
void set_termination_handler(termination_handler new_handler)
request_type const & get_request() const
Get request object.
void set_max_http_body_size(size_t new_value)
Set maximum HTTP message body size.
transport_con_type::ptr transport_con_ptr
Type of a shared pointer to the transport component of this connection.
void set_open_handshake_timeout(long dur)
Set open handshake timeout.
lib::error_code pause_reading()
Pause reading of new data.
void handle_resume_reading()
Resume reading callback.
std::vector< std::string > const & get_requested_subprotocols() const
Gets all of the subprotocols requested by the client.
void close(close::status::value const code, std::string const &reason)
Close the connection.
std::string const & get_subprotocol() const
Gets the negotated subprotocol.
void set_handle(connection_hdl hdl)
Set Connection Handle.
void handle_pong_timeout(std::string payload, lib::error_code const &ec)
Utility method that gets called back when the ping timer expires.
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.
void read_frame()
Issue a new transport read unless reading is paused.
uint16_t get_port() const
Returns the port component of the connection URI.
std::string const & get_local_close_reason() const
Get the WebSocket close reason sent by this endpoint.
size_t get_max_message_size() const
Get maximum message size.
void append_header(std::string const &key, std::string const &val)
Append a header.
config::rng_type rng_type
Type of RNG.
Stub for user supplied base class.
Creates and manages connections associated with a WebSocket endpoint.
void set_max_http_body_size(size_t new_value)
Set maximum HTTP message body size.
void set_user_agent(std::string const &ua)
Sets the user agent string that this endpoint will use.
connection_ptr get_con_from_hdl(connection_hdl hdl, lib::error_code &ec)
Retrieves a connection_ptr from a connection_hdl (exception free)
config::concurrency_type concurrency_type
Type of the concurrency component of this endpoint.
config::alog_type alog_type
Type of access logger.
void ping(connection_hdl hdl, std::string const &payload, lib::error_code &ec)
Send a ping to a specific connection.
alog_type & get_alog()
Get reference to access logger.
transport_con_type::ptr transport_con_ptr
std::string get_user_agent() const
Returns the user agent string that this endpoint will use.
void ping(connection_hdl hdl, std::string const &payload)
Send a ping to a specific connection.
void clear_access_channels(log::level channels)
Clear Access logging channels.
void resume_reading(connection_hdl hdl)
Resume reading of new data.
config::elog_type elog_type
Type of error logger.
elog_type & get_elog()
Get reference to error logger.
bool is_server() const
Returns whether or not this endpoint is a server.
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)
void set_close_handshake_timeout(long dur)
Set close handshake timeout.
connection_type::message_ptr message_ptr
Type of message pointers that this endpoint uses.
void pong(connection_hdl hdl, std::string const &payload, lib::error_code &ec)
Send a pong to a specific connection.
void set_access_channels(log::level channels)
Set Access logging channel.
void set_max_message_size(size_t new_value)
Set default maximum message size.
size_t get_max_message_size() const
Get default maximum message size.
connection_ptr get_con_from_hdl(connection_hdl hdl)
Retrieves a connection_ptr from a connection_hdl (exception version)
connection connection_type
Type of the connections that this endpoint creates.
void set_error_channels(log::level channels)
Set Error logging channel.
config::transport_type transport_type
Type of the transport component of this endpoint.
void clear_error_channels(log::level channels)
Clear Error logging channels.
void resume_reading(connection_hdl hdl, lib::error_code &ec)
Resume reading of new data (exception free)
void send(connection_hdl hdl, std::string const &payload, frame::opcode::value op)
Create a message and add it to the outgoing send queue.
connection_type::ptr connection_ptr
Shared pointer to connection_type.
transport_type::transport_con_type transport_con_type
concurrency_type::mutex_type mutex_type
Type of our concurrency policy's mutex object.
void pong(connection_hdl hdl, std::string const &payload)
Send a pong to a specific connection.
void interrupt(connection_hdl hdl, lib::error_code &ec)
void set_pong_timeout(long dur)
Set pong timeout.
size_t get_max_http_body_size() const
Get maximum HTTP message body size.
void set_open_handshake_timeout(long dur)
Set open handshake timeout.
config::rng_type rng_type
Type of RNG.
concurrency_type::scoped_lock_type scoped_lock_type
Type of our concurrency policy's scoped lock object.
void send_http_response(connection_hdl hdl, lib::error_code &ec)
Send deferred HTTP Response.
void pause_reading(connection_hdl hdl, lib::error_code &ec)
Pause reading of new data (exception free)
void send_http_response(connection_hdl hdl)
Send deferred HTTP Response (exception free)
void pause_reading(connection_hdl hdl)
Pause reading of new data.
connection_type::message_handler message_handler
Type of message_handler.
connection_type::weak_ptr connection_weak_ptr
Weak pointer to connection type.
Stub class for use when disabling permessage_deflate extension.
bool is_implemented() const
err_str_pair negotiate(http::attribute_list const &)
Negotiate extension.
lib::error_code compress(std::string const &, std::string &)
Compress bytes.
std::string generate_offer() const
Generate extension offer.
lib::error_code decompress(uint8_t const *, size_t, std::string &)
Decompress bytes.
lib::error_code init(bool)
Initialize state.
header_list const & get_headers() const
Return a list of all HTTP headers.
size_t process_body(char const *buf, size_t len)
Process body data.
std::string const & get_body() const
Get HTTP body.
bool get_header_as_plist(std::string const &key, parameter_list &out) const
Extract an HTTP parameter list from a parser header.
void process_header(std::string::iterator begin, std::string::iterator end)
Process a header line.
void set_version(std::string const &version)
Set HTTP parser Version.
void remove_header(std::string const &key)
Remove a header from the parser.
void set_body(std::string const &value)
Set body content.
bool body_ready() const
Check if the parser is done parsing the body.
bool prepare_body()
Prepare the parser to begin parsing body data.
void set_max_body_size(size_t value)
Set body size limit.
void replace_header(std::string const &key, std::string const &val)
Set a value for an HTTP header, replacing an existing value.
void append_header(std::string const &key, std::string const &val)
Append a value to an existing HTTP header.
std::string raw_headers() const
Generate and return the HTTP headers as a string.
std::string const & get_header(std::string const &key) const
Get the value of an HTTP header.
std::string const & get_version() const
Get the HTTP version string.
bool parse_parameter_list(std::string const &in, parameter_list &out) const
Extract an HTTP parameter list from a string.
size_t get_max_body_size() const
Get body size limit.
Stores, parses, and manipulates HTTP requests.
std::string raw() const
Returns the full raw request (including the body)
std::string const & get_uri() const
Return the requested URI.
std::string const & get_method() const
Return the request method.
size_t consume(char const *buf, size_t len)
Process bytes in the input buffer.
void set_uri(std::string const &uri)
Set the HTTP uri. Must be a valid HTTP uri.
bool ready() const
Returns whether or not the request is ready for reading.
void set_method(std::string const &method)
Set the HTTP method. Must be a valid HTTP token.
std::string raw_head() const
Returns the raw request headers only (similar to an HTTP HEAD request)
Stores, parses, and manipulates HTTP responses.
void set_status(status_code::value code)
Set response status code and message.
std::string raw() const
Returns the full raw response.
size_t consume(std::istream &s)
Process bytes in the input buffer (istream version)
bool headers_ready() const
Returns true if the response headers are fully parsed.
bool ready() const
Returns true if the response is ready.
void set_status(status_code::value code, std::string const &msg)
Set response status code and message.
const std::string & get_status_msg() const
Return the response status message.
status_code::value get_status_code() const
Return the response status code.
size_t consume(char const *buf, size_t len)
Process bytes in the input buffer.
Basic logger that outputs to an ostream.
void write(level channel, char const *msg)
Write a cstring message to the given channel.
void write(level channel, std::string const &msg)
Write a string message to the given channel.
bool recycle(message *)
Recycle a message.
message_ptr get_message(frame::opcode::value op, size_t size)
Get a message buffer with specified size and opcode.
message_ptr get_message()
Get an empty message buffer.
con_msg_man_ptr get_manager() const
Get a pointer to a connection message manager.
Represents a buffer for a single WebSocket message.
message(const con_msg_man_ptr manager, frame::opcode::value op, size_t size=128)
Construct a message and fill in some values.
std::string & get_raw_payload()
Get a non-const reference to the payload string.
void set_header(std::string const &header)
Set prepared frame header.
bool recycle()
Recycle the message.
bool get_compressed() const
Return whether or not the message is flagged as compressed.
void set_payload(std::string const &payload)
Set payload data.
bool get_terminal() const
Get whether or not the message is terminal.
std::string const & get_header() const
Return the prepared frame header.
void set_payload(void const *payload, size_t len)
Set payload data.
bool get_fin() const
Read the fin bit.
void append_payload(void const *payload, size_t len)
Append payload data.
void set_opcode(frame::opcode::value op)
Set the opcode.
void set_prepared(bool value)
Set or clear the flag that indicates that the message has been prepared.
frame::opcode::value get_opcode() const
Return the message opcode.
void set_terminal(bool value)
Set the terminal flag.
bool get_prepared() const
Return whether or not the message has been prepared for sending.
void append_payload(std::string const &payload)
Append payload data.
void set_compressed(bool value)
Set or clear the compression flag.
message(const con_msg_man_ptr manager)
Construct an empty message.
void set_fin(bool value)
Set the fin bit.
std::string const & get_payload() const
Get a reference to the payload string.
Category for processor errors.
Processor for Hybi Draft version 00.
Processor for Hybi Draft version 07.
Processor for Hybi Draft version 08.
Processor for Hybi version 13 (RFC6455)
WebSocket protocol processor abstract base class.
virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out)=0
Prepare a data message for writing.
virtual size_t get_bytes_needed() const
virtual size_t consume(uint8_t *buf, size_t len, lib::error_code &ec)=0
process new websocket connection bytes
virtual lib::error_code prepare_close(close::status::value code, std::string const &reason, message_ptr out) const =0
Prepare a close frame.
virtual err_str_pair negotiate_extensions(response_type const &)
Initializes extensions based on the Sec-WebSocket-Extensions header.
virtual int get_version() const =0
Get the protocol version of this processor.
virtual std::string get_raw(response_type const &request) const =0
Given a completed response, get the raw bytes to put on the wire.
virtual bool ready() const =0
Checks if there is a message ready.
virtual lib::error_code process_handshake(request_type const &req, std::string const &subprotocol, response_type &res) const =0
Calculate the appropriate response for this websocket request.
virtual lib::error_code validate_handshake(request_type const &request) const =0
validate a WebSocket handshake request for this version
virtual uri_ptr get_uri(request_type const &request) const =0
Extracts client uri from a handshake request.
virtual err_str_pair negotiate_extensions(request_type const &)
Initializes extensions based on the Sec-WebSocket-Extensions header.
virtual bool has_permessage_compress() const
Returns whether or not the permessage_compress extension is implemented.
virtual lib::error_code prepare_ping(std::string const &in, message_ptr out) const =0
Prepare a ping frame.
virtual lib::error_code validate_server_handshake_response(request_type const &req, response_type &res) const =0
Validate the server's response to an outgoing handshake request.
virtual lib::error_code client_handshake_request(request_type &req, uri_ptr uri, std::vector< std::string > const &subprotocols) const =0
Fill in an HTTP request for an outgoing connection handshake.
virtual lib::error_code extract_subprotocols(const request_type &req, std::vector< std::string > &subprotocol_list)=0
Extracts requested subprotocols from a handshake request.
virtual bool get_error() const =0
Tests whether the processor is in a fatal error state.
void set_max_message_size(size_t new_value)
Set maximum message size.
virtual std::string const & get_origin(request_type const &request) const =0
Return the value of the header containing the CORS origin.
size_t get_max_message_size() const
Get maximum message size.
virtual message_ptr get_message()=0
Retrieves the most recently processed message.
virtual lib::error_code prepare_pong(std::string const &in, message_ptr out) const =0
Prepare a pong frame.
Thread safe stub "random" integer generator.
int_type operator()()
advances the engine's state and returns the generated value
Server endpoint role based on the given config.
void start_accept(lib::error_code &ec)
Starts the server's async connection acceptance loop (exception free)
transport_type::transport_con_type transport_con_type
Type of the connection transport component.
connection_type::ptr connection_ptr
Type of a shared pointer to the connections this server will create.
server< config > type
Type of this endpoint.
endpoint< connection_type, config > endpoint_type
Type of the endpoint component of this server.
config::transport_type transport_type
Type of the endpoint transport component.
connection< config > connection_type
Type of the connections this server will create.
connection_ptr get_connection()
Create and initialize a new connection.
void handle_accept(connection_ptr con, lib::error_code const &ec)
Handler callback for start_accept.
void start_accept()
Starts the server's async connection acceptance loop.
config::concurrency_type concurrency_type
Type of the endpoint concurrency component.
transport_con_type::ptr transport_con_ptr
Type of a shared pointer to the connection transport component.
Basic Asio connection socket component.
lib::asio::ip::tcp::socket & get_raw_socket()
Retrieve a pointer to the underlying socket.
lib::shared_ptr< type > ptr
Type of a shared pointer to this connection socket component.
void set_socket_init_handler(socket_init_handler h)
Set the socket initialization handler.
void set_uri(uri_ptr)
Set uri hook.
connection type
Type of this connection socket component.
lib::asio::ip::tcp::socket & get_socket()
Retrieve a pointer to the underlying socket.
bool is_secure() const
Check whether or not this connection is secure.
lib::shared_ptr< socket_type > socket_ptr
Type of a shared pointer to the socket being used.
static lib::error_code translate_ec(lib::error_code ec)
static lib::error_code translate_ec(ErrorCodeType)
Translate any security policy specific information about an error code.
void set_handle(connection_hdl hdl)
Sets the connection handle.
lib::asio::error_code cancel_socket()
Cancel all async operations on this socket.
void pre_init(init_handler callback)
Pre-initialize security policy.
std::string get_remote_endpoint(lib::error_code &ec) const
Get the remote endpoint address.
void post_init(init_handler callback)
Post-initialize security policy.
lib::error_code init_asio(io_service_ptr service, strand_ptr, bool)
Perform one time initializations.
lib::asio::ip::tcp::socket socket_type
Type of the ASIO socket being used.
ptr get_shared()
Get a shared pointer to this component.
lib::shared_ptr< lib::asio::io_service::strand > strand_ptr
Type of a pointer to the Asio io_service strand being used.
lib::asio::ip::tcp::socket & get_next_layer()
Retrieve a pointer to the underlying socket.
lib::asio::io_service * io_service_ptr
Type of a pointer to the Asio io_service being used.
Basic ASIO endpoint socket component.
void set_socket_init_handler(socket_init_handler h)
Set socket init handler.
lib::error_code init(socket_con_ptr scon)
Initialize a connection.
endpoint type
The type of this endpoint socket component.
bool is_secure() const
Checks whether the endpoint creates secure connections.
connection socket_con_type
The type of the corresponding connection socket component.
socket_con_type::ptr socket_con_ptr
Asio based connection transport component.
void set_proxy_timeout(long duration)
Set the proxy timeout duration (exception)
void set_tcp_post_init_handler(tcp_init_handler h)
Sets the tcp post init handler.
void set_proxy_basic_auth(std::string const &username, std::string const &password)
Set the basic auth credentials to use (exception)
void set_proxy_timeout(long duration, lib::error_code &ec)
Set the proxy timeout duration (exception free)
config::elog_type elog_type
Type of this transport's error logging policy.
strand_ptr get_strand()
Get a pointer to this connection's strand.
void async_read_at_least(size_t num_bytes, char *buf, size_t len, read_handler handler)
read at least num_bytes bytes into buf and then call handler.
lib::error_code proxy_init(std::string const &authority)
initialize the proxy buffers and http parsers
socket_con_type::ptr socket_con_ptr
Type of a shared pointer to the socket connection component.
lib::error_code interrupt(interrupt_handler handler)
Trigger the on_interrupt handler.
config::alog_type alog_type
Type of this transport's access logging policy.
void handle_async_write(write_handler handler, lib::asio::error_code const &ec, size_t)
Async write callback.
void handle_timer(timer_ptr, timer_handler callback, lib::asio::error_code const &ec)
Timer callback.
lib::error_code init_asio(io_service_ptr io_service)
Finish constructing the transport.
void handle_post_init(timer_ptr post_timer, init_handler callback, lib::error_code const &ec)
Post init timeout callback.
void async_shutdown(shutdown_handler callback)
close and clean up the underlying socket
lib::asio::error_code get_transport_ec() const
Get the internal transport error code for a closed/failed connection.
config::socket_type::socket_con_type socket_con_type
Type of the socket connection component.
lib::asio::io_service * io_service_ptr
Type of a pointer to the Asio io_service being used.
void set_proxy(std::string const &uri)
Set the proxy to connect through (exception)
void handle_post_init_timeout(timer_ptr, init_handler callback, lib::error_code const &ec)
Post init timeout callback.
connection< config > type
Type of this connection transport component.
void handle_async_shutdown_timeout(timer_ptr, init_handler callback, lib::error_code const &ec)
Async shutdown timeout handler.
void set_proxy(std::string const &uri, lib::error_code &ec)
Set the proxy to connect through (exception free)
lib::shared_ptr< lib::asio::steady_timer > timer_ptr
Type of a pointer to the Asio timer class.
void set_proxy_basic_auth(std::string const &username, std::string const &password, lib::error_code &ec)
Set the basic auth credentials to use (exception free)
void async_write(const char *buf, size_t len, write_handler handler)
Initiate a potentially asyncronous write of the given buffer.
void async_write(std::vector< buffer > const &bufs, write_handler handler)
Initiate a potentially asyncronous write of the given buffers.
lib::shared_ptr< type > ptr
Type of a shared pointer to this connection transport component.
timer_ptr set_timer(long duration, timer_handler callback)
Call back a function after a period of time.
void set_tcp_init_handler(tcp_init_handler h)
Sets the tcp pre init handler (deprecated)
void handle_proxy_read(init_handler callback, lib::asio::error_code const &ec, size_t)
Proxy read callback.
void set_uri(uri_ptr u)
Set uri hook.
std::string get_remote_endpoint() const
Get the remote endpoint address.
ptr get_shared()
Get a shared pointer to this component.
void cancel_socket_checked()
Cancel the underlying socket and log any errors.
void set_handle(connection_hdl hdl)
Set Connection Handle.
void set_tcp_pre_init_handler(tcp_init_handler h)
Sets the tcp pre init handler.
lib::shared_ptr< lib::asio::io_service::strand > strand_ptr
Type of a pointer to the Asio io_service::strand being used.
void init(init_handler callback)
Initialize transport for reading.
connection_hdl get_handle() const
Get the connection handle.
Asio based endpoint transport component.
std::size_t run_one()
wraps the run_one method of the internal io_service object
socket_type::socket_con_type socket_con_type
Type of the socket connection component.
void stop_listening(lib::error_code &ec)
Stop listening (exception free)
config::socket_type socket_type
Type of the socket policy.
lib::shared_ptr< lib::asio::steady_timer > timer_ptr
Type of timer handle.
void async_connect(transport_con_ptr tcon, uri_ptr u, connect_handler cb)
Initiate a new connection.
void init_asio()
Initialize asio transport with internal io_service.
config::elog_type elog_type
Type of the error logging policy.
void init_logging(const lib::shared_ptr< alog_type > &a, const lib::shared_ptr< elog_type > &e)
Initialize logging.
bool is_secure() const
Return whether or not the endpoint produces secure connections.
void init_asio(io_service_ptr ptr)
initialize asio transport with external io_service
lib::asio::ip::tcp::endpoint get_local_endpoint(lib::asio::error_code &ec)
Get local TCP endpoint.
void set_reuse_addr(bool value)
Sets whether to use the SO_REUSEADDR flag when opening listening sockets.
void set_tcp_init_handler(tcp_init_handler h)
Sets the tcp pre init handler (deprecated)
void handle_timer(timer_ptr, timer_handler callback, lib::asio::error_code const &ec)
Timer handler.
void start_perpetual()
Marks the endpoint as perpetual, stopping it from exiting when empty.
void stop()
wraps the stop method of the internal io_service object
std::size_t run()
wraps the run method of the internal io_service object
void set_tcp_post_init_handler(tcp_init_handler h)
Sets the tcp post init handler.
void set_listen_backlog(int backlog)
Sets the maximum length of the queue of pending connections.
bool stopped() const
wraps the stopped method of the internal io_service object
timer_ptr set_timer(long duration, timer_handler callback)
Call back a function after a period of time.
void init_asio(io_service_ptr ptr, lib::error_code &ec)
initialize asio transport with external io_service (exception free)
socket_con_type::ptr socket_con_ptr
Type of a shared pointer to the socket connection component.
lib::error_code init(transport_con_ptr tcon)
Initialize a connection.
asio::connection< config > transport_con_type
void init_asio(lib::error_code &ec)
Initialize asio transport with internal io_service (exception free)
void async_accept(transport_con_ptr tcon, accept_handler callback)
Accept the next connection attempt and assign it to con.
void listen(uint16_t port)
Set up endpoint for listening on a port.
void listen(std::string const &host, std::string const &service, lib::error_code &ec)
Set up endpoint for listening on a host and service (exception free)
endpoint< config > type
Type of this endpoint transport component.
lib::asio::io_service & get_io_service()
Retrieve a reference to the endpoint's io_service.
config::concurrency_type concurrency_type
Type of the concurrency policy.
std::size_t poll()
wraps the poll method of the internal io_service object
void stop_perpetual()
Clears the endpoint's perpetual flag, allowing it to exit when empty.
lib::shared_ptr< lib::asio::ip::tcp::acceptor > acceptor_ptr
Type of a shared pointer to the acceptor being used.
void listen(lib::asio::ip::tcp::endpoint const &ep)
Set up endpoint for listening manually.
void handle_resolve_timeout(timer_ptr, connect_handler callback, lib::error_code const &ec)
DNS resolution timeout handler.
void listen(lib::asio::ip::tcp::endpoint const &ep, lib::error_code &ec)
Set up endpoint for listening manually (exception free)
transport_con_type::ptr transport_con_ptr
lib::shared_ptr< lib::asio::io_service::work > work_ptr
Type of a shared pointer to an io_service work object.
void reset()
wraps the reset method of the internal io_service object
void set_tcp_pre_bind_handler(tcp_pre_bind_handler h)
Sets the tcp pre bind handler.
config::alog_type alog_type
Type of the access logging policy.
lib::asio::io_service * io_service_ptr
Type of a pointer to the ASIO io_service being used.
void listen(InternetProtocol const &internet_protocol, uint16_t port)
Set up endpoint for listening with protocol and port.
void set_tcp_pre_init_handler(tcp_init_handler h)
Sets the tcp pre init handler.
void listen(std::string const &host, std::string const &service)
Set up endpoint for listening on a host and service.
void handle_connect_timeout(transport_con_ptr tcon, timer_ptr, connect_handler callback, lib::error_code const &ec)
Asio connect timeout handler.
void async_accept(transport_con_ptr tcon, accept_handler callback, lib::error_code &ec)
Accept the next connection attempt and assign it to con (exception free)
std::size_t poll_one()
wraps the poll_one method of the internal io_service object
void listen(InternetProtocol const &internet_protocol, uint16_t port, lib::error_code &ec)
Set up endpoint for listening with protocol and port (exception free)
void listen(uint16_t port, lib::error_code &ec)
Set up endpoint for listening on a port (exception free)
bool is_listening() const
Check if the endpoint is listening.
void stop_listening()
Stop listening.
lib::shared_ptr< lib::asio::ip::tcp::resolver > resolver_ptr
Type of a shared pointer to the resolver being used.
lib::function< lib::error_code(acceptor_ptr)> tcp_pre_bind_handler
Type of socket pre-bind handler.
Asio transport error category.
Error category related to asio transport socket policies.
lib::shared_ptr< type > ptr
Type of a shared pointer to this connection transport component.
connection_hdl get_handle() const
Get the connection handle.
config::alog_type alog_type
Type of this transport's access logging policy.
lib::error_code dispatch(dispatch_handler handler)
Call given handler back within the transport's event system (if present)
void set_uri(uri_ptr)
Set uri hook.
void async_shutdown(transport::shutdown_handler handler)
Perform cleanup on socket shutdown_handler.
void set_write_handler(write_handler h)
Sets the write handler.
void set_secure(bool value)
Set whether or not this connection is secure.
void set_shutdown_handler(shutdown_handler h)
Sets the shutdown handler.
connection< config > type
Type of this connection transport component.
config::elog_type elog_type
Type of this transport's error logging policy.
void fatal_error()
Signal transport error.
size_t read_some(char const *buf, size_t len)
Manual input supply (read some)
size_t read_all(char const *buf, size_t len)
Manual input supply (read all)
void async_write(char const *buf, size_t len, transport::write_handler handler)
Asyncronous Transport Write.
size_t readsome(char const *buf, size_t len)
Manual input supply (DEPRECATED)
config::concurrency_type concurrency_type
transport concurrency policy
void init(init_handler handler)
Initialize the connection transport.
timer_ptr set_timer(long, timer_handler)
Call back a function after a period of time.
void set_remote_endpoint(std::string value)
Set human readable remote endpoint address.
friend std::istream & operator>>(std::istream &in, type &t)
Overloaded stream input operator.
void set_vector_write_handler(vector_write_handler h)
Sets the vectored write handler.
bool is_secure() const
Tests whether or not the underlying transport is secure.
std::string get_remote_endpoint() const
Get human readable remote endpoint address.
void set_handle(connection_hdl hdl)
Set Connection Handle.
void register_ostream(std::ostream *o)
Register a std::ostream with the transport for writing output.
void async_read_at_least(size_t num_bytes, char *buf, size_t len, read_handler handler)
Initiate an async_read for at least num_bytes bytes into buf.
void async_write(std::vector< buffer > const &bufs, transport::write_handler handler)
Asyncronous Transport Write (scatter-gather)
ptr get_shared()
Get a shared pointer to this component.
iostream::connection< config > transport_con_type
config::elog_type elog_type
Type of this endpoint's error logging policy.
void set_write_handler(write_handler h)
Sets the write handler.
void set_shutdown_handler(shutdown_handler h)
Sets the shutdown handler.
bool is_secure() const
Tests whether or not the underlying transport is secure.
lib::shared_ptr< type > ptr
Type of a pointer to this endpoint transport component.
transport_con_type::ptr transport_con_ptr
void async_connect(transport_con_ptr, uri_ptr, connect_handler cb)
Initiate a new connection.
lib::error_code init(transport_con_ptr tcon)
Initialize a connection.
void init_logging(lib::shared_ptr< alog_type > a, lib::shared_ptr< elog_type > e)
Initialize logging.
endpoint type
Type of this endpoint transport component.
void register_ostream(std::ostream *o)
Register a default output stream.
config::concurrency_type concurrency_type
Type of this endpoint's concurrency policy.
void set_secure(bool value)
Set whether or not endpoint can create secure connections.
config::alog_type alog_type
Type of this endpoint's access logging policy.
iostream transport error category
std::string get_query() const
Return the query portion.
Provides streaming UTF8 validation functionality.
bool decode(iterator_type begin, iterator_type end)
Advance validator state with input from an iterator pair.
validator()
Construct and initialize the validator.
bool complete()
Return whether the input sequence ended on a valid utf8 codepoint.
void reset()
Reset the validator to decode another message.
bool consume(uint8_t byte)
Advance the state of the validator with the next input byte.
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_
A package of types and methods for manipulating WebSocket close status'.
static value const service_restart
static value const message_too_big
An endpoint received a message too large to process.
static value const try_again_later
static value const force_tcp_drop
Close the connection with a forced TCP drop.
static value const tls_handshake
An endpoint failed to perform a TLS handshake.
static value const rsv_end
Last value in range reserved for future protocol use.
static value const invalid_payload
An endpoint received message data inconsistent with its type.
bool terminal(value code)
Determine if the code represents an unrecoverable error.
static value const protocol_error
A protocol error occurred.
std::string get_string(value code)
Return a human readable interpretation of a WebSocket close code.
static value const bad_gateway
static value const invalid_subprotocol_data
A invalid subprotocol data.
static value const invalid_high
Last value in range that is always invalid on the wire.
static value const unsupported_data
static value const no_status
A dummy value to indicate that no status code was received.
static value const omit_handshake
Close the connection without a WebSocket close handshake.
static value const normal
static value const blank
A blank value for internal use.
static value const invalid_low
First value in range that is always invalid on the wire.
static value const abnormal_close
A dummy value to indicate that the connection was closed abnormally.
static value const rsv_start
First value in range reserved for future protocol use.
uint16_t value
The type of a close code value.
static value const policy_violation
An endpoint received a message that violated its policy.
static value const extension_required
A client expected the server to accept a required extension request.
bool invalid(value code)
Test whether a close code is invalid on the wire.
static value const internal_endpoint_error
static value const subprotocol_error
A generic subprotocol error.
bool reserved(value code)
Test whether a close code is in a reserved range.
static value const going_away
A package of types and methods for manipulating WebSocket close codes.
std::string extract_reason(std::string const &payload, lib::error_code &ec)
Extract the reason string from a close payload.
status::value extract_code(std::string const &payload, lib::error_code &ec)
Extract a close code value from a close payload.
Concurrency handling support.
Library level error codes.
@ general
Catch-all library error.
@ unrequested_subprotocol
Selected subprotocol was not requested by the client.
@ invalid_port
Invalid port in URI.
@ client_only
Attempted to use a client specific feature on a server endpoint.
@ http_connection_ended
HTTP connection ended.
@ async_accept_not_listening
@ operation_canceled
The requested operation was canceled.
@ no_outgoing_buffers
The endpoint is out of outgoing message buffers.
@ http_parse_error
HTTP parse error.
@ reserved_close_code
Close code is in a reserved range.
@ con_creation_failed
Connection creation attempted failed.
@ no_incoming_buffers
The endpoint is out of incoming message buffers.
@ invalid_state
The connection was in the wrong state for this operation.
@ extension_neg_failed
Extension negotiation failed.
@ rejected
Connection rejected.
@ unsupported_version
Unsupported WebSocket protocol version.
@ invalid_utf8
Invalid UTF-8.
@ invalid_close_code
Close code is invalid.
@ server_only
Attempted to use a server specific feature on a client endpoint.
@ endpoint_not_secure
Attempted to open a secure connection with an insecure endpoint.
@ close_handshake_timeout
WebSocket close handshake timed out.
@ invalid_subprotocol
Invalid subprotocol.
@ bad_close_code
Unable to parse close code.
@ open_handshake_timeout
WebSocket opening handshake timed out.
@ invalid_version
Invalid WebSocket protocol version.
@ send_queue_full
send attempted when endpoint write queue was full
@ test
Unit testing utility error code.
@ invalid_uri
An invalid uri was supplied.
Implementation of RFC 7692, the permessage-deflate WebSocket extension.
Constants related to frame and payload limits.
static uint8_t const close_reason_size
Maximum size of close frame reason.
static uint64_t const payload_size_jumbo
Maximum size of a jumbo WebSocket payload (basic payload = 127)
static unsigned int const max_extended_header_length
Maximum length of the variable portion of the WebSocket header.
static unsigned int const max_header_length
Maximum length of a WebSocket header.
static uint16_t const payload_size_extended
Maximum size of an extended WebSocket payload (basic payload = 126)
static uint8_t const payload_size_basic
Maximum size of a basic WebSocket payload.
static unsigned int const basic_header_length
Minimum length of a WebSocket frame header.
Constants and utility functions related to WebSocket opcodes.
bool invalid(value v)
Check if an opcode is invalid.
bool reserved(value v)
Check if an opcode is reserved.
bool is_control(value v)
Check if an opcode is for a control frame.
Data structures and utility functions for manipulating WebSocket frames.
unsigned int get_masking_key_offset(basic_header const &)
Calculate the offset location of the masking key within the extended header.
void set_rsv2(basic_header &h, bool value)
Set the frame's RSV2 bit.
static unsigned int const MAX_HEADER_LENGTH
Maximum length of a WebSocket header.
opcode::value get_opcode(basic_header const &h)
Extract opcode from basic header.
void set_rsv3(basic_header &h, bool value)
Set the frame's RSV3 bit.
uint64_t get_payload_size(basic_header const &, extended_header const &)
Extract the full payload size field from a WebSocket header.
uint8_t get_basic_size(basic_header const &)
Extracts the raw payload length specified in the basic header.
size_t byte_mask_circ(uint8_t *input, uint8_t *output, size_t length, size_t prepared_key)
Circular byte aligned mask/unmask.
void byte_mask(input_iter b, input_iter e, output_iter o, masking_key_type const &key, size_t key_offset=0)
Byte by byte mask/unmask.
static unsigned int const MAX_EXTENDED_HEADER_LENGTH
Maximum length of the variable portion of the WebSocket header.
bool get_rsv3(basic_header const &h)
check whether the frame's RSV3 bit is set
bool get_masked(basic_header const &h)
check whether the frame is masked
bool get_rsv2(basic_header const &h)
check whether the frame's RSV2 bit is set
void byte_mask(iter_type b, iter_type e, masking_key_type const &key, size_t key_offset=0)
Byte by byte mask/unmask (in place)
uint16_t get_extended_size(extended_header const &)
Extract the extended size field from an extended header.
size_t byte_mask_circ(uint8_t *data, size_t length, size_t prepared_key)
Circular byte aligned mask/unmask (in place)
bool get_fin(basic_header const &h)
Check whether the frame's FIN bit is set.
size_t circshift_prepared_key(size_t prepared_key, size_t offset)
circularly shifts the supplied prepared masking key by offset bytes
bool get_rsv1(basic_header const &h)
check whether the frame's RSV1 bit is set
void set_masked(basic_header &h, bool value)
Set the frame's MASK bit.
size_t word_mask_circ(uint8_t *input, uint8_t *output, size_t length, size_t prepared_key)
Circular word aligned mask/unmask.
void word_mask_exact(uint8_t *data, size_t length, masking_key_type const &key)
Exact word aligned mask/unmask (in place)
void set_rsv1(basic_header &h, bool value)
Set the frame's RSV1 bit.
size_t get_header_len(basic_header const &)
Calculates the full length of the header based on the first bytes.
void set_fin(basic_header &h, bool value)
Set the frame's FIN bit.
uint64_t get_jumbo_size(extended_header const &)
Extract the jumbo size field from an extended header.
void word_mask_exact(uint8_t *input, uint8_t *output, size_t length, masking_key_type const &key)
Exact word aligned mask/unmask.
std::string prepare_header(const basic_header &h, const extended_header &e)
Generate a properly sized contiguous string that encodes a full frame header.
masking_key_type get_masking_key(basic_header const &, extended_header const &)
Extract the masking key from a frame header.
static unsigned int const BASIC_HEADER_LENGTH
Minimum length of a WebSocket frame header.
size_t word_mask_circ(uint8_t *data, size_t length, size_t prepared_key)
Circular word aligned mask/unmask (in place)
size_t prepare_masking_key(masking_key_type const &key)
Extract a masking key into a value the size of a machine word.
size_t const max_body_size
Default Maximum size in bytes for HTTP message bodies.
static char const header_separator[]
Literal value of the HTTP header separator.
std::vector< std::pair< std::string, attribute_list > > parameter_list
The type of an HTTP parameter list.
size_t const istream_buffer
Number of bytes to use for temporary istream read buffers.
bool is_not_token_char(unsigned char c)
Is the character a non-token.
size_t const max_header_size
Maximum size in bytes before rejecting an HTTP header as too big.
static char const header_delimiter[]
Literal value of the HTTP header delimiter.
bool is_whitespace_char(unsigned char c)
Is the character whitespace.
static char const header_token[]
invalid HTTP token characters
bool is_not_whitespace_char(unsigned char c)
Is the character non-whitespace.
std::map< std::string, std::string > attribute_list
The type of an HTTP attribute list.
bool is_token_char(unsigned char c)
Is the character a token.
static std::string const empty_header
Literal value of an empty header.
Constants related to processing WebSocket connections.
Processor class related error codes.
Error code category and codes used by all processor types.
lib::error_category const & get_processor_category()
Get a reference to a static copy of the processor error category.
close::status::value to_ws(lib::error_code ec)
Converts a processor error_code into a websocket close code.
@ missing_required_header
Missing Required Header.
@ control_too_big
Control frame too large.
@ invalid_http_method
Invalid HTTP method.
@ invalid_rsv_bit
Illegal use of reserved bit.
@ reason_requires_code
Using a reason requires a close code.
@ invalid_close_code
Invalid close code used.
@ masking_required
Clients may not send unmasked frames.
@ protocol_violation
Processor encountered a protocol violation in an incoming message.
@ extensions_disabled
Extension related operation was ignored because extensions are disabled.
@ reserved_close_code
Reserved close code used.
@ extension_parse_error
Error parsing extensions.
@ masking_forbidden
Servers may not send masked frames.
@ not_implemented
Operation required not implemented functionality.
@ invalid_opcode
Opcode was invalid for requested operation.
@ sha1_library
Embedded SHA-1 library error.
@ requires_64bit
Not supported on 32 bit systems.
@ subprotocol_parse_error
Error parsing subprotocols.
@ bad_request
Error was the result of improperly formatted user input.
@ invalid_utf8
Invalid UTF-8 encoding.
@ invalid_http_status
Invalid HTTP status.
@ invalid_payload
Processor encountered invalid payload data.
@ invalid_http_version
Invalid HTTP version.
@ message_too_big
Processor encountered a message that was too large.
@ no_protocol_support
No support for this feature in this protocol version.
@ invalid_arguments
The processor method was called with invalid arguments.
@ invalid_continuation
Continuation without message.
@ non_minimal_encoding
Payload length not minimally encoded.
@ fragmented_control
Fragmented control message.
lib::error_code make_error_code(error::processor_errors e)
Create an error code with the given value and the processor category.
Processors encapsulate the protocol rules specific to each WebSocket version.
int get_websocket_version(request_type &r)
Extract the version from a WebSocket handshake request.
uri_ptr get_uri_from_host(request_type &request, std::string scheme)
Extract a URI ptr from the host header of the request.
bool is_websocket_handshake(request_type &r)
Determine whether or not a generic HTTP request is a WebSocket handshake.
Stub RNG policy that always returns 0.
Random number generation policies.
lib::function< void(connection_hdl, lib::asio::ip::tcp::socket &)> socket_init_handler
The signature of the socket init handler for this socket policy.
lib::error_category const & get_category()
Get a reference to a static copy of the asio transport error category.
lib::error_code make_error_code(error::value e)
Create an error code with the given value and the asio transport category.
@ proxy_invalid
Invalid Proxy URI.
@ pass_through
there was an error in the underlying transport library
@ proxy_failed
The connection to the requested proxy server failed.
@ invalid_num_bytes
async_read_at_least call requested more bytes than buffer can store
@ invalid_host_service
Invalid host or service.
Errors related to asio transport sockets.
@ missing_tls_init_handler
Required tls_init handler not present.
@ invalid_state
A function was called in a state that it was illegal to do so.
@ tls_failed_sni_hostname
Failed to set TLS SNI hostname.
@ tls_handshake_failed
TLS Handshake Failed.
@ tls_handshake_timeout
TLS Handshake Timeout.
@ pass_through
pass_through from underlying library
Transport policy that uses asio.
Generic transport related errors.
@ pass_through
underlying transport pass through
@ operation_not_supported
Operation not supported.
@ operation_aborted
Operation aborted.
@ tls_error
Other TLS error.
@ invalid_num_bytes
async_read_at_least call requested more bytes than buffer can store
@ action_after_shutdown
read or write after shutdown
@ tls_short_read
TLS short read.
@ double_read
async_read called while another async_read was in progress
iostream transport errors
@ invalid_num_bytes
async_read_at_least call requested more bytes than buffer can store
@ double_read
async_read called while another async_read was in progress
lib::error_code make_error_code(error::value e)
Get an error code with the given value and the iostream transport category.
lib::error_category const & get_category()
Get a reference to a static copy of the iostream transport error category.
Transport policy that uses STL iostream for I/O and does not support timers.
lib::function< lib::error_code(connection_hdl, std::vector< transport::buffer > const &bufs)> vector_write_handler
lib::function< lib::error_code(connection_hdl)> shutdown_handler
lib::function< lib::error_code(connection_hdl, char const *, size_t)> write_handler
The type and signature of the callback used by iostream transport to write.
Transport policies provide network connectivity and timers.
lib::function< void(lib::error_code const &, size_t)> read_handler
The type and signature of the callback passed to the read method.
lib::function< void()> dispatch_handler
The type and signature of the callback passed to the dispatch method.
lib::function< void()> interrupt_handler
The type and signature of the callback passed to the interrupt method.
lib::function< void(lib::error_code const &)> accept_handler
The type and signature of the callback passed to the accept method.
lib::function< void(lib::error_code const &)> timer_handler
The type and signature of the callback passed to the read method.
lib::function< void(lib::error_code const &)> connect_handler
The type and signature of the callback passed to the connect method.
lib::function< void(lib::error_code const &)> write_handler
The type and signature of the callback passed to the write method.
lib::function< void(lib::error_code const &)> init_handler
The type and signature of the callback passed to the init hook.
lib::function< void(lib::error_code const &)> shutdown_handler
The type and signature of the callback passed to the shutdown method.
Generic non-websocket specific utility functions and data structures.
std::string to_hex(std::string const &input)
Convert std::string to ascii printed string of hex digits.
std::string to_hex(uint8_t const *input, size_t length)
Convert byte array (uint8_t) to ascii printed string of hex digits.
T::const_iterator ci_find_substr(T const &haystack, T const &needle, std::locale const &loc=std::locale())
Find substring (case insensitive)
std::string string_replace_all(std::string subject, std::string const &search, std::string const &replace)
Replace all occurrances of a substring with another.
T::const_iterator ci_find_substr(T const &haystack, typename T::value_type const *needle, typename T::size_type size, std::locale const &loc=std::locale())
Find substring (case insensitive)
std::string to_hex(char const *input, size_t length)
Convert char array to ascii printed string of hex digits.
std::string to_lower(std::string const &in)
Convert a string to lowercase.
Namespace for the WebSocket++ project.
std::string base64_decode(std::string const &input)
Decode a base64 encoded string into a string of raw bytes.
lib::function< void(connection_hdl, std::string)> pong_handler
The type and function signature of a pong handler.
lib::function< void(connection_hdl)> close_handler
The type and function signature of a close handler.
lib::function< void(connection_hdl, std::string)> pong_timeout_handler
The type and function signature of a pong timeout handler.
lib::function< void(connection_hdl)> http_handler
The type and function signature of a http handler.
std::string base64_encode(std::string const &input)
Encode a string into a base64 string.
lib::function< void(connection_hdl)> open_handler
The type and function signature of an open handler.
lib::function< void(connection_hdl)> interrupt_handler
The type and function signature of an interrupt handler.
static uint16_t const uri_default_secure_port
Default port for wss://.
lib::function< void(connection_hdl)> fail_handler
The type and function signature of a fail handler.
lib::weak_ptr< void > connection_hdl
A handle to uniquely identify a connection.
static uint16_t const uri_default_port
Default port for ws://.
lib::function< bool(connection_hdl, std::string)> ping_handler
The type and function signature of a ping handler.
lib::shared_ptr< uri > uri_ptr
Pointer to a URI.
std::pair< lib::error_code, std::string > err_str_pair
Combination error code / string type for returning two values.
lib::function< bool(connection_hdl)> validate_handler
The type and function signature of a validate handler.
static bool is_base64(unsigned char c)
Test whether a character is a valid base64 character.
std::string base64_encode(unsigned char const *input, size_t len)
Encode a char buffer into a base64 string.
Server config with asio transport and TLS disabled.
Extension specific settings:
static const uint8_t minimum_outgoing_window_bits
static const bool allow_disabling_context_takeover
static const long timeout_socket_shutdown
Length of time to wait for socket shutdown.
static const long timeout_connect
Length of time to wait for TCP connect.
static const long timeout_dns_resolve
Length of time to wait for dns resolution.
static const long timeout_proxy
Length of time to wait before a proxy handshake is aborted.
static const long timeout_socket_pre_init
Default timer values (in ms)
static bool const enable_multithreading
static const long timeout_socket_post_init
Length of time to wait for socket post-initialization.
Server config with iostream transport.
websocketpp::random::none::int_generator< uint32_t > rng_type
RNG policies.
static const websocketpp::log::level elog_level
Default static error logging channels.
websocketpp::transport::iostream::endpoint< transport_config > transport_type
Transport Endpoint Component.
static const size_t max_http_body_size
Default maximum http body size.
static const long timeout_open_handshake
Default timer values (in ms)
static const size_t max_message_size
Default maximum message size.
static const bool drop_on_protocol_error
Drop connections immediately on protocol error.
static const long timeout_close_handshake
Length of time before a closing handshake is aborted.
static const websocketpp::log::level alog_level
Default static access logging channels.
websocketpp::log::basic< concurrency_type, websocketpp::log::elevel > elog_type
Logging policies.
static const long timeout_pong
Length of time to wait for a pong after a ping.
static const bool silent_close
Suppresses the return of detailed connection close information.
static bool const enable_multithreading
static const size_t connection_read_buffer_size
Size of the per-connection read buffer.
static const bool enable_extensions
Global flag for enabling/disabling extensions.
static const int client_version
WebSocket Protocol version to use as a client.
Package of log levels for logging access events.
static char const * channel_name(level channel)
Get the textual name of a channel given a channel id.
static level const fail
One line for each failed WebSocket connection with details.
static level const none
Special aggregate value representing "no levels".
static level const debug_handshake
Extra information about opening handshakes.
static level const devel
Development messages (warning: very chatty)
static level const all
Special aggregate value representing "all levels".
static level const debug_close
Extra information about closing handshakes.
static level const frame_payload
One line per frame, includes the full message payload (warning: chatty)
static level const connect
Information about new connections.
static level const app
Special channel for application specific logs. Not used by the library.
static level const frame_header
One line per frame, includes the full frame header.
static level const message_payload
Reserved.
static level const endpoint
Reserved.
static level const message_header
Reserved.
static level const control
One line per control frame.
static level const disconnect
One line for each closed connection. Includes closing codes and reasons.
static level const access_core
static level const http
Access related to HTTP requests.
Package of values for hinting at the nature of a given logger.
static value const none
No information.
static value const access
Access log.
static value const error
Error log.
uint32_t value
Type of a channel type hint value.
Package of log levels for logging errors.
static level const devel
Low level debugging information (warning: very chatty)
static char const * channel_name(level channel)
Get the textual name of a channel given a channel id.
static level const library
static level const all
Special aggregate value representing "all levels".
static level const none
Special aggregate value representing "no levels".
static level const rerror
A simple utility buffer class.
Helper less than functor for case insensitive find.
Helper functor for case insensitive find.
bool operator()(charT ch1, charT ch2)
Perform a case insensitive comparison.
my_equal(std::locale const &loc)
Construct the functor with the given locale.
#define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
#define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
Type used to convert close statuses between integer and wire representations.
Two byte conversion union.
Four byte conversion union.
Eight byte conversion union.