urlsplit issues with IPv6 addresses in python26

urlsplit can't handle RFC 2732 URLs. reuse the
parse_host_port to rectify the hostname and
port implementation of SplitResult. Added test
cases to make sure we get the right ip and port
when the urls have ipv6 in them. Added an additional
test for both ipv4 and ipv6 to ensure we are indeed
handling username password in urls as well

Change-Id: I054f5e46cc8c201aaa48ee2d8b9d0a09b30a48ce
Closes-Bug: #1298137
This commit is contained in:
Davanum Srinivas 2014-03-26 21:48:05 -04:00
parent bacdc98878
commit 8a19cf155c
2 changed files with 56 additions and 1 deletions

View File

@ -74,6 +74,24 @@ def parse_host_port(address, default_port=None):
return (host, None if port is None else int(port))
class ModifiedSplitResult(SplitResult):
"""Split results class for urlsplit."""
# NOTE(dims): The functions below are needed for Python 2.6.x.
# We can remove these when we drop support for 2.6.x.
@property
def hostname(self):
netloc = self.netloc.split('@', 1)[-1]
host, port = parse_host_port(netloc)
return host
@property
def port(self):
netloc = self.netloc.split('@', 1)[-1]
host, port = parse_host_port(netloc)
return port
def urlsplit(url, scheme='', allow_fragments=True):
"""Parse a URL using urlparse.urlsplit(), splitting query and fragments.
This function papers over Python issue9374 when needed.
@ -86,4 +104,5 @@ def urlsplit(url, scheme='', allow_fragments=True):
path, fragment = path.split('#', 1)
if '?' in path:
path, query = path.split('?', 1)
return SplitResult(scheme, netloc, path, query, fragment)
return ModifiedSplitResult(scheme, netloc,
path, query, fragment)

View File

@ -55,3 +55,39 @@ class NetworkUtilsTest(test.BaseTestCase):
self.assertEqual(result.path, '/mypath')
self.assertEqual(result.query, 'someparam#somefragment')
self.assertEqual(result.fragment, '')
result = network_utils.urlsplit(
'rpc://user:pass@myhost/mypath?someparam#somefragment',
allow_fragments=False)
self.assertEqual(result.scheme, 'rpc')
self.assertEqual(result.netloc, 'user:pass@myhost')
self.assertEqual(result.path, '/mypath')
self.assertEqual(result.query, 'someparam#somefragment')
self.assertEqual(result.fragment, '')
def test_urlsplit_ipv6(self):
ipv6_url = 'http://[::1]:443/v2.0/'
result = network_utils.urlsplit(ipv6_url)
self.assertEqual(result.scheme, 'http')
self.assertEqual(result.netloc, '[::1]:443')
self.assertEqual(result.path, '/v2.0/')
self.assertEqual(result.hostname, '::1')
self.assertEqual(result.port, 443)
ipv6_url = 'http://user:pass@[::1]/v2.0/'
result = network_utils.urlsplit(ipv6_url)
self.assertEqual(result.scheme, 'http')
self.assertEqual(result.netloc, 'user:pass@[::1]')
self.assertEqual(result.path, '/v2.0/')
self.assertEqual(result.hostname, '::1')
self.assertEqual(result.port, None)
ipv6_url = 'https://[2001:db8:85a3::8a2e:370:7334]:1234/v2.0/xy?ab#12'
result = network_utils.urlsplit(ipv6_url)
self.assertEqual(result.scheme, 'https')
self.assertEqual(result.netloc, '[2001:db8:85a3::8a2e:370:7334]:1234')
self.assertEqual(result.path, '/v2.0/xy')
self.assertEqual(result.hostname, '2001:db8:85a3::8a2e:370:7334')
self.assertEqual(result.port, 1234)
self.assertEqual(result.query, 'ab')
self.assertEqual(result.fragment, '12')