func (c *Connection) Serve() { defer c.Close() defer func() { if e := recover(); e != nil { c.send <- EncodeB64Message("error", []byte(fmt.Sprintf("%v", e))) } }() enque := c.Respond(c.Enque, base64.StdEncoding) deque := c.Respond(c.Deque, base64.StdEncoding) has := c.Respond(c.Has, echoEncoder{}) size := c.Respond(c.Size, echoEncoder{}) use := c.Respond(c.Use, echoEncoder{}) badDecode := c.Respond(c.BadDecode, base64.StdEncoding) b64cmds := func(cmd string, data []byte) { switch cmd { case "ENQUE": enque(data) case "HAS": has(data) } } for line := range netutils.Readlines(c.recv) { command, rest := DecodeCmd(line) switch command { case "ENQUE", "HAS": if rest == nil { badDecode(rest) } else { data, err := DecodeB64(rest) if err != nil { badDecode(rest) } else { b64cmds(command, data) } } case "DEQUE": deque(rest) case "SIZE": size(rest) case "USE": use(rest) default: err := fmt.Errorf("bad command recieved, '%v'", command) log.Println(err.Error()) c.send <- EncodeB64Message("ERROR", []byte(err.Error())) } } }
func (c *connection) serve() { defer c.s.closeConnection(c) c.writeString(cWELCOME) for line := range netutils.Readlines(c.recv) { bSplit := bytes.SplitN(line, []byte(" "), -1) if len(bSplit) < 1 { c.writeString(cERROR) } else { split := make([]string, 0) for _, b := range bSplit { split = append(split, string(bytes.TrimSpace(b))) } c.lastAccessLock.Lock() c.lastAccess = time.Now() c.lastAccessLock.Unlock() switch split[0] { case cPUT: if len(split) != 3 { c.writeString(cERROR) } else { c.s.Put(split[1], split[2]) c.writeString(c*K) if c.s.config.Logging.Put { c.s.logger.Println("(cid:" + strconv.FormatUint(c.cid, 10) + ") put " + split[1] + "=" + split[2]) } } case cGET: if len(split) != 2 { c.writeString(cERROR) } else { value, has := c.s.Get(split[1]) if has { c.writeString(value + "\n") } else { c.writeString(cNIL) } if c.s.config.Logging.Get { c.s.logger.Println("(cid:"+strconv.FormatUint(c.cid, 10)+") get", split[1]) } } case cHASKEY: if len(split) != 2 { c.writeString(cERROR) } else { has := c.s.HasKey(split[1]) if has { c.writeString(cTRUE) } else { c.writeString(cFALSE) } if c.s.config.Logging.Haskey { c.s.logger.Println("(cid:"+strconv.FormatUint(c.cid, 10)+") haskey", split[1]) } } case cHASVALUE: if len(split) != 2 { c.writeString(cERROR) } else { has := c.s.HasValue(split[1]) if has { c.writeString(cTRUE) } else { c.writeString(cFALSE) } if c.s.config.Logging.Haskey { c.s.logger.Println("(cid:"+strconv.FormatUint(c.cid, 10)+") hasvalue", split[1]) } } case cREMOVE: if len(split) != 2 { c.writeString(cERROR) } else { c.s.Remove(split[1]) c.writeString(c*K) if c.s.config.Logging.Remove { c.s.logger.Println("(cid:"+strconv.FormatUint(c.cid, 10)+") remove", split[1]) } } case cSIZE: if len(split) != 1 { c.writeString(cERROR) } else { c.writeString(strconv.Itoa(c.s.Size()) + "\n") if c.s.config.Logging.Size { c.s.logger.Println("(cid:" + strconv.FormatUint(c.cid, 10) + ") size") } } case cCLEAR: if len(split) != 1 { c.writeString(cERROR) } else { c.s.Clear() c.writeString(c*K) if c.s.config.Logging.Clear { c.s.logger.Println("(cid:" + strconv.FormatUint(c.cid, 10) + ") clear") } } case cLIST: if len(split) == 1 || len(split) == 2 { keys, values, size := c.s.List() if size == 0 { c.writeString(cNIL) } else { var buf bytes.Buffer buf.WriteString(strconv.Itoa(size) + "\n") if len(split) == 1 { for i := 0; i < size; i++ { buf.WriteString(keys[i] + "=" + values[i] + "\n") } if c.s.config.Logging.List { c.s.logger.Println("(cid:" + strconv.FormatUint(c.cid, 10) + ") list") } } else { switch split[1] { case cKEYS: for i := 0; i < size; i++ { buf.WriteString(keys[i] + "\n") } if c.s.config.Logging.List_keys { c.s.logger.Println("(cid:" + strconv.FormatUint(c.cid, 10) + ") list keys") } case cVALUES: for i := 0; i < size; i++ { buf.WriteString(values[i] + "\n") } if c.s.config.Logging.List_keys { c.s.logger.Println("(cid:" + strconv.FormatUint(c.cid, 10) + ") list values") } default: buf.WriteString(cERROR) } } c.writeString(buf.String()) } } else { c.writeString(cERROR) } case cQUIT: if len(split) != 1 { c.writeString(cERROR) } else { c.writeString(cBYE) if c.s.config.Logging.Quit { c.s.logger.Println("(cid:" + strconv.FormatUint(c.cid, 10) + ") quit") } return } default: c.writeString(cERROR) if c.s.config.Logging.Invalid_command { c.s.logger.Println("(cid:" + strconv.FormatUint(c.cid, 10) + ") invalid command: " + string(line)) } } } } }