MCPcopy Create free account
hub / github.com/Icinga/icinga2 / StartDetectClientSideShutdown

Method StartDetectClientSideShutdown

lib/remote/httpserverconnection.cpp:107–148  ·  view source on GitHub ↗

* Starts a coroutine that continually reads from the stream to detect a disconnect from the client. * * This can be accessed inside an @c HttpHandler via the HttpResponse::StartStreaming() method by * passing true as the argument, expressing that disconnect detection is desired. */

Source from the content-addressed store, hash-verified

105 * passing true as the argument, expressing that disconnect detection is desired.
106 */
107void HttpServerConnection::StartDetectClientSideShutdown()
108{
109 namespace asio = boost::asio;
110
111 m_ConnectionReusable = false;
112
113 HttpServerConnection::Ptr keepAlive (this);
114
115 /* Technically it would be possible to detect disconnects on the TCP-side by setting the
116 * socket to non-blocking and then performing a read directly on the socket with the message_peek
117 * flag. As the TCP FIN message will put the connection into a CLOSE_WAIT even if the kernel
118 * buffer is full, this would technically be reliable way of detecting a shutdown and free
119 * of side-effects.
120 *
121 * However, for detecting the close_notify on the SSL/TLS-side, an async_fill() would be necessary
122 * when the check on the TCP level above returns that there are readable bytes (and no FIN/eof).
123 * If this async_fill() then buffers more application data and not an immediate eof, we could
124 * attempt to read another message before disconnecting.
125 *
126 * This could either be done at the level of the handlers, via the @c HttpApiResponse class, or
127 * generally as a separate coroutine here in @c HttpServerConnection, both (mostly) side-effect
128 * free and without affecting the state of the connection.
129 *
130 * However, due to the complexity of this approach, involving several asio operations, message
131 * flags, synchronous and asynchronous operations in blocking and non-blocking mode, ioctl cmds,
132 * etc., it was decided to stick with a simple reading loop, started conditionally on request by
133 * the handler.
134 */
135 IoEngine::SpawnCoroutine(m_IoStrand, [this, keepAlive](asio::yield_context yc) {
136 if (!m_ShuttingDown) {
137 char buf[128];
138 asio::mutable_buffer readBuf (buf, 128);
139 boost::system::error_code ec;
140
141 do {
142 m_Stream->async_read_some(readBuf, yc[ec]);
143 } while (!ec);
144
145 Disconnect(yc);
146 }
147 });
148}
149
150bool HttpServerConnection::Disconnected()
151{

Callers 1

StartStreamingMethod · 0.80

Calls 1

async_read_someMethod · 0.80

Tested by

no test coverage detected