@@ -41,7 +41,7 @@ HttpServerConnection::HttpServerConnection(const WaitGroup::Ptr& waitGroup, cons
41
41
}
42
42
43
43
HttpServerConnection::HttpServerConnection (const WaitGroup::Ptr& waitGroup, const String& identity, bool authenticated, const Shared<AsioTlsStream>::Ptr& stream, boost::asio::io_context& io)
44
- : m_WaitGroup(waitGroup), m_Stream(stream), m_Seen(Utility::GetTime()), m_IoStrand(io), m_ShuttingDown(false ), m_CheckLivenessTimer(io)
44
+ : m_WaitGroup(waitGroup), m_Stream(stream), m_Seen(Utility::GetTime()), m_CanRead(io, true ), m_IoStrand(io), m_ShuttingDown(false ), m_CheckLivenessTimer(io)
45
45
{
46
46
if (authenticated) {
47
47
m_ApiUser = ApiUser::GetByClientCN (identity);
@@ -65,6 +65,7 @@ void HttpServerConnection::Start()
65
65
66
66
IoEngine::SpawnCoroutine (m_IoStrand, [this , keepAlive](asio::yield_context yc) { ProcessMessages (yc); });
67
67
IoEngine::SpawnCoroutine (m_IoStrand, [this , keepAlive](asio::yield_context yc) { CheckLiveness (yc); });
68
+ IoEngine::SpawnCoroutine (m_IoStrand, [this , keepAlive](asio::yield_context yc) { DetectClientShutdown (yc); });
68
69
}
69
70
70
71
/* *
@@ -418,6 +419,7 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc)
418
419
419
420
response.set (http::field::server, l_ServerHeader);
420
421
422
+ m_CanRead.WaitForSet (yc);
421
423
if (!EnsureValidHeaders (buf, request, response, m_ShuttingDown, yc)) {
422
424
break ;
423
425
}
@@ -476,6 +478,7 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc)
476
478
}
477
479
478
480
m_Seen = std::numeric_limits<decltype (m_Seen)>::max ();
481
+ m_CanRead.Clear ();
479
482
480
483
if (!ProcessRequest (request, response, m_WaitGroup, cpuBoundWorkTime, yc)) {
481
484
break ;
@@ -516,3 +519,27 @@ void HttpServerConnection::CheckLiveness(boost::asio::yield_context yc)
516
519
}
517
520
}
518
521
}
522
+
523
+ /* *
524
+ * Detects a shutdown initiated by the client side.
525
+ *
526
+ * @param yc The yield context for the coroutine of this function
527
+ */
528
+ void HttpServerConnection::DetectClientShutdown (boost::asio::yield_context yc)
529
+ {
530
+ using wait_type = boost::asio::socket_base::wait_type;
531
+
532
+ while (!m_ShuttingDown) {
533
+ m_CanRead.WaitForClear (yc);
534
+
535
+ boost::system::error_code ec;
536
+ m_Stream->async_fill (yc[ec]);
537
+ if (ec && !m_ShuttingDown) {
538
+ Log (LogInformation, " HttpServerConnection" ) << " Detected shutdown from client: " << m_PeerAddress << " ." ;
539
+ Disconnect (yc);
540
+ break ;
541
+ }
542
+
543
+ m_CanRead.Set ();
544
+ }
545
+ }
0 commit comments