From bbdbcc8f0553f112ff68b0950b4128bd8af000fc Mon Sep 17 00:00:00 2001
From: Nate Prewitt <Nate.Prewitt@gmail.com>
Date: Sun, 30 Sep 2018 18:36:05 -0600
Subject: [PATCH] wrap url parsing exceptions from urllib3's PoolManager

---
 HISTORY.md             |  8 ++++++--
 requests/adapters.py   |  9 +++++++--
 tests/test_requests.py | 10 ++++++++++
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/HISTORY.md b/HISTORY.md
index 2afdefcd34..116a6399a5 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -4,8 +4,12 @@ Release History
 dev
 ---
 
-**Bugfixes** - Content-Type header parsing is now case-insensitive (e.g.
-charset=utf8 v Charset=utf8).
+**Bugfixes**
+
+-   Content-Type header parsing is now case-insensitive (e.g.
+    charset=utf8 v Charset=utf8).
+-   Fixed exception leak where certain redirect urls would raise
+    uncaught urllib3 exceptions.
 
 -   \[Short description of non-trivial change.\]
 
diff --git a/requests/adapters.py b/requests/adapters.py
index 3b923a5a2c..f26391502e 100644
--- a/requests/adapters.py
+++ b/requests/adapters.py
@@ -26,6 +26,7 @@
 from urllib3.exceptions import ReadTimeoutError
 from urllib3.exceptions import SSLError as _SSLError
 from urllib3.exceptions import ResponseError
+from urllib3.exceptions import LocationValueError
 
 from .models import Response
 from .compat import urlparse, basestring
@@ -35,7 +36,8 @@
 from .structures import CaseInsensitiveDict
 from .cookies import extract_cookies_to_jar
 from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError,
-                         ProxyError, RetryError, InvalidSchema, InvalidProxyURL)
+                         ProxyError, RetryError, InvalidSchema, InvalidProxyURL,
+                         InvalidURL)
 from .auth import _basic_auth_str
 
 try:
@@ -407,7 +409,10 @@ def send(self, request, stream=False, timeout=None, verify=True, cert=None, prox
         :rtype: requests.Response
         """
 
-        conn = self.get_connection(request.url, proxies)
+        try:
+            conn = self.get_connection(request.url, proxies)
+        except LocationValueError as e:
+            raise InvalidURL(e, request=request)
 
         self.cert_verify(conn, request.url, verify, cert)
         url = self.request_url(request, proxies)
diff --git a/tests/test_requests.py b/tests/test_requests.py
index 660437988a..b4ee9f94d4 100644
--- a/tests/test_requests.py
+++ b/tests/test_requests.py
@@ -2426,6 +2426,16 @@ def test_preparing_bad_url(self, url):
         with pytest.raises(requests.exceptions.InvalidURL):
             r.prepare()
 
+    @pytest.mark.parametrize(
+        'url, exception',
+        (
+            ('http://localhost:-1', InvalidURL),
+        )
+    )
+    def test_redirecting_to_bad_url(self, httpbin, url, exception):
+        with pytest.raises(exception):
+            r = requests.get(httpbin('redirect-to'), params={'url': url})
+
     @pytest.mark.parametrize(
         'input, expected',
         (