[Bug] OAuth2 authentication makes HTTP requests with no timeout, hanging the client indefinitely
Nessuno ha ancora preso questa issue.
- #609 di @david-streamlio — chiusa senza merge
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 78/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- cpp
- Ambito
- authentication, networking
Direzione di ricerca
Inizia da lib/CurlWrapper.h, in particolare dal valore predefinito di options e dalla configurazione di CURLOPT_TIMEOUT, quindi esamina fetchTokenEndpoint() e fetchOauth2Token() in lib/auth/AuthOauth2.cc. Confronta la loro gestione del timeout con lib/HTTPLookupService.cc e lib/auth/athenz/ZTSClient.cc, quindi esegui il repro allegato rispetto allo stub issuer. Il lavoro è completo quando le chiamate HTTP OAuth2 restituiscono il controllo entro un timeout limitato invece di rimanere bloccate indefinitamente.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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!
- Lingua principale
- C++
- Stelle
- 72
- Fork
- 93
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di apache/pulsar-client-cpp
-
Difficoltà 3/5 Mezza giornata Idoneità per principianti 62/100
apache/pulsar-client-cpp#623 ·
-
[Bug] MessageTest fails to build with GCC 15.3.0 and 16.2.1 (-Werror=stringop-truncation)Forse già presa @davlgd l’ha presa 4 giorni fa. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 25/100
apache/pulsar-client-cpp#621 ·
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
apache/pulsar-client-cpp#620 ·
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
apache/pulsar-client-cpp#619 ·
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 20/100
apache/pulsar-client-cpp#618 ·
Tutte le issue di apache/pulsar-client-cpp
Issue simili
-
Code: Performance
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
CrimsonCrossBunker/Cataclysm-Cleanwater-Bomb#1167 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
meshcore-dev/MeshCore#3760 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
deepseek-ai/DeepGEMM-Ascend#29 ·
I maintainer di solito rispondono entro 1 giorno
-
ci Windows
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
aethersdr/AetherSDR#7003 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno