diff --git a/changelog.md b/changelog.md index 50e5f6f90c..c5c5a1db11 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,6 @@ HEAD +- Fixes a regression that caused servers being sent two close frames in a row + to end a connection uncleanly. #259 - Fixes a regression that caused spurious frames following a legitimate close frames to erroneously trigger handlers. #258 - Changes default HTTP response error code when no http_handler is defined from diff --git a/websocketpp/connection.hpp b/websocketpp/connection.hpp index 5d63337356..7a373680c2 100644 --- a/websocketpp/connection.hpp +++ b/websocketpp/connection.hpp @@ -193,6 +193,7 @@ public: , m_rng(rng) , m_local_close_code(close::status::abnormal_close) , m_remote_close_code(close::status::abnormal_close) + , m_was_clean(false) { m_alog.write(log::alevel::devel,"connection constructor"); } @@ -1172,6 +1173,8 @@ private: /// Detailed internal error code lib::error_code m_ec; + bool m_was_clean; + /// Whether or not this endpoint initiated the closing handshake. bool m_closed_by_me; diff --git a/websocketpp/impl/connection_impl.hpp b/websocketpp/impl/connection_impl.hpp index c13e85a951..6ebf64f5ce 100644 --- a/websocketpp/impl/connection_impl.hpp +++ b/websocketpp/impl/connection_impl.hpp @@ -1724,10 +1724,12 @@ void connection::process_control_frame(typename m_elog.write(log::elevel::devel, "send_close_ack error: "+ec.message()); } - } else if (m_state == session::state::closing) { + } else if (m_state == session::state::closing && !m_was_clean) { // ack of our close m_alog.write(log::alevel::devel,"Got acknowledgement of close"); + m_was_clean = true; + // If we are a server terminate the connection now. Clients should // leave the connection open to give the server an opportunity to // initiate the TCP close. The client's timer will handle closing @@ -1815,6 +1817,10 @@ lib::error_code connection::send_close_frame(close::status::value code, m_state = session::state::closing; + if (ack) { + m_was_clean = true; + } + // Start a timer so we don't wait forever for the acknowledgement close // frame m_handshake_timer = transport_con_type::set_timer(