mirror of
https://github.com/kennethreitz/requests.git
synced 2026-06-05 22:50:18 +00:00
Allow use of 'no_proxy' in the proxies argument
Add the ability to add 'no_proxy' and a value to the 'proxies' dictionary argument. https://github.com/kennethreitz/requests/issues/2817 Closes gh-2817
This commit is contained in:
@@ -231,13 +231,16 @@ class SessionRedirectMixin(object):
|
||||
|
||||
:rtype: dict
|
||||
"""
|
||||
proxies = proxies if proxies is not None else {}
|
||||
headers = prepared_request.headers
|
||||
url = prepared_request.url
|
||||
scheme = urlparse(url).scheme
|
||||
new_proxies = proxies.copy() if proxies is not None else {}
|
||||
new_proxies = proxies.copy()
|
||||
no_proxy = proxies.get('no_proxy')
|
||||
|
||||
if self.trust_env and not should_bypass_proxies(url):
|
||||
environ_proxies = get_environ_proxies(url)
|
||||
bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy)
|
||||
if self.trust_env and not bypass_proxy:
|
||||
environ_proxies = get_environ_proxies(url, no_proxy=no_proxy)
|
||||
|
||||
proxy = environ_proxies.get(scheme, environ_proxies.get('all'))
|
||||
|
||||
@@ -651,7 +654,8 @@ class Session(SessionRedirectMixin):
|
||||
# Gather clues from the surrounding environment.
|
||||
if self.trust_env:
|
||||
# Set environment's proxies.
|
||||
env_proxies = get_environ_proxies(url) or {}
|
||||
no_proxy = proxies.get('no_proxy') if proxies is not None else None
|
||||
env_proxies = get_environ_proxies(url, no_proxy=no_proxy)
|
||||
for (k, v) in env_proxies.items():
|
||||
proxies.setdefault(k, v)
|
||||
|
||||
|
||||
+34
-8
@@ -11,6 +11,7 @@ that are also useful for external consumption.
|
||||
import cgi
|
||||
import codecs
|
||||
import collections
|
||||
import contextlib
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
@@ -554,7 +555,29 @@ def is_valid_cidr(string_network):
|
||||
return True
|
||||
|
||||
|
||||
def should_bypass_proxies(url):
|
||||
@contextlib.contextmanager
|
||||
def set_environ(env_name, value):
|
||||
"""Set the environment variable 'env_name' to 'value'
|
||||
|
||||
Save previous value, yield, and then restore the previous value stored in
|
||||
the environment variable 'env_name'.
|
||||
|
||||
If 'value' is None, do nothing"""
|
||||
if value is not None:
|
||||
old_value = os.environ.get(env_name)
|
||||
os.environ[env_name] = value
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if value is None:
|
||||
return
|
||||
if old_value is None:
|
||||
del os.environ[env_name]
|
||||
else:
|
||||
os.environ[env_name] = old_value
|
||||
|
||||
|
||||
def should_bypass_proxies(url, no_proxy):
|
||||
"""
|
||||
Returns whether we should bypass proxies or not.
|
||||
|
||||
@@ -564,7 +587,9 @@ def should_bypass_proxies(url):
|
||||
|
||||
# First check whether no_proxy is defined. If it is, check that the URL
|
||||
# we're getting isn't in the no_proxy list.
|
||||
no_proxy = get_proxy('no_proxy')
|
||||
no_proxy_arg = no_proxy
|
||||
if no_proxy is None:
|
||||
no_proxy = get_proxy('no_proxy')
|
||||
netloc = urlparse(url).netloc
|
||||
|
||||
if no_proxy:
|
||||
@@ -597,10 +622,11 @@ def should_bypass_proxies(url):
|
||||
# of Python 2.6, so allow this call to fail. Only catch the specific
|
||||
# exceptions we've seen, though: this call failing in other ways can reveal
|
||||
# legitimate problems.
|
||||
try:
|
||||
bypass = proxy_bypass(netloc)
|
||||
except (TypeError, socket.gaierror):
|
||||
bypass = False
|
||||
with set_environ('no_proxy', no_proxy_arg):
|
||||
try:
|
||||
bypass = proxy_bypass(netloc)
|
||||
except (TypeError, socket.gaierror):
|
||||
bypass = False
|
||||
|
||||
if bypass:
|
||||
return True
|
||||
@@ -608,13 +634,13 @@ def should_bypass_proxies(url):
|
||||
return False
|
||||
|
||||
|
||||
def get_environ_proxies(url):
|
||||
def get_environ_proxies(url, no_proxy):
|
||||
"""
|
||||
Return a dict of environment proxies.
|
||||
|
||||
:rtype: dict
|
||||
"""
|
||||
if should_bypass_proxies(url):
|
||||
if should_bypass_proxies(url, no_proxy=no_proxy):
|
||||
return {}
|
||||
else:
|
||||
return getproxies()
|
||||
|
||||
+49
-3
@@ -161,7 +161,7 @@ class TestGetEnvironProxies:
|
||||
'http://localhost.localdomain:5000/v1.0/',
|
||||
))
|
||||
def test_bypass(self, url):
|
||||
assert get_environ_proxies(url) == {}
|
||||
assert get_environ_proxies(url, no_proxy=None) == {}
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'url', (
|
||||
@@ -170,7 +170,32 @@ class TestGetEnvironProxies:
|
||||
'http://www.requests.com/',
|
||||
))
|
||||
def test_not_bypass(self, url):
|
||||
assert get_environ_proxies(url) != {}
|
||||
assert get_environ_proxies(url, no_proxy=None) != {}
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'url', (
|
||||
'http://192.168.1.1:5000/',
|
||||
'http://192.168.1.1/',
|
||||
'http://www.requests.com/',
|
||||
))
|
||||
def test_bypass_no_proxy_keyword(self, url):
|
||||
no_proxy = '192.168.1.1,requests.com'
|
||||
assert get_environ_proxies(url, no_proxy=no_proxy) == {}
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'url', (
|
||||
'http://192.168.0.1:5000/',
|
||||
'http://192.168.0.1/',
|
||||
'http://172.16.1.1/',
|
||||
'http://172.16.1.1:5000/',
|
||||
'http://localhost.localdomain:5000/v1.0/',
|
||||
))
|
||||
def test_not_bypass_no_proxy_keyword(self, url, monkeypatch):
|
||||
# This is testing that the 'no_proxy' argument overrides the
|
||||
# environment variable 'no_proxy'
|
||||
monkeypatch.setenv('http_proxy', 'http://proxy.example.com:3128/')
|
||||
no_proxy = '192.168.1.1,requests.com'
|
||||
assert get_environ_proxies(url, no_proxy=no_proxy) != {}
|
||||
|
||||
|
||||
class TestIsIPv4Address:
|
||||
@@ -525,7 +550,7 @@ def test_should_bypass_proxies(url, expected, monkeypatch):
|
||||
"""
|
||||
monkeypatch.setenv('no_proxy', '192.168.0.0/24,127.0.0.1,localhost.localdomain,172.16.1.1')
|
||||
monkeypatch.setenv('NO_PROXY', '192.168.0.0/24,127.0.0.1,localhost.localdomain,172.16.1.1')
|
||||
assert should_bypass_proxies(url) == expected
|
||||
assert should_bypass_proxies(url, no_proxy=None) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -553,3 +578,24 @@ def test_add_dict_to_cookiejar(cookiejar):
|
||||
)
|
||||
def test_unicode_is_ascii(value, expected):
|
||||
assert unicode_is_ascii(value) is expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'url, expected', (
|
||||
('http://192.168.0.1:5000/', True),
|
||||
('http://192.168.0.1/', True),
|
||||
('http://172.16.1.1/', True),
|
||||
('http://172.16.1.1:5000/', True),
|
||||
('http://localhost.localdomain:5000/v1.0/', True),
|
||||
('http://172.16.1.12/', False),
|
||||
('http://172.16.1.12:5000/', False),
|
||||
('http://google.com:5000/v1.0/', False),
|
||||
))
|
||||
def test_should_bypass_proxies_no_proxy(
|
||||
url, expected, monkeypatch):
|
||||
"""Tests for function should_bypass_proxies to check if proxy
|
||||
can be bypassed or not using the 'no_proxy' argument
|
||||
"""
|
||||
no_proxy = '192.168.0.0/24,127.0.0.1,localhost.localdomain,172.16.1.1'
|
||||
# Test 'no_proxy' argument
|
||||
assert should_bypass_proxies(url, no_proxy=no_proxy) == expected
|
||||
|
||||
Reference in New Issue
Block a user