Skip to content

fix: keep a read limit set before NetConn - #586

Draft
mafredri wants to merge 3 commits into
masterfrom
mafredri/netconn-keep-read-limit
Draft

mafredri wants to merge 3 commits into
masterfrom
mafredri/netconn-keep-read-limit

Conversation

@mafredri

Copy link
Copy Markdown
Member

NetConn called SetReadLimit(-1) every time, so the outcome depended on call order: a limit set after NetConn applied, and a limit set before it was dropped without an error. Code that set a limit and then called NetConn had no limit at all.

NetConn now disables the limit only if SetReadLimit was never called on the Conn. A limit set before or after NetConn is kept, and so is an explicit SetReadLimit(-1). Callers that never call SetReadLimit see no change: NetConn still disables the 32768 byte default.

Behavior change: if you call SetReadLimit(n) before NetConn, that limit is now enforced. Reading a message larger than n bytes fails with ErrMessageTooBig, as SetReadLimit documents; before this change the message was read in full. To keep the old behavior, remove the SetReadLimit call or pass -1.

New tests cover a limit set before NetConn, set after it, never set, and set to -1 before it, on native and on Wasm in the browser. The before-NetConn test fails on master on both platforms. ./ci/lint.sh, go test -race ./... and the Wasm browser test pass.

Refs #244 (this PR does not add the ReadLimit option field).

Decision log
  • Keep a caller's limit instead of only documenting that SetReadLimit must follow NetConn: documentation alone leaves the call-order problem for every caller.
  • No ReadLimit field in AcceptOptions/DialOptions here: that is a separate API decision on Add ReadLimit to Option structs #244, and the field would need this rule anyway, because NetConn would otherwise discard it.
  • An atomic.Bool on both Conn types records that SetReadLimit was called: SetReadLimit takes no lock, Conn methods may run concurrently, and the limit itself is already atomic.
  • Not handled: SetReadLimit and NetConn called at the same time with no ordering can still end with the limit disabled. Closing that would need a lock or a sentinel limit value, which this PR does not add.

🤖 This PR was created with the help of Coder Agents.

NetConn always called SetReadLimit(-1), so a limit set before NetConn
was silently dropped while one set after it applied. NetConn now
disables the limit only if SetReadLimit was never called on the Conn.
The Wasm Conn tracks SetReadLimit calls separately from the native Conn,
so the same four cases run in the browser against the echo server.
The fix-close-race-net-errclosed branch adds a test at the same place in
ws_js_test.go, and the two insertions conflict on merge.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant