commit 0abb88b6ab51709deb2a6106d7c61a85f66671b2 Author: David Fifield david@bamsoftware.com Date: Mon Nov 26 00:06:30 2012 -0800
readMessage. --- websocket-transport/websocket.go | 49 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/websocket-transport/websocket.go b/websocket-transport/websocket.go index fa0de7e..4ccf1e2 100644 --- a/websocket-transport/websocket.go +++ b/websocket-transport/websocket.go @@ -2,6 +2,7 @@ package main
import ( "bufio" + "bytes" "crypto/sha1" "encoding/base64" "encoding/binary" @@ -32,6 +33,7 @@ type websocket struct { IsClient bool MaxMessageSize uint64 Subprotocol string + messageBuf bytes.Buffer }
type websocketFrame struct { @@ -44,6 +46,11 @@ func (frame *websocketFrame) IsControl() bool { return (frame.Opcode & 0x08) != 0 }
+type websocketMessage struct { + Opcode byte + Payload []byte +} + func applyMask(payload []byte, maskKey [4]byte) { for i, _ := range payload { payload[i] = payload[i] ^ maskKey[i % 4] @@ -114,6 +121,48 @@ func (ws *websocket) ReadFrame() (frame websocketFrame, err error) { return frame, nil }
+func (ws *websocket) ReadMessage() (message websocketMessage, err error) { + var opcode byte = 0 + for { + var frame websocketFrame + frame, err = ws.ReadFrame() + if err != nil { + return + } + if frame.IsControl() { + if !frame.Fin { + err = errors.New("control frame has fin bit unset") + return + } + message.Opcode = frame.Opcode + message.Payload = frame.Payload + return message, nil + } + + if opcode == 0 { + if frame.Opcode == 0 { + err = errors.New("first frame has opcode 0") + return + } + opcode = frame.Opcode + } else { + if frame.Opcode != 0 { + err = errors.New(fmt.Sprintf("non-first frame has nonzero opcode %d", frame.Opcode)) + return + } + } + ws.messageBuf.Write(frame.Payload) + if frame.Fin { + break + } + } + message.Opcode = opcode + message.Payload = ws.messageBuf.Bytes() + ws.messageBuf.Reset() + + return message, nil +} + func commaSplit(s string) []string { var result []string if strings.TrimSpace(s) == "" {
tor-commits@lists.torproject.org