diff --git a/SOURCES/fix-default-port-handling.patch b/SOURCES/fix-default-port-handling.patch new file mode 100644 index 0000000..fa9d259 --- /dev/null +++ b/SOURCES/fix-default-port-handling.patch @@ -0,0 +1,67 @@ +diff --git a/requests/sessions.py b/requests/sessions.py +index a0a23ee..9a51f33 100644 +--- a/requests/sessions.py ++++ b/requests/sessions.py +@@ -18,7 +18,7 @@ from .cookies import ( + cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies) + from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT + from .hooks import default_hooks, dispatch_hook +-from .utils import to_key_val_list, default_headers, to_native_string ++from .utils import to_key_val_list, default_headers, to_native_string, DEFAULT_PORTS + from .exceptions import ( + TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError) + from .packages.urllib3._collections import RecentlyUsedContainer +@@ -103,8 +103,17 @@ class SessionRedirectMixin(object): + if (old_parsed.scheme == 'http' and old_parsed.port in (80, None) + and new_parsed.scheme == 'https' and new_parsed.port in (443, None)): + return False ++ ++ # Handle default port usage corresponding to scheme. ++ changed_port = old_parsed.port != new_parsed.port ++ changed_scheme = old_parsed.scheme != new_parsed.scheme ++ default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None) ++ if (not changed_scheme and old_parsed.port in default_port ++ and new_parsed.port in default_port): ++ return False ++ + # Standard case: root URI must match +- return old_parsed.port != new_parsed.port or old_parsed.scheme != new_parsed.scheme ++ return changed_port or changed_scheme + + def resolve_redirects(self, resp, req, stream=False, timeout=None, + verify=True, cert=None, proxies=None): +diff --git a/requests/utils.py b/requests/utils.py +index 8fba62d..14c94bd 100644 +--- a/requests/utils.py ++++ b/requests/utils.py +@@ -37,6 +37,8 @@ NETRC_FILES = ('.netrc', '_netrc') + + DEFAULT_CA_BUNDLE_PATH = certs.where() + ++DEFAULT_PORTS = {'http': 80, 'https': 443} ++ + + def dict_to_sequence(d): + """Returns an internal sequence dictionary update.""" +diff --git a/test_requests.py b/test_requests.py +index e19b436..b76d2a4 100755 +--- a/test_requests.py ++++ b/test_requests.py +@@ -1012,6 +1012,17 @@ class RequestsTestCase(unittest.TestCase): + s = requests.Session() + assert s.should_strip_auth('http://example.com:1234/foo', 'https://example.com:4321/bar') + ++ @pytest.mark.parametrize( ++ 'old_uri, new_uri', ( ++ ('https://example.com:443/foo', 'https://example.com/bar'), ++ ('http://example.com:80/foo', 'http://example.com/bar'), ++ ('https://example.com/foo', 'https://example.com:443/bar'), ++ ('http://example.com/foo', 'http://example.com:80/bar') ++ )) ++ def test_should_strip_auth_default_port(self, old_uri, new_uri): ++ s = requests.Session() ++ assert not s.should_strip_auth(old_uri, new_uri) ++ + def test_manual_redirect_with_partial_body_read(self): + s = requests.Session() + r1 = s.get(httpbin('redirect/2'), allow_redirects=False, stream=True) diff --git a/SOURCES/fix-leaking-test.patch b/SOURCES/fix-leaking-test.patch new file mode 100644 index 0000000..bef3b6e --- /dev/null +++ b/SOURCES/fix-leaking-test.patch @@ -0,0 +1,68 @@ +From 9b63f9cd37d19f2d4bbce42caec112ad0606d8dd Mon Sep 17 00:00:00 2001 +From: Cory Benfield +Date: Thu, 22 Oct 2015 12:22:28 +0100 +Subject: [PATCH] Make sure we unapply this patch. + +--- + test_requests.py | 47 ++++++++++++++++++++++++++--------------------- + 1 file changed, 26 insertions(+), 21 deletions(-) + +diff --git a/test_requests.py b/test_requests.py +index d1c6aa4d5..cb25555aa 100755 +--- a/test_requests.py ++++ b/test_requests.py +@@ -353,28 +353,33 @@ def test_basicauth_with_netrc(self): + wrong_auth = ('wronguser', 'wrongpass') + url = httpbin('basic-auth', 'user', 'pass') + +- def get_netrc_auth_mock(url): +- return auth +- requests.sessions.get_netrc_auth = get_netrc_auth_mock ++ old_auth = requests.sessions.get_netrc_auth + +- # Should use netrc and work. +- r = requests.get(url) +- assert r.status_code == 200 +- +- # Given auth should override and fail. +- r = requests.get(url, auth=wrong_auth) +- assert r.status_code == 401 +- +- s = requests.session() +- +- # Should use netrc and work. +- r = s.get(url) +- assert r.status_code == 200 +- +- # Given auth should override and fail. +- s.auth = wrong_auth +- r = s.get(url) +- assert r.status_code == 401 ++ try: ++ def get_netrc_auth_mock(url): ++ return auth ++ requests.sessions.get_netrc_auth = get_netrc_auth_mock ++ ++ # Should use netrc and work. ++ r = requests.get(url) ++ assert r.status_code == 200 ++ ++ # Given auth should override and fail. ++ r = requests.get(url, auth=wrong_auth) ++ assert r.status_code == 401 ++ ++ s = requests.session() ++ ++ # Should use netrc and work. ++ r = s.get(url) ++ assert r.status_code == 200 ++ ++ # Given auth should override and fail. ++ s.auth = wrong_auth ++ r = s.get(url) ++ assert r.status_code == 401 ++ finally: ++ requests.sessions.get_netrc_auth = old_auth + + def test_DIGEST_HTTP_200_OK_GET(self): + diff --git a/SOURCES/modify-tests-to-run-in-pytest.patch b/SOURCES/modify-tests-to-run-in-pytest.patch new file mode 100644 index 0000000..6dffdc3 --- /dev/null +++ b/SOURCES/modify-tests-to-run-in-pytest.patch @@ -0,0 +1,85 @@ +From cc0107b311f74c78bd653fa1a84e2dcedce9fc6f Mon Sep 17 00:00:00 2001 +From: Tomas Orsava +Date: Thu, 3 Oct 2019 16:17:37 +0200 +Subject: [PATCH] Modify tests to run in pytest + +--- + test_requests.py | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +diff --git a/test_requests.py b/test_requests.py +index 15406a2..74aa5b3 100755 +--- a/test_requests.py ++++ b/test_requests.py +@@ -7,7 +7,6 @@ from __future__ import division + import json + import os + import pickle +-import unittest + import collections + + import io +@@ -53,7 +52,7 @@ def httpbin(*suffix): + return urljoin(HTTPBIN, '/'.join(suffix)) + + +-class RequestsTestCase(unittest.TestCase): ++class TestCase(): + + _multiprocess_can_split_ = True + +@@ -1070,7 +1069,7 @@ class RequestsTestCase(unittest.TestCase): + assert len(list(r.iter_lines())) == 3 + + +-class TestContentEncodingDetection(unittest.TestCase): ++class TestContentEncodingDetection(): + + def test_none(self): + encodings = requests.utils.get_encodings_from_content('') +@@ -1114,7 +1113,7 @@ class TestContentEncodingDetection(unittest.TestCase): + assert encodings == ['HTML5', 'HTML4', 'XML'] + + +-class TestCaseInsensitiveDict(unittest.TestCase): ++class TestCaseInsensitiveDict(): + + def test_mapping_init(self): + cid = CaseInsensitiveDict({'Foo': 'foo', 'BAr': 'bar'}) +@@ -1252,7 +1251,7 @@ class TestCaseInsensitiveDict(unittest.TestCase): + assert frozenset(cid) == keyset + + +-class UtilsTestCase(unittest.TestCase): ++class UtilsTestCase(): + + def test_super_len_io_streams(self): + """ Ensures that we properly deal with different kinds of IO streams. """ +@@ -1376,7 +1375,7 @@ class UtilsTestCase(unittest.TestCase): + assert quoted == requote_uri(quoted) + + +-class TestMorselToCookieExpires(unittest.TestCase): ++class TestMorselToCookieExpires(): + + """Tests for morsel_to_cookie when morsel contains expires.""" + +@@ -1413,7 +1412,7 @@ class TestMorselToCookieExpires(unittest.TestCase): + assert cookie.expires is None + + +-class TestMorselToCookieMaxAge(unittest.TestCase): ++class TestMorselToCookieMaxAge(): + + """Tests for morsel_to_cookie when morsel contains max-age.""" + +@@ -1634,6 +1633,3 @@ def test_vendor_aliases(): + + with pytest.raises(ImportError): + from requests.packages import webbrowser +- +-if __name__ == '__main__': +- unittest.main() +-- +2.20.1 + diff --git a/SPECS/python-requests.spec b/SPECS/python-requests.spec index d571d0e..6db2f4e 100644 --- a/SPECS/python-requests.spec +++ b/SPECS/python-requests.spec @@ -1,3 +1,6 @@ +# Tests need an internet connection, so they are disabled by default +%bcond_with online_tests + %if 0%{?fedora} %global _with_python3 1 %else @@ -6,7 +9,7 @@ Name: python-requests Version: 2.6.0 -Release: 5%{?dist} +Release: 7%{?dist} Summary: HTTP library, written in Python, for human beings License: ASL 2.0 @@ -19,15 +22,35 @@ Patch0: python-requests-system-cert-bundle.patch # Remove an unnecessary reference to a bundled compat lib in urllib3 Patch1: python-requests-remove-nested-bundling-dep.patch +# Modify tests to run in pytest so that we can run backported parametrized +# tests (Patch4: fix-default-port-handling.patch). +# We cannot launch the tests during build as they require internet, but QE +# launches them later. +# Minimal version of this upstream change: +# https://github.com/psf/requests/commit/6c2942b19865106a3ac65b3bfc1fc93aae2d346c +Patch2: modify-tests-to-run-in-pytest.patch + # Fix for CVE-2018-18074 # Resolved upstream: https://github.com/requests/requests/pull/4718 -Patch2: fix-CVE-2018-18074.patch +Patch3: fix-CVE-2018-18074.patch + +# Fix handling of default ports in auth stripping +# Resolved upstream: https://github.com/psf/requests/pull/4851 +Patch4: fix-default-port-handling.patch + +# Fix a leaking test that was making another test (test_auth_is_stripped_on_redirect_off_host) fail +# Resolved upstream: https://github.com/psf/requests/commit/9b63f9cd37d19f2d4bbce42caec112ad0606d8dd +Patch5: fix-leaking-test.patch BuildArch: noarch BuildRequires: python2-devel BuildRequires: python-chardet >= 2.2.1-1 BuildRequires: python-urllib3 >= 1.10.2-1 +%if %{with online_tests} +BuildRequires: pytest +%endif + Requires: ca-certificates Requires: python-chardet >= 2.2.1-1 Requires: python-urllib3 >= 1.10.2-1 @@ -52,6 +75,9 @@ Summary: HTTP library, written in Python, for human beings BuildRequires: python3-devel BuildRequires: python3-chardet BuildRequires: python3-urllib3 +%if %{with online_tests} +BuildRequires: python3-pytest +%endif Requires: python3-chardet Requires: python3-urllib3 @@ -68,6 +94,9 @@ designed to make HTTP requests easy for developers. %patch0 -p1 %patch1 -p1 %patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 # Unbundle the certificate bundle from mozilla. rm -rf requests/cacert.pem @@ -105,15 +134,17 @@ popd %py2_install -## The tests succeed if run locally, but fail in koji. -## They require an active network connection to query httpbin.org -#%%check -#%%{__python} test_requests.py -#%%if 0%%{?_with_python3} -#pushd %%{py3dir} -#%%{__python3} test_requests.py -#popd -#%%endif +%if %{with online_tests} +# The tests succeed if run locally, but fail in koji. +# They require an active network connection to query httpbin.org +%check +%{__python} -m pytest test_requests.py +%if 0%{?_with_python3} +pushd %{py3dir} +%{__python3} -m pytest test_requests.py +popd +%endif +%endif #with online_tests %files %defattr(-,root,root,-) @@ -129,6 +160,15 @@ popd %endif %changelog +* Thu Oct 03 2019 Tomas Orsava - 2.6.0-7 +- Modify tests to run in pytest +- Add a bcond online_tests to enable the tests +Related: rhbz#1754830 + +* Tue Aug 27 2019 Charalampos Stratakis - 2.6.0-6 +- Fix handling of default ports in auth stripping +Resolves: rhbz#1754830 + * Mon Nov 26 2018 Charalampos Stratakis - 2.6.0-5 - Fix CVE-2018-18074 Resolves: rhbz#1647368