Skip to content

Commit

Permalink
Stop abusing pytest-httpbin to test commonName support
Browse files Browse the repository at this point in the history
pytest-httpbin<1.0 ships with a server certificate with a commonName but
no subjectAltName. urllib3 2.0 will stop supporting those in the future,
so we want to upgrade pytest-httpbin.

Unfortunately, `test_https_warnings` was relying on this broken
certificate. With this change, we use `trustme` to create a broken
certificate specifically for this test, so that we can upgrade
pytest-httpbin and make sure that other tests relying on httpbin TLS
support will continue to work with urllib3 2.0.
  • Loading branch information
pquentin authored Jul 12, 2021
1 parent f6c0619 commit e253eba
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 4 deletions.
3 changes: 2 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
pytest>=2.8.0,<=3.10.1
pytest-cov
pytest-httpbin<1.0
pytest-httpbin==1.0.0
pytest-mock==2.0.0
httpbin==0.7.0
Flask>=1.0,<2.0
trustme
wheel
34 changes: 34 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
# -*- coding: utf-8 -*-

try:
from http.server import HTTPServer
from http.server import SimpleHTTPRequestHandler
except ImportError:
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

import ssl
import tempfile
import threading

import pytest
from requests.compat import urljoin
import trustme


def prepare_url(value):
Expand All @@ -22,3 +34,25 @@ def httpbin(httpbin):
@pytest.fixture
def httpbin_secure(httpbin_secure):
return prepare_url(httpbin_secure)


@pytest.fixture
def nosan_server(tmp_path_factory):
tmpdir = tmp_path_factory.mktemp("certs")
ca = trustme.CA()
# only commonName, no subjectAltName
server_cert = ca.issue_cert(common_name=u"localhost")
ca_bundle = str(tmpdir / "ca.pem")
ca.cert_pem.write_to_path(ca_bundle)

context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
server_cert.configure_cert(context)
server = HTTPServer(("localhost", 0), SimpleHTTPRequestHandler)
server.socket = context.wrap_socket(server.socket, server_side=True)
server_thread = threading.Thread(target=server.serve_forever)
server_thread.start()

yield "localhost", server.server_address[1], ca_bundle

server.shutdown()
server_thread.join()
6 changes: 3 additions & 3 deletions tests/test_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -874,8 +874,9 @@ def test_http_with_certificate(self, httpbin):
r = requests.get(httpbin(), cert='.')
assert r.status_code == 200

def test_https_warnings(self, httpbin_secure, httpbin_ca_bundle):
def test_https_warnings(self, nosan_server):
"""warnings are emitted with requests.get"""
host, port, ca_bundle = nosan_server
if HAS_MODERN_SSL or HAS_PYOPENSSL:
warnings_expected = ('SubjectAltNameWarning', )
else:
Expand All @@ -885,8 +886,7 @@ def test_https_warnings(self, httpbin_secure, httpbin_ca_bundle):

with pytest.warns(None) as warning_records:
warnings.simplefilter('always')
requests.get(httpbin_secure('status', '200'),
verify=httpbin_ca_bundle)
requests.get("https://localhost:{}/".format(port), verify=ca_bundle)

warning_records = [item for item in warning_records
if item.category.__name__ != 'ResourceWarning']
Expand Down

0 comments on commit e253eba

Please sign in to comment.