//go:build dev package bundler import ( "bufio" "bytes" "testing" ) // The canonical handshake vector from RFC 6455 §1.3. func TestComputeAccept(t *testing.T) { got := computeAccept("dGhlIHNhbXBsZSBub25jZQ==") const want = "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=" if got != want { t.Fatalf("computeAccept = %q, want %q", got, want) } } // A masked client frame round-trips through readFrame (payload unmasked, opcode // preserved) — the path exercised when the browser sends a ping or close. func TestReadFrameMaskedText(t *testing.T) { payload := []byte("hello hmr") mask := [4]byte{0x12, 0x34, 0x56, 0x78} var buf bytes.Buffer buf.WriteByte(0x80 | opText) // FIN + text buf.WriteByte(0x80 | byte(len(payload))) // MASK + len buf.Write(mask[:]) for i, b := range payload { buf.WriteByte(b ^ mask[i%4]) } op, got, err := readFrame(bufio.NewReader(&buf)) if err != nil { t.Fatalf("readFrame: %v", err) } if op != opText { t.Errorf("opcode = %#x, want %#x", op, opText) } if !bytes.Equal(got, payload) { t.Errorf("payload = %q, want %q", got, payload) } } // A server frame is written unmasked and parses back to the same payload. func TestWriteFrameRoundTrip(t *testing.T) { payload := bytes.Repeat([]byte("x"), 300) // exercises the 16-bit length path var raw bytes.Buffer c := &wsClient{brw: bufio.NewReadWriter(bufio.NewReader(nil), bufio.NewWriter(&raw))} if err := c.writeText(payload); err != nil { t.Fatalf("writeText: %v", err) } if raw.Bytes()[0] != (0x80 | opText) { t.Fatalf("first byte = %#x, want %#x", raw.Bytes()[0], 0x80|opText) } if raw.Bytes()[1]&0x80 != 0 { t.Fatalf("server frame must not set the mask bit") } op, got, err := readFrame(bufio.NewReader(&raw)) if err != nil { t.Fatalf("readFrame: %v", err) } if op != opText || !bytes.Equal(got, payload) { t.Errorf("round-trip mismatch: op=%#x len=%d", op, len(got)) } }