From 1a643e7e51ca50da43a9f18304b7a6a70754c12d Mon Sep 17 00:00:00 2001 From: Rafael da Fonseca Date: Wed, 29 Jan 2025 20:41:41 +0000 Subject: [PATCH 1/2] fix: protocol parsing errors when using ws compression and receiving pong messages --- ws.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ws.go b/ws.go index fbc568845..0cffcca80 100644 --- a/ws.go +++ b/ws.go @@ -316,7 +316,7 @@ func (r *websocketReader) Read(p []byte) (int, error) { // Add to the pending list if dealing with uncompressed frames or // after we have received the full compressed message and decompressed it. if addToPending { - r.pending = append(r.pending, b) + r.pending = append(r.pending, bytes.Clone(b)) } } // In case of compression, there may be nothing to drain From 66d84c6f323669786803c0e9f9397880b542d637 Mon Sep 17 00:00:00 2001 From: Rafael da Fonseca Date: Wed, 29 Jan 2025 21:46:12 +0000 Subject: [PATCH 2/2] Only clone []byte when needed --- ws.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/ws.go b/ws.go index 0cffcca80..46d8300de 100644 --- a/ws.go +++ b/ws.go @@ -76,14 +76,15 @@ var wsGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11") var compressFinalBlock = []byte{0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff} type websocketReader struct { - r io.Reader - pending [][]byte - ib []byte - ff bool - fc bool - nl bool - dc *wsDecompressor - nc *Conn + r io.Reader + pending [][]byte + compress bool + ib []byte + ff bool + fc bool + nl bool + dc *wsDecompressor + nc *Conn } type wsDecompressor struct { @@ -312,11 +313,13 @@ func (r *websocketReader) Read(p []byte) (int, error) { } r.fc = false } + } else if r.compress { + b = bytes.Clone(b) } // Add to the pending list if dealing with uncompressed frames or // after we have received the full compressed message and decompressed it. if addToPending { - r.pending = append(r.pending, bytes.Clone(b)) + r.pending = append(r.pending, b) } } // In case of compression, there may be nothing to drain @@ -647,6 +650,7 @@ func (nc *Conn) wsInitHandshake(u *url.URL) error { wsr := wsNewReader(nc.br.r) wsr.nc = nc + wsr.compress = compress // We have to slurp whatever is in the bufio reader and copy to br.r if n := br.Buffered(); n != 0 { wsr.ib, _ = br.Peek(n)