Esempio n. 1
0
func (c *client) request(cmd string, to string, payload string) (Response, error) {
	var r Response
	if c.RequestChecks {
		if !ssmp.IsValidIdentifier(to) {
			return r, ErrInvalidIdentifier
		}
		n := len(payload)
		if n > 0 {
			b := payload[0]
			if b >= 0 && b <= 3 {
				// binary payload: length prefix must match
				if n < 3 {
					return r, ErrInvalidPayload
				}
				sz := 3 + (int(b) << 8) + (int(payload[1]) & 0xff)
				if len(payload) != sz {
					return r, ErrInvalidPayload
				}
			} else if n > 1024 {
				return r, ErrRequestTooLarge
			} else if strings.ContainsAny(payload, "\x00\x01\x02\x03\n") {
				return r, ErrInvalidPayload
			}
		}
	}
	buf := bufPool.Get().(*bytes.Buffer)
	buf.Reset()
	buf.WriteString(cmd)
	if len(to) > 0 {
		buf.WriteByte(' ')
		buf.WriteString(to)
	}
	if len(payload) > 0 {
		buf.WriteByte(' ')
		buf.WriteString(payload)
	}
	buf.WriteByte('\n')
	_, err := c.c.Write(buf.Bytes())
	bufPool.Put(buf)
	if err != nil {
		c.c.Close()
		return r, err
	}
	r = <-c.responses
	if r.Code == 0 {
		return r, fmt.Errorf("connection closed")
	}
	return r, nil
}
Esempio n. 2
0
func (c *client) request(cmd string, to string, payload string) (Response, error) {
	var r Response
	if c.RequestChecks {
		if !ssmp.IsValidIdentifier(to) {
			return r, ErrInvalidIdentifier
		}
		// quick size check, before allocating buffer
		if len(cmd)+len(to)+len(payload) > 1022 {
			return r, ErrRequestTooLarge
		}
		if strings.Contains(payload, "\n") {
			return r, ErrInvalidPayload
		}
	}
	buf := bufPool.Get().(*bytes.Buffer)
	buf.Reset()
	buf.WriteString(cmd)
	if len(to) > 0 {
		buf.WriteByte(' ')
		buf.WriteString(to)
	}
	if len(payload) > 0 {
		buf.WriteByte(' ')
		buf.WriteString(payload)
	}
	buf.WriteByte('\n')
	if c.RequestChecks && buf.Len() > 1024 {
		return r, ErrRequestTooLarge
	}
	_, err := c.c.Write(buf.Bytes())
	bufPool.Put(buf)
	if err != nil {
		c.c.Close()
		return r, err
	}
	r = <-c.responses
	if r.Code == 0 {
		return r, fmt.Errorf("connection closed")
	}
	return r, nil
}