func (s *Session) ExecWithRedirect(req *ArrayResp, redirect bool) (Resp, error) { //ensure req.Args[1].Args[0] is key rc, err := s.GetRedisConnByKey(req.Args[1].Args[0], false) if err != nil { log.Warning("ExecWithRedirect GetRedisConnByKey get conn failed ", err) return nil, err } //reclaim RedisConn defer s.p.cluster.PutConn(rc) var resp Resp resp, err = s.ExecOnce(rc, req) if err != nil { log.Warning("Session forward ReadProtocol error ", err) return nil, err } er, ok := resp.(*ErrorResp) if ok { //-MOVED 15495 10.10.200.11:6481 redirect to target //-ASK 15495 10.10.200.11:6481 redirect to target,send ASKING command and then real ArrayResp //handle error response e := strings.Fields(hack.String(er.Args[0])) if len(e) == 3 && redirect { switch e[0] { case "MOVED": //we need reload Slots Info s.p.cluster.topo.reloadChan <- 1 resp = s.Redirect("MOVED", req, e[2]) case "ASK": //need not reload Slots Info, wait Migrate Done resp = s.Redirect("ASK", req, e[2]) } } } return resp, nil }
func (s *StrFilter) Inspect(r Resp) (string, error) { ar, ok := r.(*ArrayResp) if !ok { return "", InspectArgWrong } cmd := hack.String(util.UpperSlice(ar.Args[0].Args[0])) l := ar.Length() + 1 // 黑名单 if _, ok := blackList[cmd]; ok { return "", CommandForbidden } // 规则检查,参数数量 rule, exists := reqrules[cmd] if !exists { return "", BadCommandError } for i, count := 0, len(rule); i < count; i++ { switch i { case RI_MinCount: if val := rule[i].(int); val != -1 && l < val { return "", WrongArgumentCount } case RI_MaxCount: if val := rule[i].(int); val != -1 && l > val { return "", WrongArgumentCount } } } return cmd, nil }