Skip to content

Commit df60edf

Browse files
committed
Reuse header and control payload buffers
1 parent 5404d35 commit df60edf

File tree

3 files changed

+20
-8
lines changed

3 files changed

+20
-8
lines changed

header.go

+10-3
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,19 @@ func marshalHeader(h header) []byte {
7575
return b
7676
}
7777

78+
func makeHeaderBuf() []byte {
79+
return make([]byte, maxHeaderSize-2)
80+
}
81+
7882
// readHeader reads a header from the reader.
7983
// See https://tools.ietf.org/html/rfc6455#section-5.2
80-
func readHeader(r io.Reader) (header, error) {
81-
// We read the first two bytes directly so that we know
84+
func readHeader(b []byte, r io.Reader) (header, error) {
85+
if b == nil {
86+
b = makeHeaderBuf()
87+
}
88+
// We read the first two bytes first so that we know
8289
// exactly how long the header is.
83-
b := make([]byte, 2, maxHeaderSize-2)
90+
b = b[:2]
8491
_, err := io.ReadFull(r, b)
8592
if err != nil {
8693
return header{}, err

header_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func TestHeader(t *testing.T) {
3232
b[2] |= 1 << 7
3333

3434
r := bytes.NewReader(b)
35-
_, err := readHeader(r)
35+
_, err := readHeader(nil, r)
3636
if err == nil {
3737
t.Fatalf("unexpected error value: %+v", err)
3838
}
@@ -92,7 +92,7 @@ func TestHeader(t *testing.T) {
9292
func testHeader(t *testing.T, h header) {
9393
b := marshalHeader(h)
9494
r := bytes.NewReader(b)
95-
h2, err := readHeader(r)
95+
h2, err := readHeader(nil, r)
9696
if err != nil {
9797
t.Logf("header: %#v", h)
9898
t.Logf("bytes: %b", b)

websocket.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ type Conn struct {
5757

5858
activePingsMu sync.Mutex
5959
activePings map[string]chan<- struct{}
60+
61+
headerBuf []byte
62+
controlPayloadBuf []byte
6063
}
6164

6265
func (c *Conn) init() {
@@ -74,6 +77,9 @@ func (c *Conn) init() {
7477

7578
c.activePings = make(map[string]chan<- struct{})
7679

80+
c.headerBuf = makeHeaderBuf()
81+
c.controlPayloadBuf = make([]byte, maxControlFramePayload)
82+
7783
runtime.SetFinalizer(c, func(c *Conn) {
7884
c.close(xerrors.New("connection garbage collected"))
7985
})
@@ -209,7 +215,7 @@ func (c *Conn) readFrameHeader(ctx context.Context) (header, error) {
209215
case c.setReadTimeout <- ctx:
210216
}
211217

212-
h, err := readHeader(c.br)
218+
h, err := readHeader(c.headerBuf, c.br)
213219
if err != nil {
214220
select {
215221
case <-c.closed:
@@ -249,8 +255,7 @@ func (c *Conn) handleControl(ctx context.Context, h header) error {
249255
ctx, cancel := context.WithTimeout(ctx, time.Second*5)
250256
defer cancel()
251257

252-
b := make([]byte, h.payloadLength)
253-
258+
b := c.controlPayloadBuf[:h.payloadLength]
254259
_, err := c.readFramePayload(ctx, b)
255260
if err != nil {
256261
return err

0 commit comments

Comments
 (0)