// buf, shouldClose, handled, err func preCheckCommand(req *redis.Request) ([]byte, bool, bool, error) { var reply []byte shouldClose := false if req.Len() == 0 { return reply, false, true, BadCommandError } cmd := req.Name() switch cmd { case "PING": reply = []byte("+PONG\r\n") case "QUIT": reply = OK_BYTES shouldClose = true case "SELECT": //支持 select,但是到后台全部都用的 db 0 //hia hia hia hia 没办法。。。 reply = OK_BYTES case "AUTH": reply = OK_BYTES case "ECHO": if len(req.Args()) == 1 { echo := fmt.Sprintf("+%s\r\n", req.Args()[0]) return []byte(echo), false, true, nil } else { return nil, false, true, WrongArgumentCount } } if len(reply) > 0 { return reply, shouldClose, true, nil } if err := verifyCommand(req); err != nil { return nil, shouldClose, true, err } if len(req.Args()) >= 1 { if _, ok := BlackKeyLists[req.Args()[0]]; ok { // key blacked reply = []byte("-key already be blacked \r\n") return reply, shouldClose, true, nil } } return reply, shouldClose, false, nil }
func verifyCommand(req *redis.Request) error { if req == nil || req.Len() == 0 { return BadCommandError } name := req.Name() if _, ok := blackList[name]; ok { return CommandForbidden } rule, exist := reqrules[name] if !exist { // may return an error ? return BadCommandError } for i, count := 0, len(rule); i < count; i++ { switch i { case RI_MinCount: if val := rule[i].(int); val != -1 && req.Len() < val { return WrongArgumentCount } case RI_MaxCount: if val := rule[i].(int); val != -1 && req.Len() > val { return WrongArgumentCount } } } return nil }