Skip to content

Commit 4cce2aa

Browse files
committed
[feat] Add httpLookupAuthAllowRedirect option to forward auth credentials on HTTP lookup redirects
1 parent 334d1bc commit 4cce2aa

9 files changed

Lines changed: 66 additions & 1 deletion

include/pulsar/ClientConfiguration.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,33 @@ class PULSAR_PUBLIC ClientConfiguration {
186186
*/
187187
int getMaxBackoffIntervalMs() const;
188188

189+
/**
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+
189216
/**
190217
* Configure a custom logger backend to route Pulsar client library logs
191218
* to a different logger implementation.

include/pulsar/c/client_configuration.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,12 @@ PULSAR_PUBLIC void pulsar_client_configuration_set_keep_alive_interval_in_second
219219
PULSAR_PUBLIC unsigned int pulsar_client_configuration_get_keep_alive_interval_in_seconds(
220220
pulsar_client_configuration_t *conf);
221221

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+
222228
#ifdef __cplusplus
223229
}
224230
#endif

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+
}

tests/c/c_ClientConfigurationTest.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,12 @@ TEST(C_ClientConfigurationTest, testCApiConfig) {
3737

3838
pulsar_client_configuration_set_keep_alive_interval_in_seconds(conf, 60);
3939
ASSERT_EQ(pulsar_client_configuration_get_keep_alive_interval_in_seconds(conf), 60);
40+
41+
ASSERT_EQ(pulsar_client_configuration_is_http_lookup_auth_allow_redirect(conf), 0);
42+
43+
pulsar_client_configuration_set_http_lookup_auth_allow_redirect(conf, 1);
44+
ASSERT_EQ(pulsar_client_configuration_is_http_lookup_auth_allow_redirect(conf), 1);
45+
46+
pulsar_client_configuration_set_http_lookup_auth_allow_redirect(conf, 0);
47+
ASSERT_EQ(pulsar_client_configuration_is_http_lookup_auth_allow_redirect(conf), 0);
4048
}

0 commit comments

Comments
 (0)