@@ -16,6 +16,7 @@ import (
1616 "fmt"
1717 "io"
1818 "net"
19+ "reflect"
1920 "strconv"
2021 "strings"
2122 "sync"
@@ -73,6 +74,7 @@ type Conn struct {
7374 xid uint32
7475 sessionTimeoutMs int32 // session timeout in milliseconds
7576 passwd []byte
77+ chroot string
7678
7779 dialer Dialer
7880 hostProvider HostProvider
@@ -196,6 +198,7 @@ func Connect(servers []string, sessionTimeout time.Duration, options ...connOpti
196198 requests : make (map [int32 ]* request ),
197199 watchers : make (map [watchPathType ][]chan Event ),
198200 passwd : emptyPassword ,
201+ chroot : "" ,
199202 logger : DefaultLogger ,
200203 buf : make ([]byte , bufferSize ),
201204
@@ -611,6 +614,19 @@ func (c *Conn) sendData(req *request) error {
611614 return nil
612615 }
613616
617+ if req != nil && req .pkt != nil && c .chroot != "" {
618+ v := reflect .ValueOf (req .pkt )
619+ for v .Kind () == reflect .Ptr || v .Kind () == reflect .Interface {
620+ v = v .Elem ()
621+ }
622+ if v .Kind () == reflect .Struct {
623+ field := v .FieldByName ("Path" )
624+ if field .Kind () == reflect .String {
625+ field .SetString (c .chroot + field .String ())
626+ }
627+ }
628+ }
629+
614630 n2 , err := encodePacket (c .buf [4 + n :], req .pkt )
615631 if err != nil {
616632 req .recvChan <- response {- 1 , err }
@@ -708,6 +724,9 @@ func (c *Conn) recvLoop(conn net.Conn) error {
708724 if err != nil {
709725 return err
710726 }
727+ if c .chroot != "" {
728+ res .Path = strings .TrimPrefix (res .Path , c .chroot )
729+ }
711730 ev := Event {
712731 Type : res .Type ,
713732 State : res .State ,
@@ -760,6 +779,19 @@ func (c *Conn) recvLoop(conn net.Conn) error {
760779 } else {
761780 _ , err = decodePacket (buf [16 :blen ], req .recvStruct )
762781 }
782+
783+ if req != nil && req .recvStruct != nil && c .chroot != "" {
784+ v := reflect .ValueOf (req .recvStruct )
785+ for v .Kind () == reflect .Ptr || v .Kind () == reflect .Interface {
786+ v = v .Elem ()
787+ }
788+ if v .Kind () == reflect .Struct {
789+ field := v .FieldByName ("Path" )
790+ if field .Kind () == reflect .String {
791+ field .SetString (strings .TrimPrefix (field .String (), c .chroot ))
792+ }
793+ }
794+ }
763795 if req .recvFunc != nil {
764796 req .recvFunc (req , & res , err )
765797 }
@@ -804,6 +836,16 @@ func (c *Conn) request(opcode int32, req interface{}, res interface{}, recvFunc
804836 return r .zxid , r .err
805837}
806838
839+ func (c * Conn ) Chroot (path string ) error {
840+ res := & existsResponse {}
841+ _ , err := c .request (opExists , & existsRequest {Path : path , Watch : false }, res , nil )
842+ if err != nil {
843+ return err
844+ }
845+ c .chroot = path
846+ return nil
847+ }
848+
807849func (c * Conn ) AddAuth (scheme string , auth []byte ) error {
808850 _ , err := c .request (opSetAuth , & setAuthRequest {Type : 0 , Scheme : scheme , Auth : auth }, & setAuthResponse {}, nil )
809851
0 commit comments