Documentation ¶
Overview ¶
Package rmux/protocol provides a standard way to listen in on the redis protocol, look ahead to what commands are about to be executed, and ignore them or pass them on to another buffer, as desired
Index ¶
- Constants
- Variables
- func CopyMultiBulkMessage(firstLine []byte, destination *bufio.Writer, source *bufio.Reader) (err error)
- func CopyServerResponse(remoteBuffer *bufio.Reader, localBuffer *bufio.Writer) (err error)
- func Debug(format string, a ...interface{})
- func FlushLine(line []byte, destination *bufio.Writer) (err error)
- func GetCommand(source *bufio.Reader, command, firstArgument []byte) (commandLength, argumentLength int, err error)
- func IgnoreMultiBulkMessage(firstLine []byte, source *bufio.Reader) (err error)
- func IsSupportedFunction(command [20]byte, commandLength int, isMultiplexing, isMultipleArgument bool) bool
- func ParseInt(response []byte) (length int, err error)
- type TimedNetReadWriter
Constants ¶
const (
//This is set to match bufio's default buffer size, so taht we can safely read&ignore large chunks of data when necessary
BUFFER_SIZE = 4096
)
const (
DEBUG = false
)
Variables ¶
var ( //The refuse heap is a dumping ground for ignored data REFUSE_HEAP = [BUFFER_SIZE]byte{} //Used when we are trying to parse the size of a bulk or multibulk message, and do not receive a valid number ERROR_INVALID_INT = errors.New("Did not receive valid int value") //Used when we inspect a packet, and it is using the deprecated messaging format ERROR_MULTIBULK_FORMAT_REQUIRED = errors.New("Multibulk format is required") //Used when we expect a redis bulk-format payload, and do not receive one ERROR_BAD_BULK_FORMAT = errors.New("Bad bulk format supplied") ERROR_COMMAND_PARSE = errors.New("Command parse error") //Commands declared once for convenience DEL_COMMAND = []byte("del") SUBSCRIBE_COMMAND = []byte("subscribe") UNSUBSCRIBE_COMMAND = []byte("unsubscribe") PING_COMMAND = []byte("ping") INFO_COMMAND = []byte("info") SHORT_PING_COMMAND = []byte("PING") SELECT_COMMAND = []byte("select") QUIT_COMMAND = []byte("quit") //Responses declared once for convenience OK_RESPONSE = []byte("+OK") PONG_RESPONSE = []byte("+PONG") ERR_RESPONSE = []byte("$-1") //Redis expects \r\n newlines. Using this means we can stop remembering that REDIS_NEWLINE = []byte("\r\n") //These functions should not be executed through a proxy. //If you know what you're doing, you are welcome to execute them directly on your server UNSAFE_FUNCTIONS = map[string]bool{ "auth": true, "bgrewriteaof": true, "bgsave": true, "client": true, "config": true, "dbsize": true, "discard": true, "debug": true, "exec": true, "lastsave": true, "move": true, "monitor": true, "migrate": true, "multi": true, "object": true, "punsubscribe": true, "psubscribe": true, "pubsub": true, "randomkey": true, "save": true, "shutdown": true, "slaveof": true, "slowlog": true, "sync": true, "time": true, "unsubscribe": true, "unwatch": true, "watch": true, } //These functions will only work if multiplexing is disabled. //It would be rather worthless to watch on one server, multi on another, and increment on a third SINGLE_DB_FUNCTIONS = map[string]bool{ "bitop": true, "brpoplpush": true, "eval": true, "keys": true, "flushall": true, "flushdb": true, "mget": true, "mset": true, "msetnx": true, "rename": true, "renamenx": true, "rpoplpush": true, "script": true, "sdiff": true, "sdiffstore": true, "sinter": true, "sinterstore": true, "smove": true, "sunion": true, "sunionstore": true, "zinterstore": true, "zunionstore": true, } //Only Publish/Subscribe are supported at this time. Unsubscribe will come later PUBSUB_FUNCTIONS = map[string]bool{ "subscribe": true, } )
Functions ¶
func CopyMultiBulkMessage ¶
func CopyMultiBulkMessage(firstLine []byte, destination *bufio.Writer, source *bufio.Reader) (err error)
Copies a multi bulk message from source to destination, beginning with firstLine If a protocol or a buffer error is encountered, it is bubbled up
func CopyServerResponse ¶
Copies a server response from the remoteBuffer into your localBuffer, beginning with firstLine If a protocol or buffer error is encountered, it is bubbled up
func Debug ¶
func Debug(format string, a ...interface{})
If built with the 'dev' tag, routes through Printf. If not, does nothing. This is exposed publicly so that other packages that use this can optionally use the same build flag
func FlushLine ¶
Writes the given bytes to destination, with a GO_NEWLINE appended, and then flushes the buffer Bubbles up any errors from the underlying writer
func GetCommand ¶
func GetCommand(source *bufio.Reader, command, firstArgument []byte) (commandLength, argumentLength int, err error)
Inspects the incoming payload, and returns the command, and first argument for that command if there is one. If the packet is not in a valid multibulk format, ERROR_MULTIBULK_FORMAT_REQUIRED is returned
func IgnoreMultiBulkMessage ¶
Ignores a multi-bulk message from the source reader, beginning with firstLine Bubbles up any underlying protocol or buffer error
func IsSupportedFunction ¶
Types ¶
type TimedNetReadWriter ¶
type TimedNetReadWriter struct { //The underlying connection used by our remote (redis) connection NetConnection net.Conn //Timeout to use for read operations ReadTimeout time.Duration //Timeout to use for write operations WriteTimeout time.Duration }
A ReadWriter for a NetConnection's read/writer, that allows for sane & reliable timeouts applied to all of its operations
func NewTimedNetReadWriter ¶
func NewTimedNetReadWriter(connection net.Conn, readTimeout, writeTimeout time.Duration) (newReadWriter *TimedNetReadWriter)
Initializes a TimedNetReadWriter, with the given timeouts