diff --git a/test/transport/asio/timers.cpp b/test/transport/asio/timers.cpp index f37d2e9874..3a4018d70e 100644 --- a/test/transport/asio/timers.cpp +++ b/test/transport/asio/timers.cpp @@ -156,14 +156,12 @@ struct mock_endpoint : public websocketpp::transport::asio::endpoint { &mock_endpoint::handle_connect, this, m_con, - websocketpp::lib::placeholders::_1, - websocketpp::lib::placeholders::_2 + websocketpp::lib::placeholders::_1 ) ); } - void handle_connect(connection_ptr con, websocketpp::connection_hdl, - const websocketpp::lib::error_code & ec) + void handle_connect(connection_ptr con, websocketpp::lib::error_code const & ec) { BOOST_CHECK( !ec ); con->start(); diff --git a/websocketpp/roles/client_endpoint.hpp b/websocketpp/roles/client_endpoint.hpp index 7ce05eceed..1072a0f343 100644 --- a/websocketpp/roles/client_endpoint.hpp +++ b/websocketpp/roles/client_endpoint.hpp @@ -66,8 +66,7 @@ public: explicit client() : endpoint_type(false) { - endpoint_type::m_alog.write(log::alevel::devel, - "client constructor"); + endpoint_type::m_alog.write(log::alevel::devel, "client constructor"); } /// Get a new connection @@ -77,15 +76,17 @@ public: * applying connection specific settings before performing the opening * handshake. * + * @param [in] location URI to open the connection to as a uri_ptr + * @param [out] ec An status code indicating failure reasons, if any + * * @return A connection_ptr to the new connection */ - connection_ptr get_connection(uri_ptr location, lib::error_code &ec) { + connection_ptr get_connection(uri_ptr location, lib::error_code & ec) { if (location->get_secure() && !transport_type::is_secure()) { ec = error::make_error_code(error::endpoint_not_secure); return connection_ptr(); } - // create connection connection_ptr con = endpoint_type::create_connection(); if (!con) { @@ -95,7 +96,6 @@ public: con->set_uri(location); - // Success ec = lib::error_code(); return con; } @@ -106,10 +106,12 @@ public: * suitable for passing to connect(connection_ptr). This overload allows * default construction of the uri_ptr from a standard string. * + * @param [in] u URI to open the connection to as a string + * @param [out] ec An status code indicating failure reasons, if any + * * @return A connection_ptr to the new connection */ - connection_ptr get_connection(const std::string& u, lib::error_code &ec) { - // parse uri + connection_ptr get_connection(std::string const & u, lib::error_code & ec) { uri_ptr location(new uri(u)); if (!location->get_valid()) { @@ -137,35 +139,17 @@ public: lib::bind( &type::handle_connect, this, - lib::placeholders::_1, - lib::placeholders::_2 + con, + lib::placeholders::_1 ) ); return con; } - - - - // connect(...) private: // handle_connect - void handle_connect(connection_hdl hdl, const lib::error_code & ec) { - lib::error_code hdl_ec; - connection_ptr con = endpoint_type::get_con_from_hdl(hdl,hdl_ec); - - if (hdl_ec == error::bad_connection) { - endpoint_type::m_elog.write(log::elevel::fatal, - "handle_connect got an invalid handle back"); - } else if (hdl_ec) { - // There was some other unknown error attempting to convert the hdl - // to a connection. - endpoint_type::m_elog.write(log::elevel::fatal, - "handle_connect error in get_con_from_hdl: "+hdl_ec.message()); - //con->terminate(); - } else if (ec) { - // TODO - // Set connection's failure reasons + void handle_connect(connection_ptr con, lib::error_code const & ec) { + if (ec) { con->terminate(ec); endpoint_type::m_elog.write(log::elevel::rerror, diff --git a/websocketpp/roles/server_endpoint.hpp b/websocketpp/roles/server_endpoint.hpp index f2bb7efb0f..77f1c29189 100644 --- a/websocketpp/roles/server_endpoint.hpp +++ b/websocketpp/roles/server_endpoint.hpp @@ -90,37 +90,20 @@ public: lib::bind( &type::handle_accept, this, - lib::placeholders::_1, - lib::placeholders::_2 + con, + lib::placeholders::_1 ) ); } - void handle_accept(connection_hdl hdl, const lib::error_code& ec) { - lib::error_code hdl_ec; - connection_ptr con = endpoint_type::get_con_from_hdl(hdl,hdl_ec); + void handle_accept(connection_ptr con, const lib::error_code& ec) { + if (ec) { + con->terminate(ec); - if (hdl_ec == error::bad_connection) { - // The connection we were trying to connect went out of scope - // This really shouldn't happen - endpoint_type::m_elog.write(log::elevel::fatal, - "handle_accept got an invalid handle back"); - //con->terminate(); - } else if (hdl_ec) { - // There was some other unknown error attempting to convert the hdl - // to a connection. - endpoint_type::m_elog.write(log::elevel::fatal, - "handle_accept error in get_con_from_hdl: "+hdl_ec.message()); - //con->terminate(); + endpoint_type::m_elog.write(log::elevel::rerror, + "handle_accept error: "+ec.message()); } else { - if (ec) { - con->terminate(ec); - - endpoint_type::m_elog.write(log::elevel::rerror, - "handle_accept error: "+ec.message()); - } else { - con->start(); - } + con->start(); } // TODO: are there cases where we should terminate this loop? diff --git a/websocketpp/transport/asio/base.hpp b/websocketpp/transport/asio/base.hpp index a868ad9a58..35c80ef270 100644 --- a/websocketpp/transport/asio/base.hpp +++ b/websocketpp/transport/asio/base.hpp @@ -45,6 +45,11 @@ namespace transport { */ namespace asio { +// Forward declaration of class endpoint so that it can be friended/referenced +// before being included. +template +class endpoint; + typedef lib::function socket_shutdown_handler; diff --git a/websocketpp/transport/asio/connection.hpp b/websocketpp/transport/asio/connection.hpp index 545dc81849..7cfb35c3dd 100644 --- a/websocketpp/transport/asio/connection.hpp +++ b/websocketpp/transport/asio/connection.hpp @@ -84,6 +84,11 @@ public: /// Type of a pointer to the ASIO timer class typedef lib::shared_ptr timer_ptr; + // connection is friends with its associated endpoint to allow the endpoint + // to call private/protected utility methods that we don't want to expose + // to the public api. + friend class endpoint; + // generate and manage our own io_service explicit connection(bool is_server, alog_type& alog, elog_type& elog) : m_is_server(is_server) @@ -102,29 +107,13 @@ public: return socket_con_type::is_secure(); } - /// Finish constructing the transport + /// Sets the tcp init handler /** - * init_asio is called once immediately after construction to initialize - * boost::asio components to the io_service + * The tcp init handler is called after the tcp connection has been + * established. * - * TODO: this method is not protected because the endpoint needs to call it. - * need to figure out if there is a way to friend the endpoint safely across - * different compilers. - * - * @param io_service A pointer to the io_service to register with this - * connection - * - * @return Status code for the success or failure of the initialization + * @param h The handler to call on tcp init. */ - lib::error_code init_asio (io_service_ptr io_service) { - // do we need to store or use the io_service at this level? - m_io_service = io_service; - - //m_strand.reset(new boost::asio::strand(*io_service)); - - return socket_con_type::init_asio(io_service, m_is_server); - } - void set_tcp_init_handler(tcp_init_handler h) { m_tcp_init_handler = h; } @@ -251,26 +240,6 @@ public: return m_connection_hdl; } - /// initialize the proxy buffers and http parsers - /** - * - * @param authority The address of the server we want the proxy to tunnel to - * in the format of a URI authority (host:port) - */ - lib::error_code proxy_init(const std::string & authority) { - if (!m_proxy_data) { - return websocketpp::error::make_error_code( - websocketpp::error::invalid_state); - } - m_proxy_data->req.set_version("HTTP/1.1"); - m_proxy_data->req.set_method("CONNECT"); - - m_proxy_data->req.set_uri(authority); - m_proxy_data->req.replace_header("Host",authority); - - return lib::error_code(); - } - /// Call back a function after a period of time. /** * Sets a timer that calls back a function after the specified period of @@ -311,10 +280,10 @@ public: * The timer pointer is included to ensure the timer isn't destroyed until * after it has expired. * + * TODO: candidate for protected status + * * @param t Pointer to the timer in question - * * @param callback The function to call back - * * @param ec The status code */ void handle_timer(timer_ptr t, timer_handler callback, const @@ -367,6 +336,47 @@ protected: ); } + /// initialize the proxy buffers and http parsers + /** + * + * @param authority The address of the server we want the proxy to tunnel to + * in the format of a URI authority (host:port) + * + * @return Status code indicating what errors occurred, if any + */ + lib::error_code proxy_init(std::string const & authority) { + if (!m_proxy_data) { + return websocketpp::error::make_error_code( + websocketpp::error::invalid_state); + } + m_proxy_data->req.set_version("HTTP/1.1"); + m_proxy_data->req.set_method("CONNECT"); + + m_proxy_data->req.set_uri(authority); + m_proxy_data->req.replace_header("Host",authority); + + return lib::error_code(); + } + + /// Finish constructing the transport + /** + * init_asio is called once immediately after construction to initialize + * boost::asio components to the io_service + * + * @param io_service A pointer to the io_service to register with this + * connection + * + * @return Status code for the success or failure of the initialization + */ + lib::error_code init_asio (io_service_ptr io_service) { + // do we need to store or use the io_service at this level? + m_io_service = io_service; + + //m_strand.reset(new boost::asio::strand(*io_service)); + + return socket_con_type::init_asio(io_service, m_is_server); + } + void handle_pre_init(init_handler callback, const lib::error_code& ec) { if (m_alog.static_test(log::alevel::devel)) { m_alog.write(log::alevel::devel,"asio connection handle pre_init"); diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp index 08bb2aabee..7b080b2ce5 100644 --- a/websocketpp/transport/asio/endpoint.hpp +++ b/websocketpp/transport/asio/endpoint.hpp @@ -577,7 +577,6 @@ public: lib::bind( &type::handle_accept, this, - tcon->get_handle(), callback, lib::placeholders::_1 ) @@ -612,18 +611,19 @@ protected: m_elog = e; } - void handle_accept(connection_hdl hdl, accept_handler callback, - const boost::system::error_code& error) + void handle_accept(accept_handler callback, boost::system::error_code const + & boost_ec) { - if (error) { - //con->terminate(); - // TODO: Better translation of errors at this point - callback(hdl,make_error_code(error::pass_through)); - return; + lib::error_code ret_ec; + + m_alog->write(log::alevel::devel, "asio::handle_accept"); + + if (boost_ec) { + log_err(log::elevel::devel,"asio handle_accept",boost_ec); + ret_ec = make_error_code(error::pass_through); } - //con->start(); - callback(hdl,lib::error_code()); + callback(ret_ec); } /// Initiate a new connection @@ -649,13 +649,13 @@ protected: uri_ptr pu(new uri(proxy)); if (!pu->get_valid()) { - cb(tcon->get_handle(),make_error_code(error::proxy_invalid)); + cb(make_error_code(error::proxy_invalid)); return; } ec = tcon->proxy_init(u->get_authority()); if (ec) { - cb(tcon->get_handle(),ec); + cb(ec); return; } @@ -677,7 +677,6 @@ protected: lib::bind( &type::handle_resolve_timeout, this, - tcon, dns_timer, cb, lib::placeholders::_1 @@ -698,8 +697,8 @@ protected: ); } - void handle_resolve_timeout(transport_con_ptr tcon, timer_ptr dns_timer, - connect_handler callback, const lib::error_code & ec) + void handle_resolve_timeout(timer_ptr dns_timer, connect_handler callback, + lib::error_code const & ec) { lib::error_code ret_ec; @@ -718,11 +717,11 @@ protected: m_alog->write(log::alevel::devel,"DNS resolution timed out"); m_resolver->cancel(); - callback(tcon->get_handle(),ret_ec); + callback(ret_ec); } void handle_resolve(transport_con_ptr tcon, timer_ptr dns_timer, - connect_handler callback, const boost::system::error_code& ec, + connect_handler callback, boost::system::error_code const & ec, boost::asio::ip::tcp::resolver::iterator iterator) { if (ec == boost::asio::error::operation_aborted || @@ -736,7 +735,7 @@ protected: if (ec) { log_err(log::elevel::info,"asio async_resolve",ec); - callback(tcon->get_handle(),make_error_code(error::pass_through)); + callback(make_error_code(error::pass_through)); return; } @@ -759,7 +758,7 @@ protected: con_timer = set_timer( config::timeout_connect, lib::bind( - &type::handle_resolve_timeout, + &type::handle_connect_timeout, this, tcon, con_timer, @@ -783,7 +782,7 @@ protected: } void handle_connect_timeout(transport_con_ptr tcon, timer_ptr con_timer, - connect_handler callback, const lib::error_code & ec) + connect_handler callback, lib::error_code const & ec) { lib::error_code ret_ec; @@ -802,11 +801,11 @@ protected: m_alog->write(log::alevel::devel,"TCP connect timed out"); tcon->cancel_socket(); - callback(tcon->get_handle(),ret_ec); + callback(ret_ec); } void handle_connect(transport_con_ptr tcon, timer_ptr con_timer, - connect_handler callback, const boost::system::error_code& ec) + connect_handler callback, boost::system::error_code const & ec) { if (ec == boost::asio::error::operation_aborted || con_timer->expires_from_now().is_negative()) @@ -819,7 +818,7 @@ protected: if (ec) { log_err(log::elevel::info,"asio async_connect",ec); - callback(tcon->get_handle(),make_error_code(error::pass_through)); + callback(make_error_code(error::pass_through)); return; } @@ -828,7 +827,7 @@ protected: "Async connect to "+tcon->get_remote_endpoint()+" successful."); } - callback(tcon->get_handle(),lib::error_code()); + callback(lib::error_code()); } bool is_listening() const { diff --git a/websocketpp/transport/base/endpoint.hpp b/websocketpp/transport/base/endpoint.hpp index df1dc45a59..1fefd48358 100644 --- a/websocketpp/transport/base/endpoint.hpp +++ b/websocketpp/transport/base/endpoint.hpp @@ -71,12 +71,10 @@ namespace websocketpp { namespace transport { /// The type and signature of the callback passed to the accept method -typedef lib::function - accept_handler; +typedef lib::function accept_handler; /// The type and signature of the callback passed to the connect method -typedef lib::function - connect_handler; +typedef lib::function connect_handler; } // namespace transport } // namespace websocketpp diff --git a/websocketpp/transport/iostream/endpoint.hpp b/websocketpp/transport/iostream/endpoint.hpp index 91ea6fcf67..ff37866d90 100644 --- a/websocketpp/transport/iostream/endpoint.hpp +++ b/websocketpp/transport/iostream/endpoint.hpp @@ -141,7 +141,7 @@ protected: * @param cb The function to call back with the results when complete. */ void async_connect(transport_con_ptr tcon, uri_ptr u, connect_handler cb) { - cb(tcon->get_handle(),lib::error_code()); + cb(lib::error_code()); } /// Initialize a connection