Esempio n. 1
0
func (s *Session) handleSelect(r *Request) (*Request, error) {
	if len(r.Resp.Array) != 2 {
		r.Response.Resp = redis.NewError([]byte("ERR wrong number of arguments for 'SELECT' command"))
		return r, nil
	}
	if db, err := strconv.Atoi(string(r.Resp.Array[1].Value)); err != nil {
		r.Response.Resp = redis.NewError([]byte("ERR invalid DB index"))
		return r, nil
	} else if db != 0 {
		r.Response.Resp = redis.NewError([]byte("ERR invalid DB index, only accept DB 0"))
		return r, nil
	} else {
		r.Response.Resp = redis.NewString([]byte("OK"))
		return r, nil
	}
}
Esempio n. 2
0
func (s *Session) handlePing(r *Request) (*Request, error) {
	if len(r.Resp.Array) != 1 {
		r.Response.Resp = redis.NewError([]byte("ERR wrong number of arguments for 'PING' command"))
		return r, nil
	}
	r.Response.Resp = redis.NewString([]byte("PONG"))
	return r, nil
}
Esempio n. 3
0
func (s *Session) handleAuth(r *Request) (*Request, error) {
	if len(r.Resp.Array) != 2 {
		r.Response.Resp = redis.NewError([]byte("ERR wrong number of arguments for 'AUTH' command"))
		return r, nil
	}
	if s.auth == "" {
		r.Response.Resp = redis.NewError([]byte("ERR Client sent AUTH, but no password is set"))
		return r, nil
	}
	if s.auth != string(r.Resp.Array[1].Value) {
		s.authorized = false
		r.Response.Resp = redis.NewError([]byte("ERR invalid password"))
		return r, nil
	} else {
		s.authorized = true
		r.Response.Resp = redis.NewString([]byte("OK"))
		return r, nil
	}
}
Esempio n. 4
0
func (s *Session) handleRequest(resp *redis.Resp) (*Request, error) {
	opstr, err := getOpStr(resp)
	log.Infof("In handleRequest, opstr is %s", string(opstr))
	if err != nil {
		return nil, err
	}
	if isNotAllowed(opstr) {
		return nil, errors.New(fmt.Sprintf("command <%s> is not allowed", opstr))
	}

	usnow := microseconds()
	s.LastOpUnix = usnow / 1e6
	s.Ops++

	r := &Request{
		OpStr:  opstr,
		Start:  usnow,
		Resp:   resp,
		Wait:   &sync.WaitGroup{},
		Failed: &s.failed,
	}

	if opstr == "QUIT" {
		return s.handleQuit(r)
	}
	if opstr == "AUTH" {
		return s.handleAuth(r)
	}

	if !s.authorized {
		if s.auth != "" {
			r.Response.Resp = redis.NewError([]byte("NOAUTH Authentication required."))
			return r, nil
		}
		s.authorized = true
	}

	switch opstr {
	case "SELECT":
		return s.handleSelect(r)
	case "PING":
		return s.handlePing(r)
	case "MGET":
		return s.handleRequestMGet(r)
	case "MSET":
		return s.handleRequestMSet(r)
	case "DEL":
		return s.handleRequestMDel(r)
	}
	return r, s.GetDispather().Dispatch(r)
}
Esempio n. 5
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
}