From: Alfredo Deza Date: Fri, 19 Jun 2015 16:38:14 +0000 (-0400) Subject: properly detect ipv6 in client.py X-Git-Tag: v1.2.3~3^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e0d162f605f2faef194c8dc3626f512eb98fd106;p=radosgw-agent.git properly detect ipv6 in client.py Signed-off-by: Alfredo Deza --- diff --git a/radosgw_agent/client.py b/radosgw_agent/client.py index 23bbf4e..7c8ac93 100644 --- a/radosgw_agent/client.py +++ b/radosgw_agent/client.py @@ -13,7 +13,7 @@ from boto.s3.connection import S3Connection from radosgw_agent import request as aws_request from radosgw_agent import config from radosgw_agent import exceptions as exc -from radosgw_agent.util import get_dev_logger +from radosgw_agent.util import get_dev_logger, network from radosgw_agent.constants import DEFAULT_TIME from radosgw_agent.exceptions import NetworkError @@ -58,15 +58,53 @@ class Endpoint(object): return '{scheme}://{host}:{port}'.format(scheme=scheme, host=self.host, port=self.port) +def normalize_netloc(url_obj): + """ + Only needed for IPV6 addresses because ``urlparse`` is so very + inconsistent with parsing:: + + In [5]: print urlparse('http://[e40:92be:ab1c:c9c1:3e2e:dbf6:57c6:8922]:8080').hostname + e40:92be:ab1c:c9c1:3e2e:dbf6:57c6:8922 + + In [6]: print urlparse('http://e40:92be:ab1c:c9c1:3e2e:dbf6:57c6:8922').hostname + e40 + + """ + netloc = url_obj.netloc + try: + port = url_obj.port + except ValueError: + port = None + + if port is not None: + # we need to split because we don't want it as part of the URL + netloc = url_obj.netloc.split(':%s' % port)[0] + if not url_obj.netloc.startswith('[') and not url_obj.netloc.endswith(']'): + netloc = '[%s]' % url_obj.netloc + return netloc def parse_endpoint(endpoint): url = urlparse(endpoint) + # IPV6 addresses will not work correctly with urlparse and Endpoint if we + # just use netloc as default. IPV4 works with .hostname while IPV6 works + # with .netloc + # for example an IPV6 address like e40:92be:ab1c:c9c1:3e2e:dbf6:57c6:8922 + # would evaluate to 'e40' if we used .hostname + try: + port = url.port + except ValueError: + port = None + + if network.is_ipv6(url.netloc): + host = normalize_netloc(url) + else: + host = url.hostname if url.scheme not in ['http', 'https']: raise exc.InvalidProtocol('invalid protocol %r' % url.scheme) if not url.hostname: raise exc.InvalidHost('no hostname in %r' % endpoint) - return Endpoint(url.netloc, url.port, url.scheme == 'https') + return Endpoint(host, port, url.scheme == 'https') code_to_exc = { 404: exc.NotFound,