Skip to content

Commit

Permalink
Don't rely on netloc for determining hostname and port, just use host…
Browse files Browse the repository at this point in the history
…name and port (ansible#56270)

* Add changelog fragment
* Fix IPv6 address parsing for py2.6, and add tests
* make sure hostname isn't None
  • Loading branch information
sivel authored and samdoran committed May 20, 2019
1 parent 66bfa27 commit 493cf81
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 13 deletions.
4 changes: 4 additions & 0 deletions changelogs/fragments/urls-ipv6-redirects.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bugfixes:
- urls - Handle redirects properly for IPv6 address by not splitting on ``:``
and rely on already parsed hostname and port values
(https://github.com/ansible/ansible/issues/56258)
32 changes: 19 additions & 13 deletions lib/ansible/module_utils/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,8 +559,24 @@ def generic_urlparse(parts):
generic_parts['fragment'] = parts.fragment
generic_parts['username'] = parts.username
generic_parts['password'] = parts.password
generic_parts['hostname'] = parts.hostname
generic_parts['port'] = parts.port
hostname = parts.hostname
if hostname and hostname[0] == '[' and '[' in parts.netloc and ']' in parts.netloc:
# Py2.6 doesn't parse IPv6 addresses correctly
hostname = parts.netloc.split(']')[0][1:].lower()
generic_parts['hostname'] = hostname

try:
port = parts.port
except ValueError:
# Py2.6 doesn't parse IPv6 addresses correctly
netloc = parts.netloc.split('@')[-1].split(']')[-1]
if ':' in netloc:
port = netloc.split(':')[1]
if port:
port = int(port)
else:
port = None
generic_parts['port'] = port
else:
# we have to use indexes, and then parse out
# the other parts not supported by indexing
Expand Down Expand Up @@ -963,19 +979,9 @@ def maybe_add_ssl_handler(url, validate_certs):
raise NoSSLError('SSL validation is not available in your version of python. You can use validate_certs=False,'
' however this is unsafe and not recommended')

# do the cert validation
netloc = parsed.netloc
if '@' in netloc:
netloc = netloc.split('@', 1)[1]
if ':' in netloc:
hostname, port = netloc.split(':', 1)
port = int(port)
else:
hostname = netloc
port = 443
# create the SSL validation handler and
# add it to the list of handlers
return SSLValidationHandler(hostname, port)
return SSLValidationHandler(parsed.hostname, parsed.port or 443)


def rfc2822_date_string(timetuple, zone='-0000'):
Expand Down
10 changes: 10 additions & 0 deletions test/units/module_utils/urls/test_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ def test_maybe_add_ssl_handler(mocker):
handler = urls.maybe_add_ssl_handler(url, True)
assert handler is None

url = 'https://[2a00:16d8:0:7::205]:4443/'
handler = urls.maybe_add_ssl_handler(url, True)
assert handler.hostname == '2a00:16d8:0:7::205'
assert handler.port == 4443

url = 'https://[2a00:16d8:0:7::205]/'
handler = urls.maybe_add_ssl_handler(url, True)
assert handler.hostname == '2a00:16d8:0:7::205'
assert handler.port == 443


def test_basic_auth_header():
header = urls.basic_auth_header('user', 'passwd')
Expand Down

0 comments on commit 493cf81

Please sign in to comment.