Restrict URL preparation to HTTP/HTTPS

Requests treats all URLs starting with the string 'http' as HTTP URLs.
Preparation with IDNA breaks non-standard URIs like http+unix. Requests
now prepares only URLs with prefix http:// and https://.

Signed-off-by: Christian Heimes <christian@python.org>
This commit is contained in:
Christian Heimes
2016-11-21 18:00:24 +01:00
parent 268672ab33
commit 34af72c87d
2 changed files with 20 additions and 3 deletions
+3 -3
View File
@@ -347,9 +347,9 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
url = url.lstrip()
# Don't do any URL preparation for non-HTTP schemes like `mailto`,
# `data` etc to work around exceptions from `url_parse`, which
# handles RFC 3986 only.
if ':' in url and not url.lower().startswith('http'):
# `data`, `http+unix` etc to work around exceptions from `url_parse`,
# which handles RFC 3986 only.
if ':' in url and not url.lower().startswith(('http://', 'https://')):
self.url = url
return
+17
View File
@@ -2138,3 +2138,20 @@ class TestPreparingURLs(object):
r = requests.Request('GET', url=url)
with pytest.raises(requests.exceptions.InvalidURL):
r.prepare()
@pytest.mark.parametrize(
'protocol, url',
(
("http+unix://", b"http+unix://%2Fvar%2Frun%2Fsocket/path"),
("http+unix://", u"http+unix://%2Fvar%2Frun%2Fsocket/path"),
("mailto", b"mailto:user@example.org"),
("mailto", u"mailto:user@example.org"),
("data", b"data:SSDimaUgUHl0aG9uIQ=="),
)
)
def test_url_passthrough(self, protocol, url):
session = requests.Session()
session.mount(protocol, HTTPAdapter())
p = requests.Request('GET', url=url)
p.prepare()
assert p.url == url