diff --git a/src/urllib3/exceptions.py b/src/urllib3/exceptions.py index d69958d5df..232469bd13 100644 --- a/src/urllib3/exceptions.py +++ b/src/urllib3/exceptions.py @@ -289,7 +289,14 @@ class ProxySchemeUnknown(AssertionError, URLSchemeUnknown): # TODO(t-8ch): Stop inheriting from AssertionError in v2.0. def __init__(self, scheme): - message = "Not supported proxy scheme %s" % scheme + # 'localhost' is here because our URL parser parses + # localhost:8080 -> scheme=localhost, remove if we fix this. + if scheme == "localhost": + scheme = None + if scheme is None: + message = "Proxy URL had no scheme, should start with http:// or https://" + else: + message = f"Proxy URL had unsupported scheme {scheme}, should use http:// or https://" super(ProxySchemeUnknown, self).__init__(message) diff --git a/test/with_dummyserver/test_proxy_poolmanager.py b/test/with_dummyserver/test_proxy_poolmanager.py index 67cee77a58..737e5f7afa 100644 --- a/test/with_dummyserver/test_proxy_poolmanager.py +++ b/test/with_dummyserver/test_proxy_poolmanager.py @@ -23,6 +23,7 @@ ConnectTimeoutError, MaxRetryError, ProxyError, + ProxySchemeUnknown, ProxySchemeUnsupported, SSLError, ) @@ -502,6 +503,27 @@ def test_scheme_host_case_insensitive(self): r = http.request("GET", "%s/" % self.https_url.upper()) assert r.status == 200 + @pytest.mark.parametrize( + "url, error_msg", + [ + ( + "127.0.0.1", + "Proxy URL had no scheme, should start with http:// or https://", + ), + ( + "localhost:8080", + "Proxy URL had no scheme, should start with http:// or https://", + ), + ( + "ftp://google.com", + "Proxy URL had unsupported scheme ftp, should use http:// or https://", + ), + ], + ) + def test_invalid_schema(self, url, error_msg): + with pytest.raises(ProxySchemeUnknown, match=error_msg): + proxy_from_url(url) + @pytest.mark.skipif(not HAS_IPV6, reason="Only runs on IPv6 systems") class TestIPv6HTTPProxyManager(IPv6HTTPDummyProxyTestCase):