Beispiel #1
0
// 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
}
Beispiel #2
0
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
		}
	}
}
Beispiel #3
0
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
}
Beispiel #4
0
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
	}
}