Skip to content

Commit 399b791

Browse files
committed
Merge remote-tracking branch 'apache/main' into scalable-topics-cpp-api
2 parents afda557 + 0711b31 commit 399b791

15 files changed

Lines changed: 124 additions & 6 deletions

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@ For the supported Pulsar features, see [Client Feature Matrix](https://pulsar.ap
2727

2828
For how to use APIs to publish and consume messages, see [examples](https://github.com/apache/pulsar-client-cpp/tree/main/examples).
2929

30+
## Custom logger lifetime
31+
32+
The C++ client supports one custom logger factory per process. A logger configured
33+
through `ClientConfiguration::setLogger` or the C API logger functions is shared
34+
by all clients in the same process and is not scoped to an individual client
35+
instance. Set the custom logger before creating clients, and do not expect
36+
different clients to have independent log handlers.
37+
38+
If an application or language binding exposes logger callbacks, the callback and
39+
its context must remain valid until all Pulsar clients are closed and no
40+
background thread can emit client logs. Avoid tying the callback lifetime to a
41+
single client when multiple clients can exist in the process.
42+
3043
## Import the library into your project
3144

3245
### CMake with vcpkg integration

include/pulsar/ClientConfiguration.h

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,49 @@ class PULSAR_PUBLIC ClientConfiguration {
187187
int getMaxBackoffIntervalMs() const;
188188

189189
/**
190-
* Configure a custom logger backend to route of Pulsar client library
190+
* Configure whether to send authentication credentials when following HTTP redirects
191+
* to a different host during lookup requests.
192+
*
193+
* When enabled, the Authorization header will be forwarded on cross-origin redirects.
194+
*
195+
* HTTP lookup redirects typically occur when the broker receiving the lookup request
196+
* is not the owner of the requested topic. In this case, the broker responds with
197+
* an HTTP redirect (3xx) pointing to the correct owner broker. If authentication is
198+
* enabled, the redirected request needs to carry the auth credentials to be accepted
199+
* by the target broker.
200+
*
201+
* If this option is not enabled and the cluster has authentication enabled, the
202+
* redirected request will not carry credentials, which may result in a 401
203+
* Unauthorized error from the target broker.
204+
*
205+
* The default value is false.
206+
*
207+
* @param allow whether to allow sending auth credentials on redirects
208+
*/
209+
ClientConfiguration& setHttpLookupAuthAllowRedirect(bool allow);
210+
211+
/**
212+
* @return whether auth credentials are sent on HTTP redirects
213+
*/
214+
bool isHttpLookupAuthAllowRedirect() const;
215+
216+
/**
217+
* Configure a custom logger backend to route Pulsar client library logs
191218
* to a different logger implementation.
192219
*
193220
* By default, log messages are printed on standard output.
194221
*
195222
* When passed in, the configuration takes ownership of the loggerFactory object.
196-
* The logger factory can only be set once per process. Any subsequent calls to
197-
* set the logger factory will have no effect, though the logger factory object
198-
* will be cleaned up.
223+
* The logger factory is process-wide and is not scoped to a Client instance.
224+
* It can only be set once per process. Any subsequent calls to set the logger
225+
* factory will have no effect, though the logger factory object will be
226+
* cleaned up.
227+
*
228+
* Applications and language bindings that use callback-based logger factories
229+
* should set the logger before creating clients and ensure callback state
230+
* outlives all Pulsar clients and background threads that can emit logs.
231+
* Avoid using per-client callback objects that can be destroyed while another
232+
* client in the same process is still running.
199233
*/
200234
ClientConfiguration& setLogger(LoggerFactory* loggerFactory);
201235

include/pulsar/c/client_configuration.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,25 @@ PULSAR_PUBLIC void pulsar_client_configuration_set_concurrent_lookup_request(
141141
PULSAR_PUBLIC int pulsar_client_configuration_get_concurrent_lookup_request(
142142
pulsar_client_configuration_t *conf);
143143

144+
/**
145+
* Configure a custom logger for Pulsar client library logs.
146+
*
147+
* The logger is process-wide and is not scoped to a pulsar_client_t instance.
148+
* It can only be set once per process. Applications and language bindings
149+
* should set the logger before creating clients and ensure the logger callback
150+
* context outlives all Pulsar clients and background threads that can emit logs.
151+
*/
144152
PULSAR_PUBLIC void pulsar_client_configuration_set_logger(pulsar_client_configuration_t *conf,
145153
pulsar_logger logger, void *ctx);
146154

155+
/**
156+
* Configure a custom logger for Pulsar client library logs.
157+
*
158+
* The logger is process-wide and is not scoped to a pulsar_client_t instance.
159+
* It can only be set once per process. Applications and language bindings
160+
* should set the logger before creating clients and ensure the logger callback
161+
* context outlives all Pulsar clients and background threads that can emit logs.
162+
*/
147163
PULSAR_PUBLIC void pulsar_client_configuration_set_logger_t(pulsar_client_configuration_t *conf,
148164
pulsar_logger_t logger);
149165

@@ -203,6 +219,12 @@ PULSAR_PUBLIC void pulsar_client_configuration_set_keep_alive_interval_in_second
203219
PULSAR_PUBLIC unsigned int pulsar_client_configuration_get_keep_alive_interval_in_seconds(
204220
pulsar_client_configuration_t *conf);
205221

222+
PULSAR_PUBLIC void pulsar_client_configuration_set_http_lookup_auth_allow_redirect(
223+
pulsar_client_configuration_t *conf, int httpLookupAuthAllowRedirect);
224+
225+
PULSAR_PUBLIC int pulsar_client_configuration_is_http_lookup_auth_allow_redirect(
226+
pulsar_client_configuration_t *conf);
227+
206228
#ifdef __cplusplus
207229
}
208230
#endif

include/pulsar/c/result.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ typedef enum
9292

9393
pulsar_result_MemoryBufferIsFull, /// Client-wide memory limit has been reached
9494
pulsar_result_Interrupted, /// Interrupted while waiting to dequeue
95+
pulsar_result_Disconnected, /// Client connection has been disconnected
9596
} pulsar_result;
9697

9798
// Return string representation of result code

lib/ClientConfiguration.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,4 +231,11 @@ ClientConfiguration& ClientConfiguration::setDescription(const std::string& desc
231231

232232
const std::string& ClientConfiguration::getDescription() const noexcept { return impl_->description; }
233233

234+
ClientConfiguration& ClientConfiguration::setHttpLookupAuthAllowRedirect(bool allow) {
235+
impl_->httpLookupAuthAllowRedirect = allow;
236+
return *this;
237+
}
238+
239+
bool ClientConfiguration::isHttpLookupAuthAllowRedirect() const { return impl_->httpLookupAuthAllowRedirect; }
240+
234241
} // namespace pulsar

lib/ClientConfigurationImpl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ struct ClientConfigurationImpl {
5353
std::string description;
5454
std::string proxyServiceUrl;
5555
ClientConfiguration::ProxyProtocol proxyProtocol;
56+
bool httpLookupAuthAllowRedirect{false};
5657

5758
std::unique_ptr<LoggerFactory> takeLogger() { return std::move(loggerFactory); }
5859

lib/CurlWrapper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class CurlWrapper {
5454
std::string userAgent;
5555
int timeoutInSeconds{0};
5656
int maxLookupRedirects{-1};
57+
bool authAllowRedirect{false};
5758
};
5859

5960
struct TlsContext {
@@ -128,6 +129,9 @@ inline CurlWrapper::Result CurlWrapper::get(const std::string& url, const std::s
128129
// Redirects
129130
curl_easy_setopt(handle_, CURLOPT_FOLLOWLOCATION, 1L);
130131
curl_easy_setopt(handle_, CURLOPT_MAXREDIRS, options.maxLookupRedirects);
132+
if (options.authAllowRedirect) {
133+
curl_easy_setopt(handle_, CURLOPT_UNRESTRICTED_AUTH, 1L);
134+
}
131135

132136
char errorBuffer[CURL_ERROR_SIZE] = "";
133137
curl_easy_setopt(handle_, CURLOPT_ERRORBUFFER, errorBuffer);

lib/HTTPLookupService.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ HTTPLookupService::HTTPLookupService(const ServiceInfo &serviceInfo,
6161
tlsTrustCertsFilePath_(serviceInfo.tlsTrustCertsFilePath().value_or("")),
6262
isUseTls_(serviceInfo.useTls()),
6363
tlsAllowInsecure_(clientConfiguration.isTlsAllowInsecureConnection()),
64-
tlsValidateHostname_(clientConfiguration.isValidateHostName()) {}
64+
tlsValidateHostname_(clientConfiguration.isValidateHostName()),
65+
httpLookupAuthAllowRedirect_(clientConfiguration.isHttpLookupAuthAllowRedirect()) {}
6566

6667
auto HTTPLookupService::getBroker(const TopicName &topicName) -> LookupResultFuture {
6768
LookupResultPromise promise;
@@ -228,6 +229,7 @@ Error HTTPLookupService::sendHTTPRequest(const std::string &completeUrl, std::st
228229
options.timeoutInSeconds = lookupTimeoutInSeconds_;
229230
options.userAgent = std::string("Pulsar-CPP-v") + PULSAR_VERSION_STR;
230231
options.maxLookupRedirects = maxLookupRedirects_;
232+
options.authAllowRedirect = httpLookupAuthAllowRedirect_;
231233
auto result = curl.get(completeUrl, authDataContent->getHttpHeaders(), options, tlsContext.get());
232234

233235
responseData = result.responseData;

lib/HTTPLookupService.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class HTTPLookupService : public LookupService, public std::enable_shared_from_t
5454
bool isUseTls_;
5555
bool tlsAllowInsecure_;
5656
bool tlsValidateHostname_;
57+
bool httpLookupAuthAllowRedirect_;
5758

5859
static LookupDataResultPtr parsePartitionData(const std::string&);
5960
static LookupDataResultPtr parseLookupData(const std::string&);

lib/c/c_ClientConfiguration.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,12 @@ unsigned int pulsar_client_configuration_get_keep_alive_interval_in_seconds(
204204
pulsar_client_configuration_t *conf) {
205205
return conf->conf.getKeepAliveIntervalInSeconds();
206206
}
207+
208+
void pulsar_client_configuration_set_http_lookup_auth_allow_redirect(pulsar_client_configuration_t *conf,
209+
int httpLookupAuthAllowRedirect) {
210+
conf->conf.setHttpLookupAuthAllowRedirect(httpLookupAuthAllowRedirect);
211+
}
212+
213+
int pulsar_client_configuration_is_http_lookup_auth_allow_redirect(pulsar_client_configuration_t *conf) {
214+
return conf->conf.isHttpLookupAuthAllowRedirect();
215+
}

0 commit comments

Comments
 (0)