Unverified Commit a54a4fab authored by Jiankun Yu's avatar Jiankun Yu Committed by GitHub

fix issue-193 (#819)

* fix issue-193

The client implementation isn't compliant with HTTP 1.1 standard, to be
specific, it doesn't honor the "Connection: close" response header. As a
result, whenever a new request is sent, a new tcp connection is opened
to the server and is never closed (unless the server close it).

The best place to close the connection is in Connection::OnDone() method,
however, that method is provided too early, in the Connection::asyncPerform()
method, where the Http::Response object is not yet available. It's also
incorrect to blindly close the connection in OnDone() method, as there might
be more data from server.

This commit explicitly closes all opened connections on Client::shutdown(),
to guarantee all network resources are recycled on that call.

It's impossible to write any unit test case verify it, the connection pool
is invisible to Client users. It passed manual tests on crafted scenarios.

To verify this, start a Pistache server from the examples, then use the Client
library to send some requests to the server, and don't terminate client side
program. Use "netstat -an | grep <server_port>" to see if there are remaining
connections in ESTABLISHED state after client.shutdown() is called.
Signed-off-by: default avatarJiankun Yu <yujiankun@hotmail.com>

* fix formatting issue
parent d8ae8ddf
......@@ -123,6 +123,7 @@ public:
size_t availableConnections(const std::string &domain) const;
void closeIdleConnections(const std::string &domain);
void shutdown();
private:
using Connections = std::vector<std::shared_ptr<Connection>>;
......
......@@ -716,6 +716,18 @@ size_t ConnectionPool::availableConnections(const std::string &domain) const {
void ConnectionPool::closeIdleConnections(const std::string &domain){
UNUSED(domain)}
void ConnectionPool::shutdown() {
// close all connections
Guard guard(connsLock);
for (auto &it : conns) {
for (auto &conn : it.second) {
if (conn->isConnected()) {
conn->close();
}
}
}
}
RequestBuilder &RequestBuilder::method(Method method) {
request_.method_ = method;
return *this;
......@@ -801,6 +813,7 @@ void Client::init(const Client::Options &options) {
void Client::shutdown() {
reactor_->shutdown();
pool.shutdown();
Guard guard(queuesLock);
stopProcessPequestsQueues = true;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment