Skip to content

Make compression reader/writer Close() idempotent#1013

Open
veeceey wants to merge 1 commit intogorilla:mainfrom
veeceey:fix/issue-859-compress-close-duplicate
Open

Make compression reader/writer Close() idempotent#1013
veeceey wants to merge 1 commit intogorilla:mainfrom
veeceey:fix/issue-859-compress-close-duplicate

Conversation

@veeceey
Copy link

@veeceey veeceey commented Feb 17, 2026

Fixes #859

flateReadWrapper.Read() preemptively calls Close() when it encounters EOF to return the flate reader to the pool early. When NextReader() is called next, it calls Close() on the same wrapper again. This second Close() was returning io.ErrClosedPipe, causing spurious errors when compression was enabled.

The fix makes Close() on both flateReadWrapper and flateWriteWrapper idempotent — returning nil on an already-closed wrapper instead of an error. This follows Go conventions where closing an already-closed resource should be a safe no-op, and avoids the error path that was causing the log spam reported in #859.

The Read() and Write() methods still return their respective errors (io.ErrClosedPipe / errWriteClosed) when called on a closed wrapper, since those represent actual misuse.

Per RFC 6455 Section 7.1.1, a close frame should only be sent once. The underlying issue was that the error from the redundant Close() call was being surfaced or logged, making it appear something was wrong when it was actually expected behavior.

Tests added for double-close scenarios on both read and write wrappers.

The flateReadWrapper.Read() preemptively calls Close() when it
encounters EOF, returning the flate reader to the pool early. When
NextReader() is subsequently called, it calls Close() again on the
same wrapper. Previously, this second Close() returned
io.ErrClosedPipe, which caused spurious errors when compression was
enabled (e.g. "discarding reader close error: io: read/write on
closed pipe").

Per RFC 6455 and standard Go conventions, closing an already-closed
resource should be a no-op. This change makes both flateReadWrapper
and flateWriteWrapper Close() methods idempotent by returning nil
instead of an error when the underlying reader/writer is already nil.

Fixes gorilla#859

Signed-off-by: Varun Chawla <varun_6april@hotmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] websocket on compress close duplicate

1 participant