aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2019-03-12 14:40:18 +0700
committerShulhan <ms@kilabit.info>2019-03-12 14:40:18 +0700
commit3fa7caf2fda11d9a19c47c20a4102365a9213d77 (patch)
tree06e68a140515e2f49914eef210789aa9bf6bcec0
parent68d110d62a6cb756a0e19ca08643ca82abccbc16 (diff)
downloadpakakeh.go-3fa7caf2fda11d9a19c47c20a4102365a9213d77.tar.xz
websocket: move the process to validate client's frame into method
This is to minimize duplicate code on server's reader and handling chopped frame.
-rw-r--r--lib/websocket/server.go82
1 files changed, 36 insertions, 46 deletions
diff --git a/lib/websocket/server.go b/lib/websocket/server.go
index 6d6d25ec..1679761b 100644
--- a/lib/websocket/server.go
+++ b/lib/websocket/server.go
@@ -404,22 +404,7 @@ func (serv *Server) handleChopped(x, conn int, packet []byte) (rest []byte, isCl
serv.Clients.setFrame(conn, nil)
}
- if frame.masked != frameIsMasked {
- serv.handleBadRequest(conn)
- isClosing = true
- return
- }
- if frame.rsv1 > 0 && !serv.allowRsv1 {
- serv.handleBadRequest(conn)
- isClosing = true
- return
- }
- if frame.rsv2 > 0 && !serv.allowRsv2 {
- serv.handleBadRequest(conn)
- isClosing = true
- return
- }
- if frame.rsv3 > 0 && !serv.allowRsv3 {
+ if !serv.isValidFrame(frame) {
serv.handleBadRequest(conn)
isClosing = true
return
@@ -736,6 +721,40 @@ func (serv *Server) handlePing(conn int, req *Frame) {
}
//
+// isValidFrame will return true if a frame from client is valid:
+// it's masked, the reserved bits is not set (unless allowed by server), and
+// if its control frame the fin should be set and payload must be less than
+// 125.
+//
+func (serv *Server) isValidFrame(frame *Frame) bool {
+ if frame.masked != frameIsMasked {
+ return false
+ }
+ if frame.rsv1 > 0 && !serv.allowRsv1 {
+ return false
+ }
+ if frame.rsv2 > 0 && !serv.allowRsv2 {
+ return false
+ }
+ if frame.rsv3 > 0 && !serv.allowRsv3 {
+ return false
+ }
+
+ if frame.opcode == OpcodeClose || frame.opcode == OpcodePing || frame.opcode == OpcodePong {
+ if frame.fin == 0 {
+ // Control frame must set the fin.
+ return false
+ }
+ // Control frame payload must not larger than 125.
+ if frame.len > frameSmallPayload {
+ return false
+ }
+ }
+
+ return true
+}
+
+//
// reader read request from client.
//
// To avoid confusing network intermediaries (such as intercepting proxies)
@@ -797,40 +816,11 @@ func (serv *Server) reader() {
continue
}
- if frame.masked != frameIsMasked {
- serv.handleBadRequest(conn)
- isClosing = true
- break
- }
- if frame.rsv1 > 0 && !serv.allowRsv1 {
+ if !serv.isValidFrame(frame) {
serv.handleBadRequest(conn)
isClosing = true
break
}
- if frame.rsv2 > 0 && !serv.allowRsv2 {
- serv.handleBadRequest(conn)
- isClosing = true
- break
- }
- if frame.rsv3 > 0 && !serv.allowRsv3 {
- serv.handleBadRequest(conn)
- isClosing = true
- break
- }
- if frame.opcode == OpcodeClose || frame.opcode == OpcodePing || frame.opcode == OpcodePong {
- if frame.fin == 0 {
- // Control frame must set the fin.
- serv.handleBadRequest(conn)
- isClosing = true
- break
- }
- // Control frame payload must not larger than 125.
- if frame.len > frameSmallPayload {
- serv.handleBadRequest(conn)
- isClosing = true
- break
- }
- }
switch frame.opcode {
case OpcodeCont, OpcodeText, OpcodeBin: