Skip to content

Commit 0a45400

Browse files
committed
Fix parsing of IPv6 addresses in the connection URI
Plain IPv6 addresses specified in square brackets in the connection URI are now parsed correctly. Fixes: #838.
1 parent 4d39a05 commit 0a45400

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

asyncpg/connect_utils.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,25 @@ def _parse_hostlist(hostlist, port, *, unquote=False):
197197
port = _validate_port_spec(hostspecs, port)
198198

199199
for i, hostspec in enumerate(hostspecs):
200-
if not hostspec.startswith('/'):
201-
addr, _, hostspec_port = hostspec.partition(':')
202-
else:
200+
if hostspec[0] == '/':
201+
# Unix socket
203202
addr = hostspec
204203
hostspec_port = ''
204+
elif hostspec[0] == '[':
205+
# IPv6 address
206+
m = re.match(r'(?:\[([^\]]+)\])(?::([0-9]+))?', hostspec)
207+
if m:
208+
addr = m.group(1)
209+
hostspec_port = m.group(2)
210+
else:
211+
raise ValueError(
212+
'invalid IPv6 address in the connection URI: {!r}'.format(
213+
hostspec
214+
)
215+
)
216+
else:
217+
# IPv4 address
218+
addr, _, hostspec_port = hostspec.partition(':')
205219

206220
if unquote:
207221
addr = urllib.parse.unquote(addr)

tests/test_connect.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,34 @@ class TestConnectParams(tb.TestCase):
511511
})
512512
},
513513

514+
{
515+
'name': 'dsn_ipv6_multi_host',
516+
'dsn': 'postgresql://user@[2001:db8::1234%25eth0],[::1]/db',
517+
'result': ([('2001:db8::1234%eth0', 5432), ('::1', 5432)], {
518+
'database': 'db',
519+
'user': 'user',
520+
})
521+
},
522+
523+
{
524+
'name': 'dsn_ipv6_multi_host_port',
525+
'dsn': 'postgresql://user@[2001:db8::1234]:1111,[::1]:2222/db',
526+
'result': ([('2001:db8::1234', 1111), ('::1', 2222)], {
527+
'database': 'db',
528+
'user': 'user',
529+
})
530+
},
531+
532+
{
533+
'name': 'dsn_ipv6_multi_host_query_part',
534+
'dsn': 'postgresql:///db?user=user&host=[2001:db8::1234],[::1]',
535+
'result': ([('2001:db8::1234', 5432), ('::1', 5432)], {
536+
'database': 'db',
537+
'user': 'user',
538+
})
539+
},
540+
541+
514542
{
515543
'name': 'dsn_combines_env_multi_host',
516544
'env': {

0 commit comments

Comments
 (0)