Skip to content

Commit b94add9

Browse files
committed
Fix leaking proxy env vars
1 parent e0d8456 commit b94add9

File tree

5 files changed

+47
-62
lines changed

5 files changed

+47
-62
lines changed

src/snowflake/connector/connection.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from time import strptime
2323
from typing import Any, Callable, Generator, Iterable, NamedTuple, Sequence
2424

25-
from . import errors, proxy
25+
from . import errors
2626
from .auth import (
2727
FIRST_PARTY_AUTHENTICATORS,
2828
Auth,
@@ -715,16 +715,16 @@ def __open_connection(self):
715715
use_numpy=self._numpy, support_negative_year=self._support_negative_year
716716
)
717717

718-
proxy.set_proxies(
719-
self.proxy_host, self.proxy_port, self.proxy_user, self.proxy_password
720-
)
721-
722718
self._rest = SnowflakeRestful(
723719
host=self.host,
724720
port=self.port,
725721
protocol=self._protocol,
726722
inject_client_pause=self._inject_client_pause,
727723
connection=self,
724+
proxy_host=self.proxy_host,
725+
proxy_port=self.proxy_port,
726+
proxy_user=self.proxy_user,
727+
proxy_password=self.proxy_password,
728728
)
729729
logger.debug("REST API object was created: %s:%s", self.host, self.port)
730730

src/snowflake/connector/network.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
ProgrammingError,
7676
ServiceUnavailableError,
7777
)
78+
from .proxy import get_proxy_url
7879
from .sqlstate import (
7980
SQLSTATE_CONNECTION_NOT_EXISTS,
8081
SQLSTATE_CONNECTION_REJECTED,
@@ -346,9 +347,14 @@ def __init__(
346347
protocol="http",
347348
inject_client_pause=0,
348349
connection: SnowflakeConnection | None = None,
350+
proxy_host: str | None = None,
351+
proxy_port: str | None = None,
352+
proxy_user: str | None = None,
353+
proxy_password: str | None = None,
349354
):
350355
self._host = host
351356
self._port = port
357+
self._proxy = get_proxy_url(proxy_host, proxy_port, proxy_user, proxy_password)
352358
self._protocol = protocol
353359
self._inject_client_pause = inject_client_pause
354360
self._connection = connection
@@ -1130,6 +1136,7 @@ def make_requests_session(self):
11301136
s.mount("http://", ProxySupportAdapter(max_retries=REQUESTS_RETRY))
11311137
s.mount("https://", ProxySupportAdapter(max_retries=REQUESTS_RETRY))
11321138
s._reuse_count = itertools.count()
1139+
s.proxies = {"http": self._proxy, "https": self._proxy}
11331140
return s
11341141

11351142
@contextlib.contextmanager

src/snowflake/connector/proxy.py

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,26 @@
55

66
from __future__ import annotations
77

8-
import os
98

9+
def get_proxy_url(
10+
proxy_host: str | None,
11+
proxy_port: str | None,
12+
proxy_user: str | None = None,
13+
proxy_password: str | None = None,
14+
) -> str | None:
15+
http_prefix = "http://"
16+
https_prefix = "https://"
1017

11-
def set_proxies(proxy_host, proxy_port, proxy_user=None, proxy_password=None):
12-
"""Sets proxy dict for requests."""
13-
PREFIX_HTTP = "http://"
14-
PREFIX_HTTPS = "https://"
15-
proxies = None
1618
if proxy_host and proxy_port:
17-
if proxy_host.startswith(PREFIX_HTTP):
18-
proxy_host = proxy_host[len(PREFIX_HTTP) :]
19-
elif proxy_host.startswith(PREFIX_HTTPS):
20-
proxy_host = proxy_host[len(PREFIX_HTTPS) :]
21-
if proxy_user or proxy_password:
22-
proxy_auth = "{proxy_user}:{proxy_password}@".format(
23-
proxy_user=proxy_user if proxy_user is not None else "",
24-
proxy_password=proxy_password if proxy_password is not None else "",
25-
)
19+
if proxy_host.startswith(http_prefix):
20+
host = proxy_host[len(http_prefix) :]
21+
elif proxy_host.startswith(https_prefix):
22+
host = proxy_host[len(https_prefix) :]
2623
else:
27-
proxy_auth = ""
28-
proxies = {
29-
"http": "http://{proxy_auth}{proxy_host}:{proxy_port}".format(
30-
proxy_host=proxy_host,
31-
proxy_port=str(proxy_port),
32-
proxy_auth=proxy_auth,
33-
),
34-
"https": "http://{proxy_auth}{proxy_host}:{proxy_port}".format(
35-
proxy_host=proxy_host,
36-
proxy_port=str(proxy_port),
37-
proxy_auth=proxy_auth,
38-
),
39-
}
40-
os.environ["HTTP_PROXY"] = proxies["http"]
41-
os.environ["HTTPS_PROXY"] = proxies["https"]
42-
return proxies
24+
host = proxy_host
25+
auth = (
26+
f"{proxy_user or ''}:{proxy_password or ''}@"
27+
if proxy_user or proxy_password
28+
else ""
29+
)
30+
return f"{http_prefix}{auth}{host}:{proxy_port}"

test/integ/test_connection.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,8 @@ def test_invalid_account_timeout():
433433

434434
@pytest.mark.timeout(15)
435435
def test_invalid_proxy(db_parameters):
436+
http_proxy = os.environ.get("HTTP_PROXY")
437+
https_proxy = os.environ.get("HTTPS_PROXY")
436438
with pytest.raises(OperationalError):
437439
snowflake.connector.connect(
438440
protocol="http",
@@ -441,13 +443,13 @@ def test_invalid_proxy(db_parameters):
441443
password=db_parameters["password"],
442444
host=db_parameters["host"],
443445
port=db_parameters["port"],
444-
login_timeout=5,
446+
login_timeout=0,
445447
proxy_host="localhost",
446448
proxy_port="3333",
447449
)
448-
# NOTE environment variable is set if the proxy parameter is specified.
449-
del os.environ["HTTP_PROXY"]
450-
del os.environ["HTTPS_PROXY"]
450+
# Proxy environment variables should not change
451+
assert os.environ.get("HTTP_PROXY") == http_proxy
452+
assert os.environ.get("HTTPS_PROXY") == https_proxy
451453

452454

453455
@pytest.mark.timeout(15)

test/unit/test_proxies.py

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,17 @@
44
#
55
from __future__ import annotations
66

7-
import os
87

8+
def test_get_proxy_url():
9+
from snowflake.connector.proxy import get_proxy_url
910

10-
def test_set_proxies():
11-
from snowflake.connector.proxy import set_proxies
11+
assert get_proxy_url("host", "port", "user", "password") == (
12+
"http://user:password@host:port"
13+
)
14+
assert get_proxy_url("host", "port") == "http://host:port"
1215

13-
assert set_proxies("proxyhost", "8080") == {
14-
"http": "http://proxyhost:8080",
15-
"https": "http://proxyhost:8080",
16-
}
17-
assert set_proxies("http://proxyhost", "8080") == {
18-
"http": "http://proxyhost:8080",
19-
"https": "http://proxyhost:8080",
20-
}
21-
assert set_proxies("http://proxyhost", "8080", "testuser", "testpass") == {
22-
"http": "http://testuser:testpass@proxyhost:8080",
23-
"https": "http://testuser:testpass@proxyhost:8080",
24-
}
25-
assert set_proxies("proxyhost", "8080", "testuser", "testpass") == {
26-
"http": "http://testuser:testpass@proxyhost:8080",
27-
"https": "http://testuser:testpass@proxyhost:8080",
28-
}
16+
assert get_proxy_url("http://host", "port") == "http://host:port"
2917

30-
# NOTE environment variable is set if the proxy parameter is specified.
31-
del os.environ["HTTP_PROXY"]
32-
del os.environ["HTTPS_PROXY"]
18+
assert get_proxy_url("https://host", "port", "user", "password") == (
19+
"http://user:password@host:port"
20+
)

0 commit comments

Comments
 (0)