Skip to content

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

Description

@aryansk

{"version": 1, "upstream": "MagicStack/asyncpg", "fork": "aryansk/asyncpg", "base": "master", "branch": "fix/tls-upgrade-error-response-1317", "commitMessage": "Preserve SSL negotiation ErrorResponse details", "prTitle": "Surface PostgreSQL ErrorResponse during SSL negotiation", "prBody": "Fixes #1317.\n\nWhen a server replies to SSLRequest with a pre-auth E... error payload, preserve the server's diagnostic text in an asyncpg InterfaceError instead of replacing it with the generic rejected SSL upgrade message.\n\nIncludes a regression test for the simplified pre-auth error form described in the issue.", "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@@ -927,6 +927,16 @@ 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+ if not message:\n+ message = 'server error during SSL negotiation'\n+ self.on_data.set_exception(\n+ exceptions.InterfaceError(\n+ 'PostgreSQL server at "{host}:{port}" reported: {message}'.format(\n+ host=self.host, port=self.port, message=message)))\n else:\n self.on_data.set_exception(\n ConnectionError(\ndiff --git a/tests/test_connect_utils.py b/tests/test_connect_utils.py\nnew file mode 100644\n--- /dev/null\n+++ b/tests/test_connect_utils.py\n@@ -0,0 +1,31 @@\n+import asyncio\n+import ssl\n+import unittest\n+\n+from asyncpg import connect_utils, exceptions\n+\n+\n+class TLSUpgradeProtoTests(unittest.TestCase):\n+ def setUp(self):\n+ self.loop = asyncio.new_event_loop()\n+ self.addCleanup(self.loop.close)\n+\n+ def make_proto(self):\n+ context = ssl.create_default_context()\n+ return connect_utils.TLSUpgradeProto(\n+ self.loop,\n+ 'localhost',\n+ 5432,\n+ context,\n+ False,\n+ )\n+\n+ def test_server_error_response_is_preserved(self):\n+ proto = self.make_proto()\n+ proto.data_received(\n+ b'Ecould not fork new process for connection: Cannot allocate memory\n\x00'\n+ )\n+\n+ with self.assertRaisesRegex(\n+ exceptions.InterfaceError,\n+ 'could not fork new process for connection: Cannot allocate memory',\n+ ):\n+ self.loop.run_until_complete(proto.on_data)\n", "draft": true, "upstreamIssue": 1317}

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