diff --git a/instruction.go b/instruction.go index 46452af..c15500c 100644 --- a/instruction.go +++ b/instruction.go @@ -39,28 +39,16 @@ func (i *Instruction) Byte() []byte { return []byte(i.String()) } -// ReadOne takes an instruction from the stream and parses it into an Instruction -func ReadOne(stream *Stream) (instruction *Instruction, err error) { - var instructionBuffer []byte - - // Get instruction - instructionBuffer, err = stream.ReadSome() - - // If EOF, return EOF - if err != nil { - return - } - - // Start of element +func Parse(data []byte) (*Instruction, error) { elementStart := 0 // Build list of elements elements := make([]string, 0, 1) - for elementStart < len(instructionBuffer) { + for elementStart < len(data) { // Find end of length lengthEnd := -1 - for i := elementStart; i < len(instructionBuffer); i++ { - if instructionBuffer[i] == '.' { + for i := elementStart; i < len(data); i++ { + if data[i] == '.' { lengthEnd = i break } @@ -68,27 +56,25 @@ func ReadOne(stream *Stream) (instruction *Instruction, err error) { // read() is required to return a complete instruction. If it does // not, this is a severe internal error. if lengthEnd == -1 { - err = ErrServer.NewError("ReadSome returned incomplete instruction.") - return + return nil, ErrServer.NewError("ReadSome returned incomplete instruction.") } // Parse length - length, e := strconv.Atoi(string(instructionBuffer[elementStart:lengthEnd])) + length, e := strconv.Atoi(string(data[elementStart:lengthEnd])) if e != nil { - err = ErrServer.NewError("ReadSome returned wrong pattern instruction.", e.Error()) - return + return nil, ErrServer.NewError("ReadSome returned wrong pattern instruction.", e.Error()) } // Parse element from just after period elementStart = lengthEnd + 1 - element := string(instructionBuffer[elementStart : elementStart+length]) + element := string(data[elementStart : elementStart+length]) // Append element to list of elements elements = append(elements, element) // ReadSome terminator after element elementStart += length - terminator := instructionBuffer[elementStart] + terminator := data[elementStart] // Continue reading instructions after terminator elementStart++ @@ -100,10 +86,16 @@ func ReadOne(stream *Stream) (instruction *Instruction, err error) { } - // Pull Opcode off elements list - // Create instruction - instruction = NewInstruction(elements[0], elements[1:]...) + return NewInstruction(elements[0], elements[1:]...), nil +} + +// ReadOne takes an instruction from the stream and parses it into an Instruction +func ReadOne(stream *Stream) (instruction *Instruction, err error) { + var instructionBuffer []byte + instructionBuffer, err = stream.ReadSome() + if err != nil { + return + } - // Return parsed instruction - return + return Parse(instructionBuffer) } diff --git a/stream.go b/stream.go index 08c25d9..ad38fa6 100644 --- a/stream.go +++ b/stream.go @@ -10,7 +10,7 @@ import ( const ( SocketTimeout = 15 * time.Second - maxGuacMessage = 8192 + MaxGuacMessage = 8192 ) // Stream wraps the connection to Guacamole providing timeouts and reading @@ -31,7 +31,7 @@ type Stream struct { // NewStream creates a new stream func NewStream(conn net.Conn, timeout time.Duration) (ret *Stream) { - buffer := make([]byte, 0, maxGuacMessage*3) + buffer := make([]byte, 0, MaxGuacMessage*3) return &Stream{ conn: conn, timeout: timeout, @@ -128,7 +128,7 @@ func (s *Stream) ReadSome() (instruction []byte, err error) { } } - if cap(s.buffer) < maxGuacMessage { + if cap(s.buffer) < MaxGuacMessage { s.Flush() } diff --git a/ws_server.go b/ws_server.go index a831771..2321a9d 100644 --- a/ws_server.go +++ b/ws_server.go @@ -42,8 +42,8 @@ func NewWebsocketServerWs(connect func(*websocket.Conn, *http.Request) (Tunnel, } const ( - websocketReadBufferSize = maxGuacMessage - websocketWriteBufferSize = maxGuacMessage * 2 + websocketReadBufferSize = MaxGuacMessage + websocketWriteBufferSize = MaxGuacMessage * 2 ) func (s *WebsocketServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -145,7 +145,7 @@ type MessageWriter interface { } func guacdToWs(ws MessageWriter, guacd InstructionReader) { - buf := bytes.NewBuffer(make([]byte, 0, maxGuacMessage*2)) + buf := bytes.NewBuffer(make([]byte, 0, MaxGuacMessage*2)) for { ins, err := guacd.ReadSome() @@ -165,7 +165,7 @@ func guacdToWs(ws MessageWriter, guacd InstructionReader) { } // if the buffer has more data in it or we've reached the max buffer size, send the data and reset - if !guacd.Available() || buf.Len() >= maxGuacMessage { + if !guacd.Available() || buf.Len() >= MaxGuacMessage { if err = ws.WriteMessage(1, buf.Bytes()); err != nil { if err == websocket.ErrCloseSent { return