Skip to content

Commit

Permalink
Fully support --trusted-host inside requirements files.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjerdonek committed Jun 13, 2019
1 parent a240a98 commit d727583
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 18 deletions.
1 change: 1 addition & 0 deletions docs/html/reference/pip_install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ The following options are supported:
* :ref:`--no-binary <install_--no-binary>`
* :ref:`--only-binary <install_--only-binary>`
* :ref:`--require-hashes <--require-hashes>`
* :ref:`--trusted-host <--trusted-host>`

For example, to specify :ref:`--no-index <--no-index>` and two
:ref:`--find-links <--find-links>` locations:
Expand Down
1 change: 1 addition & 0 deletions news/3799.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fully support using ``--trusted-host`` inside requirements files.
8 changes: 7 additions & 1 deletion src/pip/_internal/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,8 @@ def __init__(self, *args, **kwargs):
# well as any https:// host that we've marked as ignoring TLS errors
# for.
insecure_adapter = InsecureHTTPAdapter(max_retries=retries)
# Save this for later use in add_insecure_host().
self._insecure_adapter = insecure_adapter

self.mount("https://", secure_adapter)
self.mount("http://", insecure_adapter)
Expand All @@ -598,7 +600,11 @@ def __init__(self, *args, **kwargs):
# We want to use a non-validating adapter for any requests which are
# deemed insecure.
for host in insecure_hosts:
self.mount("https://{}/".format(host), insecure_adapter)
self.add_insecure_host(host)

def add_insecure_host(self, host):
# type: (str) -> None
self.mount('https://{}/'.format(host), self._insecure_adapter)

def request(self, method, url, *args, **kwargs):
# Allow setting a default timeout on a session
Expand Down
19 changes: 11 additions & 8 deletions src/pip/_internal/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,8 +608,8 @@ def create(
# type: (...) -> PackageFinder
"""Create a PackageFinder.
:param trusted_hosts: Domains that we won't emit warnings for when
not using HTTPS.
:param trusted_hosts: Domains not to emit warnings for when not using
HTTPS.
:param session: The Session to use to make requests.
:param format_control: A FormatControl object or None. Used to control
the selection of source packages / binary packages when consulting
Expand Down Expand Up @@ -676,12 +676,15 @@ def set_allow_all_prereleases(self):
# type: () -> None
self.candidate_evaluator.allow_all_prereleases = True

def extend_trusted_hosts(self, hosts):
# type: (List[str]) -> None
for host in hosts:
if host in self.trusted_hosts:
continue
self.trusted_hosts.append(host)
def add_trusted_host(self, host):
# type: (str) -> None
# It is okay to add a previously added host because PipSession stores
# the resulting prefixes in a dict.
self.session.add_insecure_host(host)
if host in self.trusted_hosts:
return

self.trusted_hosts.append(host)

def iter_secure_origins(self):
# type: () -> Iterator[SecureOrigin]
Expand Down
4 changes: 2 additions & 2 deletions src/pip/_internal/req/req_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ def process_line(
finder.find_links.append(value)
if opts.pre:
finder.set_allow_all_prereleases()
if opts.trusted_hosts:
finder.extend_trusted_hosts(opts.trusted_hosts)
for host in opts.trusted_hosts or []:
finder.add_trusted_host(host)


def break_args_options(line):
Expand Down
34 changes: 27 additions & 7 deletions tests/unit/test_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,33 @@ def test_create__target_python(self):
assert actual_target_python is target_python
assert actual_target_python.py_version_info == (3, 7, 3)

def test_extend_trusted_hosts(self):
trusted_hosts = ['host1', 'host2']
finder = make_test_finder(trusted_hosts=trusted_hosts)

# Check that extend_trusted_hosts() prevents duplicates.
finder.extend_trusted_hosts(['host2', 'host3', 'host2'])
assert finder.trusted_hosts == ['host1', 'host2', 'host3'], (
def test_add_trusted_host(self):
# Leave a gap to test how the ordering is affected.
trusted_hosts = ['host1', 'host3']
session = PipSession(insecure_hosts=trusted_hosts)
finder = make_test_finder(
session=session,
trusted_hosts=trusted_hosts,
)
insecure_adapter = session._insecure_adapter
prefix2 = 'https://host2/'
prefix3 = 'https://host3/'

# Confirm some initial conditions as a baseline.
assert finder.trusted_hosts == ['host1', 'host3']
assert session.adapters[prefix3] is insecure_adapter
assert prefix2 not in session.adapters

# Test adding a new host.
finder.add_trusted_host('host2')
assert finder.trusted_hosts == ['host1', 'host3', 'host2']
# Check that prefix3 is still present.
assert session.adapters[prefix3] is insecure_adapter
assert session.adapters[prefix2] is insecure_adapter

# Test that adding the same host doesn't create a duplicate.
finder.add_trusted_host('host3')
assert finder.trusted_hosts == ['host1', 'host3', 'host2'], (
'actual: {}'.format(finder.trusted_hosts)
)

Expand Down
2 changes: 2 additions & 0 deletions tests/unit/test_req_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ def test_set_finder_extra_index_urls(self, finder):
def test_set_finder_trusted_host(self, finder):
list(process_line("--trusted-host=url", "file", 1, finder=finder))
assert finder.trusted_hosts == ['url']
session = finder.session
assert session.adapters['https://url/'] is session._insecure_adapter

def test_noop_always_unzip(self, finder):
# noop, but confirm it can be set
Expand Down

0 comments on commit d727583

Please sign in to comment.