Bump cheroot from 8.6.0 to 9.0.0 (#1903)

* Bump cheroot from 8.6.0 to 9.0.0

Bumps [cheroot](https://github.com/cherrypy/cheroot) from 8.6.0 to 9.0.0.
- [Release notes](https://github.com/cherrypy/cheroot/releases)
- [Changelog](https://github.com/cherrypy/cheroot/blob/main/CHANGES.rst)
- [Commits](https://github.com/cherrypy/cheroot/compare/v8.6.0...v9.0.0)

---
updated-dependencies:
- dependency-name: cheroot
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update cheroot==9.0.0

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com>

[skip ci]
This commit is contained in:
dependabot[bot] 2022-12-21 15:58:54 -08:00 committed by GitHub
commit 3d378eb583
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 287 additions and 851 deletions

View file

@ -8,6 +8,7 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
import pytest
import six
pytest_version = tuple(map(int, pytest.__version__.split('.')))
@ -43,8 +44,17 @@ def pytest_load_initial_conftests(early_config, parser, args):
'<socket.socket fd=-1, family=AF_INET6, '
'type=SocketKind.SOCK_STREAM, proto=.:'
'pytest.PytestUnraisableExceptionWarning:_pytest.unraisableexception',
'ignore:Exception ignored in. '
'<ssl.SSLSocket fd=-1, family=AddressFamily.AF_UNIX, '
'type=SocketKind.SOCK_STREAM, proto=.:'
'pytest.PytestUnraisableExceptionWarning:_pytest.unraisableexception',
))
if six.PY2:
return
# NOTE: `ResourceWarning` does not exist under Python 2 and so using
# NOTE: it in warning filters results in an `_OptionError` exception
# NOTE: being raised.
early_config._inicache['filterwarnings'].extend((
# FIXME: Try to figure out what causes this and ensure that the socket
# FIXME: gets closed.
'ignore:unclosed <socket.socket fd=:ResourceWarning',
'ignore:unclosed <ssl.SSLSocket fd=:ResourceWarning',
))

View file

@ -4,14 +4,12 @@ Contains fixtures, which are tightly bound to the Cheroot framework
itself, useless for end-users' app testing.
"""
from __future__ import absolute_import, division, print_function
__metaclass__ = type # pylint: disable=invalid-name
import threading
import time
import pytest
from .._compat import IS_MACOS, IS_WINDOWS # noqa: WPS436
from ..server import Gateway, HTTPServer
from ..testing import ( # noqa: F401 # pylint: disable=unused-import
native_server, wsgi_server,
@ -19,6 +17,20 @@ from ..testing import ( # noqa: F401 # pylint: disable=unused-import
from ..testing import get_server_client
@pytest.fixture
def http_request_timeout():
"""Return a common HTTP request timeout for tests with queries."""
computed_timeout = 0.1
if IS_MACOS:
computed_timeout *= 2
if IS_WINDOWS:
computed_timeout *= 10
return computed_timeout
@pytest.fixture
# pylint: disable=redefined-outer-name
def wsgi_server_client(wsgi_server): # noqa: F811

View file

@ -1,8 +1,5 @@
"""A library of helper functions for the Cheroot test suite."""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import datetime
import logging
import os
@ -10,10 +7,7 @@ import sys
import time
import threading
import types
from six.moves import http_client
import six
import http.client
import cheroot.server
import cheroot.wsgi
@ -60,14 +54,14 @@ class CherootWebCase(webtest.WebCase):
cls.scheme = 'http'
else:
ssl = ' (ssl)'
cls.HTTP_CONN = http_client.HTTPSConnection
cls.HTTP_CONN = http.client.HTTPSConnection
cls.scheme = 'https'
v = sys.version.split()[0]
log.info('Python version used to run this test script: %s' % v)
log.info('Cheroot version: %s' % cheroot.__version__)
log.info('HTTP server version: %s%s' % (cls.httpserver.protocol, ssl))
log.info('PID: %s' % os.getpid())
log.info('Python version used to run this test script: %s', v)
log.info('Cheroot version: %s', cheroot.__version__)
log.info('HTTP server version: %s%s', cls.httpserver.protocol, ssl)
log.info('PID: %s', os.getpid())
if hasattr(cls, 'setup_server'):
# Clear the wsgi server so that
@ -135,9 +129,9 @@ class Response:
"""Generate iterable response body object."""
if self.body is None:
return []
elif isinstance(self.body, six.text_type):
elif isinstance(self.body, str):
return [self.body.encode('iso-8859-1')]
elif isinstance(self.body, six.binary_type):
elif isinstance(self.body, bytes):
return [self.body]
else:
return [x.encode('iso-8859-1') for x in self.body]

View file

@ -1,13 +1,8 @@
# -*- coding: utf-8 -*-
"""Test suite for cross-python compatibility helpers."""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import pytest
import six
from cheroot._compat import extract_bytes, memoryview, ntob, ntou, bton
from cheroot._compat import extract_bytes, ntob, ntou, bton
@pytest.mark.parametrize(
@ -32,7 +27,7 @@ def test_compat_functions_positive(func, inp, out):
)
def test_compat_functions_negative_nonnative(func):
"""Check that compatibility functions fail loudly for incorrect input."""
non_native_test_str = u'bar' if six.PY2 else b'bar'
non_native_test_str = b'bar'
with pytest.raises(TypeError):
func(non_native_test_str, encoding='utf-8')

View file

@ -4,11 +4,8 @@
cli
"""
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
import sys
import six
import pytest
from cheroot.cli import (
@ -69,12 +66,6 @@ def wsgi_app(monkeypatch):
app = WSGIAppMock()
# patch sys.modules, to include the an instance of WSGIAppMock
# under a specific namespace
if six.PY2:
# python2 requires the previous namespaces to be part of sys.modules
# (e.g. for 'a.b.c' we need to insert 'a', 'a.b' and 'a.b.c')
# otherwise it fails, we're setting the same instance on each level,
# we don't really care about those, just the last one.
monkeypatch.setitem(sys.modules, 'mypkg', app)
monkeypatch.setitem(sys.modules, 'mypkg.wsgi', app)
return app

View file

@ -1,18 +1,14 @@
"""Tests for TCP connection handling, including proper and timely close."""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import errno
import socket
import time
import logging
import traceback as traceback_
from collections import namedtuple
import http.client
import urllib.request
from six.moves import range, http_client, urllib
import six
import pytest
from jaraco.text import trim, unwrap
@ -94,8 +90,6 @@ class Controller(helper.Controller):
WSGI 1.0 is a mess around unicode. Create endpoints
that match the PATH_INFO that it produces.
"""
if six.PY2:
return string
return string.encode('utf-8').decode('latin-1')
handlers = {
@ -242,7 +236,7 @@ def test_HTTP11_persistent_connections(test_client):
assert header_has_value('Connection', 'close', actual_headers)
# Make another request on the same connection, which should error.
with pytest.raises(http_client.NotConnected):
with pytest.raises(http.client.NotConnected):
test_client.get('/pov', http_conn=http_connection)
@ -309,7 +303,7 @@ def test_streaming_11(test_client, set_cl):
# Make another request on the same connection, which should
# error.
with pytest.raises(http_client.NotConnected):
with pytest.raises(http.client.NotConnected):
test_client.get('/pov', http_conn=http_connection)
# Try HEAD.
@ -324,6 +318,9 @@ def test_streaming_11(test_client, set_cl):
assert actual_resp_body == b''
assert not header_exists('Transfer-Encoding', actual_headers)
# Prevent the resource warnings:
http_connection.close()
@pytest.mark.parametrize(
'set_cl',
@ -389,7 +386,7 @@ def test_streaming_10(test_client, set_cl):
assert not header_exists('Transfer-Encoding', actual_headers)
# Make another request on the same connection, which should error.
with pytest.raises(http_client.NotConnected):
with pytest.raises(http.client.NotConnected):
test_client.get(
'/pov', http_conn=http_connection,
protocol='HTTP/1.0',
@ -397,6 +394,9 @@ def test_streaming_10(test_client, set_cl):
test_client.server_instance.protocol = original_server_protocol
# Prevent the resource warnings:
http_connection.close()
@pytest.mark.parametrize(
'http_server_protocol',
@ -466,6 +466,9 @@ def test_keepalive(test_client, http_server_protocol):
test_client.server_instance.protocol = original_server_protocol
# Prevent the resource warnings:
http_connection.close()
def test_keepalive_conn_management(test_client):
"""Test management of Keep-Alive connections."""
@ -511,9 +514,9 @@ def test_keepalive_conn_management(test_client):
)
disconnect_errors = (
http_client.BadStatusLine,
http_client.CannotSendRequest,
http_client.NotConnected,
http.client.BadStatusLine,
http.client.CannotSendRequest,
http.client.NotConnected,
)
# Make a new connection.
@ -565,6 +568,11 @@ def test_keepalive_conn_management(test_client):
# Restore original timeout.
test_client.server_instance.timeout = timeout
# Prevent the resource warnings:
c1.close()
c2.close()
c3.close()
@pytest.mark.parametrize(
('simulated_exception', 'error_number', 'exception_leaks'),
@ -597,7 +605,6 @@ def test_keepalive_conn_management(test_client):
pytest.param(RuntimeError, 666, True, id='RuntimeError(666)'),
pytest.param(socket.error, -1, True, id='socket.error(-1)'),
) + (
() if six.PY2 else (
pytest.param(
ConnectionResetError, errno.ECONNRESET, False,
id='ConnectionResetError(ECONNRESET)',
@ -610,7 +617,6 @@ def test_keepalive_conn_management(test_client):
BrokenPipeError, errno.ESHUTDOWN, False,
id='BrokenPipeError(ESHUTDOWN)',
),
)
),
)
def test_broken_connection_during_tcp_fin(
@ -765,7 +771,7 @@ def test_HTTP11_Timeout_after_request(test_client):
response = conn.response_class(conn.sock, method='GET')
try:
response.begin()
except (socket.error, http_client.BadStatusLine):
except (socket.error, http.client.BadStatusLine):
pass
except Exception as ex:
pytest.fail(fail_msg % ex)
@ -795,7 +801,7 @@ def test_HTTP11_Timeout_after_request(test_client):
response = conn.response_class(conn.sock, method='GET')
try:
response.begin()
except (socket.error, http_client.BadStatusLine):
except (socket.error, http.client.BadStatusLine):
pass
except Exception as ex:
pytest.fail(fail_msg % ex)
@ -845,8 +851,7 @@ def test_HTTP11_pipelining(test_client):
# ``conn.sock``. Until that bug get's fixed we will
# monkey patch the ``response`` instance.
# https://bugs.python.org/issue23377
if not six.PY2:
response.fp = conn.sock.makefile('rb', 0)
response.fp = conn.sock.makefile('rb', 0)
response.begin()
body = response.read(13)
assert response.status == 200
@ -1026,6 +1031,9 @@ def test_No_Message_Body(test_client):
assert actual_resp_body == b''
assert not header_exists('Connection', actual_headers)
# Prevent the resource warnings:
http_connection.close()
@pytest.mark.xfail(
reason=unwrap(

View file

@ -1,16 +1,10 @@
"""Tests for managing HTTP issues (malformed requests, etc)."""
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import errno
import socket
import urllib.parse # noqa: WPS301
import pytest
import six
from six.moves import urllib
from cheroot.test import helper
@ -54,8 +48,6 @@ class HelloController(helper.Controller):
WSGI 1.0 is a mess around unicode. Create endpoints
that match the PATH_INFO that it produces.
"""
if six.PY2:
return string
return string.encode('utf-8').decode('latin-1')
handlers = {
@ -63,7 +55,13 @@ class HelloController(helper.Controller):
'/no_body': hello,
'/body_required': body_required,
'/query_string': query_string,
# FIXME: Unignore the pylint rules in pylint >= 2.15.4.
# Refs:
# * https://github.com/PyCQA/pylint/issues/6592
# * https://github.com/PyCQA/pylint/pull/7395
# pylint: disable-next=too-many-function-args
_munge('/привіт'): hello,
# pylint: disable-next=too-many-function-args
_munge('/Юххууу'): hello,
'/\xa0Ðblah key 0 900 4 data': hello,
'/*': asterisk,
@ -151,7 +149,6 @@ def test_parse_acceptable_uri(test_client, uri):
assert actual_status == HTTP_OK
@pytest.mark.xfail(six.PY2, reason='Fails on Python 2')
def test_parse_uri_unsafe_uri(test_client):
"""Test that malicious URI does not allow HTTP injection.
@ -263,6 +260,8 @@ def test_no_content_length(test_client):
assert actual_status == HTTP_OK
assert actual_resp_body == b'Hello world!'
c.close() # deal with the resource warning
def test_content_length_required(test_client):
"""Test POST query with body failing because of missing Content-Length."""
@ -278,6 +277,8 @@ def test_content_length_required(test_client):
actual_status = response.status
assert actual_status == HTTP_LENGTH_REQUIRED
c.close() # deal with the resource warning
@pytest.mark.xfail(
reason='https://github.com/cherrypy/cheroot/issues/106',
@ -350,6 +351,8 @@ def test_malformed_http_method(test_client):
actual_resp_body = response.read(21)
assert actual_resp_body == b'Malformed method name'
c.close() # deal with the resource warning
def test_malformed_header(test_client):
"""Check that broken HTTP header results in Bad Request."""
@ -366,6 +369,8 @@ def test_malformed_header(test_client):
actual_resp_body = response.read(20)
assert actual_resp_body == b'Illegal header line.'
c.close() # deal with the resource warning
def test_request_line_split_issue_1220(test_client):
"""Check that HTTP request line of exactly 256 chars length is OK."""

View file

@ -1,8 +1,4 @@
"""Tests for the HTTP server."""
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
from __future__ import absolute_import, division, print_function
from cheroot.wsgi import PathInfoDispatcher

View file

@ -3,9 +3,6 @@
from cheroot import makefile
__metaclass__ = type
class MockSocket:
"""A mock socket."""

View file

@ -1,23 +1,18 @@
"""Tests for the HTTP server."""
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import os
import queue
import socket
import tempfile
import threading
import uuid
import urllib.parse # noqa: WPS301
import pytest
import requests
import requests_unixsocket
import six
from pypytools.gc.custom import DefaultGc
from six.moves import queue, urllib
from .._compat import bton, ntob
from .._compat import IS_LINUX, IS_MACOS, IS_WINDOWS, SYS_PLATFORM
@ -259,12 +254,12 @@ def peercreds_enabled_server(http_server, unix_sock_file):
@unix_only_sock_test
@non_macos_sock_test
def test_peercreds_unix_sock(peercreds_enabled_server):
def test_peercreds_unix_sock(http_request_timeout, peercreds_enabled_server):
"""Check that ``PEERCRED`` lookup works when enabled."""
httpserver = peercreds_enabled_server
bind_addr = httpserver.bind_addr
if isinstance(bind_addr, six.binary_type):
if isinstance(bind_addr, bytes):
bind_addr = bind_addr.decode()
# pylint: disable=possibly-unused-variable
@ -275,11 +270,17 @@ def test_peercreds_unix_sock(peercreds_enabled_server):
expected_peercreds = '|'.join(map(str, expected_peercreds))
with requests_unixsocket.monkeypatch():
peercreds_resp = requests.get(unix_base_uri + PEERCRED_IDS_URI)
peercreds_resp = requests.get(
unix_base_uri + PEERCRED_IDS_URI,
timeout=http_request_timeout,
)
peercreds_resp.raise_for_status()
assert peercreds_resp.text == expected_peercreds
peercreds_text_resp = requests.get(unix_base_uri + PEERCRED_TEXTS_URI)
peercreds_text_resp = requests.get(
unix_base_uri + PEERCRED_TEXTS_URI,
timeout=http_request_timeout,
)
assert peercreds_text_resp.status_code == 500
@ -290,14 +291,17 @@ def test_peercreds_unix_sock(peercreds_enabled_server):
)
@unix_only_sock_test
@non_macos_sock_test
def test_peercreds_unix_sock_with_lookup(peercreds_enabled_server):
def test_peercreds_unix_sock_with_lookup(
http_request_timeout,
peercreds_enabled_server,
):
"""Check that ``PEERCRED`` resolution works when enabled."""
httpserver = peercreds_enabled_server
httpserver.peercreds_resolve_enabled = True
bind_addr = httpserver.bind_addr
if isinstance(bind_addr, six.binary_type):
if isinstance(bind_addr, bytes):
bind_addr = bind_addr.decode()
# pylint: disable=possibly-unused-variable
@ -312,7 +316,10 @@ def test_peercreds_unix_sock_with_lookup(peercreds_enabled_server):
)
expected_textcreds = '!'.join(map(str, expected_textcreds))
with requests_unixsocket.monkeypatch():
peercreds_text_resp = requests.get(unix_base_uri + PEERCRED_TEXTS_URI)
peercreds_text_resp = requests.get(
unix_base_uri + PEERCRED_TEXTS_URI,
timeout=http_request_timeout,
)
peercreds_text_resp.raise_for_status()
assert peercreds_text_resp.text == expected_textcreds
@ -363,7 +370,10 @@ def test_high_number_of_file_descriptors(native_server_client, resource_limit):
assert any(fn >= resource_limit for fn in native_process_conn.filenos)
if not IS_WINDOWS:
ISSUE511 = IS_MACOS
if not IS_WINDOWS and not ISSUE511:
test_high_number_of_file_descriptors = pytest.mark.forked(
test_high_number_of_file_descriptors,
)

View file

@ -1,9 +1,4 @@
"""Tests for TLS support."""
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import functools
import json
@ -14,11 +9,11 @@ import sys
import threading
import time
import traceback
import http.client
import OpenSSL.SSL
import pytest
import requests
import six
import trustme
from .._compat import bton, ntob, ntou
@ -49,9 +44,6 @@ IS_PYOPENSSL_SSL_VERSION_1_0 = (
OpenSSL.SSL.SSLeay_version(OpenSSL.SSL.SSLEAY_VERSION).
startswith(b'OpenSSL 1.0.')
)
PY27 = sys.version_info[:2] == (2, 7)
PY34 = sys.version_info[:2] == (3, 4)
PY3 = not six.PY2
PY310_PLUS = sys.version_info[:2] >= (3, 10)
@ -64,13 +56,12 @@ _stdlib_to_openssl_verify = {
fails_under_py3 = pytest.mark.xfail(
not six.PY2,
reason='Fails under Python 3+',
)
fails_under_py3_in_pypy = pytest.mark.xfail(
not six.PY2 and IS_PYPY,
IS_PYPY,
reason='Fails under PyPy3',
)
@ -213,6 +204,7 @@ def thread_exceptions():
),
)
def test_ssl_adapters(
http_request_timeout,
tls_http_server, adapter_type,
tls_certificate,
tls_certificate_chain_pem_path,
@ -241,6 +233,7 @@ def test_ssl_adapters(
resp = requests.get(
'https://{host!s}:{port!s}/'.format(host=interface, port=port),
timeout=http_request_timeout,
verify=tls_ca_certificate_pem_path,
)
@ -276,8 +269,9 @@ def test_ssl_adapters(
reason='Fails under PyPy in CI for unknown reason',
strict=False,
)
def test_tls_client_auth( # noqa: C901 # FIXME
def test_tls_client_auth( # noqa: C901, WPS213 # FIXME
# FIXME: remove twisted logic, separate tests
http_request_timeout,
mocker,
tls_http_server, adapter_type,
ca,
@ -331,6 +325,9 @@ def test_tls_client_auth( # noqa: C901 # FIXME
requests.get,
'https://{host!s}:{port!s}/'.format(host=interface, port=port),
# Don't wait for the first byte forever:
timeout=http_request_timeout,
# Server TLS certificate verification:
verify=tls_ca_certificate_pem_path,
@ -348,12 +345,13 @@ def test_tls_client_auth( # noqa: C901 # FIXME
and tls_verify_mode == ssl.CERT_REQUIRED
and tls_client_identity == 'localhost'
and is_trusted_cert
) or PY34:
):
pytest.xfail(
'OpenSSL 1.0 has problems with verifying client certs',
)
assert is_req_successful
assert resp.text == 'Hello world!'
resp.close()
return
# xfail some flaky tests
@ -366,29 +364,16 @@ def test_tls_client_auth( # noqa: C901 # FIXME
if issue_237:
pytest.xfail('Test sometimes fails')
expected_ssl_errors = (
requests.exceptions.SSLError,
OpenSSL.SSL.Error,
) if PY34 else (
requests.exceptions.SSLError,
)
expected_ssl_errors = requests.exceptions.SSLError,
if IS_WINDOWS or IS_GITHUB_ACTIONS_WORKFLOW:
expected_ssl_errors += requests.exceptions.ConnectionError,
with pytest.raises(expected_ssl_errors) as ssl_err:
make_https_request()
if PY34 and isinstance(ssl_err, OpenSSL.SSL.Error):
pytest.xfail(
'OpenSSL behaves wierdly under Python 3.4 '
'because of an outdated urllib3',
)
make_https_request().close()
try:
err_text = ssl_err.value.args[0].reason.args[0].args[0]
except AttributeError:
if PY34:
pytest.xfail('OpenSSL behaves wierdly under Python 3.4')
elif IS_WINDOWS or IS_GITHUB_ACTIONS_WORKFLOW:
if IS_WINDOWS or IS_GITHUB_ACTIONS_WORKFLOW:
err_text = str(ssl_err.value)
else:
raise
@ -400,9 +385,8 @@ def test_tls_client_auth( # noqa: C901 # FIXME
'sslv3 alert bad certificate' if IS_LIBRESSL_BACKEND
else 'tlsv1 alert unknown ca',
)
if not six.PY2:
if IS_MACOS and IS_PYPY and adapter_type == 'pyopenssl':
expected_substrings = ('tlsv1 alert unknown ca',)
if IS_MACOS and IS_PYPY and adapter_type == 'pyopenssl':
expected_substrings = ('tlsv1 alert unknown ca',)
if (
tls_verify_mode in (
ssl.CERT_REQUIRED,
@ -469,9 +453,9 @@ def test_tls_client_auth( # noqa: C901 # FIXME
pytest.param(
'builtin',
marks=pytest.mark.xfail(
IS_GITHUB_ACTIONS_WORKFLOW and IS_MACOS and PY310_PLUS,
IS_MACOS and PY310_PLUS,
reason='Unclosed TLS resource warnings happen on macOS '
'under Python 3.10',
'under Python 3.10 (#508)',
strict=False,
),
),
@ -492,6 +476,7 @@ def test_ssl_env( # noqa: C901 # FIXME
thread_exceptions,
recwarn,
mocker,
http_request_timeout,
tls_http_server, adapter_type,
ca, tls_verify_mode, tls_certificate,
tls_certificate_chain_pem_path,
@ -532,13 +517,10 @@ def test_ssl_env( # noqa: C901 # FIXME
resp = requests.get(
'https://' + interface + ':' + str(port) + '/env',
timeout=http_request_timeout,
verify=tls_ca_certificate_pem_path,
cert=cl_pem if use_client_cert else None,
)
if PY34 and resp.status_code != 200:
pytest.xfail(
'Python 3.4 has problems with verifying client certs',
)
env = json.loads(resp.content.decode('utf-8'))
@ -620,7 +602,7 @@ def test_https_over_http_error(http_server, ip_addr):
httpserver = http_server.send((ip_addr, EPHEMERAL_PORT))
interface, _host, port = _get_conn_data(httpserver.bind_addr)
with pytest.raises(ssl.SSLError) as ssl_err:
six.moves.http_client.HTTPSConnection(
http.client.HTTPSConnection(
'{interface}:{port}'.format(
interface=interface,
port=port,
@ -633,20 +615,10 @@ def test_https_over_http_error(http_server, ip_addr):
assert expected_substring in ssl_err.value.args[-1]
http_over_https_error_builtin_marks = []
if IS_WINDOWS and six.PY2:
http_over_https_error_builtin_marks.append(
pytest.mark.flaky(reruns=5, reruns_delay=2),
)
@pytest.mark.parametrize(
'adapter_type',
(
pytest.param(
'builtin',
marks=http_over_https_error_builtin_marks,
),
'builtin',
'pyopenssl',
),
)
@ -657,7 +629,9 @@ if IS_WINDOWS and six.PY2:
pytest.param(ANY_INTERFACE_IPV6, marks=missing_ipv6),
),
)
@pytest.mark.flaky(reruns=3, reruns_delay=2)
def test_http_over_https_error(
http_request_timeout,
tls_http_server, adapter_type,
ca, ip_addr,
tls_certificate,
@ -697,36 +671,12 @@ def test_http_over_https_error(
expect_fallback_response_over_plain_http = (
(
adapter_type == 'pyopenssl'
and (IS_ABOVE_OPENSSL10 or not six.PY2)
)
or PY27
) or (
IS_GITHUB_ACTIONS_WORKFLOW
and IS_WINDOWS
and six.PY2
and not IS_WIN2016
)
if (
IS_GITHUB_ACTIONS_WORKFLOW
and IS_WINDOWS
and six.PY2
and IS_WIN2016
and adapter_type == 'builtin'
and ip_addr is ANY_INTERFACE_IPV6
):
expect_fallback_response_over_plain_http = True
if (
IS_GITHUB_ACTIONS_WORKFLOW
and IS_WINDOWS
and six.PY2
and not IS_WIN2016
and adapter_type == 'builtin'
and ip_addr is not ANY_INTERFACE_IPV6
):
expect_fallback_response_over_plain_http = False
if expect_fallback_response_over_plain_http:
resp = requests.get(
'http://{host!s}:{port!s}/'.format(host=fqdn, port=port),
timeout=http_request_timeout,
)
assert resp.status_code == 400
assert resp.text == (
@ -738,6 +688,7 @@ def test_http_over_https_error(
with pytest.raises(requests.exceptions.ConnectionError) as ssl_err:
requests.get( # FIXME: make stdlib ssl behave like PyOpenSSL
'http://{host!s}:{port!s}/'.format(host=fqdn, port=port),
timeout=http_request_timeout,
)
if IS_LINUX:

View file

@ -37,6 +37,7 @@ def simple_wsgi_server():
yield locals()
@pytest.mark.flaky(reruns=3, reruns_delay=2)
def test_connection_keepalive(simple_wsgi_server):
"""Test the connection keepalive works (duh)."""
session = Session(base_url=simple_wsgi_server['url'])
@ -59,6 +60,7 @@ def test_connection_keepalive(simple_wsgi_server):
]
failures = sum(task.result() for task in tasks)
session.close()
assert not failures

View file

@ -15,9 +15,6 @@ the traceback to stdout, and keep any assertions you have from running
be of further significance to your tests).
"""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import pprint
import re
import socket
@ -29,9 +26,8 @@ import json
import unittest # pylint: disable=deprecated-module,preferred-module
import warnings
import functools
from six.moves import http_client, map, urllib_parse
import six
import http.client
import urllib.parse
from more_itertools.more import always_iterable
import jaraco.functools
@ -105,7 +101,7 @@ class WebCase(unittest.TestCase):
HOST = '127.0.0.1'
PORT = 8000
HTTP_CONN = http_client.HTTPConnection
HTTP_CONN = http.client.HTTPConnection
PROTOCOL = 'HTTP/1.1'
scheme = 'http'
@ -127,7 +123,7 @@ class WebCase(unittest.TestCase):
* from :py:mod:`python:http.client`.
"""
cls_name = '{scheme}Connection'.format(scheme=self.scheme.upper())
return getattr(http_client, cls_name)
return getattr(http.client, cls_name)
def get_conn(self, auto_open=False):
"""Return a connection to our HTTP server."""
@ -201,9 +197,9 @@ class WebCase(unittest.TestCase):
"""
ServerError.on = False
if isinstance(url, six.text_type):
if isinstance(url, str):
url = url.encode('utf-8')
if isinstance(body, six.text_type):
if isinstance(body, str):
body = body.encode('utf-8')
# for compatibility, support raise_subcls is None
@ -386,7 +382,7 @@ class WebCase(unittest.TestCase):
def assertBody(self, value, msg=None):
"""Fail if value != self.body."""
if isinstance(value, six.text_type):
if isinstance(value, str):
value = value.encode(self.encoding)
if value != self.body:
if msg is None:
@ -397,7 +393,7 @@ class WebCase(unittest.TestCase):
def assertInBody(self, value, msg=None):
"""Fail if value not in self.body."""
if isinstance(value, six.text_type):
if isinstance(value, str):
value = value.encode(self.encoding)
if value not in self.body:
if msg is None:
@ -406,7 +402,7 @@ class WebCase(unittest.TestCase):
def assertNotInBody(self, value, msg=None):
"""Fail if value in self.body."""
if isinstance(value, six.text_type):
if isinstance(value, str):
value = value.encode(self.encoding)
if value in self.body:
if msg is None:
@ -415,7 +411,7 @@ class WebCase(unittest.TestCase):
def assertMatchesBody(self, pattern, msg=None, flags=0):
"""Fail if value (a regex pattern) is not in self.body."""
if isinstance(pattern, six.text_type):
if isinstance(pattern, str):
pattern = pattern.encode(self.encoding)
if re.search(pattern, self.body, flags) is None:
if msg is None:
@ -464,25 +460,7 @@ def shb(response):
"""Return status, headers, body the way we like from a response."""
resp_status_line = '%s %s' % (response.status, response.reason)
if not six.PY2:
return resp_status_line, response.getheaders(), response.read()
h = []
key, value = None, None
for line in response.msg.headers:
if line:
if line[0] in ' \t':
value += line.strip()
else:
if key and value:
h.append((key, value))
key, value = line.split(':', 1)
key = key.strip()
value = value.strip()
if key and value:
h.append((key, value))
return resp_status_line, h, response.read()
return resp_status_line, response.getheaders(), response.read()
# def openURL(*args, raise_subcls=(), **kwargs):
@ -514,7 +492,7 @@ def openURL(*args, **kwargs):
def _open_url_once(
url, headers=None, method='GET', body=None,
host='127.0.0.1', port=8000, http_conn=http_client.HTTPConnection,
host='127.0.0.1', port=8000, http_conn=http.client.HTTPConnection,
protocol='HTTP/1.1', ssl_context=None,
):
"""Open the given HTTP resource and return status, headers, and body."""
@ -530,7 +508,7 @@ def _open_url_once(
conn = http_conn(interface(host), port, **kw)
conn._http_vsn_str = protocol
conn._http_vsn = int(''.join([x for x in protocol if x.isdigit()]))
if not six.PY2 and isinstance(url, bytes):
if isinstance(url, bytes):
url = url.decode()
conn.putrequest(
method.upper(), url, skip_host=True,
@ -572,10 +550,10 @@ def strip_netloc(url):
>>> strip_netloc('/foo/bar?bing#baz')
'/foo/bar?bing'
"""
parsed = urllib_parse.urlparse(url)
parsed = urllib.parse.urlparse(url)
_scheme, _netloc, path, params, query, _fragment = parsed
stripped = '', '', path, params, query, ''
return urllib_parse.urlunparse(stripped)
return urllib.parse.urlunparse(stripped)
# Add any exceptions which your web framework handles