Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions asyncpg/connect_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,12 @@ def data_received(self, data: bytes) -> None:
# sslmode=prefer. But be extra sure to disallow insecure
# connections when the ssl context asks for real security.
self.on_data.set_result(False)
elif data.startswith(b'E'):
message = data[1:].rstrip(b'\x00\r\n').decode(
'utf-8', errors='replace')
self.on_data.set_exception(
exceptions.InterfaceError(
message or 'server error during SSL negotiation'))
else:
self.on_data.set_exception(
ConnectionError(
Expand Down
13 changes: 13 additions & 0 deletions tests/test_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@ def mock_dev_null_home_dir():
yield


class TestTLSUpgradeProto(tb.TestCase):

async def test_error_response_preserves_server_message(self):
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
proto = connect_utils.TLSUpgradeProto(
self.loop, 'localhost', 5432, context, False)

proto.data_received(b'Etoo many connections\n\x00')
with self.assertRaisesRegex(
exceptions.InterfaceError, 'too many connections'):
await proto.on_data


class TestSettings(tb.ConnectedTestCase):

async def test_get_settings_01(self):
Expand Down