Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,25 @@ func TestConn(t *testing.T) {
err = c1.Close(websocket.StatusNormalClosure, "")
assert.Success(t, err)
})

t.Run("ReadLimitExceededReturnsErrMessageTooBig", func(t *testing.T) {
tt, c1, c2 := newConnTest(t, nil, nil)

c1.SetReadLimit(1024)
_ = c2.CloseRead(tt.ctx)

writeDone := xsync.Go(func() error {
payload := strings.Repeat("x", 4096)
return c2.Write(tt.ctx, websocket.MessageText, []byte(payload))
})

_, _, err := c1.Read(tt.ctx)
assert.ErrorIs(t, websocket.ErrMessageTooBig, err)
assert.Contains(t, err, "read limited at 1025 bytes")

_ = c2.CloseNow()
<-writeDone
})
}

func TestWasm(t *testing.T) {
Expand Down
8 changes: 8 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package websocket

import (
"errors"
)

// ErrMessageTooBig is returned when a message exceeds the read limit.
var ErrMessageTooBig = errors.New("websocket: message too big")
9 changes: 5 additions & 4 deletions read.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ func (c *Conn) CloseRead(ctx context.Context) context.Context {
//
// By default, the connection has a message read limit of 32768 bytes.
//
// When the limit is hit, the connection will be closed with StatusMessageTooBig.
// When the limit is hit, reads return an error wrapping ErrMessageTooBig and
// the connection is closed with StatusMessageTooBig.
//
// Set to -1 to disable.
func (c *Conn) SetReadLimit(n int64) {
Expand Down Expand Up @@ -520,9 +521,9 @@ func (lr *limitReader) Read(p []byte) (int, error) {
}

if lr.n == 0 {
err := fmt.Errorf("read limited at %v bytes", lr.limit.Load())
lr.c.writeError(StatusMessageTooBig, err)
return 0, err
reason := fmt.Errorf("read limited at %d bytes", lr.limit.Load())
lr.c.writeError(StatusMessageTooBig, reason)
return 0, fmt.Errorf("%w: %v", ErrMessageTooBig, reason)
}

if int64(len(p)) > lr.n {
Expand Down
6 changes: 3 additions & 3 deletions ws_js.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ func (c *Conn) Read(ctx context.Context) (MessageType, []byte, error) {
}
readLimit := c.msgReadLimit.Load()
if readLimit >= 0 && int64(len(p)) > readLimit {
err := fmt.Errorf("read limited at %v bytes", c.msgReadLimit.Load())
c.Close(StatusMessageTooBig, err.Error())
return 0, nil, err
reason := fmt.Errorf("read limited at %d bytes", c.msgReadLimit.Load())
c.Close(StatusMessageTooBig, reason.Error())
return 0, nil, fmt.Errorf("%w: %v", ErrMessageTooBig, reason)
}
return typ, p, nil
}
Expand Down