Skip to content

Add OAuth2 HTTP request timeouts - #606

Draft
RobertIndie wants to merge 3 commits into
mainfrom
oauth2-http-timeouts
Draft

Add OAuth2 HTTP request timeouts#606
RobertIndie wants to merge 3 commits into
mainfrom
oauth2-http-timeouts

Conversation

@RobertIndie

@RobertIndieRobertIndie commented Aug 10, 2026

Copy link
Copy Markdown
Member

Motivation

OAuth2 issuer discovery and token requests previously used libcurl without application-level connection or total request deadlines. An unavailable or stalled issuer could therefore delay client startup and recovery for several minutes.

Modifications

Add a distinct CurlWrapper connection timeout and configurable OAuth2 connect_timeout_seconds and request_timeout_seconds parameters, defaulting to 10 and 30 seconds. Validate both parameters as positive integers, apply them to discovery, token acquisition, and refresh for both OAuth2 flows, document the public configuration, and add black-box regression coverage.

Verifying this change

Built the modified production and AuthPluginTest objects with -Werror. Ran three new timeout and validation tests plus four existing OAuth TLS tests; all 7 passed. The complete pulsar-tests target remains blocked by the pre-existing DagWatchSession incompatibility with the installed Boost.Asio API.

Usage

Configure the OAuth2 HTTP timeouts through the authentication parameters:

pulsar::ParamMap params;
params["issuer_url"] = "https://auth.example.com";
params["private_key"] = "file:///path/to/oauth-credentials.json";
params["audience"] = "https://pulsar.example.com";
params["connect_timeout_seconds"] = "5";
params["request_timeout_seconds"] = "15";
pulsar::ClientConfiguration config;
config.setAuth(pulsar::AuthOauth2::create(params));
pulsar::Client client("pulsar+ssl://broker.example.com:6651", config);

The parameters can also be supplied as JSON:

const std::string authParams = R"({ "issuer_url": "https://auth.example.com", "private_key": "file:///path/to/oauth-credentials.json", "audience": "https://pulsar.example.com", "connect_timeout_seconds": "5", "request_timeout_seconds": "15"})";
pulsar::ClientConfiguration config;
config.setAuth(pulsar::AuthOauth2::create(authParams));
pulsar::Client client("pulsar+ssl://broker.example.com:6651", config);
  • connect_timeout_seconds controls the OAuth HTTP connection timeout and defaults to 10 seconds.
  • request_timeout_seconds controls the total OAuth HTTP request timeout and defaults to 30 seconds.
  • Both values must be positive integers.
  • The timeouts apply to issuer discovery, initial token acquisition, and token refresh.

Python client users can pass the same JSON parameters:

importjsonimportpulsarauth=pulsar.AuthenticationOauth2(json.dumps({
"issuer_url": "https://auth.example.com",
"private_key": "file:///path/to/oauth-credentials.json",
"audience": "https://pulsar.example.com",
"connect_timeout_seconds": "5",
"request_timeout_seconds": "15",
}))
client=pulsar.Client(
"pulsar+ssl://broker.example.com:6651",
authentication=auth,
)

Documentation

  • doc-required
    (Your PR needs to update docs and you will update later)

  • doc-not-needed
    (Please explain why)

  • doc
    (Your PR contains doc changes)

  • doc-complete
    (Docs have been already added)

@RobertIndieRobertIndie self-assigned this Aug 10, 2026
@RobertIndieRobertIndie added the enhancement New feature or request label Aug 10, 2026
@RobertIndieRobertIndie added this to the 4.3.0 milestone Aug 10, 2026
@RobertIndie
RobertIndie requested a lite review from CopilotAugust 10, 2026 08:36
Motivation:
OAuth2 issuer discovery and token requests previously used libcurl without application-level connection or total request deadlines. An unavailable or stalled issuer could therefore delay client startup and recovery for several minutes.
Modification:
Add a distinct CurlWrapper connection timeout and configurable OAuth2 connect_timeout_seconds and request_timeout_seconds parameters, defaulting to 10 and 30 seconds. Validate both parameters as positive integers, apply them to discovery, token acquisition, and refresh for both OAuth2 flows, document the public configuration, and add black-box regression coverage.
Testing:
Built the modified production and AuthPluginTest objects with -Werror. Ran three new timeout and validation tests plus four existing OAuth TLS tests; all 7 passed. The complete pulsar-tests target remains blocked by the pre-existing DagWatchSession incompatibility with the installed Boost.Asio API.
Usage:
Set connect_timeout_seconds and request_timeout_seconds as positive integer strings in the AuthOauth2 parameter map or JSON passed to AuthOauth2::create. If omitted, the client uses 10-second connection and 30-second total-request timeouts.

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds configurable OAuth2 HTTP connection and total-request timeouts to prevent issuer discovery / token requests from stalling client startup and token refresh.

Changes:

  • Introduces connect_timeout_seconds and request_timeout_seconds OAuth2 parameters (defaults 10s/30s) with positive-integer validation.
  • Extends CurlWrapper::Options with a connection timeout and applies it via CURLOPT_CONNECTTIMEOUT.
  • Adds black-box tests covering issuer discovery timeout, token request timeout, and parameter validation; updates public header docs.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
tests/AuthPluginTest.ccAdds mock-server delay support and new OAuth2 timeout/validation regression tests.
oauth2-http-timeout-analysis.mdAdds an in-repo analysis/design write-up for the OAuth2 timeout change.
lib/CurlWrapper.hAdds connectTimeoutInSeconds and applies CURLOPT_CONNECTTIMEOUT.
lib/auth/AuthOauth2.hIntroduces Oauth2HttpTimeouts and stores it in OAuth2 flows.
lib/auth/AuthOauth2.ccParses/validates timeout params and applies them to issuer discovery + token requests (incl. timeout logging).
include/pulsar/Authentication.hDocuments new OAuth2 timeout parameters in the public API header.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +718 to +721
wellKnownServer.stop();
tokenServer.stop();
wellKnownThread.join();
tokenThread.join();
Make the OAuth2 mock server poll accept in non-blocking mode so stop can terminate a server that never receives a connection. Replace the unconditional response delay with an interruptible condition-variable wait to keep test cleanup bounded across platforms.
Verified the test object with Boost.Asio and standalone Asio, ran the 7 focused OAuth tests, and repeated both timeout tests 10 times.
Read builtin-baseline from vcpkg.json and check out that revision during Alpine packaging instead of building against the moving vcpkg master branch. This keeps the packaging toolchain reproducible and avoids requiring CMake 4.3 features on Alpine 3.19.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@RobertIndie