From af88af64e6c5bc026247f18e2e6de20605f51e7f Mon Sep 17 00:00:00 2001 From: Alvaro Gutierrez Perez Date: Thu, 19 Oct 2017 16:36:17 +0200 Subject: Add test for Session.get_adapter() case-insensitivity --- tests/test_requests.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'tests') diff --git a/tests/test_requests.py b/tests/test_requests.py index 4d399518..76a528c9 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -1351,6 +1351,18 @@ class TestRequests: assert 'http://' in s2.adapters assert 'https://' in s2.adapters + def test_session_get_adapter_prefix_matching_is_case_insensitive(self, httpbin): + mixed_case_prefix = 'hTtPs://eXamPle.CoM/MixEd_CAse_PREfix' + url_matching_prefix = mixed_case_prefix + '/full_url' + url_matching_prefix_with_different_case = 'HtTpS://exaMPLe.cOm/MiXeD_caSE_preFIX/another_url' + + s = requests.Session() + my_adapter = HTTPAdapter() + s.mount(mixed_case_prefix, my_adapter) + + assert s.get_adapter(url_matching_prefix) is my_adapter + assert s.get_adapter(url_matching_prefix_with_different_case) is my_adapter + def test_header_remove_is_case_insensitive(self, httpbin): # From issue #1321 s = requests.Session() -- cgit v1.2.1 From e11989e8ec5885ea36b9be25641fbd4ce9f0c4dd Mon Sep 17 00:00:00 2001 From: Alvaro Gutierrez Perez Date: Thu, 19 Oct 2017 16:37:09 +0200 Subject: Add test for Session.get_adapter() prefix matching --- tests/test_requests.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'tests') diff --git a/tests/test_requests.py b/tests/test_requests.py index 76a528c9..a14a2c50 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -1351,6 +1351,24 @@ class TestRequests: assert 'http://' in s2.adapters assert 'https://' in s2.adapters + def test_session_get_adapter_prefix_matching(self, httpbin): + prefix = 'https://example.com' + more_specific_prefix = prefix + '/some/path' + + url_matching_only_prefix = prefix + '/another/path' + url_matching_more_specific_prefix = more_specific_prefix + '/longer/path' + url_not_matching_prefix = 'https://another.example.com/' + + s = requests.Session() + prefix_adapter = HTTPAdapter() + more_specific_prefix_adapter = HTTPAdapter() + s.mount(prefix, prefix_adapter) + s.mount(more_specific_prefix, more_specific_prefix_adapter) + + assert s.get_adapter(url_matching_only_prefix) is prefix_adapter + assert s.get_adapter(url_matching_more_specific_prefix) is more_specific_prefix_adapter + assert s.get_adapter(url_not_matching_prefix) not in (prefix_adapter, more_specific_prefix_adapter) + def test_session_get_adapter_prefix_matching_is_case_insensitive(self, httpbin): mixed_case_prefix = 'hTtPs://eXamPle.CoM/MixEd_CAse_PREfix' url_matching_prefix = mixed_case_prefix + '/full_url' -- cgit v1.2.1 From d165b18b6e0c1aaabd8f652f88308008769f6625 Mon Sep 17 00:00:00 2001 From: Alvaro Gutierrez Perez Date: Thu, 19 Oct 2017 17:04:48 +0200 Subject: Split test in two better-defined tests --- tests/test_requests.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/test_requests.py b/tests/test_requests.py index a14a2c50..05fe63e3 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -1369,16 +1369,24 @@ class TestRequests: assert s.get_adapter(url_matching_more_specific_prefix) is more_specific_prefix_adapter assert s.get_adapter(url_not_matching_prefix) not in (prefix_adapter, more_specific_prefix_adapter) - def test_session_get_adapter_prefix_matching_is_case_insensitive(self, httpbin): + def test_session_get_adapter_prefix_matching_mixed_case(self, httpbin): mixed_case_prefix = 'hTtPs://eXamPle.CoM/MixEd_CAse_PREfix' url_matching_prefix = mixed_case_prefix + '/full_url' - url_matching_prefix_with_different_case = 'HtTpS://exaMPLe.cOm/MiXeD_caSE_preFIX/another_url' s = requests.Session() my_adapter = HTTPAdapter() s.mount(mixed_case_prefix, my_adapter) assert s.get_adapter(url_matching_prefix) is my_adapter + + def test_session_get_adapter_prefix_matching_is_case_insensitive(self, httpbin): + mixed_case_prefix = 'hTtPs://eXamPle.CoM/MixEd_CAse_PREfix' + url_matching_prefix_with_different_case = 'HtTpS://exaMPLe.cOm/MiXeD_caSE_preFIX/another_url' + + s = requests.Session() + my_adapter = HTTPAdapter() + s.mount(mixed_case_prefix, my_adapter) + assert s.get_adapter(url_matching_prefix_with_different_case) is my_adapter def test_header_remove_is_case_insensitive(self, httpbin): -- cgit v1.2.1 From c86b09b3c67a437f8851d3be9232b0a1c8585e20 Mon Sep 17 00:00:00 2001 From: Arthur Vigil Date: Sun, 5 Nov 2017 10:50:35 -0800 Subject: support extraction of certificate bundle from a zip archive --- tests/test_utils.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_utils.py b/tests/test_utils.py index 32e4d4a5..2292a8f0 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -2,14 +2,16 @@ import os import copy +import filecmp from io import BytesIO +import zipfile import pytest from requests import compat from requests.cookies import RequestsCookieJar from requests.structures import CaseInsensitiveDict from requests.utils import ( - address_in_network, dotted_netmask, + address_in_network, dotted_netmask, extract_zipped_paths, get_auth_from_url, get_encoding_from_headers, get_encodings_from_content, get_environ_proxies, guess_filename, guess_json_utf, is_ipv4_address, @@ -256,6 +258,32 @@ class TestGuessFilename: assert isinstance(result, expected_type) +class TestExtractZippedPaths: + + @pytest.mark.parametrize( + 'path', ( + '/', + __file__, + pytest.__file__, + '/etc/invalid/location', + )) + def test_unzipped_paths_unchanged(self, path): + assert path == extract_zipped_paths(path) + + def test_zipped_paths_extracted(self, tmpdir): + zipped_py = tmpdir.join('test.zip') + with zipfile.ZipFile(zipped_py.strpath, 'w') as f: + f.write(__file__) + + _, name = os.path.splitdrive(__file__) + zipped_path = os.path.join(zipped_py.strpath, name.lstrip(r'\/')) + extracted_path = extract_zipped_paths(zipped_path) + + assert extracted_path != zipped_path + assert os.path.exists(extracted_path) + assert filecmp.cmp(extracted_path, __file__) + + class TestContentEncodingDetection: def test_none(self): -- cgit v1.2.1 From 9a8a826f226e6973d72914b4a4fc806e0b5036f4 Mon Sep 17 00:00:00 2001 From: Nehal J Wani Date: Thu, 26 Oct 2017 10:33:05 -0400 Subject: Check if host is invalid for proxy According to RFC3986, the authority section can be empty for a given URL, however, for a proxy URL, it shouldn't be. This patch adds a check to verify that the parsed URL will have a valid host before creating the proxy manager. Fixes #4353 --- tests/test_requests.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_requests.py b/tests/test_requests.py index 05fe63e3..e6a026f2 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -23,7 +23,7 @@ from requests.cookies import ( from requests.exceptions import ( ConnectionError, ConnectTimeout, InvalidSchema, InvalidURL, MissingSchema, ReadTimeout, Timeout, RetryError, TooManyRedirects, - ProxyError, InvalidHeader, UnrewindableBodyError, SSLError) + ProxyError, InvalidHeader, UnrewindableBodyError, SSLError, InvalidProxyURL) from requests.models import PreparedRequest from requests.structures import CaseInsensitiveDict from requests.sessions import SessionRedirectMixin @@ -526,6 +526,19 @@ class TestRequests: with pytest.raises(ProxyError): requests.get('http://localhost:1', proxies={'http': 'non-resolvable-address'}) + def test_proxy_error_on_bad_url(self, httpbin, httpbin_secure): + with pytest.raises(InvalidProxyURL): + requests.get(httpbin_secure(), proxies={'https': 'http:/badproxyurl:3128'}) + + with pytest.raises(InvalidProxyURL): + requests.get(httpbin(), proxies={'http': 'http://:8080'}) + + with pytest.raises(InvalidProxyURL): + requests.get(httpbin_secure(), proxies={'https': 'https://'}) + + with pytest.raises(InvalidProxyURL): + requests.get(httpbin(), proxies={'http': 'http:///example.com:8080'}) + def test_basicauth_with_netrc(self, httpbin): auth = ('user', 'pass') wrong_auth = ('wronguser', 'wrongpass') -- cgit v1.2.1 From acd2645444d280ac0c5d2d227fdd222cb1ac609c Mon Sep 17 00:00:00 2001 From: Mingyuan Xia Date: Tue, 21 Nov 2017 04:01:04 +0800 Subject: #4373, fix possible winreg value type difference (#4377) * #4373, fix possible winreg value type difference * add a test for ProxyOverride and ProxyEnable on win32 * add tests for winreg key ProxyEnable with two possible types * fixing AppVeyor failures --- tests/test_utils.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_utils.py b/tests/test_utils.py index 2292a8f0..2dd16923 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -5,6 +5,7 @@ import copy import filecmp from io import BytesIO import zipfile +from collections import deque import pytest from requests import compat @@ -666,6 +667,7 @@ def test_should_bypass_proxies_win_registry(url, expected, override, pass ie_settings = RegHandle() + proxyEnableValues = deque([1, "1"]) def OpenKey(key, subkey): return ie_settings @@ -673,7 +675,9 @@ def test_should_bypass_proxies_win_registry(url, expected, override, def QueryValueEx(key, value_name): if key is ie_settings: if value_name == 'ProxyEnable': - return [1] + # this could be a string (REG_SZ) or a 32-bit number (REG_DWORD) + proxyEnableValues.rotate() + return [proxyEnableValues[0]] elif value_name == 'ProxyOverride': return [override] @@ -684,6 +688,7 @@ def test_should_bypass_proxies_win_registry(url, expected, override, monkeypatch.setenv('NO_PROXY', '') monkeypatch.setattr(winreg, 'OpenKey', OpenKey) monkeypatch.setattr(winreg, 'QueryValueEx', QueryValueEx) + assert should_bypass_proxies(url, None) == expected @pytest.mark.parametrize( -- cgit v1.2.1 From 1988d9cf72c3a3a6da87968e04ad57fb32df01cb Mon Sep 17 00:00:00 2001 From: dbairaktaris1 Date: Mon, 1 Jan 2018 14:20:55 -0600 Subject: Move nested function up to module level and rename. Add more tests for function. --- tests/test_utils.py | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_utils.py b/tests/test_utils.py index 2dd16923..e734b8f8 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -13,7 +13,7 @@ from requests.cookies import RequestsCookieJar from requests.structures import CaseInsensitiveDict from requests.utils import ( address_in_network, dotted_netmask, extract_zipped_paths, - get_auth_from_url, get_encoding_from_headers, + get_auth_from_url, _parse_content_type_header, get_encoding_from_headers, get_encodings_from_content, get_environ_proxies, guess_filename, guess_json_utf, is_ipv4_address, is_valid_cidr, iter_slices, parse_dict_header, @@ -470,6 +470,41 @@ def test_parse_dict_header(value, expected): assert parse_dict_header(value) == expected +@pytest.mark.parametrize( + 'value, expected', ( + ( + None, + None + ), +( + '', + None + ), + ( + 'application/xml', + ('application/xml', dict()) + ), + ( + 'application/json ; charset=utf-8', + ('application/json', {'charset': 'utf-8'}) + ), + ( + 'text/plain', + ('text/plain', dict()) + ), + ( + 'multipart/form-data; boundary = something ; \'boundary2=something_else\' ; no_equals ', + ('multipart/form-data', {'boundary': 'something', 'boundary2': 'something_else', 'no_equals': True}) + ), + ( + 'application/json ;; ; ', + ('application/json', dict()) + ) + )) +def test__parse_content_type_header(value, expected): + assert _parse_content_type_header(value) == expected + + @pytest.mark.parametrize( 'value, expected', ( ( -- cgit v1.2.1 From 071796d83f1bfb79793170945fdb4f623a1f344a Mon Sep 17 00:00:00 2001 From: dbairaktaris1 Date: Wed, 3 Jan 2018 23:40:08 -0600 Subject: implement changes after code review --- tests/test_utils.py | 8 -------- 1 file changed, 8 deletions(-) (limited to 'tests') diff --git a/tests/test_utils.py b/tests/test_utils.py index e734b8f8..f89d15aa 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -472,14 +472,6 @@ def test_parse_dict_header(value, expected): @pytest.mark.parametrize( 'value, expected', ( - ( - None, - None - ), -( - '', - None - ), ( 'application/xml', ('application/xml', dict()) -- cgit v1.2.1 From cb0914407b6bb8153c8be5d52bc497e1d10b04ac Mon Sep 17 00:00:00 2001 From: dbairaktaris1 Date: Thu, 4 Jan 2018 10:30:50 -0600 Subject: Continue to refactor, remove list comprehension, add double quotes test case. --- tests/test_utils.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/test_utils.py b/tests/test_utils.py index f89d15aa..53d27a26 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -474,7 +474,7 @@ def test_parse_dict_header(value, expected): 'value, expected', ( ( 'application/xml', - ('application/xml', dict()) + ('application/xml', {}) ), ( 'application/json ; charset=utf-8', @@ -482,15 +482,19 @@ def test_parse_dict_header(value, expected): ), ( 'text/plain', - ('text/plain', dict()) + ('text/plain', {}) ), ( 'multipart/form-data; boundary = something ; \'boundary2=something_else\' ; no_equals ', ('multipart/form-data', {'boundary': 'something', 'boundary2': 'something_else', 'no_equals': True}) ), ( - 'application/json ;; ; ', - ('application/json', dict()) + 'multipart/form-data; boundary = something ; \"boundary2=something_else\" ; no_equals ', + ('multipart/form-data', {'boundary': 'something', 'boundary2': 'something_else', 'no_equals': True}) + ), + ( + 'application/json ; ; ', + ('application/json', {}) ) )) def test__parse_content_type_header(value, expected): -- cgit v1.2.1 From e0ab287317fcde8fa4631bc7bee5aa1749bc4ac5 Mon Sep 17 00:00:00 2001 From: dbairaktaris1 Date: Thu, 4 Jan 2018 10:59:47 -0600 Subject: added more to test scenarios --- tests/test_utils.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_utils.py b/tests/test_utils.py index 53d27a26..01cabe23 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -484,12 +484,20 @@ def test_parse_dict_header(value, expected): 'text/plain', ('text/plain', {}) ), + ( + 'multipart/form-data; boundary = something ; boundary2=\'something_else\' ; no_equals ', + ('multipart/form-data', {'boundary': 'something', 'boundary2': 'something_else', 'no_equals': True}) + ), + ( + 'multipart/form-data; boundary = something ; boundary2="something_else" ; no_equals ', + ('multipart/form-data', {'boundary': 'something', 'boundary2': 'something_else', 'no_equals': True}) + ), ( 'multipart/form-data; boundary = something ; \'boundary2=something_else\' ; no_equals ', ('multipart/form-data', {'boundary': 'something', 'boundary2': 'something_else', 'no_equals': True}) ), ( - 'multipart/form-data; boundary = something ; \"boundary2=something_else\" ; no_equals ', + 'multipart/form-data; boundary = something ; "boundary2=something_else" ; no_equals ', ('multipart/form-data', {'boundary': 'something', 'boundary2': 'something_else', 'no_equals': True}) ), ( -- cgit v1.2.1 From 2255c34a65b5b1353004dc8d49cc397cd794ec15 Mon Sep 17 00:00:00 2001 From: Darren Dormer Date: Tue, 12 Dec 2017 15:53:09 +0100 Subject: Fix DNS resolution by using hostname instead of netloc and strip username and password when comparing against proxy bypass items. --- tests/test_utils.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/test_utils.py b/tests/test_utils.py index 01cabe23..f39cd67b 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -614,6 +614,7 @@ def test_urldefragauth(url, expected): ('http://172.16.1.1/', True), ('http://172.16.1.1:5000/', True), ('http://localhost.localdomain:5000/v1.0/', True), + ('http://google.com:6000/', True), ('http://172.16.1.12/', False), ('http://172.16.1.12:5000/', False), ('http://google.com:5000/v1.0/', False), @@ -622,11 +623,31 @@ def test_should_bypass_proxies(url, expected, monkeypatch): """Tests for function should_bypass_proxies to check if proxy can be bypassed or not """ - monkeypatch.setenv('no_proxy', '192.168.0.0/24,127.0.0.1,localhost.localdomain,172.16.1.1') - monkeypatch.setenv('NO_PROXY', '192.168.0.0/24,127.0.0.1,localhost.localdomain,172.16.1.1') + monkeypatch.setenv('no_proxy', '192.168.0.0/24,127.0.0.1,localhost.localdomain,172.16.1.1, google.com:6000') + monkeypatch.setenv('NO_PROXY', '192.168.0.0/24,127.0.0.1,localhost.localdomain,172.16.1.1, google.com:6000') assert should_bypass_proxies(url, no_proxy=None) == expected +@pytest.mark.parametrize( + 'url, expected', ( + ('http://172.16.1.1/', '172.16.1.1'), + ('http://172.16.1.1:5000/', '172.16.1.1'), + ('http://user:pass@172.16.1.1', '172.16.1.1'), + ('http://user:pass@172.16.1.1:5000', '172.16.1.1'), + ('http://hostname/', 'hostname'), + ('http://hostname:5000/', 'hostname'), + ('http://user:pass@hostname', 'hostname'), + ('http://user:pass@hostname:5000', 'hostname'), + )) +def test_should_bypass_proxies_pass_only_hostname(url, expected, mocker): + """The proxy_bypass function should be called with a hostname or IP without + a port number or auth credentials. + """ + proxy_bypass = mocker.patch('requests.utils.proxy_bypass') + should_bypass_proxies(url, no_proxy=None) + proxy_bypass.assert_called_once_with(expected) + + @pytest.mark.parametrize( 'cookiejar', ( compat.cookielib.CookieJar(), -- cgit v1.2.1 From f60324a3de41c10dd7af17cadd4322c895068a25 Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Sun, 7 Jan 2018 17:24:09 -0800 Subject: append previous url fragment on redirect --- tests/test_lowlevel.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ tests/test_requests.py | 8 ++++++ 2 files changed, 80 insertions(+) (limited to 'tests') diff --git a/tests/test_lowlevel.py b/tests/test_lowlevel.py index c87234bc..6d6268cd 100644 --- a/tests/test_lowlevel.py +++ b/tests/test_lowlevel.py @@ -235,3 +235,75 @@ def test_redirect_rfc1808_to_non_ascii_location(): assert r.url == u'{0}/{1}'.format(url, expected_path.decode('ascii')) close_server.set() + +def test_fragment_not_sent_with_request(): + """Verify that the fragment portion of a URI isn't sent to the server.""" + def response_handler(sock): + req = consume_socket_content(sock, timeout=0.5) + sock.send( + b'HTTP/1.1 200 OK\r\n' + b'Content-Length: '+bytes(len(req))+b'\r\n' + b'\r\n'+req + ) + + close_server = threading.Event() + server = Server(response_handler, wait_to_close_event=close_server) + + with server as (host, port): + url = 'http://{0}:{1}/path/to/thing/#view=edit&token=hunter2'.format(host, port) + r = requests.get(url) + raw_request = r.content + + assert r.status_code == 200 + headers, body = raw_request.split(b'\r\n\r\n', 1) + status_line, headers = headers.split(b'\r\n', 1) + + assert status_line == b'GET /path/to/thing/ HTTP/1.1' + for frag in (b'view', b'edit', b'token', b'hunter2'): + assert frag not in headers + assert frag not in body + + close_server.set() + +def test_fragment_update_on_redirect(): + """Verify we only append previous fragment if one doesn't exist on new + location. If a new fragment is encounterd in a Location header, it should + be added to all subsequent requests. + """ + + def response_handler(sock): + consume_socket_content(sock, timeout=0.5) + sock.send( + b'HTTP/1.1 302 FOUND\r\n' + b'Content-Length: 0\r\n' + b'Location: /get#relevant-section\r\n\r\n' + ) + consume_socket_content(sock, timeout=0.5) + sock.send( + b'HTTP/1.1 302 FOUND\r\n' + b'Content-Length: 0\r\n' + b'Location: /final-url/\r\n\r\n' + ) + consume_socket_content(sock, timeout=0.5) + sock.send( + b'HTTP/1.1 200 OK\r\n\r\n' + ) + + close_server = threading.Event() + server = Server(response_handler, wait_to_close_event=close_server) + + with server as (host, port): + url = 'http://{0}:{1}/path/to/thing/#view=edit&token=hunter2'.format(host, port) + r = requests.get(url) + raw_request = r.content + + assert r.status_code == 200 + assert len(r.history) == 2 + assert r.history[0].request.url == url + + # Verify we haven't overwritten the location with our previous fragment. + assert r.history[1].request.url == 'http://{0}:{1}/get#relevant-section'.format(host, port) + # Verify previous fragment is used and not the original. + assert r.url == 'http://{0}:{1}/final-url/#relevant-section'.format(host, port) + + close_server.set() diff --git a/tests/test_requests.py b/tests/test_requests.py index e6a026f2..b3747474 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -294,6 +294,14 @@ class TestRequests: for header in purged_headers: assert header not in next_resp.request.headers + def test_fragment_maintained_on_redirect(self, httpbin): + fragment = "#view=edit&token=hunter2" + r = requests.get(httpbin('redirect-to?url=get')+fragment) + + assert len(r.history) > 0 + assert r.history[0].request.url == httpbin('redirect-to?url=get')+fragment + assert r.url == httpbin('get')+fragment + def test_HTTP_200_OK_GET_WITH_PARAMS(self, httpbin): heads = {'User-agent': 'Mozilla/5.0'} -- cgit v1.2.1