399 c.writeFatal(ErrCloseSent) |
400 c.writeFatal(ErrCloseSent) |
400 } |
401 } |
401 return nil |
402 return nil |
402 } |
403 } |
403 |
404 |
|
405 func (c *Conn) writeBufs(bufs ...[]byte) error { |
|
406 b := net.Buffers(bufs) |
|
407 _, err := b.WriteTo(c.conn) |
|
408 return err |
|
409 } |
|
410 |
404 // WriteControl writes a control message with the given deadline. The allowed |
411 // WriteControl writes a control message with the given deadline. The allowed |
405 // message types are CloseMessage, PingMessage and PongMessage. |
412 // message types are CloseMessage, PingMessage and PongMessage. |
406 func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error { |
413 func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error { |
407 if !isControl(messageType) { |
414 if !isControl(messageType) { |
408 return errBadWriteOpCode |
415 return errBadWriteOpCode |
792 return noFrame, err |
799 return noFrame, err |
793 } |
800 } |
794 } |
801 } |
795 |
802 |
796 // 2. Read and parse first two bytes of frame header. |
803 // 2. Read and parse first two bytes of frame header. |
|
804 // To aid debugging, collect and report all errors in the first two bytes |
|
805 // of the header. |
|
806 |
|
807 var errors []string |
797 |
808 |
798 p, err := c.read(2) |
809 p, err := c.read(2) |
799 if err != nil { |
810 if err != nil { |
800 return noFrame, err |
811 return noFrame, err |
801 } |
812 } |
802 |
813 |
|
814 frameType := int(p[0] & 0xf) |
803 final := p[0]&finalBit != 0 |
815 final := p[0]&finalBit != 0 |
804 frameType := int(p[0] & 0xf) |
816 rsv1 := p[0]&rsv1Bit != 0 |
|
817 rsv2 := p[0]&rsv2Bit != 0 |
|
818 rsv3 := p[0]&rsv3Bit != 0 |
805 mask := p[1]&maskBit != 0 |
819 mask := p[1]&maskBit != 0 |
806 c.setReadRemaining(int64(p[1] & 0x7f)) |
820 c.setReadRemaining(int64(p[1] & 0x7f)) |
807 |
821 |
808 c.readDecompress = false |
822 c.readDecompress = false |
809 if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 { |
823 if rsv1 { |
810 c.readDecompress = true |
824 if c.newDecompressionReader != nil { |
811 p[0] &^= rsv1Bit |
825 c.readDecompress = true |
812 } |
826 } else { |
813 |
827 errors = append(errors, "RSV1 set") |
814 if rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 { |
828 } |
815 return noFrame, c.handleProtocolError("unexpected reserved bits 0x" + strconv.FormatInt(int64(rsv), 16)) |
829 } |
|
830 |
|
831 if rsv2 { |
|
832 errors = append(errors, "RSV2 set") |
|
833 } |
|
834 |
|
835 if rsv3 { |
|
836 errors = append(errors, "RSV3 set") |
816 } |
837 } |
817 |
838 |
818 switch frameType { |
839 switch frameType { |
819 case CloseMessage, PingMessage, PongMessage: |
840 case CloseMessage, PingMessage, PongMessage: |
820 if c.readRemaining > maxControlFramePayloadSize { |
841 if c.readRemaining > maxControlFramePayloadSize { |
821 return noFrame, c.handleProtocolError("control frame length > 125") |
842 errors = append(errors, "len > 125 for control") |
822 } |
843 } |
823 if !final { |
844 if !final { |
824 return noFrame, c.handleProtocolError("control frame not final") |
845 errors = append(errors, "FIN not set on control") |
825 } |
846 } |
826 case TextMessage, BinaryMessage: |
847 case TextMessage, BinaryMessage: |
827 if !c.readFinal { |
848 if !c.readFinal { |
828 return noFrame, c.handleProtocolError("message start before final message frame") |
849 errors = append(errors, "data before FIN") |
829 } |
850 } |
830 c.readFinal = final |
851 c.readFinal = final |
831 case continuationFrame: |
852 case continuationFrame: |
832 if c.readFinal { |
853 if c.readFinal { |
833 return noFrame, c.handleProtocolError("continuation after final message frame") |
854 errors = append(errors, "continuation after FIN") |
834 } |
855 } |
835 c.readFinal = final |
856 c.readFinal = final |
836 default: |
857 default: |
837 return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType)) |
858 errors = append(errors, "bad opcode "+strconv.Itoa(frameType)) |
|
859 } |
|
860 |
|
861 if mask != c.isServer { |
|
862 errors = append(errors, "bad MASK") |
|
863 } |
|
864 |
|
865 if len(errors) > 0 { |
|
866 return noFrame, c.handleProtocolError(strings.Join(errors, ", ")) |
838 } |
867 } |
839 |
868 |
840 // 3. Read and parse frame length as per |
869 // 3. Read and parse frame length as per |
841 // https://tools.ietf.org/html/rfc6455#section-5.2 |
870 // https://tools.ietf.org/html/rfc6455#section-5.2 |
842 // |
871 // |
933 closeCode := CloseNoStatusReceived |
958 closeCode := CloseNoStatusReceived |
934 closeText := "" |
959 closeText := "" |
935 if len(payload) >= 2 { |
960 if len(payload) >= 2 { |
936 closeCode = int(binary.BigEndian.Uint16(payload)) |
961 closeCode = int(binary.BigEndian.Uint16(payload)) |
937 if !isValidReceivedCloseCode(closeCode) { |
962 if !isValidReceivedCloseCode(closeCode) { |
938 return noFrame, c.handleProtocolError("invalid close code") |
963 return noFrame, c.handleProtocolError("bad close code " + strconv.Itoa(closeCode)) |
939 } |
964 } |
940 closeText = string(payload[2:]) |
965 closeText = string(payload[2:]) |
941 if !utf8.ValidString(closeText) { |
966 if !utf8.ValidString(closeText) { |
942 return noFrame, c.handleProtocolError("invalid utf8 payload in close frame") |
967 return noFrame, c.handleProtocolError("invalid utf8 payload in close frame") |
943 } |
968 } |
950 |
975 |
951 return frameType, nil |
976 return frameType, nil |
952 } |
977 } |
953 |
978 |
954 func (c *Conn) handleProtocolError(message string) error { |
979 func (c *Conn) handleProtocolError(message string) error { |
955 c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait)) |
980 data := FormatCloseMessage(CloseProtocolError, message) |
|
981 if len(data) > maxControlFramePayloadSize { |
|
982 data = data[:maxControlFramePayloadSize] |
|
983 } |
|
984 c.WriteControl(CloseMessage, data, time.Now().Add(writeWait)) |
956 return errors.New("websocket: " + message) |
985 return errors.New("websocket: " + message) |
957 } |
986 } |
958 |
987 |
959 // NextReader returns the next data message received from the peer. The |
988 // NextReader returns the next data message received from the peer. The |
960 // returned messageType is either TextMessage or BinaryMessage. |
989 // returned messageType is either TextMessage or BinaryMessage. |