From 34af72c87d79bd8852e8564c050dd7711c6a08d6 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Mon, 21 Nov 2016 18:00:24 +0100 Subject: [PATCH] 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 --- requests/models.py | 6 +++--- tests/test_requests.py | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/requests/models.py b/requests/models.py index 1b77b303..24aa9ae3 100644 --- a/requests/models.py +++ b/requests/models.py @@ -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 diff --git a/tests/test_requests.py b/tests/test_requests.py index e2892f83..1b063eed 100755 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -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