Skip to content

Commit 88b44b5

Browse files
committed
Enhance proxy handling in SessionRedirectMixin to respect user-defined proxies during redirects. Added a flag to prevent environment proxy settings from overriding explicit user settings. Updated tests to verify correct behavior when proxies are explicitly set to None.
1 parent 7029833 commit 88b44b5

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

src/requests/sessions.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ def resolve_redirects(
166166
cert=None,
167167
proxies=None,
168168
yield_requests=False,
169+
_user_explicitly_set_proxies=False,
169170
**adapter_kwargs,
170171
):
171172
"""Receives a Response. Returns a generator of Responses or Requests."""
@@ -242,7 +243,7 @@ def resolve_redirects(
242243
prepared_request.prepare_cookies(prepared_request._cookies)
243244

244245
# Rebuild auth and proxy information.
245-
proxies = self.rebuild_proxies(prepared_request, proxies)
246+
proxies = self.rebuild_proxies(prepared_request, proxies, _user_explicitly_set_proxies)
246247
self.rebuild_auth(prepared_request, resp)
247248

248249
# A failed tell() sets `_body_position` to `object()`. This non-None
@@ -299,7 +300,7 @@ def rebuild_auth(self, prepared_request, response):
299300
if new_auth is not None:
300301
prepared_request.prepare_auth(new_auth)
301302

302-
def rebuild_proxies(self, prepared_request, proxies):
303+
def rebuild_proxies(self, prepared_request, proxies, _user_explicitly_set_proxies=False):
303304
"""This method re-evaluates the proxy configuration by considering the
304305
environment variables. If we are redirected to a URL covered by
305306
NO_PROXY, we strip the proxy configuration. Otherwise, we set missing
@@ -313,7 +314,9 @@ def rebuild_proxies(self, prepared_request, proxies):
313314
"""
314315
headers = prepared_request.headers
315316
scheme = urlparse(prepared_request.url).scheme
316-
new_proxies = resolve_proxies(prepared_request, proxies, self.trust_env)
317+
# Don't trust environment if user explicitly set proxies (even if empty after merge)
318+
trust_env = self.trust_env if not _user_explicitly_set_proxies else False
319+
new_proxies = resolve_proxies(prepared_request, proxies, trust_env)
317320

318321
if "Proxy-Authorization" in headers:
319322
del headers["Proxy-Authorization"]
@@ -720,7 +723,9 @@ def send(self, request, **kwargs):
720723
# Resolve redirects if allowed.
721724
if allow_redirects:
722725
# Redirect resolving generator.
723-
gen = self.resolve_redirects(r, request, **kwargs)
726+
# Track if user explicitly set proxies to avoid environment override on redirects
727+
user_set_proxies = "proxies" in kwargs and kwargs.get("proxies") is not None
728+
gen = self.resolve_redirects(r, request, _user_explicitly_set_proxies=user_set_proxies, **kwargs)
724729
history = [resp for resp in gen]
725730
else:
726731
history = []
@@ -736,8 +741,9 @@ def send(self, request, **kwargs):
736741
# If redirects aren't being followed, store the response on the Request for Response.next().
737742
if not allow_redirects:
738743
try:
744+
user_set_proxies = "proxies" in kwargs and kwargs.get("proxies") is not None
739745
r._next = next(
740-
self.resolve_redirects(r, request, yield_requests=True, **kwargs)
746+
self.resolve_redirects(r, request, yield_requests=True, _user_explicitly_set_proxies=user_set_proxies, **kwargs)
741747
)
742748
except StopIteration:
743749
pass

tests/test_requests.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,19 @@ def test_proxy_authorization_not_appended_to_https_request(
670670

671671
assert ("Proxy-Authorization" in prep.headers) is has_proxy_auth
672672

673+
def test_proxy_bypass_on_redirect_with_explicit_none(self, httpbin):
674+
"""Test that explicit proxies={'http': None} bypasses proxy on redirects.
675+
676+
This tests issue #6981 where redirects would incorrectly use environment
677+
proxy settings even when the user explicitly passed proxies={'http': None}
678+
to bypass the proxy.
679+
"""
680+
with override_environ(http_proxy=INVALID_PROXY):
681+
# This should succeed because we explicitly bypass the proxy
682+
session = requests.Session()
683+
resp = session.get(httpbin("redirect/1"), proxies={'http': None, 'https': None})
684+
assert resp.status_code == 200
685+
673686
def test_basicauth_with_netrc(self, httpbin):
674687
auth = ("user", "pass")
675688
wrong_auth = ("wronguser", "wrongpass")

0 commit comments

Comments
 (0)