mirror of
https://github.com/kennethreitz/requests.git
synced 2026-06-05 22:50:18 +00:00
New helper method set_http_proxy in Session to set proxies in a more user friendly way
This commit is contained in:
@@ -698,6 +698,91 @@ class Session(SessionRedirectMixin):
|
|||||||
|
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
def set_http_proxy(self,
|
||||||
|
http_scheme='http', # type: str
|
||||||
|
http_host=None, # type: str
|
||||||
|
http_port=80, # type: int
|
||||||
|
http_url=None, # type: str
|
||||||
|
use_http_proxy_for_https_requests=False, # type: bool
|
||||||
|
https_scheme='https', # type: str
|
||||||
|
https_host=None, # type: str
|
||||||
|
https_port=443, # type: int
|
||||||
|
https_url=None, # type: str
|
||||||
|
replace=False # type: bool
|
||||||
|
):
|
||||||
|
"""Update or replace self.proxies with the provided proxy information.
|
||||||
|
|
||||||
|
This method updates or replaces (depending on the value of `replace`) the dictionary in `self.proxies` with the
|
||||||
|
provided information. For each kind of connection (http and https), there are two ways to pass the information:
|
||||||
|
either as an url string (`http_url`, `https_url`), or split in schema/host/port, with sensible defaults.
|
||||||
|
In addition if the exact same proxy information is to be used for http and https, you can pass only the http
|
||||||
|
one and set `use_http_proxy_for_https_requests` to True.
|
||||||
|
|
||||||
|
See :ref:`Proxies documentation <_proxies>` for details.
|
||||||
|
|
||||||
|
:param http_host: (optional) a string indicating the http proxy host, for example '10.10.1.10' or 'acme.com'.
|
||||||
|
:param http_port: (optional) an int indicating the http proxy port, for example `3128`.
|
||||||
|
:param http_scheme: (optional) a string indicating the scheme to use for http proxy. By default this is 'http'
|
||||||
|
but you can consider using 'socks5', 'socks5h'. See documentation for details.
|
||||||
|
:param http_url: (optional) a string indicating the full http proxy url. For example 'http://10.10.1.10:3128'
|
||||||
|
or 'http://user:pass@10.10.1.10:3128/' or 'socks5://user:pass@host:port'.
|
||||||
|
Only one of {http_scheme + http_host + http_port} or {http_url} should be provided.
|
||||||
|
:param use_http_proxy_for_https_requests: (optional) a boolean indicating whether the information provided for
|
||||||
|
the http proxy should be copied for the https proxy. Note that the full url will be copied including the
|
||||||
|
scheme (so by default 'http').
|
||||||
|
:param https_host: (optional) a string indicating the https proxy host, for example '10.10.1.10' or 'acme.com'.
|
||||||
|
:param https_port: (optional) an int indicating the https proxy port, for example `3128`.
|
||||||
|
:param https_scheme: (optional) a string indicating the scheme to use for https proxy. By default this is
|
||||||
|
'https' but you can consider using 'socks5', 'socks5h'. See documentation for details.
|
||||||
|
:param https_url: (optional) a string indicating the full https proxy url. For example 'https://10.10.1.10:3128'
|
||||||
|
or 'http://user:pass@10.10.1.10:3128/' or 'socks5://user:pass@host:port'.
|
||||||
|
Only one of {https_scheme + https_host + https_port} or {https_url} should be provided.
|
||||||
|
:param replace: (optional) a boolean indicating if the provided information should replace the existing one
|
||||||
|
(True) or just update it (False, default).
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
proxies = dict()
|
||||||
|
|
||||||
|
# HTTPS
|
||||||
|
if http_host is not None:
|
||||||
|
# (a) scheme + host + port
|
||||||
|
if http_url is not None:
|
||||||
|
raise ValueError("Only one of `http_host` and `http_url` should be provided")
|
||||||
|
proxies['http'] = "%s://%s:%s" % (http_scheme, http_host, http_port)
|
||||||
|
elif http_url is not None:
|
||||||
|
# (b) full url
|
||||||
|
proxies['http'] = http_url
|
||||||
|
elif http_port != 80 or http_scheme != 'http':
|
||||||
|
raise ValueError("An `http_host` should be provided if you wish to change `http_port` or `http_scheme`")
|
||||||
|
|
||||||
|
# HTTPS
|
||||||
|
if use_http_proxy_for_https_requests:
|
||||||
|
# (a) copy the information from http
|
||||||
|
if https_host is not None or https_url is not None or https_port != 443 or https_scheme != "https":
|
||||||
|
raise ValueError("`use_http_proxy_for_https_requests` was set to `True` but custom information for "
|
||||||
|
"https was provided.")
|
||||||
|
try:
|
||||||
|
proxies['https'] = proxies['http']
|
||||||
|
except KeyError:
|
||||||
|
raise ValueError("`use_http_proxy_for_https_requests` was set to `True` but no information was "
|
||||||
|
"provided for the http proxy")
|
||||||
|
elif https_host is not None:
|
||||||
|
# (b) scheme + host + port
|
||||||
|
if https_url is not None:
|
||||||
|
raise ValueError("Only one of `https_host` and `https_url` should be provided")
|
||||||
|
proxies['https'] = '%s://%s:%s' % (https_scheme, https_host, https_port)
|
||||||
|
elif https_url is not None:
|
||||||
|
# (c) full url
|
||||||
|
proxies['https'] = https_url
|
||||||
|
elif https_port != 443 or https_scheme != 'https':
|
||||||
|
raise ValueError("An `https_host` should be provided if you wish to change `https_port` or `https_scheme`")
|
||||||
|
|
||||||
|
# Replace or update (default) the configuration
|
||||||
|
if replace:
|
||||||
|
self.proxies = proxies
|
||||||
|
else:
|
||||||
|
self.proxies.update(proxies)
|
||||||
|
|
||||||
def merge_environment_settings(self, url, proxies, stream, verify, cert):
|
def merge_environment_settings(self, url, proxies, stream, verify, cert):
|
||||||
"""
|
"""
|
||||||
Check the environment and merge it with some settings.
|
Check the environment and merge it with some settings.
|
||||||
|
|||||||
@@ -151,6 +151,41 @@ class TestRequests:
|
|||||||
request = requests.Request('GET', ' http://example.com').prepare()
|
request = requests.Request('GET', ' http://example.com').prepare()
|
||||||
assert request.url == 'http://example.com/'
|
assert request.url == 'http://example.com/'
|
||||||
|
|
||||||
|
def test_proxies_shortcut(self):
|
||||||
|
"""Test that the set_http_proxy helper function works correctly"""
|
||||||
|
s = requests.Session()
|
||||||
|
|
||||||
|
# nominal
|
||||||
|
s.set_http_proxy(http_scheme='socks5', http_host='acme.com', http_port=999)
|
||||||
|
assert s.proxies == {'http': 'socks5://acme.com:999'}
|
||||||
|
s.set_http_proxy(https_scheme='socks5h', https_host='acme.org', https_port=80)
|
||||||
|
assert s.proxies == {'http': 'socks5://acme.com:999', 'https': 'socks5h://acme.org:80'}
|
||||||
|
|
||||||
|
# one can not specify a scheme or a port without passing a host
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
s.set_http_proxy(http_scheme='socks5')
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
s.set_http_proxy(https_scheme='socks5')
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
s.set_http_proxy(http_port=999)
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
s.set_http_proxy(https_port=999)
|
||||||
|
|
||||||
|
# use_http_proxy_for_https_requests requires http related information to be present
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
s.set_http_proxy(use_http_proxy_for_https_requests=True)
|
||||||
|
|
||||||
|
# reuse http info for https
|
||||||
|
s.set_http_proxy(http_url='http://10.10.10.10:80', use_http_proxy_for_https_requests=True)
|
||||||
|
assert s.proxies == {'http': 'http://10.10.10.10:80', 'https': 'http://10.10.10.10:80'}
|
||||||
|
|
||||||
|
# replace instead of update
|
||||||
|
s.set_http_proxy(https_url='http://10.10.10.20:80', replace=True)
|
||||||
|
assert s.proxies == {'https': 'http://10.10.10.20:80'}
|
||||||
|
|
||||||
|
# https url
|
||||||
|
s.set_http_proxy(https_url='http://10.10.10.20:80', replace=True)
|
||||||
|
|
||||||
@pytest.mark.parametrize('scheme', ('http://', 'HTTP://', 'hTTp://', 'HttP://'))
|
@pytest.mark.parametrize('scheme', ('http://', 'HTTP://', 'hTTp://', 'HttP://'))
|
||||||
def test_mixed_case_scheme_acceptable(self, httpbin, scheme):
|
def test_mixed_case_scheme_acceptable(self, httpbin, scheme):
|
||||||
s = requests.Session()
|
s = requests.Session()
|
||||||
|
|||||||
Reference in New Issue
Block a user