Skip to content

Commit 56e81cb

Browse files
committedJun 9, 2013
impliment close handshake timeouts references XRPLF#226
1 parent c228f70 commit 56e81cb

File tree

2 files changed

+84
-2
lines changed

2 files changed

+84
-2
lines changed
 

‎test/transport/integration.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,3 +299,58 @@ BOOST_AUTO_TEST_CASE( server_open_handshake_timeout ) {
299299

300300
sthread.join();
301301
}
302+
303+
BOOST_AUTO_TEST_CASE( client_self_initiated_close_handshake_timeout ) {
304+
server s;
305+
client c;
306+
307+
// on open server sleeps for longer than the timeout
308+
// on open client sends close handshake
309+
// client handshake timer should be triggered
310+
s.set_open_handler(bind(&delay,::_1,1));
311+
s.set_close_handler(bind(&stop_on_close,&s,::_1));
312+
313+
c.set_open_handler(bind(&close<client>,&c,::_1));
314+
c.set_close_handler(bind(&check_ec<client>,&c,
315+
websocketpp::error::close_handshake_timeout,::_1));
316+
317+
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
318+
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
319+
tthread.detach();
320+
321+
run_client(c, "http://localhost:9005",false);
322+
323+
sthread.join();
324+
}
325+
326+
BOOST_AUTO_TEST_CASE( client_peer_initiated_close_handshake_timeout ) {
327+
// on open server sends close
328+
// client should ack normally and then wait
329+
// server leaves TCP connection open
330+
// client handshake timer should be triggered
331+
332+
// TODO: how to make a mock server that leaves the TCP connection open?
333+
}
334+
335+
BOOST_AUTO_TEST_CASE( server_self_initiated_close_handshake_timeout ) {
336+
server s;
337+
client c;
338+
339+
// on open server sends close
340+
// on open client sleeps for longer than the timeout
341+
// server handshake timer should be triggered
342+
343+
s.set_open_handler(bind(&close<server>,&s,::_1));
344+
s.set_close_handler(bind(&check_ec_and_stop<server>,&s,
345+
websocketpp::error::close_handshake_timeout,::_1));
346+
347+
c.set_open_handler(bind(&delay,::_1,1));
348+
349+
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
350+
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
351+
tthread.detach();
352+
353+
run_client(c, "http://localhost:9005",false);
354+
355+
sthread.join();
356+
}

‎websocketpp/impl/connection_impl.hpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,15 +1368,31 @@ template <typename config>
13681368
void connection<config>::handle_close_handshake_timeout(
13691369
lib::error_code const & ec)
13701370
{
1371-
1371+
if (ec == transport::error::operation_aborted) {
1372+
m_alog.write(log::alevel::devel,
1373+
"asio close handshake timer cancelled");
1374+
} else if (ec) {
1375+
m_alog.write(log::alevel::devel,
1376+
"asio open handle_close_handshake_timeout error: "+ec.message());
1377+
// TODO: ignore or fail here?
1378+
} else {
1379+
m_alog.write(log::alevel::devel, "asio close handshake timer expired");
1380+
terminate(make_error_code(error::close_handshake_timeout));
1381+
}
13721382
}
13731383

13741384
template <typename config>
13751385
void connection<config>::terminate(const lib::error_code & ec) {
13761386
if (m_alog.static_test(log::alevel::devel)) {
13771387
m_alog.write(log::alevel::devel,"connection terminate");
13781388
}
1379-
1389+
1390+
// Cancel close handshake timer
1391+
if (m_handshake_timer) {
1392+
m_handshake_timer->cancel();
1393+
m_handshake_timer.reset();
1394+
}
1395+
13801396
terminate_status tstat = unknown;
13811397
if (ec) {
13821398
m_ec = ec;
@@ -1768,6 +1784,17 @@ lib::error_code connection<config>::send_close_frame(close::status::value code,
17681784

17691785
m_state = session::state::closing;
17701786

1787+
// Start a timer so we don't wait forever for the acknowledgement close
1788+
// frame
1789+
m_handshake_timer = transport_con_type::set_timer(
1790+
config::timeout_close_handshake,
1791+
lib::bind(
1792+
&type::handle_close_handshake_timeout,
1793+
type::shared_from_this(),
1794+
lib::placeholders::_1
1795+
)
1796+
);
1797+
17711798
bool needs_writing = false;
17721799
{
17731800
scoped_lock_type lock(m_write_lock);

0 commit comments

Comments
 (0)