// Ported from: ZooKeeper's PathUtils.java func (p *Path) Init() { p.isValid = false runeCount := 0 runes := make([]rune, len(p.Value)) for i, rune := range p.Value { runes[i] = rune runeCount = runeCount + 1 } if runeCount == 0 { log.Error("Path length must be > 0") return } if runes[0] != '/' { log.Error("Path must start with / character") return } // done checking - it's the root if runeCount == 1 { p.isValid = true return } if runes[runeCount-1] == '/' { log.Error("Path must not end with / character") return } lastRune := rune(0x0000) for i, rune := range runes { if rune == 0x0000 { log.Error(fmt.Sprintf("null character not allowed @%d", i)) return } else if rune == '/' && lastRune == '/' { log.Error(fmt.Sprintf("empty node name specified @%d", i)) return } else if rune == '.' && lastRune == '.' { if runes[i-2] == '/' && ((i+1 == runeCount) || runes[i+1] == '/') { log.Error(fmt.Sprintf("relative paths not allowed @%d", i)) return } } else if rune == '.' { if runes[i-1] == '/' && ((i+1 == runeCount) || runes[i+1] == '/') { log.Error(fmt.Sprintf("relative paths not allowed @%d", i)) return } } else if rune > 0x0000 && rune <= 0x001f || rune >= 0x007f && rune <= 0x009f || rune >= 0xd8f3 && rune <= 0xf8ff || rune >= 0xfff0 && rune <= 0xffff { log.Error(fmt.Sprintf("invalid charater @%d", i)) return } lastRune = rune } p.isValid = true }
func (k *Keeper) requestLoop(t *tomb.Tomb) error { for { select { case buf := <-k.recvChan: // current & total bytes read bytesRead := 0 totalBytesRead := 0 // parse request header reqHdr := &OpReqHeader{} bytesRead, err := DecodePacket(buf, reqHdr) totalBytesRead = totalBytesRead + bytesRead if err != nil { log.Error(fmt.Sprintf("unable to decode request header: %s", err.Error())) return err } // create request creator, found := creatorByOpCode[reqHdr.OpCode] if !found { log.Error(fmt.Sprintf("cannot create opcode: %d", reqHdr.OpCode)) return err } // parse request req := creator() bytesRead, err = DecodePacket(buf[bytesRead:], req) totalBytesRead = totalBytesRead + bytesRead if err != nil { log.Error(fmt.Sprintf("unable to decode request: %s", err.Error())) return err } // queue processor k.processorChan <- func() error { processOpReq(OpReq{Hdr: reqHdr, Req: req}, k.storeClient, k.sendChan) if reqHdr.OpCode == opClose { return errors.New("graceful connection close requested") } return nil } case <-t.Dying(): close(k.recvChan) return nil } } }
func mapBackendError(err *kv.Error) int32 { errCode := err.Code() keeperErr, found := keeperErrFromBackendErr[errCode] if !found { log.Error(fmt.Sprintf("unexpected client error: ", errCode)) return errSystemError } return keeperErr }
func processOpReq(opReq OpReq, storeClient kv.Client, sendChan chan Rep) { // find processor processor, found := processorByOpCode[opReq.Hdr.OpCode] if !found { log.Error(fmt.Sprintf("cannot process opcode: %d", opReq.Hdr.OpCode)) return } // process request & write rep (if needed) rep := processor(opReq, storeClient) if rep != nil { sendChan <- rep } }