@@ -13,6 +13,7 @@ import (
13
13
"math/rand"
14
14
"net"
15
15
"strconv"
16
+ "strings"
16
17
"sync"
17
18
"time"
18
19
"unicode/utf8"
@@ -794,47 +795,69 @@ func (c *Conn) advanceFrame() (int, error) {
794
795
}
795
796
796
797
// 2. Read and parse first two bytes of frame header.
798
+ // To aid debugging, collect and report all errors in the first two bytes
799
+ // of the header.
800
+
801
+ var errors []string
797
802
798
803
p , err := c .read (2 )
799
804
if err != nil {
800
805
return noFrame , err
801
806
}
802
807
803
- final := p [0 ]& finalBit != 0
804
808
frameType := int (p [0 ] & 0xf )
809
+ final := p [0 ]& finalBit != 0
810
+ rsv1 := p [0 ]& rsv1Bit != 0
811
+ rsv2 := p [0 ]& rsv2Bit != 0
812
+ rsv3 := p [0 ]& rsv3Bit != 0
805
813
mask := p [1 ]& maskBit != 0
806
814
c .setReadRemaining (int64 (p [1 ] & 0x7f ))
807
815
808
816
c .readDecompress = false
809
- if c .newDecompressionReader != nil && (p [0 ]& rsv1Bit ) != 0 {
810
- c .readDecompress = true
811
- p [0 ] &^= rsv1Bit
817
+ if rsv1 {
818
+ if c .newDecompressionReader != nil {
819
+ c .readDecompress = true
820
+ } else {
821
+ errors = append (errors , "RSV1 set" )
822
+ }
812
823
}
813
824
814
- if rsv := p [0 ] & (rsv1Bit | rsv2Bit | rsv3Bit ); rsv != 0 {
815
- return noFrame , c .handleProtocolError ("unexpected reserved bits 0x" + strconv .FormatInt (int64 (rsv ), 16 ))
825
+ if rsv2 {
826
+ errors = append (errors , "RSV2 set" )
827
+ }
828
+
829
+ if rsv3 {
830
+ errors = append (errors , "RSV3 set" )
816
831
}
817
832
818
833
switch frameType {
819
834
case CloseMessage , PingMessage , PongMessage :
820
835
if c .readRemaining > maxControlFramePayloadSize {
821
- return noFrame , c . handleProtocolError ( "control frame length > 125" )
836
+ errors = append ( errors , "len > 125 for control " )
822
837
}
823
838
if ! final {
824
- return noFrame , c . handleProtocolError ( "control frame not final " )
839
+ errors = append ( errors , "FIN not set on control " )
825
840
}
826
841
case TextMessage , BinaryMessage :
827
842
if ! c .readFinal {
828
- return noFrame , c . handleProtocolError ( "message start before final message frame " )
843
+ errors = append ( errors , "data before FIN " )
829
844
}
830
845
c .readFinal = final
831
846
case continuationFrame :
832
847
if c .readFinal {
833
- return noFrame , c . handleProtocolError ( "continuation after final message frame " )
848
+ errors = append ( errors , "continuation after FIN " )
834
849
}
835
850
c .readFinal = final
836
851
default :
837
- return noFrame , c .handleProtocolError ("unknown opcode " + strconv .Itoa (frameType ))
852
+ errors = append (errors , "bad opcode " + strconv .Itoa (frameType ))
853
+ }
854
+
855
+ if mask != c .isServer {
856
+ errors = append (errors , "bad MASK" )
857
+ }
858
+
859
+ if len (errors ) > 0 {
860
+ return noFrame , c .handleProtocolError (strings .Join (errors , ", " ))
838
861
}
839
862
840
863
// 3. Read and parse frame length as per
@@ -872,10 +895,6 @@ func (c *Conn) advanceFrame() (int, error) {
872
895
873
896
// 4. Handle frame masking.
874
897
875
- if mask != c .isServer {
876
- return noFrame , c .handleProtocolError ("incorrect mask flag" )
877
- }
878
-
879
898
if mask {
880
899
c .readMaskPos = 0
881
900
p , err := c .read (len (c .readMaskKey ))
@@ -935,7 +954,7 @@ func (c *Conn) advanceFrame() (int, error) {
935
954
if len (payload ) >= 2 {
936
955
closeCode = int (binary .BigEndian .Uint16 (payload ))
937
956
if ! isValidReceivedCloseCode (closeCode ) {
938
- return noFrame , c .handleProtocolError ("invalid close code" )
957
+ return noFrame , c .handleProtocolError ("bad close code " + strconv . Itoa ( closeCode ) )
939
958
}
940
959
closeText = string (payload [2 :])
941
960
if ! utf8 .ValidString (closeText ) {
@@ -952,7 +971,11 @@ func (c *Conn) advanceFrame() (int, error) {
952
971
}
953
972
954
973
func (c * Conn ) handleProtocolError (message string ) error {
955
- c .WriteControl (CloseMessage , FormatCloseMessage (CloseProtocolError , message ), time .Now ().Add (writeWait ))
974
+ data := FormatCloseMessage (CloseProtocolError , message )
975
+ if len (data ) > maxControlFramePayloadSize {
976
+ data = data [:maxControlFramePayloadSize ]
977
+ }
978
+ c .WriteControl (CloseMessage , data , time .Now ().Add (writeWait ))
956
979
return errors .New ("websocket: " + message )
957
980
}
958
981
0 commit comments