Closed
Description
Long story short
I'd like to catch all client errors, including certificate errors, but except aiohttp.errors.ClientError
is not sufficient.
Expected behaviour
All kinds of certificate error should cause an instance of (a subclass of) aiohttp.errors.ClientConnectionError
to be raised.
Actual behaviour
When there's mismatch between the hostname and the certificate's CN/SAN, ssl.CertificateError
is raised.
(And, for some reason, its traceback is printed on stderr, even when I catch it. 😬)
Steps to reproduce
Run the following code:
import asyncio
import aiohttp
async def main(url):
async with aiohttp.ClientSession() as session:
try:
async with session.get(url):
await response.read()
except aiohttp.errors.ClientError as exc:
pass
except Exception as exc:
print('Unexpected {!r}'.format(exc))
url = 'https://wrong.host.badssl.com'
loop = asyncio.get_event_loop()
loop.run_until_complete(main(url))
loop.close()
You will get:
Exception in callback None
handle: <Handle cancelled>
Traceback (most recent call last):
File "/usr/lib/python3.5/asyncio/events.py", line 125, in _run
self._callback(*self._args)
File "/usr/lib/python3.5/asyncio/selector_events.py", line 677, in _read_ready
self._protocol.data_received(data)
File "/usr/lib/python3.5/asyncio/sslproto.py", line 493, in data_received
ssldata, appdata = self._sslpipe.feed_ssldata(data)
File "/usr/lib/python3.5/asyncio/sslproto.py", line 201, in feed_ssldata
self._sslobj.do_handshake()
File "/usr/lib/python3.5/ssl.py", line 638, in do_handshake
match_hostname(self.getpeercert(), self.server_hostname)
File "/usr/lib/python3.5/ssl.py", line 297, in match_hostname
% (hostname, ', '.join(map(repr, dnsnames))))
ssl.CertificateError: hostname 'wrong.host.badssl.com' doesn't match either of '*.badssl.com', 'badssl.com'
Unexpected CertificateError("hostname 'wrong.host.badssl.com' doesn't match either of '*.badssl.com', 'badssl.com'",)
Your environment
aiohttp from git master (d8848dd), Python 3.5.2, Linux.