Merge pull request #7885 from NoahGorny/cache-trusted-host

Cache trusted host
This commit is contained in:
Pradyun Gedam 2020-04-14 02:26:28 +05:30 committed by GitHub
commit 3c1cf3e139
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 23 deletions

1
news/7847.feature Normal file
View File

@ -0,0 +1 @@
Change default behaviour to always cache responses from trusted-host source.

View File

@ -217,6 +217,14 @@ class InsecureHTTPAdapter(HTTPAdapter):
)
class InsecureCacheControlAdapter(CacheControlAdapter):
def cert_verify(self, conn, url, verify, cert):
super(InsecureCacheControlAdapter, self).cert_verify(
conn=conn, url=url, verify=False, cert=cert
)
class PipSession(requests.Session):
timeout = None # type: Optional[int]
@ -263,8 +271,16 @@ class PipSession(requests.Session):
backoff_factor=0.25,
)
# We want to _only_ cache responses on securely fetched origins. We do
# this because we can't validate the response of an insecurely fetched
# Our Insecure HTTPAdapter disables HTTPS validation. It does not
# support caching so we'll use it for all http:// URLs.
# If caching is disabled, we will also use it for
# https:// hosts that we've marked as ignoring
# TLS errors for (trusted-hosts).
insecure_adapter = InsecureHTTPAdapter(max_retries=retries)
# We want to _only_ cache responses on securely fetched origins or when
# the host is specified as trusted. We do this because
# we can't validate the response of an insecurely/untrusted fetched
# origin, and we don't want someone to be able to poison the cache and
# require manual eviction from the cache to fix it.
if cache:
@ -272,16 +288,13 @@ class PipSession(requests.Session):
cache=SafeFileCache(cache),
max_retries=retries,
)
self._trusted_host_adapter = InsecureCacheControlAdapter(
cache=SafeFileCache(cache),
max_retries=retries,
)
else:
secure_adapter = HTTPAdapter(max_retries=retries)
# Our Insecure HTTPAdapter disables HTTPS validation. It does not
# support caching (see above) so we'll use it for all http:// URLs as
# 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._trusted_host_adapter = insecure_adapter
self.mount("https://", secure_adapter)
self.mount("http://", insecure_adapter)
@ -310,12 +323,15 @@ class PipSession(requests.Session):
if host_port not in self.pip_trusted_origins:
self.pip_trusted_origins.append(host_port)
self.mount(build_url_from_netloc(host) + '/', self._insecure_adapter)
self.mount(
build_url_from_netloc(host) + '/',
self._trusted_host_adapter
)
if not host_port[1]:
# Mount wildcard ports for the same host.
self.mount(
build_url_from_netloc(host) + ':',
self._insecure_adapter
self._trusted_host_adapter
)
def iter_secure_origins(self):

View File

@ -72,7 +72,7 @@ class TestPipSession:
assert not hasattr(session.adapters["http://"], "cache")
def test_insecure_host_adapter(self, tmpdir):
def test_trusted_hosts_adapter(self, tmpdir):
session = PipSession(
cache=tmpdir.joinpath("test-cache"),
trusted_hosts=["example.com"],
@ -81,14 +81,14 @@ class TestPipSession:
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")
# Check that the cache is enabled.
assert hasattr(session.adapters["https://example.com/"], "cache")
def test_add_trusted_host(self):
# Leave a gap to test how the ordering is affected.
trusted_hosts = ['host1', 'host3']
session = PipSession(trusted_hosts=trusted_hosts)
insecure_adapter = session._insecure_adapter
trusted_host_adapter = session._trusted_host_adapter
prefix2 = 'https://host2/'
prefix3 = 'https://host3/'
prefix3_wildcard = 'https://host3:'
@ -97,8 +97,8 @@ class TestPipSession:
assert session.pip_trusted_origins == [
('host1', None), ('host3', None)
]
assert session.adapters[prefix3] is insecure_adapter
assert session.adapters[prefix3_wildcard] is insecure_adapter
assert session.adapters[prefix3] is trusted_host_adapter
assert session.adapters[prefix3_wildcard] is trusted_host_adapter
assert prefix2 not in session.adapters
@ -108,8 +108,8 @@ class TestPipSession:
('host1', None), ('host3', None), ('host2', None)
]
# Check that prefix3 is still present.
assert session.adapters[prefix3] is insecure_adapter
assert session.adapters[prefix2] is insecure_adapter
assert session.adapters[prefix3] is trusted_host_adapter
assert session.adapters[prefix2] is trusted_host_adapter
# Test that adding the same host doesn't create a duplicate.
session.add_trusted_host('host3')
@ -123,7 +123,7 @@ class TestPipSession:
('host1', None), ('host3', None),
('host2', None), ('host4', 8080)
]
assert session.adapters[prefix4] is insecure_adapter
assert session.adapters[prefix4] is trusted_host_adapter
def test_add_trusted_host__logging(self, caplog):
"""

View File

@ -401,10 +401,13 @@ class TestProcessLine(object):
)
assert list(finder.trusted_hosts) == ['host1', 'host2:8080']
session = finder._link_collector.session
assert session.adapters['https://host1/'] is session._insecure_adapter
assert (
session.adapters['https://host1/']
is session._trusted_host_adapter
)
assert (
session.adapters['https://host2:8080/']
is session._insecure_adapter
is session._trusted_host_adapter
)
# Test the log message.