diff options
| author | Shulhan <ms@kilabit.info> | 2019-03-12 14:40:18 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2019-03-12 14:40:18 +0700 |
| commit | 3fa7caf2fda11d9a19c47c20a4102365a9213d77 (patch) | |
| tree | 06e68a140515e2f49914eef210789aa9bf6bcec0 | |
| parent | 68d110d62a6cb756a0e19ca08643ca82abccbc16 (diff) | |
| download | pakakeh.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.go | 82 |
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: |
