diff --git a/lib/remote/httpserverconnection.cpp b/lib/remote/httpserverconnection.cpp index 42adeda4c..524916b4e 100644 --- a/lib/remote/httpserverconnection.cpp +++ b/lib/remote/httpserverconnection.cpp @@ -21,10 +21,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -88,13 +90,13 @@ void HttpServerConnection::Disconnect() */ boost::system::error_code ec; - m_Stream->next_layer().async_shutdown(yc[ec]); - - m_Stream->lowest_layer().shutdown(m_Stream->lowest_layer().shutdown_both, ec); + m_CheckLivenessTimer.cancel(); m_Stream->lowest_layer().cancel(ec); - m_CheckLivenessTimer.cancel(); + m_Stream->next_layer().async_shutdown(yc[ec]); + + m_Stream->lowest_layer().shutdown(m_Stream->lowest_layer().shutdown_both, ec); auto listener (ApiListener::GetInstance()); @@ -141,11 +143,15 @@ bool EnsureValidHeaders( boost::beast::flat_buffer& buf, boost::beast::http::parser& parser, boost::beast::http::response& response, + bool& shuttingDown, boost::asio::yield_context& yc ) { namespace http = boost::beast::http; + if (shuttingDown) + return false; + bool httpError = false; String errorMsg; @@ -154,16 +160,19 @@ bool EnsureValidHeaders( http::async_read_header(stream, buf, parser, yc[ec]); if (ec) { + if (ec == boost::asio::error::operation_aborted) + return false; + errorMsg = ec.message(); httpError = true; - } - - switch (parser.get().version()) { - case 10: - case 11: - break; - default: - errorMsg = "Unsupported HTTP version"; + } else { + switch (parser.get().version()) { + case 10: + case 11: + break; + default: + errorMsg = "Unsupported HTTP version"; + } } if (!errorMsg.IsEmpty() || httpError) { @@ -343,6 +352,7 @@ bool EnsureValidBody( boost::beast::http::parser& parser, ApiUser::Ptr& authenticatedUser, boost::beast::http::response& response, + bool& shuttingDown, boost::asio::yield_context& yc ) { @@ -385,11 +395,17 @@ bool EnsureValidBody( parser.body_limit(maxSize); } + if (shuttingDown) + return false; + boost::system::error_code ec; http::async_read(stream, buf, parser, yc[ec]); if (ec) { + if (ec == boost::asio::error::operation_aborted) + return false; + /** * Unfortunately there's no way to tell an HTTP protocol error * from an error on a lower layer: @@ -443,6 +459,12 @@ bool ProcessRequest( return false; } + auto sysErr (dynamic_cast(&ex)); + + if (sysErr && sysErr->code() == boost::asio::error::operation_aborted) { + throw; + } + http::response response; HttpUtility::SendJsonError(response, nullptr, 500, "Unhandled exception" , DiagnosticInformation(ex)); @@ -488,7 +510,7 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc) // Best practice is to always reset the buffer. buf = {}; - if (!EnsureValidHeaders(*m_Stream, buf, parser, response, yc)) { + if (!EnsureValidHeaders(*m_Stream, buf, parser, response, m_ShuttingDown, yc)) { break; } @@ -535,7 +557,7 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc) // Best practice is to always reset the buffer. buf = {}; - if (!EnsureValidBody(*m_Stream, buf, parser, authenticatedUser, response, yc)) { + if (!EnsureValidBody(*m_Stream, buf, parser, authenticatedUser, response, m_ShuttingDown, yc)) { break; } diff --git a/lib/remote/jsonrpcconnection.cpp b/lib/remote/jsonrpcconnection.cpp index e8279eac2..5a26812a2 100644 --- a/lib/remote/jsonrpcconnection.cpp +++ b/lib/remote/jsonrpcconnection.cpp @@ -224,14 +224,14 @@ void JsonRpcConnection::Disconnect() */ boost::system::error_code ec; - m_Stream->next_layer().async_shutdown(yc[ec]); - - m_Stream->lowest_layer().shutdown(m_Stream->lowest_layer().shutdown_both, ec); + m_CheckLivenessTimer.cancel(); + m_HeartbeatTimer.cancel(); m_Stream->lowest_layer().cancel(ec); - m_CheckLivenessTimer.cancel(); - m_HeartbeatTimer.cancel(); + m_Stream->next_layer().async_shutdown(yc[ec]); + + m_Stream->lowest_layer().shutdown(m_Stream->lowest_layer().shutdown_both, ec); } }); }