fix(google): give avatar HTTP client a timeout - #12
Conversation
Give fetchAvatarURL a dedicated http.Client with avatarLookupTimeout instead of http.DefaultClient. Request contexts still apply. Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: needs maintainer review before merge. Reviewed September 4, 2026, 1:01 PM ET / 17:01 UTC. ClawSweeper reviewWhat this changesThe PR gives Google contact-avatar downloads their own 20-second HTTP timeout and adds a regression test for a server that accepts a connection but never responds. Regression provenancePossible regression — probable (reviewed change; failure trace). No predecessor PR is attributed. Merge readiness✅ Ready for maintainer review The focused timeout change remains absent from current main, has direct stalled-connection proof, and introduces no actionable correctness or security defect. Priority: P3 Review scores
Verification
How this fits togetherThe Google import adapter lists contacts, obtains photo URLs through the gog CLI, and downloads images into imported contact records. The new HTTP-client boundary limits avatar-request wait time while preserving caller cancellation. flowchart LR
A[Google contact import] --> B[Contact and photo lookup]
B --> C[Avatar URL]
C --> D[Timed HTTP download]
D --> E[Avatar byte limit]
E --> F[Imported contact avatar]
Before mergeNone. Agent review detailsSecurityNone. Review metrics
Technical reviewBest possible solution: Merge the focused timeout guard and retain the stalled-connection regression coverage. Do we have a high-confidence way to reproduce the issue? Yes: the added regression exercises the production helper against a real local HTTP server that stalls after accepting a request, and the PR records the observed timeout result. Is this the best way to solve the issue? Yes: applying the existing 20-second adapter timeout at the HTTP-client boundary preserves caller cancellation and adds a narrow defensive limit to the image request. AGENTS.md: not found in the target repository. Codex review notes: model internal, reasoning high; reviewed against baa945d86da0. LabelsLabel changes:
Label justifications:
EvidenceWhat I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (5 earlier review cycles)
|
What Problem This Solves
clawdex import google --avatarsdownloads each contact photo throughfetchAvatarURL. That helper usedhttp.DefaultClient, which has noTimeout. ProductionattachAvataralready wraps the call in a 20slookupCtx, so a stalling photo host does not hang forever on the currentcall path.
DefaultClientcan still stall when a caller passes an unbounded context(tests use
t.Context(), andfetchAvatarURLis the public importpath). The Google adapter should own a client timeout, the same
belt-and-suspenders pattern as sibling HTTP clients.
This change adds a package-level
avatarHTTPClientwithTimeout: avatarLookupTimeout(20s) and uses it for the GET. Requestcontexts still apply via
http.NewRequestWithContext.Evidence
Live
go runagainst a TCP listener that accepts and never writes HTTP.A 50ms client returns in 51ms.
http.DefaultClientwith only a 2s requestcontext waits the full deadline:
After the patch,
fetchAvatarURLuses that timed client. Grep of theproduction helper:
A stalled photo URL through
fetchAvatarURL(context.Background(), ...)now returns in 52ms with
Client.Timeout exceeded while awaiting headersinstead of sitting until an outer 2s bound.
Real behavior proof
Behavior or issue addressed: Google avatar HTTP GETs use a dedicated client with a 20s Timeout so an unbounded caller context cannot wait forever on a peer that accepts and never responds.
Real environment tested: macOS Darwin 25.6.0 arm64, Go 1.27.0, clawdex worktree
/tmp/clawdex-F001at branchfix/google-avatar-http-timeout.Exact steps or command run after this patch:
Evidence after fix: terminal output from the patched tree:
Observed result after fix: A stalling photo host no longer depends on the caller to cancel.
avatarHTTPClientreturnsClient.Timeout exceeded while awaiting headersin about 50ms when the client Timeout is 50ms. Production keeps the 20savatarLookupTimeout.http.DefaultClientis gone fromfetchAvatarURL.What was not tested: A live
gog contacts rawcall against a real Google account whose photo URL hangs. Redirect-heavy CDN photo URLs.Summary
fetchAvatarURLnow usesavatarHTTPClient(Timeout: 20s) instead ofhttp.DefaultClient.http.NewRequestWithContextis unchanged so callerdeadlines still apply. Success-path coverage in
TestFetchAvatarURLstillpasses through the new client.
Related:
e419451(feat: fetch Google contact avatars, 2026-05-08)http.Client.Timeoutincludes connect, redirects, and body read;DefaultClientis zero