Skip to content

[pr-relay] MagicStack/asyncpg #1317 #75

Description

@aryansk

{"version":1,"upstream":"MagicStack/asyncpg","fork":"aryansk/asyncpg","base":"master","branch":"fix/1317-ssl-error-response","commitMessage":"fix: surface pre-auth SSL server errors","prTitle":"Surface server errors during SSL negotiation","prBody":"## Summary\n\nPreserve the PostgreSQL server's diagnostic when it returns an early error while asyncpg is waiting for the one-byte SSL negotiation response.\n\n## Changes\n\n- recognize pre-auth responses beginning with the PostgreSQL ErrorResponse marker (E)\n- decode and surface the server-provided text as an asyncpg InterfaceError\n- retain the existing S, advisory N, and generic fallback behavior\n- add a unit regression test using the reported pre-auth response shape\n\n## Test plan\n\npython -m unittest tests.test_connect.TestTLSUpgradeProto.test_error_response_preserves_server_message\n\nFixes #1317","patch":"diff --git a/asyncpg/connect_utils.py b/asyncpg/connect_utils.py\n--- a/asyncpg/connect_utils.py\n+++ b/asyncpg/connect_utils.py\n@@ -929,6 +929,13 @@ class TLSUpgradeProto(asyncio.Protocol):\n # connections when the ssl context asks for real security.\n self.on_data.set_result(False)\n+ elif data.startswith(b'E'):\n+ message = data[1:].rstrip(b'\x00\r\n').decode(\n+ 'utf-8', errors='replace')\n+ self.on_data.set_exception(\n+ exceptions.InterfaceError(\n+ message or 'server error during SSL negotiation'))\n else:\n self.on_data.set_exception(\n ConnectionError(\n 'PostgreSQL server at "{host}:{port}" '\ndiff --git a/tests/test_connect.py b/tests/test_connect.py\n--- a/tests/test_connect.py\n+++ b/tests/test_connect.py\n@@ -93,6 +93,18 @@ def mock_dev_null_home_dir():\n yield\n \n \n+class TestTLSUpgradeProto(tb.TestCase):\n+\n+ async def test_error_response_preserves_server_message(self):\n+ context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)\n+ proto = connect_utils.TLSUpgradeProto(\n+ self.loop, 'localhost', 5432, context, False)\n+\n+ proto.data_received(b'Etoo many connections\n\x00')\n+ with self.assertRaisesRegex(\n+ exceptions.InterfaceError, 'too many connections'):\n+ await proto.on_data\n+\n+\n class TestSettings(tb.ConnectedTestCase):\n \n async def test_get_settings_01(self):\n","draft":true,"upstreamIssue":1317}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    relay/successRelay job created a pull request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions