[Bug] OAuth2 authentication makes HTTP requests with no timeout, hanging the client indefinitely
还没有人认领这个 Issue。
- #609 来自 @david-streamlio —— 已关闭,未合并
评估
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 新手友好度
- 78/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- cpp
调研方向
从 lib/CurlWrapper.h 开始,重点检查 options 的默认值和 CURLOPT_TIMEOUT 的设置,然后检查 lib/auth/AuthOauth2.cc 中的 fetchTokenEndpoint() 和 fetchOauth2Token()。将它们的超时处理与 lib/HTTPLookupService.cc 和 lib/auth/athenz/ZTSClient.cc 进行比较,并针对 stub issuer 运行随附的 repro。完成标准是 OAuth2 HTTP 调用能在有界超时时间内返回,而不是无限期挂起。
由索引模型根据 Issue 内容生成。
描述
Search before asking
- I searched in the issues and found nothing similar.
Version
pulsar-client-cpp v4.2.0 (also verified at master, commit 1d08b2b, 2026-07-21)
Reproduced through pulsar-client (Python) 3.13.0 from PyPI, which pins pulsar-cpp 4.2.0
via dependencies.yaml.
OS: Linux x86_64
Minimal reproduce step
Requires no Pulsar broker and no real OAuth2 issuer. The script below starts a stub TCP
listener that accepts the connection and then never replies — the behaviour of a
black-holed or overloaded issuer.
pip install pulsar-client==3.13.0
python3 repro_oauth_timeout.py 100
Script attached. It configures the client with operation_timeout_seconds=5 and
connection_timeout_ms=5000, points issuer_url at the stub, and calls create_producer().
What did you expect to see?
The OAuth2 flow fails within a bounded, ideally configurable, period — and at minimum
within the client's own configured timeouts.
What did you see instead?
The call never returns. Observed output:
[*] pulsar-client 3.13.0
[*] operation_timeout_seconds=5, connection_timeout_ms=5000
[*] Calling create_producer(); watchdog set to 100s
[stub:issuer] accepted TCP connection, now stalling (will never respond)
still blocked after 15.0s (no client-side timeout has fired)
still blocked after 30.0s (no client-side timeout has fired)
still blocked after 45.0s (no client-side timeout has fired)
still blocked after 60.0s (no client-side timeout has fired)
still blocked after 75.0s (no client-side timeout has fired)
still blocked after 90.0s (no client-side timeout has fired)
still blocked after 105.0s (no client-side timeout has fired)
[RESULT] REPRODUCED. Still blocked in OAuth2 discovery after 105.0s.
Both configured client timeouts were exceeded by more than 20x with no sign of returning.
Neither operationTimeoutSeconds nor connectionTimeoutMs bounds the auth flow's HTTP calls.
Anything else?
Root cause: CurlWrapper::Options::timeoutInSeconds defaults to 0 (lib/CurlWrapper.h:55) and
is applied unconditionally at lib/CurlWrapper.h:123:
curl_easy_setopt(handle_, CURLOPT_TIMEOUT, options.timeoutInSeconds);
CURLOPT_TIMEOUT of 0 means no timeout in libcurl. CURLOPT_CONNECTTIMEOUT is never set
anywhere in the repository, leaving only libcurl's 300s default for the connect phase and
nothing at all once connected.
Both OAuth2 call sites leave the default in place:
-
Issuer discovery — lib/auth/AuthOauth2.cc:277, in fetchTokenEndpoint(), passes a
default-constructed options object:
curl.get(wellKnownUrl, "Accept: application/json", {}, tlsContext); -
Token endpoint — lib/auth/AuthOauth2.cc:336-339, in fetchOauth2Token(), constructs
options but sets only postFields.
This looks specific to the OAuth2 path. Other components set a timeout on the same wrapper:
- lib/HTTPLookupService.cc:229 -> options.timeoutInSeconds = lookupTimeoutInSeconds_;
- lib/auth/athenz/ZTSClient.cc:369 -> options.timeoutInSeconds = REQUEST_TIMEOUT;
Impact, as hit in production by a user running OAuth2 in Kubernetes: pods hang rather than
fail, so the problem stays invisible to health checks; and a transient issuer fault cannot
self-heal because recovery never starts.
Suggested fix: set a default timeout at both OAuth2 call sites following the existing
HTTPLookupService/ZTSClient pattern, and set CURLOPT_CONNECTTIMEOUT in CurlWrapper. Ideally
expose the value as an OAuth2 parameter.
Are you willing to submit a PR?
- I'm willing to submit a PR!
- 主要语言
- C++
- 星标
- 72
- 派生
- 93
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
apache/pulsar-client-cpp 的其他 Issue
-
难度 3/5 半天 新手友好度 62/100
apache/pulsar-client-cpp#623 ·
-
[Bug] MessageTest fails to build with GCC 15.3.0 and 16.2.1 (-Werror=stringop-truncation)可能已有人在做 @davlgd 于 4 天前认领。 未关闭
难度 1/5 1 小时以内 新手友好度 25/100
apache/pulsar-client-cpp#621 ·
-
难度 4/5 3-5 天 新手友好度 55/100
apache/pulsar-client-cpp#620 ·
-
难度 4/5 3-5 天 新手友好度 48/100
apache/pulsar-client-cpp#619 ·
-
难度 4/5 3-5 天 新手友好度 20/100
apache/pulsar-client-cpp#618 ·
查看 apache/pulsar-client-cpp 的全部 Issue
相似的 Issue
-
bug module:nodes tests
难度 2/5 1-3 小时 新手友好度 78/100
rocketride-org/rocketride-server#3020 ·
维护者通常 2 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 75/100
pocoproject/poco#5636 ·
维护者通常 2 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
enhancement
难度 2/5 1-3 小时 新手友好度 75/100
-
难度 2/5 1-3 小时 新手友好度 72/100
microsoft/cppwinrt#1646 · 7 条评论 ·
维护者通常 1 天内回复