Skip to content

Commit

Permalink
Allow for trailing '/' for Create with FlagSequence (samuel#172)
Browse files Browse the repository at this point in the history
@neolf pointed out that Create calls with FlagSequence flag set can have
a trailing slash.

This replicates what Java check does and allows for a trailing slash for
when Create is called with FlagSequence.
  • Loading branch information
nemith authored and samuel committed Aug 15, 2017
1 parent 8ac67fa commit e6b59f6
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 38 deletions.
26 changes: 13 additions & 13 deletions zk/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,7 @@ func (c *Conn) AddAuth(scheme string, auth []byte) error {
}

func (c *Conn) Children(path string) ([]string, *Stat, error) {
if err := validatePath(path); err != nil {
if err := validatePath(path, false); err != nil {
return nil, nil, err
}

Expand All @@ -916,7 +916,7 @@ func (c *Conn) Children(path string) ([]string, *Stat, error) {
}

func (c *Conn) ChildrenW(path string) ([]string, *Stat, <-chan Event, error) {
if err := validatePath(path); err != nil {
if err := validatePath(path, false); err != nil {
return nil, nil, nil, err
}

Expand All @@ -934,7 +934,7 @@ func (c *Conn) ChildrenW(path string) ([]string, *Stat, <-chan Event, error) {
}

func (c *Conn) Get(path string) ([]byte, *Stat, error) {
if err := validatePath(path); err != nil {
if err := validatePath(path, false); err != nil {
return nil, nil, err
}

Expand All @@ -945,7 +945,7 @@ func (c *Conn) Get(path string) ([]byte, *Stat, error) {

// GetW returns the contents of a znode and sets a watch
func (c *Conn) GetW(path string) ([]byte, *Stat, <-chan Event, error) {
if err := validatePath(path); err != nil {
if err := validatePath(path, false); err != nil {
return nil, nil, nil, err
}

Expand All @@ -963,7 +963,7 @@ func (c *Conn) GetW(path string) ([]byte, *Stat, <-chan Event, error) {
}

func (c *Conn) Set(path string, data []byte, version int32) (*Stat, error) {
if err := validatePath(path); err != nil {
if err := validatePath(path, false); err != nil {
return nil, err
}

Expand All @@ -973,7 +973,7 @@ func (c *Conn) Set(path string, data []byte, version int32) (*Stat, error) {
}

func (c *Conn) Create(path string, data []byte, flags int32, acl []ACL) (string, error) {
if err := validatePath(path); err != nil {
if err := validatePath(path, flags&FlagSequence == FlagSequence); err != nil {
return "", err
}

Expand All @@ -987,7 +987,7 @@ func (c *Conn) Create(path string, data []byte, flags int32, acl []ACL) (string,
// ephemeral node still exists. Therefore, on reconnect we need to check if a node
// with a GUID generated on create exists.
func (c *Conn) CreateProtectedEphemeralSequential(path string, data []byte, acl []ACL) (string, error) {
if err := validatePath(path); err != nil {
if err := validatePath(path, true); err != nil {
return "", err
}

Expand Down Expand Up @@ -1032,7 +1032,7 @@ func (c *Conn) CreateProtectedEphemeralSequential(path string, data []byte, acl
}

func (c *Conn) Delete(path string, version int32) error {
if err := validatePath(path); err != nil {
if err := validatePath(path, false); err != nil {
return err
}

Expand All @@ -1041,7 +1041,7 @@ func (c *Conn) Delete(path string, version int32) error {
}

func (c *Conn) Exists(path string) (bool, *Stat, error) {
if err := validatePath(path); err != nil {
if err := validatePath(path, false); err != nil {
return false, nil, err
}

Expand All @@ -1056,7 +1056,7 @@ func (c *Conn) Exists(path string) (bool, *Stat, error) {
}

func (c *Conn) ExistsW(path string) (bool, *Stat, <-chan Event, error) {
if err := validatePath(path); err != nil {
if err := validatePath(path, false); err != nil {
return false, nil, nil, err
}

Expand All @@ -1081,7 +1081,7 @@ func (c *Conn) ExistsW(path string) (bool, *Stat, <-chan Event, error) {
}

func (c *Conn) GetACL(path string) ([]ACL, *Stat, error) {
if err := validatePath(path); err != nil {
if err := validatePath(path, false); err != nil {
return nil, nil, err
}

Expand All @@ -1090,7 +1090,7 @@ func (c *Conn) GetACL(path string) ([]ACL, *Stat, error) {
return res.Acl, &res.Stat, err
}
func (c *Conn) SetACL(path string, acl []ACL, version int32) (*Stat, error) {
if err := validatePath(path); err != nil {
if err := validatePath(path, false); err != nil {
return nil, err
}

Expand All @@ -1100,7 +1100,7 @@ func (c *Conn) SetACL(path string, acl []ACL, version int32) (*Stat, error) {
}

func (c *Conn) Sync(path string) (string, error) {
if err := validatePath(path); err != nil {
if err := validatePath(path, false); err != nil {
return "", err
}

Expand Down
4 changes: 2 additions & 2 deletions zk/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func stringShuffle(s []string) {
}

// validatePath will make sure a path is valid before sending the request
func validatePath(path string) error {
func validatePath(path string, isSequential bool) error {
if path == "" {
return ErrInvalidPath
}
Expand All @@ -70,7 +70,7 @@ func validatePath(path string) error {
return nil
}

if path[n-1] == '/' {
if !isSequential && path[n-1] == '/' {
return ErrInvalidPath
}

Expand Down
48 changes: 25 additions & 23 deletions zk/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,36 @@ func TestFormatServers(t *testing.T) {
func TestValidatePath(t *testing.T) {
tt := []struct {
path string
seq bool
valid bool
}{
{"/this is / a valid/path", true},
{"/", true},
{"", false},
{"not/valid", false},
{"/ends/with/slash/", false},
{"/test\u0000", false},
{"/double//slash", false},
{"/single/./period", false},
{"/double/../period", false},
{"/double/..ok/period", true},
{"/double/alsook../period", true},
{"/double/period/at/end/..", false},
{"/name/with.period", true},
{"/test\u0001", false},
{"/test\u001f", false},
{"/test\u0020", true}, // first allowable
{"/test\u007e", true}, // last valid ascii
{"/test\u007f", false},
{"/test\u009f", false},
{"/test\uf8ff", false},
{"/test\uffef", true},
{"/test\ufff0", false},
{"/this is / a valid/path", false, true},
{"/", false, true},
{"", false, false},
{"not/valid", false, false},
{"/ends/with/slash/", false, false},
{"/sequential/", true, true},
{"/test\u0000", false, false},
{"/double//slash", false, false},
{"/single/./period", false, false},
{"/double/../period", false, false},
{"/double/..ok/period", false, true},
{"/double/alsook../period", false, true},
{"/double/period/at/end/..", false, false},
{"/name/with.period", false, true},
{"/test\u0001", false, false},
{"/test\u001f", false, false},
{"/test\u0020", false, true}, // first allowable
{"/test\u007e", false, true}, // last valid ascii
{"/test\u007f", false, false},
{"/test\u009f", false, false},
{"/test\uf8ff", false, false},
{"/test\uffef", false, true},
{"/test\ufff0", false, false},
}

for _, tc := range tt {
err := validatePath(tc.path)
err := validatePath(tc.path, tc.seq)
if (err != nil) == tc.valid {
t.Errorf("failed to validate path %q", tc.path)
}
Expand Down

0 comments on commit e6b59f6

Please sign in to comment.