gruns / furl

🌐 URL parsing and manipulation made easy.
Other
2.63k stars 152 forks source link

Tolerate and correct IPv6 without brackets #166

Open azmeuk opened 2 years ago

azmeuk commented 2 years ago

This PR is based on #165 and fixes #124. If #124 is too controversial, I can rebase this PR on master, just tell me :)

Depending on the contexts, people does not always agree on brackets usage with IPv6. For instance, the ipaddress core module handles IPv6 without brackets as do some other low-level python modules. Another example: DNS AAAA records usually handles IPv6 without brackets. However in a URL context, with a port number being optionally associated with an IP, the brackets become mandatory to distinguish the columns inside the IP from the column that separate the port number from the IP.

As suggested in #124, I think this would be nice if a convenience utility like furl would tolerate and correct any usage. This would allow users to not need to check and correct manually the IPv6 they get from other libraries that may generate IPv6 without brackets because this is relevant in their development context. For instance a DNS SRV record being read with aiodns.

This is what this PR allows. There is not much code here, everything lies here:

    def host(self, host):
        ...
        if (
            is_valid_ipv6(host)
            and callable_attr(host, 'startswith')
            and callable_attr(host, 'endswith')
            and not host.startswith("[")
            and not host.endswith("]")
        ):
            host = "[" + host + "]"
        ...

This allows this usage:

        f.set(host="::1")
        assert f.host == "[::1]"
        assert f.url == "http://[::1]/"

        f.set(host="[::]")
        assert f.host == "[::]"
        assert f.url == "http://[::]/"