furl icon indicating copy to clipboard operation
furl copied to clipboard

IPv6 addresses do not quite work as advertised

Open fingon opened this issue 5 years ago • 5 comments

>>> from furl import furl
>>> f = furl()
>>> f.host = '::1'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/mstenber/.local/lib/python3.7/site-packages/furl/furl.py", line 1851, in __setattr__
    object.__setattr__(self, attr, value)
  File "/home/mstenber/.local/lib/python3.7/site-packages/furl/furl.py", line 1425, in host
    raise ValueError(errmsg % (host, INVALID_HOST_CHARS))
ValueError: Invalid host '::1'. Host strings must have at least one non-period character, can't contain any of '!@#$%^&'"*()+=:;/', and can't have adjacent periods.
>>> f.host = '[::1]'
>>> f
furl('//[::1]')

As the documentation says 'host' can accept IPv6 address, it is not quite right :)

 |    host: URL host (hostname, IPv4 address, or IPv6 address), not
 |      including port. All lowercase. Initially None.

At least as user I'd be happier if []s just showed up, and IPv6 address was compressed automatically (e.g. str(ip_address.ipaddress(addr)) )

fingon avatar Feb 18 '20 07:02 fingon

[] format is the (only) correct way to enter IP only IPv6 as a URI.

systemcrash avatar Jun 06 '20 13:06 systemcrash

Indeed. But user of convenience api should not care. Or alternatively it should be documented.

fingon avatar Jun 06 '20 16:06 fingon

before this is implemented and added, are there any 1) ambiguous strings that are both valid IPv6 literals and valid hostnames, or 2) surprising IPv6 literals that look confusingly like a valid hostname (or vice versa)? none come to my mind

If none, I agree: furl should implicitly accept f.host = '::1' as if the user typed f.host = '[::1]'. ::1 isn't a valid host name but is an obvious IPv6 address. furl should be liberal in what it accepts, ie Postel's law

@fingon do you have time to submit a PR to fix this?

py3 has the handy https://docs.python.org/3/library/ipaddress.html module to help

a dependency may be needed for py2

gruns avatar Jan 08 '21 23:01 gruns

[] format is the (only) correct way to enter IP only IPv6 as a URI.

Well, the support is not uniform at all:

>>> import socket
>>> socket.inet_pton(socket.AF_INET6,'::')
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> socket.inet_pton(socket.AF_INET6,'[::]')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: illegal IP address string passed to inet_pton

On python it seems that some of the builtin features based on libc will depend on how libc handles brackets in IPV6.

azmeuk avatar Sep 24 '22 11:09 azmeuk

Well, the support is not uniform at all:

>>> import socket
>>> socket.inet_pton(socket.AF_INET6,'::')
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> socket.inet_pton(socket.AF_INET6,'[::]')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: illegal IP address string passed to inet_pton

On python it seems that some of the builtin features based on libc will depend on how libc handles brackets in IPV6.

[] format is the (only) correct way to enter IP only IPv6 as a URI.

Well, the support is not uniform at all:

>>> import socket
>>> socket.inet_pton(socket.AF_INET6,'::')
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> socket.inet_pton(socket.AF_INET6,'[::]')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: illegal IP address string passed to inet_pton

On python it seems that some of the builtin features based on libc will depend on how libc handles brackets in IPV6.

Sure an api that does not accept url does not accept url style IPs. But is that unexpected? Socket deals with ips directly.

fingon avatar Sep 24 '22 21:09 fingon