From 402a55b647c852553ff6967403b12f6b6efc0fd8 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Wed, 30 Nov 2016 21:19:31 +0000 Subject: [PATCH 1/2] Revert "Restrict URL preparation to HTTP/HTTPS" This reverts commit 34af72c87d79bd8852e8564c050dd7711c6a08d6. --- requests/models.py | 6 +++--- tests/test_requests.py | 17 ----------------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/requests/models.py b/requests/models.py index cb44eddd..91555b58 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`, `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://')): + # `data` etc to work around exceptions from `url_parse`, which + # handles RFC 3986 only. + if ':' in url and not url.lower().startswith('http'): self.url = url return diff --git a/tests/test_requests.py b/tests/test_requests.py index ca90297e..3a5a3256 100755 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -2175,20 +2175,3 @@ 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 From 6f659a41794045292b836859f1281d33eeed8260 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Wed, 30 Nov 2016 21:45:09 +0000 Subject: [PATCH 2/2] Tests for our URL handling. --- tests/test_requests.py | 71 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/tests/test_requests.py b/tests/test_requests.py index 3a5a3256..2c298bab 100755 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -2175,3 +2175,74 @@ class TestPreparingURLs(object): r = requests.Request('GET', url=url) with pytest.raises(requests.exceptions.InvalidURL): r.prepare() + + @pytest.mark.parametrize( + 'input, expected', + ( + ( + b"http+unix://%2Fvar%2Frun%2Fsocket/path", + u"http+unix://%2fvar%2frun%2fsocket/path", + ), + ( + u"http+unix://%2Fvar%2Frun%2Fsocket/path", + u"http+unix://%2fvar%2frun%2fsocket/path", + ), + ( + b"mailto:user@example.org", + u"mailto:user@example.org", + ), + ( + u"mailto:user@example.org", + u"mailto:user@example.org", + ), + ( + b"data:SSDimaUgUHl0aG9uIQ==", + u"data:SSDimaUgUHl0aG9uIQ==", + ) + ) + ) + def test_url_mutation(self, input, expected): + """ + This test validates that we correctly exclude some URLs from + preparation, and that we handle others. Specifically, it tests that + any URL whose scheme doesn't begin with "http" is left alone, and + those whose scheme *does* begin with "http" are mutated. + """ + r = requests.Request('GET', url=input) + p = r.prepare() + assert p.url == expected + + @pytest.mark.parametrize( + 'input, params, expected', + ( + ( + b"http+unix://%2Fvar%2Frun%2Fsocket/path", + {"key": "value"}, + u"http+unix://%2fvar%2frun%2fsocket/path?key=value", + ), + ( + u"http+unix://%2Fvar%2Frun%2Fsocket/path", + {"key": "value"}, + u"http+unix://%2fvar%2frun%2fsocket/path?key=value", + ), + ( + b"mailto:user@example.org", + {"key": "value"}, + u"mailto:user@example.org", + ), + ( + u"mailto:user@example.org", + {"key": "value"}, + u"mailto:user@example.org", + ), + ) + ) + def test_parameters_for_nonstandard_schemes(self, input, params, expected): + """ + Setting paramters for nonstandard schemes is allowed if those schemes + begin with "http", and is forbidden otherwise. + """ + r = requests.Request('GET', url=input, params=params) + p = r.prepare() + assert p.url == expected +