Repository navigation
socket: add timeout to websocket dial - #3
Open
ADAMAYAMEOGO wants to merge 1 commit into
Open
ADAMAYAMEOGO wants to merge 1 commit into
ADAMAYAMEOGO wants to merge 1 commit into
Conversation
The dial used the context passed to Connect, which normally has no deadline, and neither net/http nor coder/websocket limit how long to wait for the upgrade response. A proxy or middlebox that accepts the connection but never answers the upgrade request made Connect block forever while holding the socket lock, so Disconnect blocked too and the client could only be recovered by restarting the process. Limit the dial to DialTimeout (20 seconds by default, zero disables it). The timeout only covers the dial, the established connection still uses the parent context. A timed out dial returns ErrDialFailed, so it is retried like any other connection failure.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs devlikeapro/waha#1043.
FrameSocket.Connectdials with the context passed toConnect(BackgroundEventCtx, no deadline), and neithernet/httpnorcoder/websocketlimit the wait for the upgrade response. A proxy or middlebox that accepts the connection but never answers the upgrade request blocksConnectforever while it holdssocketLock: the reconnect loop never tries again andDisconnect()blocks too. In WAHA this is a GOWS session stuck inSTARTINGwhoserestart/stopend inMaximum execution time is exceededuntil the container is restarted.This adds
socket.DialTimeout(20 s by default, likeNoiseHandshakeResponseTimeout, 0 disables it). Only the dial gets the timeout; the established connection keeps the parent context, ascoder/websocketalready does forHTTPClient.Timeout. A timed out dial returnsErrDialFailed, so it is retried like any other network failure.Tests: a server that never answers the upgrade (fails without the timeout), and a websocket that only sends after 3× the timeout (the connection must survive).
gofmt,go vetandgo test -race -count=10 ./socket/pass onfork-main-2026-10-13. (The repository-widestaticcheckhook currently reportsgetButtonTypeFromMessageandgetButtonAttributesas unused insend.go, on the base branch as well.)We reproduced the hang with a
CONNECTproxy that stalls after TLS: before,POST /restartreturned 500 after 30 s and the session never retried; with this change, 201 after 23.5 s, a retry every 20 s, andWORKINGagain 28 s after the proxy recovered. We have run GOWS with it in production since 1 October.Based on
fork-main-2026-10-13. The same commit applies to tulir/whatsmeowmain.