#include "base/timer.hpp"
#include "base/tlsstream.hpp"
#include "base/utility.hpp"
+#include <limits>
#include <memory>
#include <stdexcept>
#include <boost/asio/spawn.hpp>
auto const l_ServerHeader ("Icinga/" + Application::GetAppVersion());
HttpServerConnection::HttpServerConnection(const String& identity, bool authenticated, const std::shared_ptr<AsioTlsStream>& stream)
- : m_Stream(stream), m_IoStrand(stream->get_io_service()), m_ShuttingDown(false)
+ : m_Stream(stream), m_Seen(Utility::GetTime()), m_IoStrand(stream->get_io_service()), m_ShuttingDown(false)
{
if (authenticated) {
m_ApiUser = ApiUser::GetByClientCN(identity);
HttpServerConnection::Ptr preventGc (this);
asio::spawn(m_IoStrand, [this, preventGc](asio::yield_context yc) { ProcessMessages(yc); });
+ asio::spawn(m_IoStrand, [this, preventGc](asio::yield_context yc) { CheckLiveness(yc); });
}
void HttpServerConnection::Disconnect()
boost::beast::http::request<boost::beast::http::string_body>& request,
ApiUser::Ptr& authenticatedUser,
boost::beast::http::response<boost::beast::http::string_body>& response,
+ double& seen,
boost::asio::yield_context& yc
)
{
try {
CpuBoundWork handlingRequest (yc);
+ Defer updateSeen ([&seen]() { seen = Utility::GetTime(); });
+
HttpHandler::ProcessRequest(stream, authenticatedUser, request, response, yc, hasStartedStreaming);
} catch (const std::exception& ex) {
if (hasStartedStreaming) {
break;
}
+ m_Seen = Utility::GetTime();
+
auto& request (parser.get());
{
break;
}
- if (!ProcessRequest(*m_Stream, request, authenticatedUser, response, yc)) {
+ m_Seen = std::numeric_limits<decltype(m_Seen)>::max();
+
+ if (!ProcessRequest(*m_Stream, request, authenticatedUser, response, m_Seen, yc)) {
break;
}
}
}
}
+
+void HttpServerConnection::CheckLiveness(boost::asio::yield_context yc)
+{
+ boost::asio::deadline_timer timer (m_Stream->get_io_service());
+
+ for (;;) {
+ timer.expires_from_now(boost::posix_time::seconds(5));
+ timer.async_wait(yc);
+
+ if (m_ShuttingDown) {
+ break;
+ }
+
+ if (m_Seen < Utility::GetTime() - 10) {
+ Log(LogInformation, "HttpServerConnection")
+ << "No messages for HTTP connection have been received in the last 10 seconds.";
+
+ Disconnect();
+ break;
+ }
+ }
+}