Skip to content

Commit b9d84af

Browse files
ozturkberkaysfc-gh-mkeller
authored andcommitted
Fix leaking proxy env vars
1 parent 2b44cd3 commit b9d84af

File tree

5 files changed

+46
-66
lines changed

5 files changed

+46
-66
lines changed

src/snowflake/connector/connection.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
from cryptography.hazmat.primitives import serialization
3333
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
3434

35-
from . import errors, proxy
35+
from . import errors
3636
from ._query_context_cache import QueryContextCache
3737
from .auth import (
3838
FIRST_PARTY_AUTHENTICATORS,
@@ -927,16 +927,16 @@ def __open_connection(self):
927927
use_numpy=self._numpy, support_negative_year=self._support_negative_year
928928
)
929929

930-
proxy.set_proxies(
931-
self.proxy_host, self.proxy_port, self.proxy_user, self.proxy_password
932-
)
933-
934930
self._rest = SnowflakeRestful(
935931
host=self.host,
936932
port=self.port,
937933
protocol=self._protocol,
938934
inject_client_pause=self._inject_client_pause,
939935
connection=self,
936+
proxy_host=self.proxy_host,
937+
proxy_port=self.proxy_port,
938+
proxy_user=self.proxy_user,
939+
proxy_password=self.proxy_password,
940940
)
941941
logger.debug("REST API object was created: %s:%s", self.host, self.port)
942942

src/snowflake/connector/network.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
ServiceUnavailableError,
8888
TooManyRequests,
8989
)
90+
from .proxy import get_proxy_url
9091
from .sqlstate import (
9192
SQLSTATE_CONNECTION_NOT_EXISTS,
9293
SQLSTATE_CONNECTION_REJECTED,
@@ -363,9 +364,14 @@ def __init__(
363364
protocol: str = "http",
364365
inject_client_pause: int = 0,
365366
connection: SnowflakeConnection | None = None,
367+
proxy_host: str | None = None,
368+
proxy_port: str | None = None,
369+
proxy_user: str | None = None,
370+
proxy_password: str | None = None,
366371
) -> None:
367372
self._host = host
368373
self._port = port
374+
self._proxy = get_proxy_url(proxy_host, proxy_port, proxy_user, proxy_password)
369375
self._protocol = protocol
370376
self._inject_client_pause = inject_client_pause
371377
self._connection = connection
@@ -1160,6 +1166,7 @@ def make_requests_session(self) -> Session:
11601166
s.mount("http://", ProxySupportAdapter(max_retries=REQUESTS_RETRY))
11611167
s.mount("https://", ProxySupportAdapter(max_retries=REQUESTS_RETRY))
11621168
s._reuse_count = itertools.count()
1169+
s.proxies = {"http": self._proxy, "https": self._proxy}
11631170
return s
11641171

11651172
@contextlib.contextmanager

src/snowflake/connector/proxy.py

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,43 +5,26 @@
55

66
from __future__ import annotations
77

8-
import os
98

10-
11-
def set_proxies(
9+
def get_proxy_url(
1210
proxy_host: str | None,
1311
proxy_port: str | None,
1412
proxy_user: str | None = None,
1513
proxy_password: str | None = None,
16-
) -> dict[str, str] | None:
17-
"""Sets proxy dict for requests."""
18-
PREFIX_HTTP = "http://"
19-
PREFIX_HTTPS = "https://"
20-
proxies = None
14+
) -> str | None:
15+
http_prefix = "http://"
16+
https_prefix = "https://"
17+
2118
if proxy_host and proxy_port:
22-
if proxy_host.startswith(PREFIX_HTTP):
23-
proxy_host = proxy_host[len(PREFIX_HTTP) :]
24-
elif proxy_host.startswith(PREFIX_HTTPS):
25-
proxy_host = proxy_host[len(PREFIX_HTTPS) :]
26-
if proxy_user or proxy_password:
27-
proxy_auth = "{proxy_user}:{proxy_password}@".format(
28-
proxy_user=proxy_user if proxy_user is not None else "",
29-
proxy_password=proxy_password if proxy_password is not None else "",
30-
)
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) :]
3123
else:
32-
proxy_auth = ""
33-
proxies = {
34-
"http": "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-
"https": "http://{proxy_auth}{proxy_host}:{proxy_port}".format(
40-
proxy_host=proxy_host,
41-
proxy_port=str(proxy_port),
42-
proxy_auth=proxy_auth,
43-
),
44-
}
45-
os.environ["HTTP_PROXY"] = proxies["http"]
46-
os.environ["HTTPS_PROXY"] = proxies["https"]
47-
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
@@ -524,6 +524,8 @@ def test_invalid_account_timeout():
524524

525525
@pytest.mark.timeout(15)
526526
def test_invalid_proxy(db_parameters):
527+
http_proxy = os.environ.get("HTTP_PROXY")
528+
https_proxy = os.environ.get("HTTPS_PROXY")
527529
with pytest.raises(OperationalError):
528530
snowflake.connector.connect(
529531
protocol="http",
@@ -532,13 +534,13 @@ def test_invalid_proxy(db_parameters):
532534
password=db_parameters["password"],
533535
host=db_parameters["host"],
534536
port=db_parameters["port"],
535-
login_timeout=5,
537+
login_timeout=0,
536538
proxy_host="localhost",
537539
proxy_port="3333",
538540
)
539-
# NOTE environment variable is set if the proxy parameter is specified.
540-
del os.environ["HTTP_PROXY"]
541-
del os.environ["HTTPS_PROXY"]
541+
# Proxy environment variables should not change
542+
assert os.environ.get("HTTP_PROXY") == http_proxy
543+
assert os.environ.get("HTTPS_PROXY") == https_proxy
542544

543545

544546
@pytest.mark.timeout(15)

test/unit/test_proxies.py

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,18 @@
1414
import snowflake.connector
1515
from snowflake.connector.errors import OperationalError
1616

17-
18-
def test_set_proxies():
19-
from snowflake.connector.proxy import set_proxies
20-
21-
assert set_proxies("proxyhost", "8080") == {
22-
"http": "http://proxyhost:8080",
23-
"https": "http://proxyhost:8080",
24-
}
25-
assert set_proxies("http://proxyhost", "8080") == {
26-
"http": "http://proxyhost:8080",
27-
"https": "http://proxyhost:8080",
28-
}
29-
assert set_proxies("http://proxyhost", "8080", "testuser", "testpass") == {
30-
"http": "http://testuser:testpass@proxyhost:8080",
31-
"https": "http://testuser:testpass@proxyhost:8080",
32-
}
33-
assert set_proxies("proxyhost", "8080", "testuser", "testpass") == {
34-
"http": "http://testuser:testpass@proxyhost:8080",
35-
"https": "http://testuser:testpass@proxyhost:8080",
36-
}
37-
38-
# NOTE environment variable is set if the proxy parameter is specified.
39-
del os.environ["HTTP_PROXY"]
40-
del os.environ["HTTPS_PROXY"]
17+
def test_get_proxy_url():
18+
from snowflake.connector.proxy import get_proxy_url
19+
20+
assert get_proxy_url("host", "port", "user", "password") == (
21+
"http://user:password@host:port"
22+
)
23+
assert get_proxy_url("host", "port") == "http://host:port"
24+
25+
assert get_proxy_url("http://host", "port") == "http://host:port"
26+
assert get_proxy_url("https://host", "port", "user", "password") == (
27+
"http://user:password@host:port"
28+
)
4129

4230

4331
@pytest.mark.skipolddriver

0 commit comments

Comments
 (0)