@@ -14,6 +14,7 @@ import (
14
14
"net"
15
15
"strconv"
16
16
"time"
17
+ "unicode/utf8"
17
18
)
18
19
19
20
const (
@@ -43,6 +44,8 @@ const (
43
44
CloseMessageTooBig = 1009
44
45
CloseMandatoryExtension = 1010
45
46
CloseInternalServerErr = 1011
47
+ CloseServiceRestart = 1012
48
+ CloseTryAgainLater = 1013
46
49
CloseTLSHandshake = 1015
47
50
)
48
51
@@ -184,6 +187,29 @@ func isData(frameType int) bool {
184
187
return frameType == TextMessage || frameType == BinaryMessage
185
188
}
186
189
190
+ var validReceivedCloseCodes = map [int ]bool {
191
+ // see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number
192
+
193
+ CloseNormalClosure : true ,
194
+ CloseGoingAway : true ,
195
+ CloseProtocolError : true ,
196
+ CloseUnsupportedData : true ,
197
+ CloseNoStatusReceived : false ,
198
+ CloseAbnormalClosure : false ,
199
+ CloseInvalidFramePayloadData : true ,
200
+ ClosePolicyViolation : true ,
201
+ CloseMessageTooBig : true ,
202
+ CloseMandatoryExtension : true ,
203
+ CloseInternalServerErr : true ,
204
+ CloseServiceRestart : true ,
205
+ CloseTryAgainLater : true ,
206
+ CloseTLSHandshake : false ,
207
+ }
208
+
209
+ func isValidReceivedCloseCode (code int ) bool {
210
+ return validReceivedCloseCodes [code ] || (code >= 3000 && code <= 4999 )
211
+ }
212
+
187
213
func maskBytes (key [4 ]byte , pos int , b []byte ) int {
188
214
for i := range b {
189
215
b [i ] ^= key [pos & 3 ]
@@ -747,7 +773,13 @@ func (c *Conn) advanceFrame() (int, error) {
747
773
if len (payload ) >= 2 {
748
774
echoMessage = payload [:2 ]
749
775
closeCode = int (binary .BigEndian .Uint16 (payload ))
776
+ if ! isValidReceivedCloseCode (closeCode ) {
777
+ return noFrame , c .handleProtocolError ("invalid close code" )
778
+ }
750
779
closeText = string (payload [2 :])
780
+ if ! utf8 .ValidString (closeText ) {
781
+ return noFrame , c .handleProtocolError ("invalid utf8 payload in close frame" )
782
+ }
751
783
}
752
784
c .WriteControl (CloseMessage , echoMessage , time .Now ().Add (writeWait ))
753
785
return noFrame , & CloseError {Code : closeCode , Text : closeText }
0 commit comments