Commit bbfb6d12 authored by Levin Zimmermann's avatar Levin Zimmermann

go/client/zurl: Sync format to py upstream

NEO/go and NEO/py zurl format diverged over time:

- kirr/neo@8c974485

However with nexedi/neoppod!21 a
common solution was found. From there, this patch aims to adjust NEO/go zurl
format to be in sync with NEO/py zurl format again.
parent 1ad088c8
...@@ -484,7 +484,7 @@ func openClientByURL(ctx context.Context, u *url.URL, opt *zodb.DriverOptions) ( ...@@ -484,7 +484,7 @@ func openClientByURL(ctx context.Context, u *url.URL, opt *zodb.DriverOptions) (
// parseURL extracts information from a NEO URI and puts this information into // parseURL extracts information from a NEO URI and puts this information into
// a urlInfo. // a urlInfo.
func parseURL(ctx context.Context, u *url.URL) (urlinfo *urlInfo, err error) { func parseURL(ctx context.Context, u *url.URL) (urlinfo *urlInfo, err error) {
// neo(s)://[credentials@]master1,master2,...,masterN/name?options // neo(s)://name@master1,master2,...,masterN?options
var ssl bool var ssl bool
switch u.Scheme { switch u.Scheme {
...@@ -493,49 +493,40 @@ func parseURL(ctx context.Context, u *url.URL) (urlinfo *urlInfo, err error) { ...@@ -493,49 +493,40 @@ func parseURL(ctx context.Context, u *url.URL) (urlinfo *urlInfo, err error) {
default: return nil, fmt.Errorf("invalid scheme") default: return nil, fmt.Errorf("invalid scheme")
} }
cred := u.User.String() name := u.User.String()
// ca=ca.crt;cert=my.crt;key=my.key if name == "" {
cred = strings.ReplaceAll(cred, ";", "&") // ; is no longer in default separators set https://github.com/golang/go/issues/25192 return nil, fmt.Errorf("cluster name not specified")
x, err := xurl.ParseQuery(cred) }
q, err := xurl.ParseQuery(u.RawQuery)
if err != nil { if err != nil {
return nil, fmt.Errorf("credentials: %s", err) return nil, err
} }
// xpop pops k from credentials, defaulting to $NEO_<K> if envok.
xpop := func(k string, envok bool) string { // qpop pops k from query, defaulting to $NEO_<K> if envok.
v, ok := x[k] qpop := func(k string, envok bool) string {
v, ok := q[k]
if !ok && envok { if !ok && envok {
v = os.Getenv("NEO_"+strings.ToUpper(k)) v = os.Getenv("NEO_"+strings.ToUpper(k))
} }
delete(x, k) delete(q, k)
return v return v
} }
netcfg := neonet.Config{} netcfg := neonet.Config{}
netcfg.LoNode = xpop("lonode", false) netcfg.LoNode = qpop("lonode", false)
if !ssl { if !ssl {
if len(x) != 0 { _, ok0 := q["ca"]
_, ok1 := q["cert"]
_, ok2 := q["key"]
if ok0 || ok1 || ok2 {
return nil, fmt.Errorf("credentials can be specified only with neos:// scheme") return nil, fmt.Errorf("credentials can be specified only with neos:// scheme")
} }
} else { } else {
netcfg.CA = xpop("ca", true) netcfg.CA = qpop("ca", true)
netcfg.Cert = xpop("cert", true) netcfg.Cert = qpop("cert", true)
netcfg.Key = xpop("key", true) netcfg.Key = qpop("key", true)
if len(x) != 0 {
return nil, fmt.Errorf("invalid credentials: %v", x)
}
}
name := u.Path
name = strings.TrimPrefix(name, "/")
if name == "" {
return nil, fmt.Errorf("cluster name not specified")
}
q, err := xurl.ParseQuery(u.RawQuery)
if err != nil {
return nil, err
} }
// pop not yet used client options // pop not yet used client options
......
...@@ -175,7 +175,7 @@ func (n *NEOPySrv) clusterName() string { ...@@ -175,7 +175,7 @@ func (n *NEOPySrv) clusterName() string {
} }
func (n *NEOPySrv) URL() string { func (n *NEOPySrv) URL() string {
return fmt.Sprintf("%s%s/%s", n.opt.URLPrefix(), strings.Join(n.masterAddrSlice, ","), n.clusterName()) return fmt.Sprintf("%s%s?%s", n.opt.URLPrefix(), strings.Join(n.masterAddrSlice, ","), n.opt.URLQuery())
} }
func (n *NEOPySrv) LogTail() (string, error) { func (n *NEOPySrv) LogTail() (string, error) {
...@@ -361,7 +361,7 @@ func (n *NEOGoSrv) masterAddrSlice() []string { ...@@ -361,7 +361,7 @@ func (n *NEOGoSrv) masterAddrSlice() []string {
} }
func (n *NEOGoSrv) URL() string { func (n *NEOGoSrv) URL() string {
return fmt.Sprintf("%s%s/%s", n.opt.URLPrefix(), strings.Join(n.masterAddrSlice(), ","), n.opt.name) return fmt.Sprintf("%s%s?%s", n.opt.URLPrefix(), strings.Join(n.masterAddrSlice(), ","), n.opt.URLQuery())
} }
...@@ -391,22 +391,30 @@ func (opt NEOSrvOptions) Key() string { ...@@ -391,22 +391,30 @@ func (opt NEOSrvOptions) Key() string {
} }
// URLPrefix returns start of URL for a NEO server started with opt. // URLPrefix returns start of URL for a NEO server started with opt.
// e.g. neo:// or neos://ca=1;cert=2;key=3@ // e.g. neo://test@ or neos://test@
// To be come complete returned URL has to be appended with host and path parts. // To be come complete returned URL has to be appended with host and query parts.
func (opt NEOSrvOptions) URLPrefix() string { func (opt NEOSrvOptions) URLPrefix() string {
zurl := "" zurl := ""
if !opt.SSL { if !opt.SSL {
zurl = "neo://" zurl = "neo://"
} else { } else {
zurl = "neos://" zurl = "neos://"
zurl += "ca=" + url.QueryEscape(opt.CA()) +";"
zurl += "cert=" + url.QueryEscape(opt.Cert()) +";"
zurl += "key=" + url.QueryEscape(opt.Key())
zurl += "@"
} }
zurl += opt.name
zurl += "@"
return zurl return zurl
} }
func (opt NEOSrvOptions) URLQuery() string {
query := ""
if opt.SSL {
query += "ca=" + url.QueryEscape(opt.CA()) +"&"
query += "cert=" + url.QueryEscape(opt.Cert()) +"&"
query += "key=" + url.QueryEscape(opt.Key())
}
return query
}
// ---------------- // ----------------
...@@ -677,14 +685,14 @@ func TestWatch(t *testing.T) { ...@@ -677,14 +685,14 @@ func TestWatch(t *testing.T) {
// scheme neo(s)://[credentials@]master1,master2,...,masterN/name?options) // scheme neo(s)://[credentials@]master1,master2,...,masterN/name?options)
func TestParseURL(t *testing.T) { func TestParseURL(t *testing.T) {
// Most simple valid URI // Most simple valid URI
testParseURL(t, "neo://127.0.0.1/test", urlInfo{}) testParseURL(t, "neo://test@127.0.0.1", urlInfo{})
// With 2 masters // With 2 masters
testParseURL(t, "neo://127.0.0.1,127.0.0.2/test", urlInfo{masterAddr: "127.0.0.1,127.0.0.2"}) testParseURL(t, "neo://test@127.0.0.1,127.0.0.2", urlInfo{masterAddr: "127.0.0.1,127.0.0.2"})
// With ssl // With ssl
u := "neos://ca=ca;cert=cert;key=key@127.0.0.1/test" u := "neos://test@127.0.0.1?ca=ca&cert=cert&key=key"
testParseURL(t, u, urlInfo{netcfg: neonet.Config{CA: "ca", Cert: "cert", Key: "key"}}) testParseURL(t, u, urlInfo{netcfg: neonet.Config{CA: "ca", Cert: "cert", Key: "key"}})
// With query parameters // With query parameters
u = "neo://127.0.0.1/test?compress=true&logfile=n.log&cache-size=256" u = "neo://test@127.0.0.1/compress=true&logfile=n.log&cache-size=256"
testParseURL(t, u, urlInfo{}) testParseURL(t, u, urlInfo{})
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment