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 }