]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1390] Http connection closed on timeout
authorMarcin Siodelski <marcin@isc.org>
Thu, 20 Aug 2020 11:23:22 +0000 (13:23 +0200)
committerMarcin Siodelski <marcin@isc.org>
Fri, 21 Aug 2020 13:36:08 +0000 (15:36 +0200)
When the client gets the timeout trying to communicate with the server it
now closes connection and re-establishes it when next request is to be
sent.

src/lib/http/client.cc
src/lib/http/tests/server_client_unittests.cc

index f66f4b3079700f9534cbaa5c598e790d057b9682..63dd8ca1e336dfb0e9891ecca02f1eeb352f0501 100644 (file)
@@ -968,9 +968,9 @@ Connection::terminateInternal(const boost::system::error_code& ec,
         } catch (...) {
         }
 
-        // If we're not requesting connection persistence, we should close the socket.
-        // We're going to reconnect for the next transaction.
-        if (!current_request_->isPersistent()) {
+        // If we're not requesting connection persistence or the connection has timed out,
+        // we should close the socket. We're going to reconnect for the next transaction.
+        if (!current_request_->isPersistent() || (ec == boost::asio::error::timed_out)) {
             closeInternal();
         }
 
index fa91b150de93ad2dc1eda277832e14fc92934e19..6717128a5fff9580fec2ef117cf85333db866b22 100644 (file)
@@ -1480,20 +1480,29 @@ public:
         // rest of the response to be provided and will eventually time out.
         PostHttpRequestJsonPtr request1 = createRequest("partial-response", true);
         HttpResponseJsonPtr response1(new HttpResponseJson());
+        // This value will be set to true if the connection close callback is
+        // invoked upon time out.
+        auto connection_closed = false;
         ASSERT_NO_THROW(client.asyncSendRequest(url, request1, response1,
             [this, &cb_num](const boost::system::error_code& ec,
                             const HttpResponsePtr& response,
                             const std::string&) {
-            if (++cb_num > 1) {
-                io_service_.stop();
-            }
-            // In this particular case we know exactly the type of the
-            // IO error returned, because the client explicitly sets this
-            // error code.
-            EXPECT_TRUE(ec.value() == boost::asio::error::timed_out);
-            // There should be no response returned.
-            EXPECT_FALSE(response);
-        }, HttpClient::RequestTimeout(100)));
+                if (++cb_num > 1) {
+                    io_service_.stop();
+                }
+                // In this particular case we know exactly the type of the
+                // IO error returned, because the client explicitly sets this
+                // error code.
+                EXPECT_TRUE(ec.value() == boost::asio::error::timed_out);
+                // There should be no response returned.
+                EXPECT_FALSE(response);
+            }, HttpClient::RequestTimeout(100), HttpClient::ConnectHandler(),
+            [&connection_closed](const int) {
+                // This callback is called when the connection gets closed
+                // by the client.
+                connection_closed = true;
+            })
+        );
 
         // Create another request after the timeout. It should be handled ok.
         PostHttpRequestJsonPtr request2 = createRequest("sequence", 1);
@@ -1509,6 +1518,8 @@ public:
 
         // Actually trigger the requests.
         ASSERT_NO_THROW(runIOService());
+        // Make sure that the client has closed the connection upon timeout.
+        EXPECT_TRUE(connection_closed);
     }
 
     /// @brief Test that client times out when connection takes too long.
@@ -1527,9 +1538,9 @@ public:
         PostHttpRequestJsonPtr request = createRequest("sequence", 1);
         HttpResponseJsonPtr response(new HttpResponseJson());
         ASSERT_NO_THROW(client.asyncSendRequest(url, request, response,
-            [this, &cb_num](const boost::system::error_code& ec,
-                            const HttpResponsePtr& response,
-                            const std::string&) {
+            [this, &cb_num, &client](const boost::system::error_code& ec,
+                                     const HttpResponsePtr& response,
+                                     const std::string&) {
             if (++cb_num > 1) {
                 io_service_.stop();
             }