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 }
// 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 (ps *ProxyServer) Dispatch(req *redis.Request) redis.Cmder { name := req.Name() method, ok := ps.RedisMethod[name] if !ok { method = reflect.ValueOf(ps.Backend).MethodByName("On" + name) ps.RedisMethod[name] = method } if method.IsValid() { in := []reflect.Value{reflect.ValueOf(req)} callResult := method.Call(in) if callResult[0].Interface() != nil { return callResult[0].Interface().(redis.Cmder) } } else { return ps.Backend.OnReflectUnvalid(req) } return ps.Backend.OnUnDenfined(req) }
func (s *Session) SpecCommandProcess(req *redis.Request) { // log.Info("Spec command Process ", req) switch req.Name() { case "SINTERSTORE": s.SINTERSTORE(req) case "SMOVE": s.SMOVE(req) case "DEL": s.DEL(req) case "RPOPLPUSH": s.RPOPLPUSH(req) case "SDIFFSTORE": s.SDIFFSTORE(req) case "SINTER": s.SINTER(req) case "SDIFF": s.SDIFF(req) case "MGET": s.MGET(req) case "ZINTERSTORE": s.ZINTERSTORE(req) case "ZUNIONSTORE": s.ZUNIONSTORE(req) case "RENAME": s.RENAME(req) case "RENAMENX": s.RENAMENX(req) case "MSET": s.MSET(req) case "MSETNX": s.MSETNX(req) case "PROXY": s.PROXY(req) default: log.Fatalf("Unknown Spec Command: %s, we won't expect this happen ", req.Name()) } }