Fix incorrect error message during connection errors to HTTPS websites using a HTTP proxy
MODIFY
src/urllib3/connection.py
src/urllib3/connection.py
@@ -60,6 +60,7 @@ from .util.ssl_ import (
ssl_wrap_socket,
)
from .util.ssl_match_hostname import CertificateError, match_hostname
+from .util.url import Url
# Not a no-op, we're adding this to the namespace so it can be imported.
ConnectionError = ConnectionError
@@ -141,7 +142,7 @@ class HTTPConnection(_HTTPConnection):
socket_options: Optional[
connection._TYPE_SOCKET_OPTIONS
] = default_socket_options,
- proxy: Optional[str] = None,
+ proxy: Optional[Url] = None,
proxy_config: Optional[ProxyConfig] = None,
) -> None:
# Pre-set source_address.
@@ -386,7 +387,7 @@ class HTTPSConnection(HTTPConnection):
socket_options: Optional[
connection._TYPE_SOCKET_OPTIONS
] = HTTPConnection.default_socket_options,
- proxy: Optional[str] = None,
+ proxy: Optional[Url] = None,
proxy_config: Optional[ProxyConfig] = None,
) -> None:
@@ -685,7 +686,7 @@ def _match_hostname(
raise
-def _wrap_proxy_error(err: Exception) -> ProxyError:
+def _wrap_proxy_error(err: Exception, proxy_scheme: Optional[str]) -> ProxyError:
# Look for the phrase 'wrong version number', if found
# then we should warn the user that we're very sure that
# this proxy is HTTP-only and they have a configuration issue.
@@ -702,7 +703,7 @@ def _wrap_proxy_error(err: Exception) -> ProxyError:
)
new_err = ProxyError(
f"Unable to connect to proxy"
- f"{http_proxy_warning if is_likely_http_proxy else ''}",
+ f"{http_proxy_warning if is_likely_http_proxy and proxy_scheme == 'https' else ''}",
err,
)
new_err.__cause__ = err

MODIFY
src/urllib3/connectionpool.py
src/urllib3/connectionpool.py
@@ -420,8 +420,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
new_e = SSLError(e)
if isinstance(
new_e, (OSError, NewConnectionError, TimeoutError, SSLError)
- ) and (conn and conn._connecting_to_proxy):
- new_e = _wrap_proxy_error(new_e)
+ ) and (conn and conn._connecting_to_proxy and conn.proxy):
+ new_e = _wrap_proxy_error(new_e, conn.proxy.scheme)
raise new_e
# conn.request() calls http.client.*.request, not the method in
@@ -786,8 +786,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
SSLError,
HTTPException,
),
- ) and (conn and conn._connecting_to_proxy):
- new_e = _wrap_proxy_error(new_e)
+ ) and (conn and conn._connecting_to_proxy and conn.proxy):
+ new_e = _wrap_proxy_error(new_e, conn.proxy.scheme)
elif isinstance(new_e, (OSError, HTTPException)):
new_e = ProtocolError("Connection aborted.", new_e)

MODIFY
test/test_connection.py
test/test_connection.py
@@ -10,7 +10,9 @@ from urllib3.connection import ( # type: ignore[attr-defined]
CertificateError,
HTTPSConnection,
_match_hostname,
+ _wrap_proxy_error,
)
+from urllib3.exceptions import HTTPError, ProxyError
from urllib3.util.ssl_match_hostname import (
CertificateError as ImplementationCertificateError,
)
@@ -183,3 +185,18 @@ class TestConnection:
def test_HTTPSConnection_default_socket_options(self) -> None:
conn = HTTPSConnection("not.a.real.host", port=443)
assert conn.socket_options == [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]
+
+ @pytest.mark.parametrize(
+ "proxy_scheme, err_part",
+ [
+ ("http", "Unable to connect to proxy"),
+ (
+ "https",
+ "Unable to connect to proxy. Your proxy appears to only use HTTP and not HTTPS",
+ ),
+ ],
+ )
+ def test_wrap_proxy_error(self, proxy_scheme: str, err_part: str) -> None:
+ new_err = _wrap_proxy_error(HTTPError("unknown protocol"), proxy_scheme)
+ assert isinstance(new_err, ProxyError) is True
+ assert err_part in new_err.args[0]

Fix incorrect error message during connection errors to HTTPS websites using a HTTP proxy