Skip to content

fix(http): bound watch serve and OAuth callback read timeouts - #998

Merged
steipete merged 1 commit into
openclaw:mainfrom
SebTardif:fix/watch-serve-read-timeout
Aug 16, 2026
Merged

fix(http): bound watch serve and OAuth callback read timeouts#998
steipete merged 1 commit into
openclaw:mainfrom
SebTardif:fix/watch-serve-read-timeout

Conversation

@SebTardif

Copy link
Copy Markdown
Contributor

What Problem This Solves

gog gmail watch serve only set ReadHeaderTimeout. After headers, a client can dribble the body forever. gog drive changes serve already sets ReadTimeout, IdleTimeout, and MaxHeaderBytes. The local OAuth callback server had the same gap.

This PR does not change DefaultClient usage (that is #995).

Evidence

$ go test ./internal/cmd ./internal/googleauth
ok

TestGmailWatchServeCmd_HTTPServerTimeouts and TestNewOAuthCallbackServer_ReadTimeout assert ReadTimeout, ReadHeaderTimeout, IdleTimeout, and MaxHeaderBytes are non-zero.

Real behavior proof

Behavior addressed: Watch-serve and OAuth callback listeners now have the same read/idle timeouts as drive-changes serve.
Real environment tested: macOS, Go from the worktree, gogcli /tmp/oc-impl-gogcli-timeout head b6c463b.
Exact steps or command run after this patch: go test ./internal/cmd ./internal/googleauth
Evidence after fix: tests pass.
Observed result after fix: constructed http.Server values have a 10s read timeout and 30s idle timeout.
What was not tested: A live Pub/Sub client that dribbles a POST body.

gmail watch serve and the local OAuth callback listener only set
ReadHeaderTimeout. Copy the Drive changes serve pattern so both
servers also set ReadTimeout, IdleTimeout, and MaxHeaderBytes.

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
@clawsweeper

clawsweeper Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@clawsweeper clawsweeper Bot added merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 15, 2026
@clawsweeper

clawsweeper Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed August 15, 2026, 4:59 PM ET / 20:59 UTC.

ClawSweeper review

What this changes

The PR adds read, idle, and header-size limits to the Gmail watch and local OAuth callback HTTP listeners, with constructor-level tests.

Merge readiness

Blocked until real behavior proof from a real setup is added - 4 items remain

Keep open: the timeout hardening addresses a source-visible gap, but the new fixed 10-second Gmail push-body deadline can reject previously accepted slow deliveries and needs compatibility proof before merge.

Priority: P2
Reviewed head: b6c463b50f2cf894d3ecd8f5e7b1f841c390149f

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) The implementation is focused, but runtime proof and Gmail delivery compatibility are not yet established.
Proof confidence 🦪 silver shellfish (2/6) Needs real behavior proof before merge: The supplied evidence is passing unit tests that inspect server fields; it does not show an after-fix slow request being terminated or a normal request succeeding through either real listener. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🦐 gold shrimp (3/6) 1 actionable review finding remain.

Verification

Check Result Evidence
Real behavior Needs proof Needs real behavior proof before merge: The supplied evidence is passing unit tests that inspect server fields; it does not show an after-fix slow request being terminated or a normal request succeeding through either real listener. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 7 items Current Gmail listener gap: Current main only sets ReadHeaderTimeout on the Gmail watch server; its handler reads the complete request body after headers.
Distinct Gmail body path: The Gmail handler permits push bodies up to 1 MiB and reads them fully, so ReadTimeout covers a materially different request shape than the Drive notification listener used as the precedent.
Existing server precedent: Drive changes serve already uses a 10-second ReadTimeout, 30-second idle timeout, and 64 KiB header limit; its notifications do not establish Gmail Pub/Sub body-delivery compatibility.
Findings 1 actionable finding [P1] Prove the Gmail push-body deadline accepts supported deliveries
Security None None.

How this fits together

Gmail watch and OAuth authorization each start a local HTTP listener. Pub/Sub push requests or browser callback requests enter these listeners before Gmail processing or OAuth token exchange continues.

flowchart LR
A[Pub/Sub push request] --> B[Gmail watch listener]
C[Browser OAuth callback] --> D[OAuth callback listener]
B --> E[HTTP read and header limits]
D --> E
E --> F[Request handler]
F --> G[Watch processing or authorization result]
Loading

Before merge

  • Add real behavior proof - Needs real behavior proof before merge: The supplied evidence is passing unit tests that inspect server fields; it does not show an after-fix slow request being terminated or a normal request succeeding through either real listener. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Prove the Gmail push-body deadline accepts supported deliveries (P1) - ReadTimeout covers the whole request, not only headers. Gmail watch reads up to 1 MiB of Pub/Sub JSON, while existing --bind deployments had no body deadline; this fixed 10-second cap can now drop a legitimate slow or proxied delivery. Exercise a real request through the listener—including an allowed supported-size request and a dribbled-body cutoff—and adjust or document the bound before making it the default.
  • Resolve merge risk (P1) - A Gmail watch deployment whose valid push body takes more than 10 seconds to arrive will now lose that delivery attempt, whereas current main accepts it without a complete-read deadline.
  • Complete next step (P2) - Contributor-supplied runtime proof and a compatibility judgment for public Gmail watch deployments are required before merge; this is not a safe autonomous repair.

Findings

  • [P1] Prove the Gmail push-body deadline accepts supported deliveries — internal/cmd/gmail_watch_cmds.go:433
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Code and test delta production +56/-43, tests +62, changelog +4 across 6 files Most of the production churn is extracting the OAuth listener constructor; the remaining changes alter two listener defaults.

Merge-risk options

Maintainer options:

  1. Prove the Gmail delivery boundary (recommended)
    Before merge, demonstrate a supported Gmail push completes through the real listener and a dribbled body is cut off, then revise the 10-second value if the supported path needs more time.
  2. Accept the fixed deadline
    Maintainers may accept 10 seconds as the public-listener delivery contract, with the known risk that unusually slow existing push paths will reconnect or retry.

Technical review

Best possible solution:

Keep bounded listener reads, but establish that the selected Gmail push deadline admits supported deliveries and rejects deliberate slow-body abuse; adjust the default if that evidence does not hold.

Do we have a high-confidence way to reproduce the issue?

Yes: current main sets only a header-read deadline, while the Gmail handler performs a complete body read; a post-header dribble request reaches that unbounded path from source inspection.

Is this the best way to solve the issue?

No: bounding reads is the right direction, but copying the Drive listener’s 10-second value is not yet shown to be safe for Gmail’s up-to-1 MiB push-body path.

Full review comments:

  • [P1] Prove the Gmail push-body deadline accepts supported deliveries — internal/cmd/gmail_watch_cmds.go:433
    ReadTimeout covers the whole request, not only headers. Gmail watch reads up to 1 MiB of Pub/Sub JSON, while existing --bind deployments had no body deadline; this fixed 10-second cap can now drop a legitimate slow or proxied delivery. Exercise a real request through the listener—including an allowed supported-size request and a dribbled-body cutoff—and adjust or document the bound before making it the default.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 45b5d766e137.

Labels

Label changes:

  • add P2: This is a focused local-listener availability hardening change with limited blast radius.
  • add merge-risk: 🚨 availability: The new unconditional full-read deadline can terminate existing Gmail push requests that previously remained connected.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦐 gold shrimp.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The supplied evidence is passing unit tests that inspect server fields; it does not show an after-fix slow request being terminated or a normal request succeeding through either real listener. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Label justifications:

  • P2: This is a focused local-listener availability hardening change with limited blast radius.
  • merge-risk: 🚨 availability: The new unconditional full-read deadline can terminate existing Gmail push requests that previously remained connected.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The supplied evidence is passing unit tests that inspect server fields; it does not show an after-fix slow request being terminated or a normal request succeeding through either real listener. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Evidence

What I checked:

Likely related people:

  • Peter Steinberger: Current code-line blame and file history connect him to Gmail watch transport extraction and terminal OAuth-watch recovery work. (role: feature-history contributor; confidence: medium; commits: 45b5d766e137, 24183272c3f0, fd3d054499f3; files: internal/cmd/gmail_watch_cmds.go, internal/googleauth/oauth_flow.go, internal/gmailwatch/http.go)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Provide a redacted terminal trace of a real slow-body connection being cut off after the configured deadline.
  • Show a supported Gmail-style push request completing through the listener at the selected limit.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@steipete
steipete merged commit 75aec7f into openclaw:main Aug 16, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants