From 20d02156ee61a579f896c270820ac51dc86455b4 Mon Sep 17 00:00:00 2001 From: Hannu Valtonen Date: Tue, 1 Aug 2017 15:46:00 +0300 Subject: [PATCH] conn: Catch ssl.EOFErrors on Python3.3 so we close the failing conn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I saw this traceback as a recurring loop in my client which uses KafkaConsumer: ... File "/usr/lib/python3.5/site-packages/kafka/client_async.py", line 491, in send if not self._maybe_connect(node_id): File "/usr/lib/python3.5/site-packages/kafka/client_async.py", line 368, in _maybe_connect conn.connect() File "/usr/lib/python3.5/site-packages/kafka/conn.py", line 355, in connect if self._try_handshake(): File "/usr/lib/python3.5/site-packages/kafka/conn.py", line 420, in _try_handshake self._sock.do_handshake() File "/usr/lib64/python3.5/ssl.py", line 996, in do_handshake self._sslobj.do_handshake() File "/usr/lib64/python3.5/ssl.py", line 641, in do_handshake self._sslobj.do_handshake() ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:720) Based on: https://docs.python.org/3/library/ssl.html: exception ssl.SSLEOFError A subclass of SSLError raised when the SSL connection has been terminated abruptly. Generally, you shouldn’t try to reuse the underlying transport when this error is encountered. So start closing the connection if we get EOFError from the connection instead of just raising the exception up the stack. --- kafka/conn.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kafka/conn.py b/kafka/conn.py index 16eaf62f1..6a9c200c7 100644 --- a/kafka/conn.py +++ b/kafka/conn.py @@ -35,6 +35,7 @@ import ssl ssl_available = True try: + SSLEOFError = ssl.SSLEOFError SSLWantReadError = ssl.SSLWantReadError SSLWantWriteError = ssl.SSLWantWriteError SSLZeroReturnError = ssl.SSLZeroReturnError @@ -43,6 +44,7 @@ log.warning('Old SSL module detected.' ' SSL error handling may not operate cleanly.' ' Consider upgrading to Python 3.3 or 2.7.9') + SSLEOFError = ssl.SSLError SSLWantReadError = ssl.SSLError SSLWantWriteError = ssl.SSLError SSLZeroReturnError = ssl.SSLError @@ -421,7 +423,7 @@ def _try_handshake(self): # old ssl in python2.6 will swallow all SSLErrors here... except (SSLWantReadError, SSLWantWriteError): pass - except (SSLZeroReturnError, ConnectionError): + except (SSLZeroReturnError, ConnectionError, SSLEOFError): log.warning('SSL connection closed by server during handshake.') self.close(Errors.ConnectionError('SSL connection closed by server during handshake')) # Other SSLErrors will be raised to user