github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/gorilla/websocket/conn.go (about)

     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  	"time"
    17  )
    18  
    19  const (
    20  	maxFrameHeaderSize         = 2 + 8 + 4 // Fixed header + length + mask
    21  	maxControlFramePayloadSize = 125
    22  	finalBit                   = 1 << 7
    23  	maskBit                    = 1 << 7
    24  	writeWait                  = time.Second
    25  
    26  	defaultReadBufferSize  = 4096
    27  	defaultWriteBufferSize = 4096
    28  
    29  	continuationFrame = 0
    30  	noFrame           = -1
    31  )
    32  
    33  // Close codes defined in RFC 6455, section 11.7.
    34  const (
    35  	CloseNormalClosure           = 1000
    36  	CloseGoingAway               = 1001
    37  	CloseProtocolError           = 1002
    38  	CloseUnsupportedData         = 1003
    39  	CloseNoStatusReceived        = 1005
    40  	CloseAbnormalClosure         = 1006
    41  	CloseInvalidFramePayloadData = 1007
    42  	ClosePolicyViolation         = 1008
    43  	CloseMessageTooBig           = 1009
    44  	CloseMandatoryExtension      = 1010
    45  	CloseInternalServerErr       = 1011
    46  	CloseTLSHandshake            = 1015
    47  )
    48  
    49  // The message types are defined in RFC 6455, section 11.8.
    50  const (
    51  	// TextMessage denotes a text data message. The text message payload is
    52  	// interpreted as UTF-8 encoded text data.
    53  	TextMessage = 1
    54  
    55  	// BinaryMessage denotes a binary data message.
    56  	BinaryMessage = 2
    57  
    58  	// CloseMessage denotes a close control message. The optional message
    59  	// payload contains a numeric code and text. Use the FormatCloseMessage
    60  	// function to format a close message payload.
    61  	CloseMessage = 8
    62  
    63  	// PingMessage denotes a ping control message. The optional message payload
    64  	// is UTF-8 encoded text.
    65  	PingMessage = 9
    66  
    67  	// PongMessage denotes a ping control message. The optional message payload
    68  	// is UTF-8 encoded text.
    69  	PongMessage = 10
    70  )
    71  
    72  // ErrCloseSent is returned when the application writes a message to the
    73  // connection after sending a close message.
    74  var ErrCloseSent = errors.New("websocket: close sent")
    75  
    76  // ErrReadLimit is returned when reading a message that is larger than the
    77  // read limit set for the connection.
    78  var ErrReadLimit = errors.New("websocket: read limit exceeded")
    79  
    80  // netError satisfies the net Error interface.
    81  type netError struct {
    82  	msg       string
    83  	temporary bool
    84  	timeout   bool
    85  }
    86  
    87  func (e *netError) Error() string   { return e.msg }
    88  func (e *netError) Temporary() bool { return e.temporary }
    89  func (e *netError) Timeout() bool   { return e.timeout }
    90  
    91  // CloseError represents close frame.
    92  type CloseError struct {
    93  
    94  	// Code is defined in RFC 6455, section 11.7.
    95  	Code int
    96  
    97  	// Text is the optional text payload.
    98  	Text string
    99  }
   100  
   101  func (e *CloseError) Error() string {
   102  	s := []byte("websocket: close ")
   103  	s = strconv.AppendInt(s, int64(e.Code), 10)
   104  	switch e.Code {
   105  	case CloseNormalClosure:
   106  		s = append(s, " (normal)"...)
   107  	case CloseGoingAway:
   108  		s = append(s, " (going away)"...)
   109  	case CloseProtocolError:
   110  		s = append(s, " (protocol error)"...)
   111  	case CloseUnsupportedData:
   112  		s = append(s, " (unsupported data)"...)
   113  	case CloseNoStatusReceived:
   114  		s = append(s, " (no status)"...)
   115  	case CloseAbnormalClosure:
   116  		s = append(s, " (abnormal closure)"...)
   117  	case CloseInvalidFramePayloadData:
   118  		s = append(s, " (invalid payload data)"...)
   119  	case ClosePolicyViolation:
   120  		s = append(s, " (policy violation)"...)
   121  	case CloseMessageTooBig:
   122  		s = append(s, " (message too big)"...)
   123  	case CloseMandatoryExtension:
   124  		s = append(s, " (mandatory extension missing)"...)
   125  	case CloseInternalServerErr:
   126  		s = append(s, " (internal server error)"...)
   127  	case CloseTLSHandshake:
   128  		s = append(s, " (TLS handshake error)"...)
   129  	}
   130  	if e.Text != "" {
   131  		s = append(s, ": "...)
   132  		s = append(s, e.Text...)
   133  	}
   134  	return string(s)
   135  }
   136  
   137  // IsCloseError returns boolean indicating whether the error is a *CloseError
   138  // with one of the specified codes.
   139  func IsCloseError(err error, codes ...int) bool {
   140  	if e, ok := err.(*CloseError); ok {
   141  		for _, code := range codes {
   142  			if e.Code == code {
   143  				return true
   144  			}
   145  		}
   146  	}
   147  	return false
   148  }
   149  
   150  // IsUnexpectedCloseError returns boolean indicating whether the error is a
   151  // *CloseError with a code not in the list of expected codes.
   152  func IsUnexpectedCloseError(err error, expectedCodes ...int) bool {
   153  	if e, ok := err.(*CloseError); ok {
   154  		for _, code := range expectedCodes {
   155  			if e.Code == code {
   156  				return false
   157  			}
   158  		}
   159  		return true
   160  	}
   161  	return false
   162  }
   163  
   164  var (
   165  	errWriteTimeout        = &netError{msg: "websocket: write timeout", timeout: true, temporary: true}
   166  	errUnexpectedEOF       = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()}
   167  	errBadWriteOpCode      = errors.New("websocket: bad write message type")
   168  	errWriteClosed         = errors.New("websocket: write closed")
   169  	errInvalidControlFrame = errors.New("websocket: invalid control frame")
   170  )
   171  
   172  func hideTempErr(err error) error {
   173  	if e, ok := err.(net.Error); ok && e.Temporary() {
   174  		err = &netError{msg: e.Error(), timeout: e.Timeout()}
   175  	}
   176  	return err
   177  }
   178  
   179  func isControl(frameType int) bool {
   180  	return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage
   181  }
   182  
   183  func isData(frameType int) bool {
   184  	return frameType == TextMessage || frameType == BinaryMessage
   185  }
   186  
   187  func maskBytes(key [4]byte, pos int, b []byte) int {
   188  	for i := range b {
   189  		b[i] ^= key[pos&3]
   190  		pos++
   191  	}
   192  	return pos & 3
   193  }
   194  
   195  func newMaskKey() [4]byte {
   196  	n := rand.Uint32()
   197  	return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}
   198  }
   199  
   200  // Conn represents a WebSocket connection.
   201  type Conn struct {
   202  	conn        net.Conn
   203  	isServer    bool
   204  	subprotocol string
   205  
   206  	// Write fields
   207  	mu        chan bool // used as mutex to protect write to conn and closeSent
   208  	closeSent bool      // true if close message was sent
   209  
   210  	// Message writer fields.
   211  	writeErr       error
   212  	writeBuf       []byte // frame is constructed in this buffer.
   213  	writePos       int    // end of data in writeBuf.
   214  	writeFrameType int    // type of the current frame.
   215  	writeSeq       int    // incremented to invalidate message writers.
   216  	writeDeadline  time.Time
   217  	isWriting      bool // for best-effort concurrent write detection
   218  
   219  	// Read fields
   220  	readErr       error
   221  	br            *bufio.Reader
   222  	readRemaining int64 // bytes remaining in current frame.
   223  	readFinal     bool  // true the current message has more frames.
   224  	readSeq       int   // incremented to invalidate message readers.
   225  	readLength    int64 // Message size.
   226  	readLimit     int64 // Maximum message size.
   227  	readMaskPos   int
   228  	readMaskKey   [4]byte
   229  	handlePong    func(string) error
   230  	handlePing    func(string) error
   231  	readErrCount  int
   232  }
   233  
   234  func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int) *Conn {
   235  	mu := make(chan bool, 1)
   236  	mu <- true
   237  
   238  	if readBufferSize == 0 {
   239  		readBufferSize = defaultReadBufferSize
   240  	}
   241  	if writeBufferSize == 0 {
   242  		writeBufferSize = defaultWriteBufferSize
   243  	}
   244  
   245  	c := &Conn{
   246  		isServer:       isServer,
   247  		br:             bufio.NewReaderSize(conn, readBufferSize),
   248  		conn:           conn,
   249  		mu:             mu,
   250  		readFinal:      true,
   251  		writeBuf:       make([]byte, writeBufferSize+maxFrameHeaderSize),
   252  		writeFrameType: noFrame,
   253  		writePos:       maxFrameHeaderSize,
   254  	}
   255  	c.SetPingHandler(nil)
   256  	c.SetPongHandler(nil)
   257  	return c
   258  }
   259  
   260  // Subprotocol returns the negotiated protocol for the connection.
   261  func (c *Conn) Subprotocol() string {
   262  	return c.subprotocol
   263  }
   264  
   265  // Close closes the underlying network connection without sending or waiting for a close frame.
   266  func (c *Conn) Close() error {
   267  	return c.conn.Close()
   268  }
   269  
   270  // LocalAddr returns the local network address.
   271  func (c *Conn) LocalAddr() net.Addr {
   272  	return c.conn.LocalAddr()
   273  }
   274  
   275  // RemoteAddr returns the remote network address.
   276  func (c *Conn) RemoteAddr() net.Addr {
   277  	return c.conn.RemoteAddr()
   278  }
   279  
   280  // Write methods
   281  
   282  func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error {
   283  	<-c.mu
   284  	defer func() { c.mu <- true }()
   285  
   286  	if c.closeSent {
   287  		return ErrCloseSent
   288  	} else if frameType == CloseMessage {
   289  		c.closeSent = true
   290  	}
   291  
   292  	c.conn.SetWriteDeadline(deadline)
   293  	for _, buf := range bufs {
   294  		if len(buf) > 0 {
   295  			n, err := c.conn.Write(buf)
   296  			if n != len(buf) {
   297  				// Close on partial write.
   298  				c.conn.Close()
   299  			}
   300  			if err != nil {
   301  				return err
   302  			}
   303  		}
   304  	}
   305  	return nil
   306  }
   307  
   308  // WriteControl writes a control message with the given deadline. The allowed
   309  // message types are CloseMessage, PingMessage and PongMessage.
   310  func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error {
   311  	if !isControl(messageType) {
   312  		return errBadWriteOpCode
   313  	}
   314  	if len(data) > maxControlFramePayloadSize {
   315  		return errInvalidControlFrame
   316  	}
   317  
   318  	b0 := byte(messageType) | finalBit
   319  	b1 := byte(len(data))
   320  	if !c.isServer {
   321  		b1 |= maskBit
   322  	}
   323  
   324  	buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize)
   325  	buf = append(buf, b0, b1)
   326  
   327  	if c.isServer {
   328  		buf = append(buf, data...)
   329  	} else {
   330  		key := newMaskKey()
   331  		buf = append(buf, key[:]...)
   332  		buf = append(buf, data...)
   333  		maskBytes(key, 0, buf[6:])
   334  	}
   335  
   336  	d := time.Hour * 1000
   337  	if !deadline.IsZero() {
   338  		d = deadline.Sub(time.Now())
   339  		if d < 0 {
   340  			return errWriteTimeout
   341  		}
   342  	}
   343  
   344  	timer := time.NewTimer(d)
   345  	select {
   346  	case <-c.mu:
   347  		timer.Stop()
   348  	case <-timer.C:
   349  		return errWriteTimeout
   350  	}
   351  	defer func() { c.mu <- true }()
   352  
   353  	if c.closeSent {
   354  		return ErrCloseSent
   355  	} else if messageType == CloseMessage {
   356  		c.closeSent = true
   357  	}
   358  
   359  	c.conn.SetWriteDeadline(deadline)
   360  	n, err := c.conn.Write(buf)
   361  	if n != 0 && n != len(buf) {
   362  		c.conn.Close()
   363  	}
   364  	return hideTempErr(err)
   365  }
   366  
   367  // NextWriter returns a writer for the next message to send.  The writer's
   368  // Close method flushes the complete message to the network.
   369  //
   370  // There can be at most one open writer on a connection. NextWriter closes the
   371  // previous writer if the application has not already done so.
   372  func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
   373  	if c.writeErr != nil {
   374  		return nil, c.writeErr
   375  	}
   376  
   377  	if c.writeFrameType != noFrame {
   378  		if err := c.flushFrame(true, nil); err != nil {
   379  			return nil, err
   380  		}
   381  	}
   382  
   383  	if !isControl(messageType) && !isData(messageType) {
   384  		return nil, errBadWriteOpCode
   385  	}
   386  
   387  	c.writeFrameType = messageType
   388  	return messageWriter{c, c.writeSeq}, nil
   389  }
   390  
   391  func (c *Conn) flushFrame(final bool, extra []byte) error {
   392  	length := c.writePos - maxFrameHeaderSize + len(extra)
   393  
   394  	// Check for invalid control frames.
   395  	if isControl(c.writeFrameType) &&
   396  		(!final || length > maxControlFramePayloadSize) {
   397  		c.writeSeq++
   398  		c.writeFrameType = noFrame
   399  		c.writePos = maxFrameHeaderSize
   400  		return errInvalidControlFrame
   401  	}
   402  
   403  	b0 := byte(c.writeFrameType)
   404  	if final {
   405  		b0 |= finalBit
   406  	}
   407  	b1 := byte(0)
   408  	if !c.isServer {
   409  		b1 |= maskBit
   410  	}
   411  
   412  	// Assume that the frame starts at beginning of c.writeBuf.
   413  	framePos := 0
   414  	if c.isServer {
   415  		// Adjust up if mask not included in the header.
   416  		framePos = 4
   417  	}
   418  
   419  	switch {
   420  	case length >= 65536:
   421  		c.writeBuf[framePos] = b0
   422  		c.writeBuf[framePos+1] = b1 | 127
   423  		binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length))
   424  	case length > 125:
   425  		framePos += 6
   426  		c.writeBuf[framePos] = b0
   427  		c.writeBuf[framePos+1] = b1 | 126
   428  		binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length))
   429  	default:
   430  		framePos += 8
   431  		c.writeBuf[framePos] = b0
   432  		c.writeBuf[framePos+1] = b1 | byte(length)
   433  	}
   434  
   435  	if !c.isServer {
   436  		key := newMaskKey()
   437  		copy(c.writeBuf[maxFrameHeaderSize-4:], key[:])
   438  		maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:c.writePos])
   439  		if len(extra) > 0 {
   440  			c.writeErr = errors.New("websocket: internal error, extra used in client mode")
   441  			return c.writeErr
   442  		}
   443  	}
   444  
   445  	// Write the buffers to the connection with best-effort detection of
   446  	// concurrent writes. See the concurrency section in the package
   447  	// documentation for more info.
   448  
   449  	if c.isWriting {
   450  		panic("concurrent write to websocket connection")
   451  	}
   452  	c.isWriting = true
   453  
   454  	c.writeErr = c.write(c.writeFrameType, c.writeDeadline, c.writeBuf[framePos:c.writePos], extra)
   455  
   456  	if !c.isWriting {
   457  		panic("concurrent write to websocket connection")
   458  	}
   459  	c.isWriting = false
   460  
   461  	// Setup for next frame.
   462  	c.writePos = maxFrameHeaderSize
   463  	c.writeFrameType = continuationFrame
   464  	if final {
   465  		c.writeSeq++
   466  		c.writeFrameType = noFrame
   467  	}
   468  	return c.writeErr
   469  }
   470  
   471  type messageWriter struct {
   472  	c   *Conn
   473  	seq int
   474  }
   475  
   476  func (w messageWriter) err() error {
   477  	c := w.c
   478  	if c.writeSeq != w.seq {
   479  		return errWriteClosed
   480  	}
   481  	if c.writeErr != nil {
   482  		return c.writeErr
   483  	}
   484  	return nil
   485  }
   486  
   487  func (w messageWriter) ncopy(max int) (int, error) {
   488  	n := len(w.c.writeBuf) - w.c.writePos
   489  	if n <= 0 {
   490  		if err := w.c.flushFrame(false, nil); err != nil {
   491  			return 0, err
   492  		}
   493  		n = len(w.c.writeBuf) - w.c.writePos
   494  	}
   495  	if n > max {
   496  		n = max
   497  	}
   498  	return n, nil
   499  }
   500  
   501  func (w messageWriter) write(final bool, p []byte) (int, error) {
   502  	if err := w.err(); err != nil {
   503  		return 0, err
   504  	}
   505  
   506  	if len(p) > 2*len(w.c.writeBuf) && w.c.isServer {
   507  		// Don't buffer large messages.
   508  		err := w.c.flushFrame(final, p)
   509  		if err != nil {
   510  			return 0, err
   511  		}
   512  		return len(p), nil
   513  	}
   514  
   515  	nn := len(p)
   516  	for len(p) > 0 {
   517  		n, err := w.ncopy(len(p))
   518  		if err != nil {
   519  			return 0, err
   520  		}
   521  		copy(w.c.writeBuf[w.c.writePos:], p[:n])
   522  		w.c.writePos += n
   523  		p = p[n:]
   524  	}
   525  	return nn, nil
   526  }
   527  
   528  func (w messageWriter) Write(p []byte) (int, error) {
   529  	return w.write(false, p)
   530  }
   531  
   532  func (w messageWriter) WriteString(p string) (int, error) {
   533  	if err := w.err(); err != nil {
   534  		return 0, err
   535  	}
   536  
   537  	nn := len(p)
   538  	for len(p) > 0 {
   539  		n, err := w.ncopy(len(p))
   540  		if err != nil {
   541  			return 0, err
   542  		}
   543  		copy(w.c.writeBuf[w.c.writePos:], p[:n])
   544  		w.c.writePos += n
   545  		p = p[n:]
   546  	}
   547  	return nn, nil
   548  }
   549  
   550  func (w messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {
   551  	if err := w.err(); err != nil {
   552  		return 0, err
   553  	}
   554  	for {
   555  		if w.c.writePos == len(w.c.writeBuf) {
   556  			err = w.c.flushFrame(false, nil)
   557  			if err != nil {
   558  				break
   559  			}
   560  		}
   561  		var n int
   562  		n, err = r.Read(w.c.writeBuf[w.c.writePos:])
   563  		w.c.writePos += n
   564  		nn += int64(n)
   565  		if err != nil {
   566  			if err == io.EOF {
   567  				err = nil
   568  			}
   569  			break
   570  		}
   571  	}
   572  	return nn, err
   573  }
   574  
   575  func (w messageWriter) Close() error {
   576  	if err := w.err(); err != nil {
   577  		return err
   578  	}
   579  	return w.c.flushFrame(true, nil)
   580  }
   581  
   582  // WriteMessage is a helper method for getting a writer using NextWriter,
   583  // writing the message and closing the writer.
   584  func (c *Conn) WriteMessage(messageType int, data []byte) error {
   585  	wr, err := c.NextWriter(messageType)
   586  	if err != nil {
   587  		return err
   588  	}
   589  	w := wr.(messageWriter)
   590  	if _, err := w.write(true, data); err != nil {
   591  		return err
   592  	}
   593  	if c.writeSeq == w.seq {
   594  		if err := c.flushFrame(true, nil); err != nil {
   595  			return err
   596  		}
   597  	}
   598  	return nil
   599  }
   600  
   601  // SetWriteDeadline sets the write deadline on the underlying network
   602  // connection. After a write has timed out, the websocket state is corrupt and
   603  // all future writes will return an error. A zero value for t means writes will
   604  // not time out.
   605  func (c *Conn) SetWriteDeadline(t time.Time) error {
   606  	c.writeDeadline = t
   607  	return nil
   608  }
   609  
   610  // Read methods
   611  
   612  // readFull is like io.ReadFull except that io.EOF is never returned.
   613  func (c *Conn) readFull(p []byte) (err error) {
   614  	var n int
   615  	for n < len(p) && err == nil {
   616  		var nn int
   617  		nn, err = c.br.Read(p[n:])
   618  		n += nn
   619  	}
   620  	if n == len(p) {
   621  		err = nil
   622  	} else if err == io.EOF {
   623  		err = errUnexpectedEOF
   624  	}
   625  	return
   626  }
   627  
   628  func (c *Conn) advanceFrame() (int, error) {
   629  
   630  	// 1. Skip remainder of previous frame.
   631  
   632  	if c.readRemaining > 0 {
   633  		if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil {
   634  			return noFrame, err
   635  		}
   636  	}
   637  
   638  	// 2. Read and parse first two bytes of frame header.
   639  
   640  	var b [8]byte
   641  	if err := c.readFull(b[:2]); err != nil {
   642  		return noFrame, err
   643  	}
   644  
   645  	final := b[0]&finalBit != 0
   646  	frameType := int(b[0] & 0xf)
   647  	reserved := int((b[0] >> 4) & 0x7)
   648  	mask := b[1]&maskBit != 0
   649  	c.readRemaining = int64(b[1] & 0x7f)
   650  
   651  	if reserved != 0 {
   652  		return noFrame, c.handleProtocolError("unexpected reserved bits " + strconv.Itoa(reserved))
   653  	}
   654  
   655  	switch frameType {
   656  	case CloseMessage, PingMessage, PongMessage:
   657  		if c.readRemaining > maxControlFramePayloadSize {
   658  			return noFrame, c.handleProtocolError("control frame length > 125")
   659  		}
   660  		if !final {
   661  			return noFrame, c.handleProtocolError("control frame not final")
   662  		}
   663  	case TextMessage, BinaryMessage:
   664  		if !c.readFinal {
   665  			return noFrame, c.handleProtocolError("message start before final message frame")
   666  		}
   667  		c.readFinal = final
   668  	case continuationFrame:
   669  		if c.readFinal {
   670  			return noFrame, c.handleProtocolError("continuation after final message frame")
   671  		}
   672  		c.readFinal = final
   673  	default:
   674  		return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType))
   675  	}
   676  
   677  	// 3. Read and parse frame length.
   678  
   679  	switch c.readRemaining {
   680  	case 126:
   681  		if err := c.readFull(b[:2]); err != nil {
   682  			return noFrame, err
   683  		}
   684  		c.readRemaining = int64(binary.BigEndian.Uint16(b[:2]))
   685  	case 127:
   686  		if err := c.readFull(b[:8]); err != nil {
   687  			return noFrame, err
   688  		}
   689  		c.readRemaining = int64(binary.BigEndian.Uint64(b[:8]))
   690  	}
   691  
   692  	// 4. Handle frame masking.
   693  
   694  	if mask != c.isServer {
   695  		return noFrame, c.handleProtocolError("incorrect mask flag")
   696  	}
   697  
   698  	if mask {
   699  		c.readMaskPos = 0
   700  		if err := c.readFull(c.readMaskKey[:]); err != nil {
   701  			return noFrame, err
   702  		}
   703  	}
   704  
   705  	// 5. For text and binary messages, enforce read limit and return.
   706  
   707  	if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage {
   708  
   709  		c.readLength += c.readRemaining
   710  		if c.readLimit > 0 && c.readLength > c.readLimit {
   711  			c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait))
   712  			return noFrame, ErrReadLimit
   713  		}
   714  
   715  		return frameType, nil
   716  	}
   717  
   718  	// 6. Read control frame payload.
   719  
   720  	var payload []byte
   721  	if c.readRemaining > 0 {
   722  		payload = make([]byte, c.readRemaining)
   723  		c.readRemaining = 0
   724  		if err := c.readFull(payload); err != nil {
   725  			return noFrame, err
   726  		}
   727  		if c.isServer {
   728  			maskBytes(c.readMaskKey, 0, payload)
   729  		}
   730  	}
   731  
   732  	// 7. Process control frame payload.
   733  
   734  	switch frameType {
   735  	case PongMessage:
   736  		if err := c.handlePong(string(payload)); err != nil {
   737  			return noFrame, err
   738  		}
   739  	case PingMessage:
   740  		if err := c.handlePing(string(payload)); err != nil {
   741  			return noFrame, err
   742  		}
   743  	case CloseMessage:
   744  		echoMessage := []byte{}
   745  		closeCode := CloseNoStatusReceived
   746  		closeText := ""
   747  		if len(payload) >= 2 {
   748  			echoMessage = payload[:2]
   749  			closeCode = int(binary.BigEndian.Uint16(payload))
   750  			closeText = string(payload[2:])
   751  		}
   752  		c.WriteControl(CloseMessage, echoMessage, time.Now().Add(writeWait))
   753  		return noFrame, &CloseError{Code: closeCode, Text: closeText}
   754  	}
   755  
   756  	return frameType, nil
   757  }
   758  
   759  func (c *Conn) handleProtocolError(message string) error {
   760  	c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait))
   761  	return errors.New("websocket: " + message)
   762  }
   763  
   764  // NextReader returns the next data message received from the peer. The
   765  // returned messageType is either TextMessage or BinaryMessage.
   766  //
   767  // There can be at most one open reader on a connection. NextReader discards
   768  // the previous message if the application has not already consumed it.
   769  //
   770  // Applications must break out of the application's read loop when this method
   771  // returns a non-nil error value. Errors returned from this method are
   772  // permanent. Once this method returns a non-nil error, all subsequent calls to
   773  // this method return the same error.
   774  func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
   775  
   776  	c.readSeq++
   777  	c.readLength = 0
   778  
   779  	for c.readErr == nil {
   780  		frameType, err := c.advanceFrame()
   781  		if err != nil {
   782  			c.readErr = hideTempErr(err)
   783  			break
   784  		}
   785  		if frameType == TextMessage || frameType == BinaryMessage {
   786  			return frameType, messageReader{c, c.readSeq}, nil
   787  		}
   788  	}
   789  
   790  	// Applications that do handle the error returned from this method spin in
   791  	// tight loop on connection failure. To help application developers detect
   792  	// this error, panic on repeated reads to the failed connection.
   793  	c.readErrCount++
   794  	if c.readErrCount >= 1000 {
   795  		panic("repeated read on failed websocket connection")
   796  	}
   797  
   798  	return noFrame, nil, c.readErr
   799  }
   800  
   801  type messageReader struct {
   802  	c   *Conn
   803  	seq int
   804  }
   805  
   806  func (r messageReader) Read(b []byte) (int, error) {
   807  
   808  	if r.seq != r.c.readSeq {
   809  		return 0, io.EOF
   810  	}
   811  
   812  	for r.c.readErr == nil {
   813  
   814  		if r.c.readRemaining > 0 {
   815  			if int64(len(b)) > r.c.readRemaining {
   816  				b = b[:r.c.readRemaining]
   817  			}
   818  			n, err := r.c.br.Read(b)
   819  			r.c.readErr = hideTempErr(err)
   820  			if r.c.isServer {
   821  				r.c.readMaskPos = maskBytes(r.c.readMaskKey, r.c.readMaskPos, b[:n])
   822  			}
   823  			r.c.readRemaining -= int64(n)
   824  			return n, r.c.readErr
   825  		}
   826  
   827  		if r.c.readFinal {
   828  			r.c.readSeq++
   829  			return 0, io.EOF
   830  		}
   831  
   832  		frameType, err := r.c.advanceFrame()
   833  		switch {
   834  		case err != nil:
   835  			r.c.readErr = hideTempErr(err)
   836  		case frameType == TextMessage || frameType == BinaryMessage:
   837  			r.c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")
   838  		}
   839  	}
   840  
   841  	err := r.c.readErr
   842  	if err == io.EOF && r.seq == r.c.readSeq {
   843  		err = errUnexpectedEOF
   844  	}
   845  	return 0, err
   846  }
   847  
   848  // ReadMessage is a helper method for getting a reader using NextReader and
   849  // reading from that reader to a buffer.
   850  func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
   851  	var r io.Reader
   852  	messageType, r, err = c.NextReader()
   853  	if err != nil {
   854  		return messageType, nil, err
   855  	}
   856  	p, err = ioutil.ReadAll(r)
   857  	return messageType, p, err
   858  }
   859  
   860  // SetReadDeadline sets the read deadline on the underlying network connection.
   861  // After a read has timed out, the websocket connection state is corrupt and
   862  // all future reads will return an error. A zero value for t means reads will
   863  // not time out.
   864  func (c *Conn) SetReadDeadline(t time.Time) error {
   865  	return c.conn.SetReadDeadline(t)
   866  }
   867  
   868  // SetReadLimit sets the maximum size for a message read from the peer. If a
   869  // message exceeds the limit, the connection sends a close frame to the peer
   870  // and returns ErrReadLimit to the application.
   871  func (c *Conn) SetReadLimit(limit int64) {
   872  	c.readLimit = limit
   873  }
   874  
   875  // SetPingHandler sets the handler for ping messages received from the peer.
   876  // The appData argument to h is the PING frame application data. The default
   877  // ping handler sends a pong to the peer.
   878  func (c *Conn) SetPingHandler(h func(appData string) error) {
   879  	if h == nil {
   880  		h = func(message string) error {
   881  			err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
   882  			if err == ErrCloseSent {
   883  				return nil
   884  			} else if e, ok := err.(net.Error); ok && e.Temporary() {
   885  				return nil
   886  			}
   887  			return err
   888  		}
   889  	}
   890  	c.handlePing = h
   891  }
   892  
   893  // SetPongHandler sets the handler for pong messages received from the peer.
   894  // The appData argument to h is the PONG frame application data. The default
   895  // pong handler does nothing.
   896  func (c *Conn) SetPongHandler(h func(appData string) error) {
   897  	if h == nil {
   898  		h = func(string) error { return nil }
   899  	}
   900  	c.handlePong = h
   901  }
   902  
   903  // UnderlyingConn returns the internal net.Conn. This can be used to further
   904  // modifications to connection specific flags.
   905  func (c *Conn) UnderlyingConn() net.Conn {
   906  	return c.conn
   907  }
   908  
   909  // FormatCloseMessage formats closeCode and text as a WebSocket close message.
   910  func FormatCloseMessage(closeCode int, text string) []byte {
   911  	buf := make([]byte, 2+len(text))
   912  	binary.BigEndian.PutUint16(buf, uint16(closeCode))
   913  	copy(buf[2:], text)
   914  	return buf
   915  }