Skip to content

Commit 058b7bc

Browse files
author
Peter Thorson
committed
[feature] Add support for exception free mode fixes #792
1 parent 3610eeb commit 058b7bc

File tree

8 files changed

+263
-148
lines changed

8 files changed

+263
-148
lines changed

changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ HEAD
44
of the core library APIs. If any users are calling into the underlying HTTP
55
libraries directly (classes in the namespace `websocketpp::http::*`) they
66
should review any error handling they do.
7+
- Feature: WebSocket++ can now be compiled without exceptions by defining
8+
`_WEBSOCKETPP_NO_EXCEPTIONS` in the C++ preprocessor. All internal use of
9+
exceptions have been removed. External interfaces that throw exceptions are
10+
still avaliable and supported (except in exception free mode) but now have
11+
overloads that allow `error_code` based error handling.
712
- Compatibility: Overhauled the URI authority parsing logic to be more
813
compliant with RFC3986. WebSocket++ is now able to detect invalid registry
914
hosts, invalid IPv4 and IPv6 literal addresses. Dozens of additional

websocketpp/connection.hpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,7 @@ class connection
10141014
*/
10151015
void set_status(http::status_code::value code, lib::error_code & ec);
10161016

1017+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
10171018
/// Set response status code and message (exception)
10181019
/**
10191020
* Sets the response status code and message to independent custom values.
@@ -1026,10 +1027,11 @@ class connection
10261027
* @param[in] code Code to set
10271028
* @param[in] msg Message to set
10281029
* @throw websocketpp::exception
1029-
* @see websocketpp::http::response::set_status()
1030+
* @see websocketpp::http::parser::response::set_status()
10301031
* @see websocketpp::http::status_code::value (list of valid codes)
10311032
*/
10321033
void set_status(http::status_code::value code);
1034+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
10331035

10341036
/// Set response status code and message (exception free)
10351037
/**
@@ -1063,7 +1065,7 @@ class connection
10631065
* @param[in] code Code to set
10641066
* @param[in] msg Message to set
10651067
* @throw websocketpp::exception
1066-
* @see websocketpp::http::response::set_status()
1068+
* @see websocketpp::http::parser::response::set_status()
10671069
* @see websocketpp::http::status_code::value (list of valid codes)
10681070
*/
10691071
void set_status(http::status_code::value code, std::string const & msg);
@@ -1087,6 +1089,7 @@ class connection
10871089
*/
10881090
void set_body(std::string const & value, lib::error_code & ec);
10891091

1092+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
10901093
/// Set response body content (exception)
10911094
/**
10921095
* Set the body content of the HTTP response to the parameter string. Note
@@ -1104,6 +1107,17 @@ class connection
11041107
* (exception free version)
11051108
*/
11061109
void set_body(std::string const & value);
1110+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
1111+
1112+
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
1113+
/// @copydoc websocketpp::connection::set_body(std::string const &, lib::error_code &)
1114+
void set_body(std::string && value, lib::error_code & ec);
1115+
1116+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
1117+
/// @copydoc websocketpp::connection::set_body(std::string const &)
1118+
void set_body(std::string && value);
1119+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
1120+
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
11071121

11081122
/// Append a header (exception free)
11091123
/**

websocketpp/endpoint.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,7 @@ class endpoint : public config::transport_type, public config::endpoint_base {
649649
return con;
650650
}
651651

652+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
652653
/// Retrieves a connection_ptr from a connection_hdl (exception version)
653654
connection_ptr get_con_from_hdl(connection_hdl hdl) {
654655
lib::error_code ec;
@@ -658,6 +659,7 @@ class endpoint : public config::transport_type, public config::endpoint_base {
658659
}
659660
return con;
660661
}
662+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
661663
protected:
662664
connection_ptr create_connection();
663665

websocketpp/impl/connection_impl.hpp

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ void connection<config>::ping(std::string const& payload, lib::error_code& ec) {
220220
ec = lib::error_code();
221221
}
222222

223+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
223224
template<typename config>
224225
void connection<config>::ping(std::string const & payload) {
225226
lib::error_code ec;
@@ -228,6 +229,7 @@ void connection<config>::ping(std::string const & payload) {
228229
throw exception(ec);
229230
}
230231
}
232+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
231233

232234
template<typename config>
233235
void connection<config>::handle_pong_timeout(std::string payload,
@@ -291,6 +293,7 @@ void connection<config>::pong(std::string const& payload, lib::error_code& ec) {
291293
ec = lib::error_code();
292294
}
293295

296+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
294297
template<typename config>
295298
void connection<config>::pong(std::string const & payload) {
296299
lib::error_code ec;
@@ -299,6 +302,7 @@ void connection<config>::pong(std::string const & payload) {
299302
throw exception(ec);
300303
}
301304
}
305+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
302306

303307
template <typename config>
304308
void connection<config>::close(close::status::value const code,
@@ -322,6 +326,7 @@ void connection<config>::close(close::status::value const code,
322326
ec = this->send_close_frame(code,tr,false,close::status::terminal(code));
323327
}
324328

329+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
325330
template<typename config>
326331
void connection<config>::close(close::status::value const code,
327332
std::string const & reason)
@@ -332,6 +337,7 @@ void connection<config>::close(close::status::value const code,
332337
throw exception(ec);
333338
}
334339
}
340+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
335341

336342
/// Trigger the on_interrupt handler
337343
/**
@@ -474,6 +480,7 @@ void connection<config>::add_subprotocol(std::string const & value,
474480
m_requested_subprotocols.push_back(value);
475481
}
476482

483+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
477484
template <typename config>
478485
void connection<config>::add_subprotocol(std::string const & value) {
479486
lib::error_code ec;
@@ -482,6 +489,7 @@ void connection<config>::add_subprotocol(std::string const & value) {
482489
throw exception(ec);
483490
}
484491
}
492+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
485493

486494

487495
template <typename config>
@@ -513,6 +521,7 @@ void connection<config>::select_subprotocol(std::string const & value,
513521
ec = lib::error_code();
514522
}
515523

524+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
516525
template <typename config>
517526
void connection<config>::select_subprotocol(std::string const & value) {
518527
lib::error_code ec;
@@ -521,6 +530,7 @@ void connection<config>::select_subprotocol(std::string const & value) {
521530
throw exception(ec);
522531
}
523532
}
533+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
524534

525535

526536
template <typename config>
@@ -549,10 +559,10 @@ void connection<config>::set_status(http::status_code::value code,
549559
ec = error::make_error_code(error::invalid_state);
550560
return;
551561
}
552-
m_response.set_status(code);
553-
ec = lib::error_code();
562+
ec = m_response.set_status(code);
554563
}
555564

565+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
556566
template <typename config>
557567
void connection<config>::set_status(http::status_code::value code)
558568
{
@@ -562,6 +572,7 @@ void connection<config>::set_status(http::status_code::value code)
562572
throw exception("Call to set_status from invalid state", ec);
563573
}
564574
}
575+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
565576

566577
template <typename config>
567578
void connection<config>::set_status(http::status_code::value code,
@@ -572,10 +583,10 @@ void connection<config>::set_status(http::status_code::value code,
572583
return;
573584
}
574585

575-
m_response.set_status(code,msg);
576-
ec = lib::error_code();
586+
ec = m_response.set_status(code,msg);
577587
}
578588

589+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
579590
template <typename config>
580591
void connection<config>::set_status(http::status_code::value code,
581592
std::string const & msg)
@@ -586,6 +597,7 @@ void connection<config>::set_status(http::status_code::value code,
586597
throw exception("Call to set_status from invalid state", ec);
587598
}
588599
}
600+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
589601

590602
template <typename config>
591603
void connection<config>::set_body(std::string const & value,
@@ -599,14 +611,41 @@ void connection<config>::set_body(std::string const & value,
599611
ec = m_response.set_body(value);
600612
}
601613

614+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
602615
template <typename config>
603616
void connection<config>::set_body(std::string const & value) {
604617
lib::error_code ec;
605618
this->set_body(value, ec);
606619
if (ec) {
607-
throw exception("Call to set_status from invalid state", ec);
620+
throw exception("Call to set_body from invalid state", ec);
621+
}
622+
}
623+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
624+
625+
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
626+
template <typename config>
627+
void connection<config>::set_body(std::string && value,
628+
lib::error_code & ec)
629+
{
630+
if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
631+
ec = error::make_error_code(error::invalid_state);
632+
return;
633+
}
634+
635+
ec = m_response.set_body(std::move(value));
636+
}
637+
638+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
639+
template <typename config>
640+
void connection<config>::set_body(std::string && value) {
641+
lib::error_code ec;
642+
this->set_body(std::move(value), ec);
643+
if (ec) {
644+
throw exception("Call to set_body from invalid state", ec);
608645
}
609646
}
647+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
648+
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
610649

611650
template <typename config>
612651
void connection<config>::append_header(std::string const & key,
@@ -629,6 +668,7 @@ void connection<config>::append_header(std::string const & key,
629668
}
630669
}
631670

671+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
632672
template <typename config>
633673
void connection<config>::append_header(std::string const & key,
634674
std::string const & val)
@@ -639,6 +679,7 @@ void connection<config>::append_header(std::string const & key,
639679
throw exception("Call to append_header from invalid state", ec);
640680
}
641681
}
682+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
642683

643684
template <typename config>
644685
void connection<config>::replace_header(std::string const & key,
@@ -661,6 +702,7 @@ void connection<config>::replace_header(std::string const & key,
661702
}
662703
}
663704

705+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
664706
template <typename config>
665707
void connection<config>::replace_header(std::string const & key,
666708
std::string const & val)
@@ -671,6 +713,7 @@ void connection<config>::replace_header(std::string const & key,
671713
throw exception("Call to replace_header from invalid state", ec);
672714
}
673715
}
716+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
674717

675718
template <typename config>
676719
void connection<config>::remove_header(std::string const & key,
@@ -693,6 +736,7 @@ void connection<config>::remove_header(std::string const & key,
693736
}
694737
}
695738

739+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
696740
template <typename config>
697741
void connection<config>::remove_header(std::string const & key)
698742
{
@@ -702,6 +746,7 @@ void connection<config>::remove_header(std::string const & key)
702746
throw exception("Call to remove_header from invalid state", ec);
703747
}
704748
}
749+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
705750

706751
/// Defer HTTP Response until later
707752
/**
@@ -755,6 +800,7 @@ void connection<config>::send_http_response(lib::error_code & ec) {
755800
ec = lib::error_code();
756801
}
757802

803+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
758804
template <typename config>
759805
void connection<config>::send_http_response() {
760806
lib::error_code ec;
@@ -763,6 +809,7 @@ void connection<config>::send_http_response() {
763809
throw exception(ec);
764810
}
765811
}
812+
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
766813

767814

768815

@@ -1265,7 +1312,7 @@ lib::error_code connection<config>::process_handshake_request() {
12651312
return error::make_error_code(error::http_connection_ended);
12661313
}
12671314
} else {
1268-
set_status(http::status_code::upgrade_required);
1315+
m_response.set_status(http::status_code::upgrade_required);
12691316
return error::make_error_code(error::upgrade_required);
12701317
}
12711318

@@ -1370,6 +1417,7 @@ void connection<config>::write_http_response(lib::error_code const & ec) {
13701417
}
13711418

13721419
if (m_response.get_status_code() == http::status_code::uninitialized) {
1420+
lib::error_code status_ec;
13731421
m_response.set_status(http::status_code::internal_server_error);
13741422
m_ec = error::make_error_code(error::general);
13751423
} else {
@@ -1865,13 +1913,18 @@ void connection<config>::handle_terminate(terminate_status tstat,
18651913
// call the termination handler if it exists
18661914
// if it exists it might (but shouldn't) refer to a bad memory location.
18671915
// If it does, we don't care and should catch and ignore it.
1916+
// todo: there has to be a better way to do this.
18681917
if (m_termination_handler) {
1918+
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
18691919
try {
18701920
m_termination_handler(type::get_shared());
18711921
} catch (std::exception const & e) {
18721922
m_elog->write(log::elevel::warn,
18731923
std::string("termination_handler call failed. Reason was: ")+e.what());
18741924
}
1925+
#else
1926+
m_termination_handler(type::get_shared());
1927+
#endif
18751928
}
18761929
}
18771930

0 commit comments

Comments
 (0)