From 5229322fe2cfa0b4cfaf7968e5f3396f6c1cc28d Mon Sep 17 00:00:00 2001 From: q0w <43147888+q0w@users.noreply.github.com> Date: Fri, 6 May 2022 07:16:59 +0300 Subject: [PATCH 1/4] Make proxy parameter override environment proxy --- news/10685.bugfix.rst | 1 + src/pip/_internal/cli/req_command.py | 1 + tests/functional/test_proxy.py | 37 ++++++++++++++++++++++++++++ tests/requirements.txt | 1 + 4 files changed, 40 insertions(+) create mode 100644 news/10685.bugfix.rst create mode 100644 tests/functional/test_proxy.py diff --git a/news/10685.bugfix.rst b/news/10685.bugfix.rst new file mode 100644 index 00000000000..a0bc7ed5285 --- /dev/null +++ b/news/10685.bugfix.rst @@ -0,0 +1 @@ +Make the ``--proxy`` parameter take precedence over environment variables. diff --git a/src/pip/_internal/cli/req_command.py b/src/pip/_internal/cli/req_command.py index 1044809f040..c0f06b9aaa4 100644 --- a/src/pip/_internal/cli/req_command.py +++ b/src/pip/_internal/cli/req_command.py @@ -148,6 +148,7 @@ def _build_session( "http": options.proxy, "https": options.proxy, } + session.trust_env = False # Determine if we can prompt the user for authentication or not session.auth.prompting = not options.no_input diff --git a/tests/functional/test_proxy.py b/tests/functional/test_proxy.py new file mode 100644 index 00000000000..9ebca2e1d3b --- /dev/null +++ b/tests/functional/test_proxy.py @@ -0,0 +1,37 @@ +from typing import Any, Dict, Optional + +import proxy +import pytest +from proxy.http.proxy import HttpProxyBasePlugin + +from tests.lib import PipTestEnvironment +from tests.lib.path import Path + + +class AccessLogPlugin(HttpProxyBasePlugin): + def on_access_log(self, context: Dict[str, Any]) -> Optional[Dict[str, Any]]: + print(context) + return super().on_access_log(context) + + +@pytest.mark.network +def test_proxy_overrides_env( + script: PipTestEnvironment, monkeypatch: pytest.MonkeyPatch +) -> None: + monkeypatch.setenv("http_proxy", "127:0.0.1:8888") + monkeypatch.setenv("https_proxy", "127:0.0.1:8888") + with proxy.Proxy( + port=8899, + ), proxy.Proxy(plugins=[AccessLogPlugin], port=8888): + result = script.pip( + "download", + "--proxy", + "http://127.0.0.1:8899", + "--trusted-host", + "127.0.0.1", + "-d", + "pip_downloads", + "INITools==0.1", + ) + result.did_create(Path("scratch") / "pip_downloads" / "INITools-0.1.tar.gz") + assert "CONNECT" not in result.stdout diff --git a/tests/requirements.txt b/tests/requirements.txt index 9ce6d62078a..1251ec5d38c 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -11,3 +11,4 @@ virtualenv < 20.0 werkzeug wheel tomli-w +proxy.py From 759c4770ca3a842c56c05c5f559c3e66c2f99a39 Mon Sep 17 00:00:00 2001 From: q0w <43147888+q0w@users.noreply.github.com> Date: Tue, 31 May 2022 11:32:44 +0300 Subject: [PATCH 2/4] Test against netrc env --- tests/functional/test_proxy.py | 66 ++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/tests/functional/test_proxy.py b/tests/functional/test_proxy.py index 9ebca2e1d3b..0d8415f2c9f 100644 --- a/tests/functional/test_proxy.py +++ b/tests/functional/test_proxy.py @@ -1,11 +1,19 @@ +import ssl +from pathlib import Path from typing import Any, Dict, Optional import proxy import pytest from proxy.http.proxy import HttpProxyBasePlugin -from tests.lib import PipTestEnvironment -from tests.lib.path import Path +from tests.conftest import CertFactory +from tests.lib import PipTestEnvironment, TestData +from tests.lib.server import ( + authorization_response, + make_mock_server, + package_page, + server_running, +) class AccessLogPlugin(HttpProxyBasePlugin): @@ -15,14 +23,12 @@ def on_access_log(self, context: Dict[str, Any]) -> Optional[Dict[str, Any]]: @pytest.mark.network -def test_proxy_overrides_env( - script: PipTestEnvironment, monkeypatch: pytest.MonkeyPatch -) -> None: - monkeypatch.setenv("http_proxy", "127:0.0.1:8888") - monkeypatch.setenv("https_proxy", "127:0.0.1:8888") +def test_proxy_overrides_env(script: PipTestEnvironment) -> None: with proxy.Proxy( port=8899, ), proxy.Proxy(plugins=[AccessLogPlugin], port=8888): + script.environ["http_proxy"] = "127:0.0.1:8888" + script.environ["https_proxy"] = "127:0.0.1:8888" result = script.pip( "download", "--proxy", @@ -35,3 +41,49 @@ def test_proxy_overrides_env( ) result.did_create(Path("scratch") / "pip_downloads" / "INITools-0.1.tar.gz") assert "CONNECT" not in result.stdout + + +def test_proxy_does_not_override_netrc( + script: PipTestEnvironment, + data: TestData, + cert_factory: CertFactory, +) -> None: + cert_path = cert_factory() + ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + ctx.load_cert_chain(cert_path, cert_path) + ctx.load_verify_locations(cafile=cert_path) + ctx.verify_mode = ssl.CERT_REQUIRED + + server = make_mock_server(ssl_context=ctx) + server.mock.side_effect = [ + package_page( + { + "simple-3.0.tar.gz": "/files/simple-3.0.tar.gz", + } + ), + authorization_response(data.packages / "simple-3.0.tar.gz"), + authorization_response(data.packages / "simple-3.0.tar.gz"), + ] + + url = f"https://{server.host}:{server.port}/simple" + + netrc = script.scratch_path / ".netrc" + netrc.write_text(f"machine {server.host} login USERNAME password PASSWORD") + with proxy.Proxy(port=8888), server_running(server): + script.environ["NETRC"] = netrc + script.pip( + "install", + "--proxy", + "http://127.0.0.1:8888", + "--trusted-host", + "127.0.0.1", + "--no-cache-dir", + "--index-url", + url, + "--cert", + cert_path, + "--client-cert", + cert_path, + "simple", + ) + script.assert_installed(simple="3.0") From b64d1f798018ca8b77baf3ea1796adc9ccadd910 Mon Sep 17 00:00:00 2001 From: q0w <43147888+q0w@users.noreply.github.com> Date: Wed, 15 Jun 2022 22:10:25 +0300 Subject: [PATCH 3/4] Test proxy --- tests/functional/test_proxy.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/functional/test_proxy.py b/tests/functional/test_proxy.py index 0d8415f2c9f..f85c83bd1a3 100644 --- a/tests/functional/test_proxy.py +++ b/tests/functional/test_proxy.py @@ -1,6 +1,6 @@ import ssl from pathlib import Path -from typing import Any, Dict, Optional +from typing import Any, Dict import proxy import pytest @@ -17,18 +17,18 @@ class AccessLogPlugin(HttpProxyBasePlugin): - def on_access_log(self, context: Dict[str, Any]) -> Optional[Dict[str, Any]]: + def on_access_log(self, context: Dict[str, Any]) -> None: print(context) - return super().on_access_log(context) @pytest.mark.network def test_proxy_overrides_env(script: PipTestEnvironment) -> None: with proxy.Proxy( port=8899, - ), proxy.Proxy(plugins=[AccessLogPlugin], port=8888): - script.environ["http_proxy"] = "127:0.0.1:8888" - script.environ["https_proxy"] = "127:0.0.1:8888" + num_acceptors=1, + ), proxy.Proxy(plugins=[AccessLogPlugin], port=8888, num_acceptors=1): + script.environ["http_proxy"] = "127.0.0.1:8888" + script.environ["https_proxy"] = "127.0.0.1:8888" result = script.pip( "download", "--proxy", @@ -69,7 +69,7 @@ def test_proxy_does_not_override_netrc( netrc = script.scratch_path / ".netrc" netrc.write_text(f"machine {server.host} login USERNAME password PASSWORD") - with proxy.Proxy(port=8888), server_running(server): + with proxy.Proxy(port=8888, num_acceptors=1), server_running(server): script.environ["NETRC"] = netrc script.pip( "install", From 07e51e7e3cde179ca14310370f807ea8cc5958af Mon Sep 17 00:00:00 2001 From: q0w <43147888+q0w@users.noreply.github.com> Date: Fri, 7 Oct 2022 21:40:49 +0300 Subject: [PATCH 4/4] Capture stdout by capfd --- tests/functional/test_proxy.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/functional/test_proxy.py b/tests/functional/test_proxy.py index f85c83bd1a3..ab53637900f 100644 --- a/tests/functional/test_proxy.py +++ b/tests/functional/test_proxy.py @@ -22,7 +22,9 @@ def on_access_log(self, context: Dict[str, Any]) -> None: @pytest.mark.network -def test_proxy_overrides_env(script: PipTestEnvironment) -> None: +def test_proxy_overrides_env( + script: PipTestEnvironment, capfd: pytest.CaptureFixture[str] +) -> None: with proxy.Proxy( port=8899, num_acceptors=1, @@ -40,7 +42,8 @@ def test_proxy_overrides_env(script: PipTestEnvironment) -> None: "INITools==0.1", ) result.did_create(Path("scratch") / "pip_downloads" / "INITools-0.1.tar.gz") - assert "CONNECT" not in result.stdout + out, _ = capfd.readouterr() + assert "CONNECT" not in out def test_proxy_does_not_override_netrc(