Commit 20498b2f authored by Levin Zimmermann's avatar Levin Zimmermann Committed by Kirill Smelkov

zstor_2zurl: Fix ipv6 host for NEO/ZEO + test fix

This patch allows using WCFS with a NEO or ZEO storage which is
reachable by a URL which contains an ipv6 host.

Without this patch the following example doesn't work:

>>> from wendelin.lib.zodb import dbopen
>>> root = dbopen("neo://cluster-name@[::1]:2051")
>>> # "abc" points to a ZBigArray
>>> root["abc"][0]

It doesn't work because the parser missed adding square brackets around
ipv6 hosts, due to which unparsing the resulting URL resulted in a wrong
interpretation where a port starts.

This patch furthermore amends 'test_zstor_2zurl' to test ZEO and NEO
storages with ipv6 hosts.

---

/reviewed-by @kirr
/reviewed-on nexedi/wendelin.core!13
parent 0a09d51e
...@@ -519,8 +519,12 @@ def test_zstor_2zurl(tmpdir, neo_ssl_dict): ...@@ -519,8 +519,12 @@ def test_zstor_2zurl(tmpdir, neo_ssl_dict):
_(zeo("test", "/path/to/zeo.sock"), "zeo:///path/to/zeo.sock?storage=test") # + non-default storage name _(zeo("test", "/path/to/zeo.sock"), "zeo:///path/to/zeo.sock?storage=test") # + non-default storage name
_(zeo("1", ("127.0.0.1", 1234)), "zeo://127.0.0.1:1234") # ZEO/ip4 _(zeo("1", ("127.0.0.1", 1234)), "zeo://127.0.0.1:1234") # ZEO/ip4
_(zeo("test", ("127.0.0.1", 1234)), "zeo://127.0.0.1:1234?storage=test") # + non-default storage name _(zeo("test", ("127.0.0.1", 1234)), "zeo://127.0.0.1:1234?storage=test") # + non-default storage name
_(zeo("1", ("::1", 1234)), "zeo://[::1]:1234") # ZEO/ip6
_(zeo("test", ("::1", 1234)), "zeo://[::1]:1234?storage=test") # + non-default storage name
_(neo("test", "127.0.0.1:1234"), "neo://127.0.0.1:1234/test") # NEO/ip4 _(neo("test", "127.0.0.1:1234"), "neo://127.0.0.1:1234/test") # NEO/ip4
_(neo("test", "127.0.0.1:1234", 1), "neos://%s@127.0.0.1:1234/test" % sslp) # + ssl _(neo("test", "127.0.0.1:1234", 1), "neos://%s@127.0.0.1:1234/test" % sslp) # + ssl
_(neo("test", "[::1]:1234"), "neo://[::1]:1234/test") # NEO/ip6
_(neo("test", "[::1]:1234", 1), "neos://%s@[::1]:1234/test" % sslp) # + ssl
_(demo(zeo("base", ("1.2.3.4", 5)), # DemoStorage _(demo(zeo("base", ("1.2.3.4", 5)), # DemoStorage
fs1("delta.fs")), "demo:(zeo://1.2.3.4:5?storage=base)/(file://%s/delta.fs)" % tmpdir) fs1("delta.fs")), "demo:(zeo://1.2.3.4:5?storage=base)/(file://%s/delta.fs)" % tmpdir)
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Wendelin.bigfile | common ZODB-related helpers # Wendelin.bigfile | common ZODB-related helpers
# Copyright (C) 2014-2021 Nexedi SA and Contributors. # Copyright (C) 2014-2022 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com> # Kirill Smelkov <kirr@nexedi.com>
# #
# This program is free software: you can Use, Study, Modify and Redistribute # This program is free software: you can Use, Study, Modify and Redistribute
...@@ -31,6 +31,7 @@ import zodbtools.util ...@@ -31,6 +31,7 @@ import zodbtools.util
from weakref import WeakSet from weakref import WeakSet
import gc import gc
from six.moves.urllib import parse as urlparse from six.moves.urllib import parse as urlparse
import socket
import pkg_resources import pkg_resources
...@@ -374,6 +375,8 @@ def zstor_2zurl(zstor): ...@@ -374,6 +375,8 @@ def zstor_2zurl(zstor):
u += addr u += addr
else: else:
host, port = addr host, port = addr
if _is_ipv6(host):
host = "[%s]" % host
u += '%s:%d' % (host, port) u += '%s:%d' % (host, port)
storage = zstor._storage storage = zstor._storage
...@@ -402,8 +405,11 @@ def zstor_2zurl(zstor): ...@@ -402,8 +405,11 @@ def zstor_2zurl(zstor):
raise NotImplementedError("NEO client has multiple configured masters: %r" % (masterv,)) raise NotImplementedError("NEO client has multiple configured masters: %r" % (masterv,))
master = masterv[0] master = masterv[0]
host, port = master.getAddress() host, port = master.getAddress()
u += "%s:%s" % (host, port)
if _is_ipv6(host):
host = "[%s]" % host
u += "%s:%s" % (host, port)
u += "/%s" % app.name u += "/%s" % app.name
return u return u
...@@ -416,3 +422,11 @@ def zstor_2zurl(zstor): ...@@ -416,3 +422,11 @@ def zstor_2zurl(zstor):
"\tanother in-RAM storage in WCFS process.") % ztype) "\tanother in-RAM storage in WCFS process.") % ztype)
raise NotImplementedError("don't know how to extract zurl from %r" % zstor) raise NotImplementedError("don't know how to extract zurl from %r" % zstor)
def _is_ipv6(host):
try:
socket.inet_pton(socket.AF_INET6, host)
except socket.error:
return False
return True
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