73 lines
3.0 KiB
Go
73 lines
3.0 KiB
Go
package websocket
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// TestCloseCode_Unset returns zero values before any close frame is observed.
|
|
func TestCloseCode_Unset(t *testing.T) {
|
|
c := newTestConn(nil, &bytes.Buffer{}, true)
|
|
if code, incoming := c.CloseCode(); code != 0 || incoming {
|
|
t.Fatalf("CloseCode() = (%d, %v), want (0, false)", code, incoming)
|
|
}
|
|
}
|
|
|
|
// TestCloseCode_Outgoing records a close code we write as outgoing.
|
|
func TestCloseCode_Outgoing(t *testing.T) {
|
|
c := newTestConn(nil, &bytes.Buffer{}, true)
|
|
_ = c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(time.Second))
|
|
if code, incoming := c.CloseCode(); code != CloseMessageTooBig || incoming {
|
|
t.Fatalf("CloseCode() = (%d, %v), want (%d, false)", code, incoming, CloseMessageTooBig)
|
|
}
|
|
}
|
|
|
|
// TestCloseCode_Incoming records a close code received from the peer as incoming
|
|
// (and the subsequent RFC echo must not flip it to outgoing).
|
|
func TestCloseCode_Incoming(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
// Client writes a close frame (masked) into buf.
|
|
wc := newTestConn(nil, &buf, false)
|
|
_ = wc.WriteControl(CloseMessage, FormatCloseMessage(CloseGoingAway, ""), time.Now().Add(time.Second))
|
|
|
|
// Server reads it; advanceFrame records it as incoming and echoes a close.
|
|
rc := newTestConn(&buf, &bytes.Buffer{}, true)
|
|
if _, _, err := rc.NextReader(); !IsCloseError(err, CloseGoingAway) {
|
|
t.Fatalf("NextReader err = %v, want CloseError(%d)", err, CloseGoingAway)
|
|
}
|
|
if code, incoming := rc.CloseCode(); code != CloseGoingAway || !incoming {
|
|
t.Fatalf("CloseCode() = (%d, %v), want (%d, true)", code, incoming, CloseGoingAway)
|
|
}
|
|
}
|
|
|
|
// TestCloseCode_FirstWins keeps the initiating close, ignoring later frames.
|
|
func TestCloseCode_FirstWins(t *testing.T) {
|
|
c := newTestConn(nil, &bytes.Buffer{}, true)
|
|
deadline := time.Now().Add(time.Second)
|
|
_ = c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), deadline)
|
|
_ = c.WriteControl(CloseMessage, FormatCloseMessage(CloseNormalClosure, ""), deadline)
|
|
if code, incoming := c.CloseCode(); code != CloseMessageTooBig || incoming {
|
|
t.Fatalf("CloseCode() = (%d, %v), want (%d, false)", code, incoming, CloseMessageTooBig)
|
|
}
|
|
}
|
|
|
|
// TestCloseCode_IncomingAppRangeStillIncoming proves an attacker-supplied
|
|
// application-range close code (3000-4999) is recorded as incoming, so the
|
|
// Centrifuge layer (which only records !incoming) will not turn it into a label.
|
|
func TestCloseCode_IncomingAppRangeStillIncoming(t *testing.T) {
|
|
const appCode = 4321
|
|
var buf bytes.Buffer
|
|
wc := newTestConn(nil, &buf, false)
|
|
_ = wc.WriteControl(CloseMessage, FormatCloseMessage(appCode, ""), time.Now().Add(time.Second))
|
|
|
|
rc := newTestConn(&buf, &bytes.Buffer{}, true)
|
|
if _, _, err := rc.NextReader(); !IsCloseError(err, appCode) {
|
|
t.Fatalf("NextReader err = %v, want CloseError(%d)", err, appCode)
|
|
}
|
|
code, incoming := rc.CloseCode()
|
|
if code != appCode || !incoming {
|
|
t.Fatalf("CloseCode() = (%d, %v), want (%d, true)", code, incoming, appCode)
|
|
}
|
|
}
|