From 70d2f725fe53ed63056709dd795b8d27db07c9c8 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Fri, 5 Apr 2024 10:30:29 +0900 Subject: [PATCH] Fix invalid parsing of IPv6 address in sentinel server Ensure IPv6 address is not incorrectly split to look up port, in case the address is surrounded by []. Change-Id: I0750838b0ab00c5cbabb16e177906335f369ab5d --- zaqar/storage/redis/driver.py | 12 +++++++++--- zaqar/tests/unit/storage/test_impl_redis.py | 7 +++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/zaqar/storage/redis/driver.py b/zaqar/storage/redis/driver.py index 6ec9fb34e..28c24724d 100644 --- a/zaqar/storage/redis/driver.py +++ b/zaqar/storage/redis/driver.py @@ -36,7 +36,7 @@ STRATEGY_SENTINEL = 3 class ConnectionURI(object): - def __init__(self, uri): + def __init__(self, uri): # noqa: C901 # TODO(prashanthr_): Add SSL support try: parsed_url = urllib.parse.urlparse(uri) @@ -89,7 +89,14 @@ class ConnectionURI(object): # NOTE(kgriffs): Have to parse list of sentinel hosts ourselves # since urllib doesn't support it. for each_host in netloc.split(','): - name, sep, port = each_host.partition(':') + if not each_host.endswith(']') and ':' in each_host: + name, sep, port = each_host.rpartition(':') + else: + name = each_host + port = None + + if name.startswith('[') and name.endswith(']'): + name = name[1:-1] if port: try: @@ -98,7 +105,6 @@ class ConnectionURI(object): msg = _('The Redis configuration URI contains an ' 'invalid port') raise errors.ConfigurationError(msg) - else: port = SENTINEL_DEFAULT_PORT diff --git a/zaqar/tests/unit/storage/test_impl_redis.py b/zaqar/tests/unit/storage/test_impl_redis.py index feefa6dbe..e02c4188a 100644 --- a/zaqar/tests/unit/storage/test_impl_redis.py +++ b/zaqar/tests/unit/storage/test_impl_redis.py @@ -290,6 +290,13 @@ class RedisDriverTest(testing.TestBase): self.assertEqual('dumbledore', uri.master) self.assertEqual(0.1, uri.socket_timeout) + uri = driver.ConnectionURI( + 'redis://[::1]:26389,[::2]?master=dumbledore') + self.assertEqual(driver.STRATEGY_SENTINEL, uri.strategy) + self.assertEqual([('::1', 26389), ('::2', 26379)], uri.sentinels) + self.assertEqual('dumbledore', uri.master) + self.assertEqual(0.1, uri.socket_timeout) + uri = driver.ConnectionURI( 'redis://s1?master=dumbledore&socket_timeout=0.5') self.assertEqual(driver.STRATEGY_SENTINEL, uri.strategy)