manage invalid Close codes + close() now can work without sending the CLOSE frame (if status=NONE)
[TODO] manage fragmentation
This commit is contained in:
parent
f07afb8c85
commit
75f568a1ec
67
ws/client.go
67
ws/client.go
|
@ -164,6 +164,13 @@ func clientReader(c *client){
|
||||||
if msg.Size > 2 && !utf8.Valid(msg.Data[2:]) {
|
if msg.Size > 2 && !utf8.Valid(msg.Data[2:]) {
|
||||||
errorCode = INVALID_PAYLOAD
|
errorCode = INVALID_PAYLOAD
|
||||||
}
|
}
|
||||||
|
// invalid code
|
||||||
|
if msg.Size >= 2 {
|
||||||
|
cCode := binary.BigEndian.Uint16(msg.Data[0:2])
|
||||||
|
if invalidCloseCode(cCode) {
|
||||||
|
errorCode = PROTOCOL_ERR
|
||||||
|
}
|
||||||
|
}
|
||||||
clientAck = false
|
clientAck = false
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -171,7 +178,7 @@ func clientReader(c *client){
|
||||||
|
|
||||||
/* (5) PING size error */
|
/* (5) PING size error */
|
||||||
if msg.Type == PING && msg.Size > 125 {
|
if msg.Type == PING && msg.Size > 125 {
|
||||||
fmt.Printf(" [reader] PING payload too big\n")
|
// fmt.Printf(" [reader] PING payload too big\n")
|
||||||
// fmt.Printf("[reader] PING err\n")
|
// fmt.Printf("[reader] PING err\n")
|
||||||
errorCode = PROTOCOL_ERR
|
errorCode = PROTOCOL_ERR
|
||||||
break
|
break
|
||||||
|
@ -190,14 +197,14 @@ func clientReader(c *client){
|
||||||
|
|
||||||
/* (7) Invalid UTF8 */
|
/* (7) Invalid UTF8 */
|
||||||
if msg.Type == TEXT && !utf8.Valid(msg.Data) {
|
if msg.Type == TEXT && !utf8.Valid(msg.Data) {
|
||||||
fmt.Printf(" [reader] invalid utf-8\n")
|
// fmt.Printf(" [reader] invalid utf-8\n")
|
||||||
errorCode = INVALID_PAYLOAD
|
errorCode = INVALID_PAYLOAD
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (8) Unknown opcode */
|
/* (8) Unknown opcode */
|
||||||
if msg.Type != TEXT && msg.Type != BINARY {
|
if msg.Type != TEXT && msg.Type != BINARY {
|
||||||
fmt.Printf(" [reader] unknown OpCode %d\n", msg.Type)
|
// fmt.Printf(" [reader] unknown OpCode %d\n", msg.Type)
|
||||||
errorCode = PROTOCOL_ERR
|
errorCode = PROTOCOL_ERR
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -249,10 +256,10 @@ func clientWriter(c *client){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// close writes the error message (if needed)
|
// closes the connection
|
||||||
// and it closes the socket
|
// send CLOSE frame is 'status' is not NONE
|
||||||
// if 'clientACK' is true, reads the next message (CLOSE acknowledge)
|
// wait for the next message (CLOSE acknowledge) if 'clientACK'
|
||||||
// before closing the socket
|
// then delete client
|
||||||
func (c *client) close(status MessageError, clientACK bool){
|
func (c *client) close(status MessageError, clientACK bool){
|
||||||
|
|
||||||
/* (1) Fail if already closing */
|
/* (1) Fail if already closing */
|
||||||
|
@ -277,25 +284,24 @@ func (c *client) close(status MessageError, clientACK bool){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if status == NONE {
|
if status != NONE {
|
||||||
status = NORMAL
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (3) Build message */
|
/* (3) Build message */
|
||||||
msg := &Message{
|
msg := &Message{
|
||||||
Final: true,
|
Final: true,
|
||||||
Type: CLOSE,
|
Type: CLOSE,
|
||||||
Size: 2,
|
Size: 2,
|
||||||
Data: make([]byte, 2),
|
Data: make([]byte, 2),
|
||||||
}
|
}
|
||||||
binary.BigEndian.PutUint16(msg.Data, uint16(status))
|
binary.BigEndian.PutUint16(msg.Data, uint16(status))
|
||||||
|
|
||||||
|
/* (4) Send message */
|
||||||
|
err := msg.Send(c.io.sock)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("[close] send error (%s0\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
/* (4) Send message */
|
|
||||||
err := msg.Send(c.io.sock)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("[close] send error (%s0\n", err)
|
|
||||||
}
|
}
|
||||||
// fmt.Printf("[close] frame sent\n")
|
|
||||||
|
|
||||||
|
|
||||||
/* (2) Wait for client CLOSE if needed */
|
/* (2) Wait for client CLOSE if needed */
|
||||||
|
@ -326,4 +332,19 @@ func (c *client) close(status MessageError, clientACK bool){
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func invalidCloseCode(code uint16) bool{
|
||||||
|
|
||||||
|
tolow := code < 1000
|
||||||
|
badrange1 := code >= 1004 && code <= 1006
|
||||||
|
badrange2 := code >= 1012 && code <= 1016
|
||||||
|
badspecific := code == 1100 || code == 2000 || code == 2999
|
||||||
|
|
||||||
|
return tolow || badrange1 || badrange2 || badspecific
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue