diff --git a/requests/utils.py b/requests/utils.py index 4283560e..57292c35 100644 --- a/requests/utils.py +++ b/requests/utils.py @@ -21,8 +21,8 @@ import sys from . import __version__ from . import certs from .compat import parse_http_list as _parse_list_header -from .compat import (quote, urlparse, bytes, str, OrderedDict, urlunparse, - is_py2, is_py3, builtin_str, getproxies, proxy_bypass) +from .compat import (quote, urlparse, bytes, str, OrderedDict, unquote, is_py2, + builtin_str, getproxies, proxy_bypass) from .cookies import RequestsCookieJar, cookiejar_from_dict from .structures import CaseInsensitiveDict from .exceptions import MissingSchema, InvalidURL @@ -558,6 +558,7 @@ def get_auth_from_url(url): """Given a url with authentication components, extract them into a tuple of username,password.""" if url: + url = unquote(url) parsed = urlparse(url) return (parsed.username, parsed.password) else: diff --git a/test_requests.py b/test_requests.py index 62307622..1d68c81f 100755 --- a/test_requests.py +++ b/test_requests.py @@ -598,6 +598,18 @@ class RequestsTestCase(unittest.TestCase): url = 'http://user:pass@complex.url.com/path?query=yes' assert ('user', 'pass') == requests.utils.get_auth_from_url(url) + def test_get_auth_from_url_encoded_spaces(self): + url = 'http://user:pass%20pass@complex.url.com/path?query=yes' + assert ('user', 'pass pass') == requests.utils.get_auth_from_url(url) + + def test_get_auth_from_url_not_encoded_spaces(self): + url = 'http://user:pass pass@complex.url.com/path?query=yes' + assert ('user', 'pass pass') == requests.utils.get_auth_from_url(url) + + def test_get_auth_from_url_percent_chars(self): + url = 'http://user%user:pass@complex.url.com/path?query=yes' + assert ('user%user', 'pass') == requests.utils.get_auth_from_url(url) + def test_cannot_send_unprepared_requests(self): r = requests.Request(url=HTTPBIN) with pytest.raises(ValueError):