OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / gorilla / websocket / conn.go
1 // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package websocket
6
7 import (
8         "bufio"
9         "encoding/binary"
10         "errors"
11         "io"
12         "io/ioutil"
13         "math/rand"
14         "net"
15         "strconv"
16         "sync"
17         "time"
18         "unicode/utf8"
19 )
20
21 const (
22         // Frame header byte 0 bits from Section 5.2 of RFC 6455
23         finalBit = 1 << 7
24         rsv1Bit  = 1 << 6
25         rsv2Bit  = 1 << 5
26         rsv3Bit  = 1 << 4
27
28         // Frame header byte 1 bits from Section 5.2 of RFC 6455
29         maskBit = 1 << 7
30
31         maxFrameHeaderSize         = 2 + 8 + 4 // Fixed header + length + mask
32         maxControlFramePayloadSize = 125
33
34         writeWait = time.Second
35
36         defaultReadBufferSize  = 4096
37         defaultWriteBufferSize = 4096
38
39         continuationFrame = 0
40         noFrame           = -1
41 )
42
43 // Close codes defined in RFC 6455, section 11.7.
44 const (
45         CloseNormalClosure           = 1000
46         CloseGoingAway               = 1001
47         CloseProtocolError           = 1002
48         CloseUnsupportedData         = 1003
49         CloseNoStatusReceived        = 1005
50         CloseAbnormalClosure         = 1006
51         CloseInvalidFramePayloadData = 1007
52         ClosePolicyViolation         = 1008
53         CloseMessageTooBig           = 1009
54         CloseMandatoryExtension      = 1010
55         CloseInternalServerErr       = 1011
56         CloseServiceRestart          = 1012
57         CloseTryAgainLater           = 1013
58         CloseTLSHandshake            = 1015
59 )
60
61 // The message types are defined in RFC 6455, section 11.8.
62 const (
63         // TextMessage denotes a text data message. The text message payload is
64         // interpreted as UTF-8 encoded text data.
65         TextMessage = 1
66
67         // BinaryMessage denotes a binary data message.
68         BinaryMessage = 2
69
70         // CloseMessage denotes a close control message. The optional message
71         // payload contains a numeric code and text. Use the FormatCloseMessage
72         // function to format a close message payload.
73         CloseMessage = 8
74
75         // PingMessage denotes a ping control message. The optional message payload
76         // is UTF-8 encoded text.
77         PingMessage = 9
78
79         // PongMessage denotes a pong control message. The optional message payload
80         // is UTF-8 encoded text.
81         PongMessage = 10
82 )
83
84 // ErrCloseSent is returned when the application writes a message to the
85 // connection after sending a close message.
86 var ErrCloseSent = errors.New("websocket: close sent")
87
88 // ErrReadLimit is returned when reading a message that is larger than the
89 // read limit set for the connection.
90 var ErrReadLimit = errors.New("websocket: read limit exceeded")
91
92 // netError satisfies the net Error interface.
93 type netError struct {
94         msg       string
95         temporary bool
96         timeout   bool
97 }
98
99 func (e *netError) Error() string   { return e.msg }
100 func (e *netError) Temporary() bool { return e.temporary }
101 func (e *netError) Timeout() bool   { return e.timeout }
102
103 // CloseError represents a close message.
104 type CloseError struct {
105         // Code is defined in RFC 6455, section 11.7.
106         Code int
107
108         // Text is the optional text payload.
109         Text string
110 }
111
112 func (e *CloseError) Error() string {
113         s := []byte("websocket: close ")
114         s = strconv.AppendInt(s, int64(e.Code), 10)
115         switch e.Code {
116         case CloseNormalClosure:
117                 s = append(s, " (normal)"...)
118         case CloseGoingAway:
119                 s = append(s, " (going away)"...)
120         case CloseProtocolError:
121                 s = append(s, " (protocol error)"...)
122         case CloseUnsupportedData:
123                 s = append(s, " (unsupported data)"...)
124         case CloseNoStatusReceived:
125                 s = append(s, " (no status)"...)
126         case CloseAbnormalClosure:
127                 s = append(s, " (abnormal closure)"...)
128         case CloseInvalidFramePayloadData:
129                 s = append(s, " (invalid payload data)"...)
130         case ClosePolicyViolation:
131                 s = append(s, " (policy violation)"...)
132         case CloseMessageTooBig:
133                 s = append(s, " (message too big)"...)
134         case CloseMandatoryExtension:
135                 s = append(s, " (mandatory extension missing)"...)
136         case CloseInternalServerErr:
137                 s = append(s, " (internal server error)"...)
138         case CloseTLSHandshake:
139                 s = append(s, " (TLS handshake error)"...)
140         }
141         if e.Text != "" {
142                 s = append(s, ": "...)
143                 s = append(s, e.Text...)
144         }
145         return string(s)
146 }
147
148 // IsCloseError returns boolean indicating whether the error is a *CloseError
149 // with one of the specified codes.
150 func IsCloseError(err error, codes ...int) bool {
151         if e, ok := err.(*CloseError); ok {
152                 for _, code := range codes {
153                         if e.Code == code {
154                                 return true
155                         }
156                 }
157         }
158         return false
159 }
160
161 // IsUnexpectedCloseError returns boolean indicating whether the error is a
162 // *CloseError with a code not in the list of expected codes.
163 func IsUnexpectedCloseError(err error, expectedCodes ...int) bool {
164         if e, ok := err.(*CloseError); ok {
165                 for _, code := range expectedCodes {
166                         if e.Code == code {
167                                 return false
168                         }
169                 }
170                 return true
171         }
172         return false
173 }
174
175 var (
176         errWriteTimeout        = &netError{msg: "websocket: write timeout", timeout: true, temporary: true}
177         errUnexpectedEOF       = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()}
178         errBadWriteOpCode      = errors.New("websocket: bad write message type")
179         errWriteClosed         = errors.New("websocket: write closed")
180         errInvalidControlFrame = errors.New("websocket: invalid control frame")
181 )
182
183 func newMaskKey() [4]byte {
184         n := rand.Uint32()
185         return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}
186 }
187
188 func hideTempErr(err error) error {
189         if e, ok := err.(net.Error); ok && e.Temporary() {
190                 err = &netError{msg: e.Error(), timeout: e.Timeout()}
191         }
192         return err
193 }
194
195 func isControl(frameType int) bool {
196         return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage
197 }
198
199 func isData(frameType int) bool {
200         return frameType == TextMessage || frameType == BinaryMessage
201 }
202
203 var validReceivedCloseCodes = map[int]bool{
204         // see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number
205
206         CloseNormalClosure:           true,
207         CloseGoingAway:               true,
208         CloseProtocolError:           true,
209         CloseUnsupportedData:         true,
210         CloseNoStatusReceived:        false,
211         CloseAbnormalClosure:         false,
212         CloseInvalidFramePayloadData: true,
213         ClosePolicyViolation:         true,
214         CloseMessageTooBig:           true,
215         CloseMandatoryExtension:      true,
216         CloseInternalServerErr:       true,
217         CloseServiceRestart:          true,
218         CloseTryAgainLater:           true,
219         CloseTLSHandshake:            false,
220 }
221
222 func isValidReceivedCloseCode(code int) bool {
223         return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999)
224 }
225
226 // BufferPool represents a pool of buffers. The *sync.Pool type satisfies this
227 // interface.  The type of the value stored in a pool is not specified.
228 type BufferPool interface {
229         // Get gets a value from the pool or returns nil if the pool is empty.
230         Get() interface{}
231         // Put adds a value to the pool.
232         Put(interface{})
233 }
234
235 // writePoolData is the type added to the write buffer pool. This wrapper is
236 // used to prevent applications from peeking at and depending on the values
237 // added to the pool.
238 type writePoolData struct{ buf []byte }
239
240 // The Conn type represents a WebSocket connection.
241 type Conn struct {
242         conn        net.Conn
243         isServer    bool
244         subprotocol string
245
246         // Write fields
247         mu            chan bool // used as mutex to protect write to conn
248         writeBuf      []byte    // frame is constructed in this buffer.
249         writePool     BufferPool
250         writeBufSize  int
251         writeDeadline time.Time
252         writer        io.WriteCloser // the current writer returned to the application
253         isWriting     bool           // for best-effort concurrent write detection
254
255         writeErrMu sync.Mutex
256         writeErr   error
257
258         enableWriteCompression bool
259         compressionLevel       int
260         newCompressionWriter   func(io.WriteCloser, int) io.WriteCloser
261
262         // Read fields
263         reader        io.ReadCloser // the current reader returned to the application
264         readErr       error
265         br            *bufio.Reader
266         readRemaining int64 // bytes remaining in current frame.
267         readFinal     bool  // true the current message has more frames.
268         readLength    int64 // Message size.
269         readLimit     int64 // Maximum message size.
270         readMaskPos   int
271         readMaskKey   [4]byte
272         handlePong    func(string) error
273         handlePing    func(string) error
274         handleClose   func(int, string) error
275         readErrCount  int
276         messageReader *messageReader // the current low-level reader
277
278         readDecompress         bool // whether last read frame had RSV1 set
279         newDecompressionReader func(io.Reader) io.ReadCloser
280 }
281
282 func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, writeBufferPool BufferPool, br *bufio.Reader, writeBuf []byte) *Conn {
283
284         if br == nil {
285                 if readBufferSize == 0 {
286                         readBufferSize = defaultReadBufferSize
287                 } else if readBufferSize < maxControlFramePayloadSize {
288                         // must be large enough for control frame
289                         readBufferSize = maxControlFramePayloadSize
290                 }
291                 br = bufio.NewReaderSize(conn, readBufferSize)
292         }
293
294         if writeBufferSize <= 0 {
295                 writeBufferSize = defaultWriteBufferSize
296         }
297         writeBufferSize += maxFrameHeaderSize
298
299         if writeBuf == nil && writeBufferPool == nil {
300                 writeBuf = make([]byte, writeBufferSize)
301         }
302
303         mu := make(chan bool, 1)
304         mu <- true
305         c := &Conn{
306                 isServer:               isServer,
307                 br:                     br,
308                 conn:                   conn,
309                 mu:                     mu,
310                 readFinal:              true,
311                 writeBuf:               writeBuf,
312                 writePool:              writeBufferPool,
313                 writeBufSize:           writeBufferSize,
314                 enableWriteCompression: true,
315                 compressionLevel:       defaultCompressionLevel,
316         }
317         c.SetCloseHandler(nil)
318         c.SetPingHandler(nil)
319         c.SetPongHandler(nil)
320         return c
321 }
322
323 // Subprotocol returns the negotiated protocol for the connection.
324 func (c *Conn) Subprotocol() string {
325         return c.subprotocol
326 }
327
328 // Close closes the underlying network connection without sending or waiting
329 // for a close message.
330 func (c *Conn) Close() error {
331         return c.conn.Close()
332 }
333
334 // LocalAddr returns the local network address.
335 func (c *Conn) LocalAddr() net.Addr {
336         return c.conn.LocalAddr()
337 }
338
339 // RemoteAddr returns the remote network address.
340 func (c *Conn) RemoteAddr() net.Addr {
341         return c.conn.RemoteAddr()
342 }
343
344 // Write methods
345
346 func (c *Conn) writeFatal(err error) error {
347         err = hideTempErr(err)
348         c.writeErrMu.Lock()
349         if c.writeErr == nil {
350                 c.writeErr = err
351         }
352         c.writeErrMu.Unlock()
353         return err
354 }
355
356 func (c *Conn) read(n int) ([]byte, error) {
357         p, err := c.br.Peek(n)
358         if err == io.EOF {
359                 err = errUnexpectedEOF
360         }
361         c.br.Discard(len(p))
362         return p, err
363 }
364
365 func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error {
366         <-c.mu
367         defer func() { c.mu <- true }()
368
369         c.writeErrMu.Lock()
370         err := c.writeErr
371         c.writeErrMu.Unlock()
372         if err != nil {
373                 return err
374         }
375
376         c.conn.SetWriteDeadline(deadline)
377         if len(buf1) == 0 {
378                 _, err = c.conn.Write(buf0)
379         } else {
380                 err = c.writeBufs(buf0, buf1)
381         }
382         if err != nil {
383                 return c.writeFatal(err)
384         }
385         if frameType == CloseMessage {
386                 c.writeFatal(ErrCloseSent)
387         }
388         return nil
389 }
390
391 // WriteControl writes a control message with the given deadline. The allowed
392 // message types are CloseMessage, PingMessage and PongMessage.
393 func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error {
394         if !isControl(messageType) {
395                 return errBadWriteOpCode
396         }
397         if len(data) > maxControlFramePayloadSize {
398                 return errInvalidControlFrame
399         }
400
401         b0 := byte(messageType) | finalBit
402         b1 := byte(len(data))
403         if !c.isServer {
404                 b1 |= maskBit
405         }
406
407         buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize)
408         buf = append(buf, b0, b1)
409
410         if c.isServer {
411                 buf = append(buf, data...)
412         } else {
413                 key := newMaskKey()
414                 buf = append(buf, key[:]...)
415                 buf = append(buf, data...)
416                 maskBytes(key, 0, buf[6:])
417         }
418
419         d := time.Hour * 1000
420         if !deadline.IsZero() {
421                 d = deadline.Sub(time.Now())
422                 if d < 0 {
423                         return errWriteTimeout
424                 }
425         }
426
427         timer := time.NewTimer(d)
428         select {
429         case <-c.mu:
430                 timer.Stop()
431         case <-timer.C:
432                 return errWriteTimeout
433         }
434         defer func() { c.mu <- true }()
435
436         c.writeErrMu.Lock()
437         err := c.writeErr
438         c.writeErrMu.Unlock()
439         if err != nil {
440                 return err
441         }
442
443         c.conn.SetWriteDeadline(deadline)
444         _, err = c.conn.Write(buf)
445         if err != nil {
446                 return c.writeFatal(err)
447         }
448         if messageType == CloseMessage {
449                 c.writeFatal(ErrCloseSent)
450         }
451         return err
452 }
453
454 // beginMessage prepares a connection and message writer for a new message.
455 func (c *Conn) beginMessage(mw *messageWriter, messageType int) error {
456         // Close previous writer if not already closed by the application. It's
457         // probably better to return an error in this situation, but we cannot
458         // change this without breaking existing applications.
459         if c.writer != nil {
460                 c.writer.Close()
461                 c.writer = nil
462         }
463
464         if !isControl(messageType) && !isData(messageType) {
465                 return errBadWriteOpCode
466         }
467
468         c.writeErrMu.Lock()
469         err := c.writeErr
470         c.writeErrMu.Unlock()
471         if err != nil {
472                 return err
473         }
474
475         mw.c = c
476         mw.frameType = messageType
477         mw.pos = maxFrameHeaderSize
478
479         if c.writeBuf == nil {
480                 wpd, ok := c.writePool.Get().(writePoolData)
481                 if ok {
482                         c.writeBuf = wpd.buf
483                 } else {
484                         c.writeBuf = make([]byte, c.writeBufSize)
485                 }
486         }
487         return nil
488 }
489
490 // NextWriter returns a writer for the next message to send. The writer's Close
491 // method flushes the complete message to the network.
492 //
493 // There can be at most one open writer on a connection. NextWriter closes the
494 // previous writer if the application has not already done so.
495 //
496 // All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and
497 // PongMessage) are supported.
498 func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
499         var mw messageWriter
500         if err := c.beginMessage(&mw, messageType); err != nil {
501                 return nil, err
502         }
503         c.writer = &mw
504         if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) {
505                 w := c.newCompressionWriter(c.writer, c.compressionLevel)
506                 mw.compress = true
507                 c.writer = w
508         }
509         return c.writer, nil
510 }
511
512 type messageWriter struct {
513         c         *Conn
514         compress  bool // whether next call to flushFrame should set RSV1
515         pos       int  // end of data in writeBuf.
516         frameType int  // type of the current frame.
517         err       error
518 }
519
520 func (w *messageWriter) endMessage(err error) error {
521         if w.err != nil {
522                 return err
523         }
524         c := w.c
525         w.err = err
526         c.writer = nil
527         if c.writePool != nil {
528                 c.writePool.Put(writePoolData{buf: c.writeBuf})
529                 c.writeBuf = nil
530         }
531         return err
532 }
533
534 // flushFrame writes buffered data and extra as a frame to the network. The
535 // final argument indicates that this is the last frame in the message.
536 func (w *messageWriter) flushFrame(final bool, extra []byte) error {
537         c := w.c
538         length := w.pos - maxFrameHeaderSize + len(extra)
539
540         // Check for invalid control frames.
541         if isControl(w.frameType) &&
542                 (!final || length > maxControlFramePayloadSize) {
543                 return w.endMessage(errInvalidControlFrame)
544         }
545
546         b0 := byte(w.frameType)
547         if final {
548                 b0 |= finalBit
549         }
550         if w.compress {
551                 b0 |= rsv1Bit
552         }
553         w.compress = false
554
555         b1 := byte(0)
556         if !c.isServer {
557                 b1 |= maskBit
558         }
559
560         // Assume that the frame starts at beginning of c.writeBuf.
561         framePos := 0
562         if c.isServer {
563                 // Adjust up if mask not included in the header.
564                 framePos = 4
565         }
566
567         switch {
568         case length >= 65536:
569                 c.writeBuf[framePos] = b0
570                 c.writeBuf[framePos+1] = b1 | 127
571                 binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length))
572         case length > 125:
573                 framePos += 6
574                 c.writeBuf[framePos] = b0
575                 c.writeBuf[framePos+1] = b1 | 126
576                 binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length))
577         default:
578                 framePos += 8
579                 c.writeBuf[framePos] = b0
580                 c.writeBuf[framePos+1] = b1 | byte(length)
581         }
582
583         if !c.isServer {
584                 key := newMaskKey()
585                 copy(c.writeBuf[maxFrameHeaderSize-4:], key[:])
586                 maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos])
587                 if len(extra) > 0 {
588                         return w.endMessage(c.writeFatal(errors.New("websocket: internal error, extra used in client mode")))
589                 }
590         }
591
592         // Write the buffers to the connection with best-effort detection of
593         // concurrent writes. See the concurrency section in the package
594         // documentation for more info.
595
596         if c.isWriting {
597                 panic("concurrent write to websocket connection")
598         }
599         c.isWriting = true
600
601         err := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra)
602
603         if !c.isWriting {
604                 panic("concurrent write to websocket connection")
605         }
606         c.isWriting = false
607
608         if err != nil {
609                 return w.endMessage(err)
610         }
611
612         if final {
613                 w.endMessage(errWriteClosed)
614                 return nil
615         }
616
617         // Setup for next frame.
618         w.pos = maxFrameHeaderSize
619         w.frameType = continuationFrame
620         return nil
621 }
622
623 func (w *messageWriter) ncopy(max int) (int, error) {
624         n := len(w.c.writeBuf) - w.pos
625         if n <= 0 {
626                 if err := w.flushFrame(false, nil); err != nil {
627                         return 0, err
628                 }
629                 n = len(w.c.writeBuf) - w.pos
630         }
631         if n > max {
632                 n = max
633         }
634         return n, nil
635 }
636
637 func (w *messageWriter) Write(p []byte) (int, error) {
638         if w.err != nil {
639                 return 0, w.err
640         }
641
642         if len(p) > 2*len(w.c.writeBuf) && w.c.isServer {
643                 // Don't buffer large messages.
644                 err := w.flushFrame(false, p)
645                 if err != nil {
646                         return 0, err
647                 }
648                 return len(p), nil
649         }
650
651         nn := len(p)
652         for len(p) > 0 {
653                 n, err := w.ncopy(len(p))
654                 if err != nil {
655                         return 0, err
656                 }
657                 copy(w.c.writeBuf[w.pos:], p[:n])
658                 w.pos += n
659                 p = p[n:]
660         }
661         return nn, nil
662 }
663
664 func (w *messageWriter) WriteString(p string) (int, error) {
665         if w.err != nil {
666                 return 0, w.err
667         }
668
669         nn := len(p)
670         for len(p) > 0 {
671                 n, err := w.ncopy(len(p))
672                 if err != nil {
673                         return 0, err
674                 }
675                 copy(w.c.writeBuf[w.pos:], p[:n])
676                 w.pos += n
677                 p = p[n:]
678         }
679         return nn, nil
680 }
681
682 func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {
683         if w.err != nil {
684                 return 0, w.err
685         }
686         for {
687                 if w.pos == len(w.c.writeBuf) {
688                         err = w.flushFrame(false, nil)
689                         if err != nil {
690                                 break
691                         }
692                 }
693                 var n int
694                 n, err = r.Read(w.c.writeBuf[w.pos:])
695                 w.pos += n
696                 nn += int64(n)
697                 if err != nil {
698                         if err == io.EOF {
699                                 err = nil
700                         }
701                         break
702                 }
703         }
704         return nn, err
705 }
706
707 func (w *messageWriter) Close() error {
708         if w.err != nil {
709                 return w.err
710         }
711         if err := w.flushFrame(true, nil); err != nil {
712                 return err
713         }
714         return nil
715 }
716
717 // WritePreparedMessage writes prepared message into connection.
718 func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error {
719         frameType, frameData, err := pm.frame(prepareKey{
720                 isServer:         c.isServer,
721                 compress:         c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType),
722                 compressionLevel: c.compressionLevel,
723         })
724         if err != nil {
725                 return err
726         }
727         if c.isWriting {
728                 panic("concurrent write to websocket connection")
729         }
730         c.isWriting = true
731         err = c.write(frameType, c.writeDeadline, frameData, nil)
732         if !c.isWriting {
733                 panic("concurrent write to websocket connection")
734         }
735         c.isWriting = false
736         return err
737 }
738
739 // WriteMessage is a helper method for getting a writer using NextWriter,
740 // writing the message and closing the writer.
741 func (c *Conn) WriteMessage(messageType int, data []byte) error {
742
743         if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) {
744                 // Fast path with no allocations and single frame.
745
746                 var mw messageWriter
747                 if err := c.beginMessage(&mw, messageType); err != nil {
748                         return err
749                 }
750                 n := copy(c.writeBuf[mw.pos:], data)
751                 mw.pos += n
752                 data = data[n:]
753                 return mw.flushFrame(true, data)
754         }
755
756         w, err := c.NextWriter(messageType)
757         if err != nil {
758                 return err
759         }
760         if _, err = w.Write(data); err != nil {
761                 return err
762         }
763         return w.Close()
764 }
765
766 // SetWriteDeadline sets the write deadline on the underlying network
767 // connection. After a write has timed out, the websocket state is corrupt and
768 // all future writes will return an error. A zero value for t means writes will
769 // not time out.
770 func (c *Conn) SetWriteDeadline(t time.Time) error {
771         c.writeDeadline = t
772         return nil
773 }
774
775 // Read methods
776
777 func (c *Conn) advanceFrame() (int, error) {
778         // 1. Skip remainder of previous frame.
779
780         if c.readRemaining > 0 {
781                 if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil {
782                         return noFrame, err
783                 }
784         }
785
786         // 2. Read and parse first two bytes of frame header.
787
788         p, err := c.read(2)
789         if err != nil {
790                 return noFrame, err
791         }
792
793         final := p[0]&finalBit != 0
794         frameType := int(p[0] & 0xf)
795         mask := p[1]&maskBit != 0
796         c.readRemaining = int64(p[1] & 0x7f)
797
798         c.readDecompress = false
799         if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 {
800                 c.readDecompress = true
801                 p[0] &^= rsv1Bit
802         }
803
804         if rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 {
805                 return noFrame, c.handleProtocolError("unexpected reserved bits 0x" + strconv.FormatInt(int64(rsv), 16))
806         }
807
808         switch frameType {
809         case CloseMessage, PingMessage, PongMessage:
810                 if c.readRemaining > maxControlFramePayloadSize {
811                         return noFrame, c.handleProtocolError("control frame length > 125")
812                 }
813                 if !final {
814                         return noFrame, c.handleProtocolError("control frame not final")
815                 }
816         case TextMessage, BinaryMessage:
817                 if !c.readFinal {
818                         return noFrame, c.handleProtocolError("message start before final message frame")
819                 }
820                 c.readFinal = final
821         case continuationFrame:
822                 if c.readFinal {
823                         return noFrame, c.handleProtocolError("continuation after final message frame")
824                 }
825                 c.readFinal = final
826         default:
827                 return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType))
828         }
829
830         // 3. Read and parse frame length.
831
832         switch c.readRemaining {
833         case 126:
834                 p, err := c.read(2)
835                 if err != nil {
836                         return noFrame, err
837                 }
838                 c.readRemaining = int64(binary.BigEndian.Uint16(p))
839         case 127:
840                 p, err := c.read(8)
841                 if err != nil {
842                         return noFrame, err
843                 }
844                 c.readRemaining = int64(binary.BigEndian.Uint64(p))
845         }
846
847         // 4. Handle frame masking.
848
849         if mask != c.isServer {
850                 return noFrame, c.handleProtocolError("incorrect mask flag")
851         }
852
853         if mask {
854                 c.readMaskPos = 0
855                 p, err := c.read(len(c.readMaskKey))
856                 if err != nil {
857                         return noFrame, err
858                 }
859                 copy(c.readMaskKey[:], p)
860         }
861
862         // 5. For text and binary messages, enforce read limit and return.
863
864         if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage {
865
866                 c.readLength += c.readRemaining
867                 if c.readLimit > 0 && c.readLength > c.readLimit {
868                         c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait))
869                         return noFrame, ErrReadLimit
870                 }
871
872                 return frameType, nil
873         }
874
875         // 6. Read control frame payload.
876
877         var payload []byte
878         if c.readRemaining > 0 {
879                 payload, err = c.read(int(c.readRemaining))
880                 c.readRemaining = 0
881                 if err != nil {
882                         return noFrame, err
883                 }
884                 if c.isServer {
885                         maskBytes(c.readMaskKey, 0, payload)
886                 }
887         }
888
889         // 7. Process control frame payload.
890
891         switch frameType {
892         case PongMessage:
893                 if err := c.handlePong(string(payload)); err != nil {
894                         return noFrame, err
895                 }
896         case PingMessage:
897                 if err := c.handlePing(string(payload)); err != nil {
898                         return noFrame, err
899                 }
900         case CloseMessage:
901                 closeCode := CloseNoStatusReceived
902                 closeText := ""
903                 if len(payload) >= 2 {
904                         closeCode = int(binary.BigEndian.Uint16(payload))
905                         if !isValidReceivedCloseCode(closeCode) {
906                                 return noFrame, c.handleProtocolError("invalid close code")
907                         }
908                         closeText = string(payload[2:])
909                         if !utf8.ValidString(closeText) {
910                                 return noFrame, c.handleProtocolError("invalid utf8 payload in close frame")
911                         }
912                 }
913                 if err := c.handleClose(closeCode, closeText); err != nil {
914                         return noFrame, err
915                 }
916                 return noFrame, &CloseError{Code: closeCode, Text: closeText}
917         }
918
919         return frameType, nil
920 }
921
922 func (c *Conn) handleProtocolError(message string) error {
923         c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait))
924         return errors.New("websocket: " + message)
925 }
926
927 // NextReader returns the next data message received from the peer. The
928 // returned messageType is either TextMessage or BinaryMessage.
929 //
930 // There can be at most one open reader on a connection. NextReader discards
931 // the previous message if the application has not already consumed it.
932 //
933 // Applications must break out of the application's read loop when this method
934 // returns a non-nil error value. Errors returned from this method are
935 // permanent. Once this method returns a non-nil error, all subsequent calls to
936 // this method return the same error.
937 func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
938         // Close previous reader, only relevant for decompression.
939         if c.reader != nil {
940                 c.reader.Close()
941                 c.reader = nil
942         }
943
944         c.messageReader = nil
945         c.readLength = 0
946
947         for c.readErr == nil {
948                 frameType, err := c.advanceFrame()
949                 if err != nil {
950                         c.readErr = hideTempErr(err)
951                         break
952                 }
953                 if frameType == TextMessage || frameType == BinaryMessage {
954                         c.messageReader = &messageReader{c}
955                         c.reader = c.messageReader
956                         if c.readDecompress {
957                                 c.reader = c.newDecompressionReader(c.reader)
958                         }
959                         return frameType, c.reader, nil
960                 }
961         }
962
963         // Applications that do handle the error returned from this method spin in
964         // tight loop on connection failure. To help application developers detect
965         // this error, panic on repeated reads to the failed connection.
966         c.readErrCount++
967         if c.readErrCount >= 1000 {
968                 panic("repeated read on failed websocket connection")
969         }
970
971         return noFrame, nil, c.readErr
972 }
973
974 type messageReader struct{ c *Conn }
975
976 func (r *messageReader) Read(b []byte) (int, error) {
977         c := r.c
978         if c.messageReader != r {
979                 return 0, io.EOF
980         }
981
982         for c.readErr == nil {
983
984                 if c.readRemaining > 0 {
985                         if int64(len(b)) > c.readRemaining {
986                                 b = b[:c.readRemaining]
987                         }
988                         n, err := c.br.Read(b)
989                         c.readErr = hideTempErr(err)
990                         if c.isServer {
991                                 c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n])
992                         }
993                         c.readRemaining -= int64(n)
994                         if c.readRemaining > 0 && c.readErr == io.EOF {
995                                 c.readErr = errUnexpectedEOF
996                         }
997                         return n, c.readErr
998                 }
999
1000                 if c.readFinal {
1001                         c.messageReader = nil
1002                         return 0, io.EOF
1003                 }
1004
1005                 frameType, err := c.advanceFrame()
1006                 switch {
1007                 case err != nil:
1008                         c.readErr = hideTempErr(err)
1009                 case frameType == TextMessage || frameType == BinaryMessage:
1010                         c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")
1011                 }
1012         }
1013
1014         err := c.readErr
1015         if err == io.EOF && c.messageReader == r {
1016                 err = errUnexpectedEOF
1017         }
1018         return 0, err
1019 }
1020
1021 func (r *messageReader) Close() error {
1022         return nil
1023 }
1024
1025 // ReadMessage is a helper method for getting a reader using NextReader and
1026 // reading from that reader to a buffer.
1027 func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
1028         var r io.Reader
1029         messageType, r, err = c.NextReader()
1030         if err != nil {
1031                 return messageType, nil, err
1032         }
1033         p, err = ioutil.ReadAll(r)
1034         return messageType, p, err
1035 }
1036
1037 // SetReadDeadline sets the read deadline on the underlying network connection.
1038 // After a read has timed out, the websocket connection state is corrupt and
1039 // all future reads will return an error. A zero value for t means reads will
1040 // not time out.
1041 func (c *Conn) SetReadDeadline(t time.Time) error {
1042         return c.conn.SetReadDeadline(t)
1043 }
1044
1045 // SetReadLimit sets the maximum size in bytes for a message read from the peer. If a
1046 // message exceeds the limit, the connection sends a close message to the peer
1047 // and returns ErrReadLimit to the application.
1048 func (c *Conn) SetReadLimit(limit int64) {
1049         c.readLimit = limit
1050 }
1051
1052 // CloseHandler returns the current close handler
1053 func (c *Conn) CloseHandler() func(code int, text string) error {
1054         return c.handleClose
1055 }
1056
1057 // SetCloseHandler sets the handler for close messages received from the peer.
1058 // The code argument to h is the received close code or CloseNoStatusReceived
1059 // if the close message is empty. The default close handler sends a close
1060 // message back to the peer.
1061 //
1062 // The handler function is called from the NextReader, ReadMessage and message
1063 // reader Read methods. The application must read the connection to process
1064 // close messages as described in the section on Control Messages above.
1065 //
1066 // The connection read methods return a CloseError when a close message is
1067 // received. Most applications should handle close messages as part of their
1068 // normal error handling. Applications should only set a close handler when the
1069 // application must perform some action before sending a close message back to
1070 // the peer.
1071 func (c *Conn) SetCloseHandler(h func(code int, text string) error) {
1072         if h == nil {
1073                 h = func(code int, text string) error {
1074                         message := FormatCloseMessage(code, "")
1075                         c.WriteControl(CloseMessage, message, time.Now().Add(writeWait))
1076                         return nil
1077                 }
1078         }
1079         c.handleClose = h
1080 }
1081
1082 // PingHandler returns the current ping handler
1083 func (c *Conn) PingHandler() func(appData string) error {
1084         return c.handlePing
1085 }
1086
1087 // SetPingHandler sets the handler for ping messages received from the peer.
1088 // The appData argument to h is the PING message application data. The default
1089 // ping handler sends a pong to the peer.
1090 //
1091 // The handler function is called from the NextReader, ReadMessage and message
1092 // reader Read methods. The application must read the connection to process
1093 // ping messages as described in the section on Control Messages above.
1094 func (c *Conn) SetPingHandler(h func(appData string) error) {
1095         if h == nil {
1096                 h = func(message string) error {
1097                         err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
1098                         if err == ErrCloseSent {
1099                                 return nil
1100                         } else if e, ok := err.(net.Error); ok && e.Temporary() {
1101                                 return nil
1102                         }
1103                         return err
1104                 }
1105         }
1106         c.handlePing = h
1107 }
1108
1109 // PongHandler returns the current pong handler
1110 func (c *Conn) PongHandler() func(appData string) error {
1111         return c.handlePong
1112 }
1113
1114 // SetPongHandler sets the handler for pong messages received from the peer.
1115 // The appData argument to h is the PONG message application data. The default
1116 // pong handler does nothing.
1117 //
1118 // The handler function is called from the NextReader, ReadMessage and message
1119 // reader Read methods. The application must read the connection to process
1120 // pong messages as described in the section on Control Messages above.
1121 func (c *Conn) SetPongHandler(h func(appData string) error) {
1122         if h == nil {
1123                 h = func(string) error { return nil }
1124         }
1125         c.handlePong = h
1126 }
1127
1128 // UnderlyingConn returns the internal net.Conn. This can be used to further
1129 // modifications to connection specific flags.
1130 func (c *Conn) UnderlyingConn() net.Conn {
1131         return c.conn
1132 }
1133
1134 // EnableWriteCompression enables and disables write compression of
1135 // subsequent text and binary messages. This function is a noop if
1136 // compression was not negotiated with the peer.
1137 func (c *Conn) EnableWriteCompression(enable bool) {
1138         c.enableWriteCompression = enable
1139 }
1140
1141 // SetCompressionLevel sets the flate compression level for subsequent text and
1142 // binary messages. This function is a noop if compression was not negotiated
1143 // with the peer. See the compress/flate package for a description of
1144 // compression levels.
1145 func (c *Conn) SetCompressionLevel(level int) error {
1146         if !isValidCompressionLevel(level) {
1147                 return errors.New("websocket: invalid compression level")
1148         }
1149         c.compressionLevel = level
1150         return nil
1151 }
1152
1153 // FormatCloseMessage formats closeCode and text as a WebSocket close message.
1154 // An empty message is returned for code CloseNoStatusReceived.
1155 func FormatCloseMessage(closeCode int, text string) []byte {
1156         if closeCode == CloseNoStatusReceived {
1157                 // Return empty message because it's illegal to send
1158                 // CloseNoStatusReceived. Return non-nil value in case application
1159                 // checks for nil.
1160                 return []byte{}
1161         }
1162         buf := make([]byte, 2+len(text))
1163         binary.BigEndian.PutUint16(buf, uint16(closeCode))
1164         copy(buf[2:], text)
1165         return buf
1166 }