Пример #1
0
func (bc *BackendConn) verifyAuth(c *redis.Conn) error {
	if bc.auth == "" {
		return nil
	}
	resp := redis.NewArray([]*redis.Resp{
		redis.NewBulkBytes([]byte("AUTH")),
		redis.NewBulkBytes([]byte(bc.auth)),
	})

	if err := c.Writer.Encode(resp, true); err != nil {
		return err
	}

	resp, err := c.Reader.Decode()
	if err != nil {
		return err
	}
	if resp == nil {
		return errors.New(fmt.Sprintf("error resp: nil response"))
	}
	if resp.IsError() {
		return errors.New(fmt.Sprintf("error resp: %s", resp.Value))
	}
	if resp.IsString() {
		return nil
	} else {
		return errors.New(fmt.Sprintf("error resp: should be string, but got %s", resp.Type))
	}
}
Пример #2
0
func (s *Session) handleRequestMGet(r *Request) (*Request, error) {
	nkeys := len(r.Resp.Array) - 1
	if nkeys <= 1 {
		return r, s.GetDispather().Dispatch(r)
	}
	var sub = make([]*Request, nkeys)
	for i := 0; i < len(sub); i++ {
		sub[i] = &Request{
			OpStr: r.OpStr,
			Start: r.Start,
			Resp: redis.NewArray([]*redis.Resp{
				r.Resp.Array[0],
				r.Resp.Array[i+1],
			}),
			Wait:   r.Wait,
			Failed: r.Failed,
		}
		if err := s.GetDispather().Dispatch(sub[i]); err != nil {
			return nil, err
		}
	}
	r.Coalesce = func() error {
		var array = make([]*redis.Resp, len(sub))
		for i, x := range sub {
			if err := x.Response.Err; err != nil {
				return err
			}
			resp := x.Response.Resp
			if resp == nil {
				return ErrRespIsRequired
			}
			if !resp.IsArray() || len(resp.Array) != 1 {
				return errors.New(fmt.Sprintf("bad mget resp: %s array.len = %d", resp.Type, len(resp.Array)))
			}
			array[i] = resp.Array[0]
		}
		r.Response.Resp = redis.NewArray(array)
		return nil
	}
	return r, nil
}
Пример #3
0
func (bc *BackendConn) KeepAlive() bool {
	if len(bc.input) != 0 {
		return false
	}
	r := &Request{
		Resp: redis.NewArray([]*redis.Resp{
			redis.NewBulkBytes([]byte("PING")),
		}),
	}

	select {
	case bc.input <- r:
		return true
	default:
		return false
	}
}
Пример #4
0
func (s *Session) handleRequestMSet(r *Request) (*Request, error) {
	nblks := len(r.Resp.Array) - 1
	if nblks <= 2 {
		return r, s.GetDispather().Dispatch(r)
	}
	if nblks%2 != 0 {
		r.Response.Resp = redis.NewError([]byte("ERR wrong number of arguments for 'MSET' command"))
		return r, nil
	}
	var sub = make([]*Request, nblks/2)
	for i := 0; i < len(sub); i++ {
		sub[i] = &Request{
			OpStr: r.OpStr,
			Start: r.Start,
			Resp: redis.NewArray([]*redis.Resp{
				r.Resp.Array[0],
				r.Resp.Array[i*2+1],
				r.Resp.Array[i*2+2],
			}),
			Wait:   r.Wait,
			Failed: r.Failed,
		}
		if err := s.GetDispather().Dispatch(sub[i]); err != nil {
			return nil, err
		}
	}
	r.Coalesce = func() error {
		for _, x := range sub {
			if err := x.Response.Err; err != nil {
				return err
			}
			resp := x.Response.Resp
			if resp == nil {
				return ErrRespIsRequired
			}
			if !resp.IsString() {
				return errors.New(fmt.Sprintf("bad mset resp: %s value.len = %d", resp.Type, len(resp.Value)))
			}
			r.Response.Resp = resp
		}
		return nil
	}
	return r, nil
}
Пример #5
0
func (s *Session) handleRequestMDel(r *Request) (*Request, error) {
	nkeys := len(r.Resp.Array) - 1
	if nkeys <= 1 {
		return r, s.GetDispather().Dispatch(r)
	}
	var sub = make([]*Request, nkeys)
	for i := 0; i < len(sub); i++ {
		sub[i] = &Request{
			OpStr: r.OpStr,
			Start: r.Start,
			Resp: redis.NewArray([]*redis.Resp{
				r.Resp.Array[0],
				r.Resp.Array[i+1],
			}),
			Wait:   r.Wait,
			Failed: r.Failed,
		}
		if err := s.GetDispather().Dispatch(sub[i]); err != nil {
			return nil, err
		}
	}
	r.Coalesce = func() error {
		var n int
		for _, x := range sub {
			if err := x.Response.Err; err != nil {
				return err
			}
			resp := x.Response.Resp
			if resp == nil {
				return ErrRespIsRequired
			}
			if !resp.IsInt() || len(resp.Value) != 1 {
				return errors.New(fmt.Sprintf("bad mdel resp: %s value.len = %d", resp.Type, len(resp.Value)))
			}
			if resp.Value[0] != '0' {
				n++
			}
		}
		r.Response.Resp = redis.NewInt([]byte(strconv.Itoa(n)))
		return nil
	}
	return r, nil
}
Пример #6
0
func TestGetOpStr(t *testing.T) {
	var m = map[string]string{
		"get":     "GET",
		"aBc":     "ABC",
		"おはよ":     "おはよ",
		"ni hao!": "NI HAO!",
		"":        "",
	}
	for k, v := range m {
		resp := redis.NewArray([]*redis.Resp{redis.NewBulkBytes([]byte(k))})
		s, err := getOpStr(resp)
		if v != "" {
			assert.MustNoError(err)
			assert.Must(s == v)
		} else {
			assert.Must(err != nil)
		}
	}
}
Пример #7
0
func (s *Slot) slotsmgrt(r *Request, key []byte) error {
	if len(key) == 0 || s.migrate.bc == nil {
		return nil
	}
	m := &Request{
		Resp: redis.NewArray([]*redis.Resp{
			redis.NewBulkBytes([]byte("SLOTSMGRTTAGONE")),
			redis.NewBulkBytes(s.backend.host),
			redis.NewBulkBytes(s.backend.port),
			redis.NewBulkBytes([]byte("3000")),
			redis.NewBulkBytes(key),
		}),
		Wait: &sync.WaitGroup{},
	}
	s.migrate.bc.PushBack(m)

	m.Wait.Wait()

	resp, err := m.Response.Resp, m.Response.Err
	if err != nil {
		return err
	}
	if resp == nil {
		return ErrRespIsRequired
	}
	if resp.IsError() {
		return errors.New(fmt.Sprintf("error resp: %s", resp.Value))
	}
	if resp.IsInt() {
		log.Debugf("slot-%04d migrate from %s to %s: key = %s, resp = %s",
			s.id, s.migrate.from, s.backend.addr, key, resp.Value)
		return nil
	} else {
		return errors.New(fmt.Sprintf("error resp: should be integer, but got %s", resp.Type))
	}
}
Пример #8
0
func TestGetOpStrCmd(t *testing.T) {
	var m = map[string]string{
		"del":              "DEL",
		"dump":             "DUMP",
		"exists":           "EXISTS",
		"expire":           "EXPIRE",
		"expireat":         "EXPIREAT",
		"persist":          "PERSIST",
		"pexpire":          "PEXPIRE",
		"pexpireat":        "PEXPIREAT",
		"pttl":             "PTTL",
		"restore":          "RESTORE",
		"sort":             "SORT",
		"ttl":              "TTL",
		"type":             "TYPE",
		"append":           "APPEND",
		"bitcount":         "BITCOUNT",
		"decr":             "DECR",
		"decrby":           "DECRBY",
		"get":              "GET",
		"getbit":           "GETBIT",
		"getrange":         "GETRANGE",
		"getset":           "GETSET",
		"incr":             "INCR",
		"incrby":           "INCRBY",
		"incrbyfloat":      "INCRBYFLOAT",
		"mget":             "MGET",
		"mset":             "MSET",
		"psetex":           "PSETEX",
		"set":              "SET",
		"setbit":           "SETBIT",
		"setex":            "SETEX",
		"setnx":            "SETNX",
		"setrange":         "SETRANGE",
		"strlen":           "STRLEN",
		"hdel":             "HDEL",
		"hexists":          "HEXISTS",
		"hget":             "HGET",
		"hgetall":          "HGETALL",
		"hincrby":          "HINCRBY",
		"hincrbyfloat":     "HINCRBYFLOAT",
		"hkeys":            "HKEYS",
		"hlen":             "HLEN",
		"hmget":            "HMGET",
		"hmset":            "HMSET",
		"hset":             "HSET",
		"hsetnx":           "HSETNX",
		"hvals":            "HVALS",
		"hscan":            "HSCAN",
		"lindex":           "LINDEX",
		"linsert":          "LINSERT",
		"llen":             "LLEN",
		"lpop":             "LPOP",
		"lpush":            "LPUSH",
		"lpushx":           "LPUSHX",
		"lrange":           "LRANGE",
		"lrem":             "LREM",
		"lset":             "LSET",
		"ltrim":            "LTRIM",
		"rpop":             "RPOP",
		"rpoplpush":        "RPOPLPUSH",
		"rpush":            "RPUSH",
		"rpushx":           "RPUSHX",
		"sadd":             "SADD",
		"scard":            "SCARD",
		"sdiff":            "SDIFF",
		"sdiffstore":       "SDIFFSTORE",
		"sinter":           "SINTER",
		"sinterstore":      "SINTERSTORE",
		"sismember":        "SISMEMBER",
		"smembers":         "SMEMBERS",
		"smove":            "SMOVE",
		"spop":             "SPOP",
		"srandmember":      "SRANDMEMBER",
		"srem":             "SREM",
		"sunion":           "SUNION",
		"sunionstore":      "SUNIONSTORE",
		"sscan":            "SSCAN",
		"zadd":             "ZADD",
		"zcard":            "ZCARD",
		"zcount":           "ZCOUNT",
		"zincrby":          "ZINCRBY",
		"zinterstore":      "ZINTERSTORE",
		"zlexcount":        "ZLEXCOUNT",
		"zrange":           "ZRANGE",
		"zrangebylex":      "ZRANGEBYLEX",
		"zrangebyscore":    "ZRANGEBYSCORE",
		"zrank":            "ZRANK",
		"zrem":             "ZREM",
		"zremrangebylex":   "ZREMRANGEBYLEX",
		"zremrangebyrank":  "ZREMRANGEBYRANK",
		"zremrangebyscore": "ZREMRANGEBYSCORE",
		"zrevrange":        "ZREVRANGE",
		"zrevrangebyscore": "ZREVRANGEBYSCORE",
		"zrevrank":         "ZREVRANK",
		"zscore":           "ZSCORE",
		"zunionstore":      "ZUNIONSTORE",
		"zscan":            "ZSCAN",
		"pfadd":            "PFADD",
		"pfcount":          "PFCOUNT",
		"pfmerge":          "PFMERGE",
		"eval":             "EVAL",
		"evalsha":          "EVALSHA",
	}
	for k, v := range m {
		resp := redis.NewArray([]*redis.Resp{redis.NewBulkBytes([]byte(k))})
		s, err := getOpStr(resp)
		assert.MustNoError(err)
		assert.Must(s == v)
	}
}