diff options
| author | Shulhan <ms@kilabit.info> | 2019-03-15 21:53:54 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2019-03-17 02:12:43 +0700 |
| commit | cc9990d30eb9863e56cdb52197de3610d1853d40 (patch) | |
| tree | 0288c1dc2c11e6725838bc1dfe8a70b9a50664bd | |
| parent | d4a58da2becbb4ae46d2bbe57aa8bc2c99a0845e (diff) | |
| download | pakakeh.go-cc9990d30eb9863e56cdb52197de3610d1853d40.tar.xz | |
websocket: move isValidFrame as method of Frame
This is to minimize duplicate code on client and server.
| -rw-r--r-- | lib/websocket/client.go | 36 | ||||
| -rw-r--r-- | lib/websocket/frame.go | 45 | ||||
| -rw-r--r-- | lib/websocket/server.go | 36 |
3 files changed, 47 insertions, 70 deletions
diff --git a/lib/websocket/client.go b/lib/websocket/client.go index 50856c18..0cc1e85a 100644 --- a/lib/websocket/client.go +++ b/lib/websocket/client.go @@ -452,7 +452,7 @@ func (cl *Client) handleFragment(frame *Frame) (isInvalid bool) { // handleFrame handle a single frame from client. // func (cl *Client) handleFrame(frame *Frame) (isClosing bool) { - if !cl.isValidFrame(frame) { + if !frame.isValid(false, cl.allowRsv1, cl.allowRsv2, cl.allowRsv3) { cl.handleBadRequest() return true } @@ -528,40 +528,6 @@ func (cl *Client) handleInvalidData() { } // -// isValidFrame will return true if a frame from server is valid: -// it's not masked, the reserved bits is not set (unless negotiated with -// server), and if its control frame the fin should be set and payload must be -// less than 125. -// -func (cl *Client) isValidFrame(frame *Frame) bool { - if frame.masked == frameIsMasked { - return false - } - if frame.rsv1 > 0 && !cl.allowRsv1 { - return false - } - if frame.rsv2 > 0 && !cl.allowRsv2 { - return false - } - if frame.rsv3 > 0 && !cl.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 -} - -// // SendBin send data frame as binary to server. // If handler is nil, no response will be read from server. // diff --git a/lib/websocket/frame.go b/lib/websocket/frame.go index 1b9c8690..c0e0d6ce 100644 --- a/lib/websocket/frame.go +++ b/lib/websocket/frame.go @@ -192,6 +192,51 @@ func (f *Frame) IsData() bool { } // +// isValid will return true if a frame is valid. +// If isMasked is true, the frame masked MUST be set, otherwise it will return +// false; and vice versa. +// Parameter allowRsv1, allowRsv2, and allowRsv3 are to allow one or more +// frame reserved bits to be set, in order. +// If reserved bit 1 is set but parameter allowRsv1 is false, it will return +// false; and so on. +// If its control frame the fin field should be set and payload must be less +// than 125. +// +func (f *Frame) isValid(isMasked, allowRsv1, allowRsv2, allowRsv3 bool) bool { + if isMasked { + if f.masked != frameIsMasked { + return false + } + } else { + if f.masked == frameIsMasked { + return false + } + } + if f.rsv1 > 0 && !allowRsv1 { + return false + } + if f.rsv2 > 0 && !allowRsv2 { + return false + } + if f.rsv3 > 0 && !allowRsv3 { + return false + } + + if f.opcode >= OpcodeClose { + if f.fin == 0 { + // Control frame must set the fin. + return false + } + // Control frame payload must not larger than 125. + if f.len > frameSmallPayload { + return false + } + } + + return true +} + +// // Opcode return the frame operation code. // func (f *Frame) Opcode() Opcode { diff --git a/lib/websocket/server.go b/lib/websocket/server.go index e20fb1dc..b3609e3e 100644 --- a/lib/websocket/server.go +++ b/lib/websocket/server.go @@ -398,7 +398,7 @@ func (serv *Server) handleFragment(conn int, req *Frame) (isInvalid bool) { // handleFrame handle a single frame from client. // func (serv *Server) handleFrame(conn int, frame *Frame) (isClosing bool) { - if !serv.isValidFrame(frame) { + if !frame.isValid(true, serv.allowRsv1, serv.allowRsv2, serv.allowRsv3) { serv.handleBadRequest(conn) return true } @@ -628,40 +628,6 @@ 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) |
