Skip to content

Commit

Permalink
Merge pull request #6709 from frostming/fix-trusted-host
Browse files Browse the repository at this point in the history
Fix inconsistent behavior of trusted host
  • Loading branch information
cjerdonek authored Aug 15, 2019
2 parents c2cf232 + bbae384 commit c4e45e9
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 2 deletions.
2 changes: 2 additions & 0 deletions news/6705.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix ``--trusted-host`` processing under HTTPS to trust any port number used
with the host.
10 changes: 9 additions & 1 deletion src/pip/_internal/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@
ask_password,
ask_path_exists,
backup_dir,
build_url_from_netloc,
consume,
display_path,
format_size,
get_installed_version,
netloc_has_port,
path_to_url,
remove_auth_from_url,
rmtree,
Expand Down Expand Up @@ -608,7 +610,13 @@ def __init__(self, *args, **kwargs):

def add_insecure_host(self, host):
# type: (str) -> None
self.mount('https://{}/'.format(host), self._insecure_adapter)
self.mount(build_url_from_netloc(host) + '/', self._insecure_adapter)
if not netloc_has_port(host):
# Mount wildcard ports for the same host.
self.mount(
build_url_from_netloc(host) + ':',
self._insecure_adapter
)

def request(self, method, url, *args, **kwargs):
# Allow setting a default timeout on a session
Expand Down
21 changes: 21 additions & 0 deletions src/pip/_internal/utils/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,27 @@ def path_to_url(path):
return url


def build_url_from_netloc(netloc, scheme='https'):
# type: (str, str) -> str
"""
Build a full URL from a netloc.
"""
if netloc.count(':') >= 2 and '@' not in netloc and '[' not in netloc:
# It must be a bare IPv6 address, so wrap it with brackets.
netloc = '[{}]'.format(netloc)
return '{}://{}'.format(scheme, netloc)


def netloc_has_port(netloc):
# type: (str) -> bool
"""
Return whether the netloc has a port part.
"""
url = build_url_from_netloc(netloc)
parsed = urllib_parse.urlparse(url)
return bool(parsed.port)


def split_auth_from_netloc(netloc):
"""
Parse out and remove the auth information from a netloc.
Expand Down
6 changes: 5 additions & 1 deletion tests/unit/test_download.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,12 +527,16 @@ def test_http_cache_is_not_enabled(self, tmpdir):

assert not hasattr(session.adapters["http://"], "cache")

def test_insecure_host_cache_is_not_enabled(self, tmpdir):
def test_insecure_host_adapter(self, tmpdir):
session = PipSession(
cache=tmpdir.joinpath("test-cache"),
insecure_hosts=["example.com"],
)

assert "https://example.com/" in session.adapters
# Check that the "port wildcard" is present.
assert "https://example.com:" in session.adapters
# Check that the cache isn't enabled.
assert not hasattr(session.adapters["https://example.com/"], "cache")


Expand Down
27 changes: 27 additions & 0 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@
)
from pip._internal.utils.hashes import Hashes, MissingHashes
from pip._internal.utils.misc import (
build_url_from_netloc,
call_subprocess,
egg_link_path,
ensure_dir,
format_command_args,
get_installed_distributions,
get_prog,
make_subprocess_output_error,
netloc_has_port,
normalize_path,
normalize_version_info,
path_to_display,
Expand Down Expand Up @@ -1223,6 +1225,31 @@ def test_path_to_url_win():
assert path_to_url('file') == 'file:' + urllib_request.pathname2url(path)


@pytest.mark.parametrize('netloc, expected_url, expected_has_port', [
# Test domain name.
('example.com', 'https://example.com', False),
('example.com:5000', 'https://example.com:5000', True),
# Test IPv4 address.
('127.0.0.1', 'https://127.0.0.1', False),
('127.0.0.1:5000', 'https://127.0.0.1:5000', True),
# Test bare IPv6 address.
('2001:DB6::1', 'https://[2001:DB6::1]', False),
# Test IPv6 with port.
('[2001:DB6::1]:5000', 'https://[2001:DB6::1]:5000', True),
# Test netloc with auth.
(
'user:password@localhost:5000',
'https://user:password@localhost:5000',
True
)
])
def test_build_url_from_netloc_and_netloc_has_port(
netloc, expected_url, expected_has_port,
):
assert build_url_from_netloc(netloc) == expected_url
assert netloc_has_port(netloc) is expected_has_port


@pytest.mark.parametrize('netloc, expected', [
# Test a basic case.
('example.com', ('example.com', (None, None))),
Expand Down

0 comments on commit c4e45e9

Please sign in to comment.