Skip to content

Commit 2e690cd

Browse files
committed
Fix bad_weak_ptr when close a ClientConnection during construction
Fixes #348 Fixes #349 ### Motivation When `close` is called in `ClientConnection`'s constructor, `shared_from_this()` will be called, which results in a `std::bad_weak_ptr` error. This error does not happen before #317 because `shared_from_this()` could only be called when the `producers` or `consumers` field is not empty. ### Modifications Modify the 2nd parameter of `ClientConnection::close` to represent if the construction completes. If not, just set the state to `Disconnected` and complete the future to the result. Then `ConnectionPool::getConnectionAsync` will return a future that completes with the failed result. In addition, check `authentication_` even for non-TLS URLs. Otherwise, the null authentication will be used to construct `CommandConnect`. Add `testInvalidPlugin` and `testTlsConfigError` to verify the changes.
1 parent 6d47e94 commit 2e690cd

3 files changed

Lines changed: 31 additions & 16 deletions

File tree

lib/ClientConnection.cc

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ ClientConnection::ClientConnection(const std::string& logicalAddress, const std:
187187
pool_(pool),
188188
poolIndex_(poolIndex) {
189189
LOG_INFO(cnxString_ << "Create ClientConnection, timeout=" << clientConfiguration.getConnectionTimeout());
190+
if (!authentication_) {
191+
LOG_ERROR("Invalid authentication plugin");
192+
close(ResultAuthenticationError, false);
193+
return;
194+
}
190195
if (clientConfiguration.isUseTls()) {
191196
#if BOOST_VERSION >= 105400
192197
boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12_client);
@@ -215,12 +220,6 @@ ClientConnection::ClientConnection(const std::string& logicalAddress, const std:
215220
}
216221
}
217222

218-
if (!authentication_) {
219-
LOG_ERROR("Invalid authentication plugin");
220-
close(ResultAuthenticationError, false);
221-
return;
222-
}
223-
224223
std::string tlsCertificates = clientConfiguration.getTlsCertificateFilePath();
225224
std::string tlsPrivateKey = clientConfiguration.getTlsPrivateKeyFilePath();
226225

@@ -1260,7 +1259,13 @@ void ClientConnection::handleConsumerStatsTimeout(const boost::system::error_cod
12601259
startConsumerStatsTimer(consumerStatsRequests);
12611260
}
12621261

1263-
void ClientConnection::close(Result result, bool detach) {
1262+
void ClientConnection::close(Result result, bool constructCompleted) {
1263+
if (!constructCompleted) {
1264+
state_ = Disconnected;
1265+
connectPromise_.setFailed(result);
1266+
return;
1267+
}
1268+
12641269
Lock lock(mutex_);
12651270
if (isClosed()) {
12661271
return;
@@ -1320,9 +1325,7 @@ void ClientConnection::close(Result result, bool detach) {
13201325
LOG_INFO(cnxString_ << "Connection disconnected (refCnt: " << refCount << ")");
13211326
}
13221327
// Remove the connection from the pool before completing any promise
1323-
if (detach) {
1324-
pool_.remove(logicalAddress_ + "-" + std::to_string(poolIndex_), this);
1325-
}
1328+
pool_.remove(logicalAddress_ + "-" + std::to_string(poolIndex_), this);
13261329

13271330
auto self = shared_from_this();
13281331
for (ProducersMap::iterator it = producers.begin(); it != producers.end(); ++it) {

lib/ClientConnection.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,9 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
146146
* Close the connection.
147147
*
148148
* @param result all pending futures will complete with this result
149-
* @param detach remove it from the pool if it's true
150-
*
151-
* `detach` should only be false when:
152-
* 1. Before the connection is put into the pool, i.e. during the construction.
153-
* 2. When the connection pool is closed
149+
* @param constructCompleted whether the construction is completed
154150
*/
155-
void close(Result result = ResultConnectError, bool detach = true);
151+
void close(Result result = ResultConnectError, bool constructCompleted = true);
156152

157153
bool isClosed() const;
158154

tests/AuthPluginTest.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,3 +581,19 @@ TEST(AuthPluginTest, testOauth2Failure) {
581581
ASSERT_EQ(client5.createProducer(topic, producer), ResultAuthenticationError);
582582
client5.close();
583583
}
584+
585+
TEST(AuthPluginTest, testInvalidPlugin) {
586+
Client client("pulsar://localhost:6650", ClientConfiguration{}.setAuth(AuthFactory::create("invalid")));
587+
Producer producer;
588+
ASSERT_EQ(ResultAuthenticationError, client.createProducer("my-topic", producer));
589+
client.close();
590+
}
591+
592+
TEST(AuthPluginTest, testTlsConfigError) {
593+
Client client(serviceUrlTls, ClientConfiguration{}
594+
.setAuth(AuthTls::create(clientPublicKeyPath, clientPrivateKeyPath))
595+
.setTlsTrustCertsFilePath("invalid"));
596+
Producer producer;
597+
ASSERT_EQ(ResultAuthenticationError, client.createProducer("my-topic", producer));
598+
client.close();
599+
}

0 commit comments

Comments
 (0)