Commit ae571d96 authored by Levin Zimmermann's avatar Levin Zimmermann

client: Adjust URI scheme to move client-specific options to fragment

This is the NEO/go patch part of
kirr/neo@4c9414ea.

The rationale for this move is described there:

-------------------8>--------------------

For example option `compress` controls kind of compression that _client_
performs when saving data to server. Similarly cache-size, logfile and
read-only adjust on-client behaviour, not server.

From nexedi/neoppod!18 (comment 124725) :

    In general the most correct thing to do is:

    - use host part for where to connect (host:port, list of host ports, UNIX socket, etc)
    - use path part to identify a database or other on-server resource
    - use query part for parameters that are passed to remote server (e.g. `storage` in case of ZEO)
    - use fragment part for local parameters that are not passed to remote server (e.g. local `logfile`)
    - use credentials part for things required to authenticate/encrypt.

    To normalize an URL wcfs client would drop credentials and fragment, but keep host, path and query.

    Fragments are documented not to be sent to remote side and to be evaluated by local side only.

-> Move options that control client behaviour to fragment.

-------------------<8--------------------
parent 59d136b7
...@@ -482,7 +482,7 @@ func openClientByURL(ctx context.Context, u *url.URL, opt *zodb.DriverOptions) ( ...@@ -482,7 +482,7 @@ func openClientByURL(ctx context.Context, u *url.URL, opt *zodb.DriverOptions) (
// a NEOUrlInfo and the DriverOptions. If anything fails within this process // a NEOUrlInfo and the DriverOptions. If anything fails within this process
// an error and an empty NEOUrlInfo are returned. // an error and an empty NEOUrlInfo are returned.
func parseURL(ctx context.Context, u *url.URL, opt *zodb.DriverOptions) (urlinfo NEOUrlInfo, err error) { func parseURL(ctx context.Context, u *url.URL, opt *zodb.DriverOptions) (urlinfo NEOUrlInfo, err error) {
// neo(s)://[credentials@]master1,master2,...,masterN/name?options // neo(s)://[credentials@]master1,master2,...,masterN/name?server_options#client_options
var ssl bool var ssl bool
switch u.Scheme { switch u.Scheme {
...@@ -536,10 +536,19 @@ func parseURL(ctx context.Context, u *url.URL, opt *zodb.DriverOptions) (urlinfo ...@@ -536,10 +536,19 @@ func parseURL(ctx context.Context, u *url.URL, opt *zodb.DriverOptions) (urlinfo
return NEOUrlInfo{}, err return NEOUrlInfo{}, err
} }
if len(q) != 0 {
return NEOUrlInfo{}, fmt.Errorf("invalid query: %v", q)
}
f, err := xurl.ParseQuery(u.Fragment)
if err != nil {
return NEOUrlInfo{}, err
}
// mv readonly from URL => driver opts // mv readonly from URL => driver opts
readOnly, ok := q["read-only"] readOnly, ok := f["read-only"]
if ok { if ok {
delete(q, "read-only") delete(f, "read-only")
r, err := strconv.ParseBool(readOnly) r, err := strconv.ParseBool(readOnly)
if err != nil { if err != nil {
return NEOUrlInfo{}, err return NEOUrlInfo{}, err
...@@ -550,15 +559,15 @@ func parseURL(ctx context.Context, u *url.URL, opt *zodb.DriverOptions) (urlinfo ...@@ -550,15 +559,15 @@ func parseURL(ctx context.Context, u *url.URL, opt *zodb.DriverOptions) (urlinfo
// pop not yet used client options // pop not yet used client options
// (our neo client doesn't apply their effect yet) // (our neo client doesn't apply their effect yet)
for _, k := range []string {"compress", "cache-size", "logfile"} { for _, k := range []string {"compress", "cache-size", "logfile"} {
_, ok := q[k] _, ok := f[k]
if ok { if ok {
delete(q, k) delete(f, k)
log.Warningf(ctx, "TODO client doesn't support option '%q' yet", k) log.Warningf(ctx, "TODO client doesn't support option '%q' yet", k)
} }
} }
if len(q) != 0 { if len(f) != 0 {
return NEOUrlInfo{}, fmt.Errorf("invalid query: %v", q) return NEOUrlInfo{}, fmt.Errorf("invalid fragment: %v", f)
} }
if !opt.ReadOnly { if !opt.ReadOnly {
......
...@@ -599,7 +599,7 @@ func TestWatch(t *testing.T) { ...@@ -599,7 +599,7 @@ func TestWatch(t *testing.T) {
} }
// TestParseURL ensures that parsing NEO URL works as expected (= following the // TestParseURL ensures that parsing NEO URL works as expected (= following the
// scheme neo(s)://[credentials@]master1,master2,...,masterN/name?options) // scheme neo(s)://[credentials@]master1,master2,...,masterN/name?server_options#client_options)
func TestParseURL(t *testing.T) { func TestParseURL(t *testing.T) {
o := zodb.DriverOptions{ReadOnly: true} o := zodb.DriverOptions{ReadOnly: true}
i := NEOUrlInfo{} i := NEOUrlInfo{}
...@@ -611,8 +611,8 @@ func TestParseURL(t *testing.T) { ...@@ -611,8 +611,8 @@ func TestParseURL(t *testing.T) {
// With ssl // With ssl
i.netcfg = neonet.Config{CA: "ca", Cert: "cert", Key: "key"} i.netcfg = neonet.Config{CA: "ca", Cert: "cert", Key: "key"}
testParseURL(t, "neos://ca=ca;cert=cert;key=key@127.0.0.1/test", &i, o, o) testParseURL(t, "neos://ca=ca;cert=cert;key=key@127.0.0.1/test", &i, o, o)
// With query parameters // With fragment (= client) parameters
testParseURL(t, "neo://127.0.0.1/test?read-only=true&compress=true&logfile=n.log&cache-size=256", &i, zodb.DriverOptions{}, o) testParseURL(t, "neo://127.0.0.1/test#read-only=true&compress=true&logfile=n.log&cache-size=256", &i, zodb.DriverOptions{}, o)
} }
// testParseURL tests one zurl for correctness by comparing its parsed // testParseURL tests one zurl for correctness by comparing its parsed
......
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