@@ -13,7 +13,7 @@ import (
13
13
"golang.org/x/xerrors"
14
14
)
15
15
16
- type control struct {
16
+ type frame struct {
17
17
opcode opcode
18
18
payload []byte
19
19
}
@@ -42,7 +42,8 @@ type Conn struct {
42
42
// ping on writeDone.
43
43
// writeDone will be closed if the data message write errors.
44
44
write chan MessageType
45
- control chan control
45
+ control chan frame
46
+ fastWrite chan frame
46
47
writeBytes chan []byte
47
48
writeDone chan struct {}
48
49
writeFlush chan struct {}
@@ -86,7 +87,8 @@ func (c *Conn) init() {
86
87
c .closed = make (chan struct {})
87
88
88
89
c .write = make (chan MessageType )
89
- c .control = make (chan control )
90
+ c .control = make (chan frame )
91
+ c .fastWrite = make (chan frame )
90
92
c .writeBytes = make (chan []byte )
91
93
c .writeDone = make (chan struct {})
92
94
c .writeFlush = make (chan struct {})
@@ -103,6 +105,8 @@ func (c *Conn) init() {
103
105
go c .readLoop ()
104
106
}
105
107
108
+ // We never mask inside here because our mask key is always 0,0,0,0.
109
+ // See comment on secWebSocketKey.
106
110
func (c * Conn ) writeFrame (h header , p []byte ) {
107
111
b2 := marshalHeader (h )
108
112
_ , err := c .bw .Write (b2 )
@@ -126,14 +130,14 @@ func (c *Conn) writeFrame(h header, p []byte) {
126
130
}
127
131
}
128
132
129
- func (c * Conn ) writeLoopControl ( control control ) {
133
+ func (c * Conn ) writeLoopFastWrite ( frame frame ) {
130
134
h := header {
131
135
fin : true ,
132
- opcode : control .opcode ,
133
- payloadLength : int64 (len (control .payload )),
136
+ opcode : frame .opcode ,
137
+ payloadLength : int64 (len (frame .payload )),
134
138
masked : c .client ,
135
139
}
136
- c .writeFrame (h , control .payload )
140
+ c .writeFrame (h , frame .payload )
137
141
select {
138
142
case <- c .closed :
139
143
case c .writeDone <- struct {}{}:
@@ -150,7 +154,11 @@ messageLoop:
150
154
case <- c .closed :
151
155
return
152
156
case control := <- c .control :
153
- c .writeLoopControl (control )
157
+ c .writeLoopFastWrite (control )
158
+ continue
159
+ case frame := <- c .fastWrite :
160
+ c .writeLoopFastWrite (frame )
161
+ continue
154
162
case dataType = <- c .write :
155
163
}
156
164
@@ -160,7 +168,7 @@ messageLoop:
160
168
case <- c .closed :
161
169
return
162
170
case control := <- c .control :
163
- c .writeLoopControl (control )
171
+ c .writeLoopFastWrite (control )
164
172
case b := <- c .writeBytes :
165
173
h := header {
166
174
fin : false ,
@@ -220,7 +228,7 @@ func (c *Conn) handleControl(h header) {
220
228
}
221
229
222
230
if h .masked {
223
- xor (h .maskKey , 0 , b )
231
+ fastXOR (h .maskKey , 0 , b )
224
232
}
225
233
226
234
switch h .opcode {
@@ -314,7 +322,7 @@ func (c *Conn) dataReadLoop(h header) (err error) {
314
322
left -= int64 (len (b ))
315
323
316
324
if h .masked {
317
- maskPos = xor (h .maskKey , maskPos , b )
325
+ maskPos = fastXOR (h .maskKey , maskPos , b )
318
326
}
319
327
320
328
// Must set this before we signal the read is done.
@@ -341,7 +349,7 @@ func (c *Conn) writePong(p []byte) error {
341
349
ctx , cancel := context .WithTimeout (context .Background (), time .Second * 5 )
342
350
defer cancel ()
343
351
344
- err := c .writeControl (ctx , opPong , p )
352
+ err := c .writeSingleFrame (ctx , opPong , p )
345
353
return err
346
354
}
347
355
@@ -384,7 +392,7 @@ func (c *Conn) writeClose(p []byte, cerr CloseError) error {
384
392
ctx , cancel := context .WithTimeout (context .Background (), time .Second * 5 )
385
393
defer cancel ()
386
394
387
- err := c .writeControl (ctx , opClose , p )
395
+ err := c .writeSingleFrame (ctx , opClose , p )
388
396
389
397
c .close (cerr )
390
398
@@ -399,11 +407,15 @@ func (c *Conn) writeClose(p []byte, cerr CloseError) error {
399
407
return nil
400
408
}
401
409
402
- func (c * Conn ) writeControl (ctx context.Context , opcode opcode , p []byte ) error {
410
+ func (c * Conn ) writeSingleFrame (ctx context.Context , opcode opcode , p []byte ) error {
411
+ ch := c .fastWrite
412
+ if opcode .controlOp () {
413
+ ch = c .control
414
+ }
403
415
select {
404
416
case <- c .closed :
405
417
return c .closeErr
406
- case c . control <- control {
418
+ case ch <- frame {
407
419
opcode : opcode ,
408
420
payload : p ,
409
421
}:
0 commit comments