-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
fef68cd
commit 30f8e1d
Showing
13 changed files
with
491 additions
and
197 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package core | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"io" | ||
|
||
"github.com/dicedb/dice/config" | ||
) | ||
|
||
type RESPParser struct { | ||
c io.ReadWriter | ||
buf *bytes.Buffer | ||
} | ||
|
||
func NewRESPParser(c io.ReadWriter) *RESPParser { | ||
return NewRESPParserWithBytes(c, []byte{}) | ||
} | ||
|
||
func NewRESPParserWithBytes(c io.ReadWriter, initBytes []byte) *RESPParser { | ||
var b []byte | ||
var buf *bytes.Buffer = bytes.NewBuffer(b) | ||
buf.Write(initBytes) | ||
return &RESPParser{ | ||
c: c, | ||
buf: buf, | ||
} | ||
} | ||
|
||
func (rp *RESPParser) DecodeOne() (interface{}, error) { | ||
// assigning temporary buffer to read 512 bytes in one shot | ||
// and reading them in a loop until we have all the data | ||
// we want. | ||
// note: the size 512 is arbitrarily chosen, and we can put | ||
// a decent thought into deciding the optimal value (in case it affects the perf) | ||
var buf []byte = make([]byte, config.IOBufferLength) | ||
|
||
// keep reading the bytes from the buffer until the first /r is found | ||
// note: there may be extra bytes read over the socket post /r | ||
// but that is fine. | ||
for { | ||
n, err := rp.c.Read(buf) | ||
if n <= 0 { | ||
break | ||
} | ||
if err != nil { | ||
if err == io.EOF { | ||
break | ||
} | ||
return nil, err | ||
} | ||
rp.buf.Write(buf[:n]) | ||
|
||
if bytes.Contains(buf, []byte{'\r', '\n'}) { | ||
break | ||
} | ||
} | ||
|
||
b, err := rp.buf.ReadByte() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
switch b { | ||
case '+': | ||
return readSimpleString(rp.c, rp.buf) | ||
case '-': | ||
return readError(rp.c, rp.buf) | ||
case ':': | ||
return readInt64(rp.c, rp.buf) | ||
case '$': | ||
return readBulkString(rp.c, rp.buf) | ||
case '*': | ||
return readArray(rp.c, rp.buf, rp) | ||
} | ||
|
||
// this also captures the Cross Protocol Scripting attack. | ||
// Since we do not support simple strings, anything that does | ||
// not start with any of the above special chars will be a potential | ||
// attack. | ||
// Details: https://bou.ke/blog/hacking-developers/ | ||
return nil, errors.New("possible cross protocol scripting attack detected") | ||
} | ||
|
||
func (rp *RESPParser) DecodeMultiple() ([]interface{}, error) { | ||
var values []interface{} = make([]interface{}, 0) | ||
for { | ||
value, err := rp.DecodeOne() | ||
if err != nil { | ||
return nil, err | ||
} | ||
values = append(values, value) | ||
if rp.buf.Len() == 0 { | ||
break | ||
} | ||
} | ||
return values, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.