impliment close handshake timeouts references #226

This commit is contained in:
Peter Thorson
2013-06-09 07:33:30 -05:00
parent c228f70a9f
commit 56e81cb6eb
2 changed files with 84 additions and 2 deletions

View File

@@ -299,3 +299,58 @@ BOOST_AUTO_TEST_CASE( server_open_handshake_timeout ) {
sthread.join();
}
BOOST_AUTO_TEST_CASE( client_self_initiated_close_handshake_timeout ) {
server s;
client c;
// on open server sleeps for longer than the timeout
// on open client sends close handshake
// client handshake timer should be triggered
s.set_open_handler(bind(&delay,::_1,1));
s.set_close_handler(bind(&stop_on_close,&s,::_1));
c.set_open_handler(bind(&close<client>,&c,::_1));
c.set_close_handler(bind(&check_ec<client>,&c,
websocketpp::error::close_handshake_timeout,::_1));
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
tthread.detach();
run_client(c, "http://localhost:9005",false);
sthread.join();
}
BOOST_AUTO_TEST_CASE( client_peer_initiated_close_handshake_timeout ) {
// on open server sends close
// client should ack normally and then wait
// server leaves TCP connection open
// client handshake timer should be triggered
// TODO: how to make a mock server that leaves the TCP connection open?
}
BOOST_AUTO_TEST_CASE( server_self_initiated_close_handshake_timeout ) {
server s;
client c;
// on open server sends close
// on open client sleeps for longer than the timeout
// server handshake timer should be triggered
s.set_open_handler(bind(&close<server>,&s,::_1));
s.set_close_handler(bind(&check_ec_and_stop<server>,&s,
websocketpp::error::close_handshake_timeout,::_1));
c.set_open_handler(bind(&delay,::_1,1));
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
tthread.detach();
run_client(c, "http://localhost:9005",false);
sthread.join();
}

View File

@@ -1368,7 +1368,17 @@ template <typename config>
void connection<config>::handle_close_handshake_timeout(
lib::error_code const & ec)
{
if (ec == transport::error::operation_aborted) {
m_alog.write(log::alevel::devel,
"asio close handshake timer cancelled");
} else if (ec) {
m_alog.write(log::alevel::devel,
"asio open handle_close_handshake_timeout error: "+ec.message());
// TODO: ignore or fail here?
} else {
m_alog.write(log::alevel::devel, "asio close handshake timer expired");
terminate(make_error_code(error::close_handshake_timeout));
}
}
template <typename config>
@@ -1376,7 +1386,13 @@ void connection<config>::terminate(const lib::error_code & ec) {
if (m_alog.static_test(log::alevel::devel)) {
m_alog.write(log::alevel::devel,"connection terminate");
}
// Cancel close handshake timer
if (m_handshake_timer) {
m_handshake_timer->cancel();
m_handshake_timer.reset();
}
terminate_status tstat = unknown;
if (ec) {
m_ec = ec;
@@ -1768,6 +1784,17 @@ lib::error_code connection<config>::send_close_frame(close::status::value code,
m_state = session::state::closing;
// Start a timer so we don't wait forever for the acknowledgement close
// frame
m_handshake_timer = transport_con_type::set_timer(
config::timeout_close_handshake,
lib::bind(
&type::handle_close_handshake_timeout,
type::shared_from_this(),
lib::placeholders::_1
)
);
bool needs_writing = false;
{
scoped_lock_type lock(m_write_lock);