There are inconsistencies when working with proxy environment variables using Session objects.
When using Session#request or verb methods (get, post, put), those work correctly and use the proxy when they are present.
However Session#send(PreparedRequest) does not respect the variables by default, but does when it handles redirect responses, e.g. 303.
I've written a test class to present this behavior.
Expected Result
All methods in Session to respect the proxy variable.
Actual Result
Session#send(PreparedRequest) does not respect proxy environment variables.
Reproduction Steps
Test case 1 fails with a successful request.
import requests
import pytest
# Copied from requests/tests/utils.py for making this a standalone
import os
import contextlib
@contextlib.contextmanager
def override_environ(**kwargs):
save_env = dict(os.environ)
for key, value in kwargs.items():
if value is None:
del os.environ[key]
else:
os.environ[key] = value
try:
yield
finally:
os.environ.clear()
os.environ.update(save_env)
class TestSession:
def test_respect_proxy_env_on_send(self):
session = requests.Session()
# Does not respect the proxy configuration and ignores the proxy
request = requests.Request(
method='GET', url='https://www.google.com/'
)
with override_environ(https_proxy='http://example.com'):
try:
session.send(request.prepare())
assert False, "The proxy is invalid this request should not be successful."
except requests.exceptions.ProxyError as e:
assert 'Cannot connect to proxy' in str(e)
def test_respect_proxy_env_on_send_with_redirects(self):
session = requests.Session()
# Returns a 303 to www.google.com and respects the proxy
request = requests.Request(
method='GET', url='https://google.com/'
)
with override_environ(https_proxy='http://example.com'):
try:
session.send(request.prepare())
assert False, "The proxy is invalid this request should not be successful."
except requests.exceptions.ProxyError as e:
assert 'Cannot connect to proxy' in str(e)
def test_respect_proxy_env_on_get(self):
session = requests.Session()
with override_environ(https_proxy='http://example.com'):
try:
# No redirects
session.get('https://www.google.com')
assert False, "The proxy is invalid this request should not be successful."
except requests.exceptions.ProxyError as e:
assert 'Cannot connect to proxy' in str(e)
def test_respect_proxy_env_on_request(self):
session = requests.Session()
with override_environ(https_proxy='http://example.com'):
try:
# No redirects
session.request(method='GET', url='https://www.google.com')
assert False, "The proxy is invalid this request should not be successful."
except requests.exceptions.ProxyError as e:
assert 'Cannot connect to proxy' in str(e)
System Information
$ python -m requests.help
{
"chardet": {
"version": "3.0.4"
},
"cryptography": {
"version": ""
},
"idna": {
"version": "2.10"
},
"implementation": {
"name": "CPython",
"version": "3.8.1"
},
"platform": {
"release": "5.9.8-100.fc32.x86_64",
"system": "Linux"
},
"pyOpenSSL": {
"openssl_version": "",
"version": null
},
"requests": {
"version": "2.25.0"
},
"system_ssl": {
"version": "100020ff"
},
"urllib3": {
"version": "1.26.2"
},
"using_pyopenssl": false
}
There are inconsistencies when working with proxy environment variables using
Sessionobjects.When using
Session#requestor verb methods (get,post,put), those work correctly and use the proxy when they are present.However
Session#send(PreparedRequest)does not respect the variables by default, but does when it handles redirect responses, e.g.303.I've written a test class to present this behavior.
Expected Result
All methods in
Sessionto respect the proxy variable.Actual Result
Session#send(PreparedRequest)does not respect proxy environment variables.Reproduction Steps
Test case 1 fails with a successful request.
System Information