Skip to content

Fix SSL connection testing in Python 3.7 #1661

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from

Conversation

seanthegeek
Copy link

@seanthegeek seanthegeek commented Nov 27, 2018

Closes issue #1549


This change is Reviewable

Fix SSL connection testing in Python 3.7
@jeffwidman
Copy link
Contributor

jeffwidman commented Nov 30, 2018

Thanks for this! A couple of comments... I have no convenient way to test this, so which environment(s) have you tested it in?

@seanthegeek
Copy link
Author

@jeffwidman Python 3.7 on Windows and Python 3.6 on Debian Buster.

@mooperd
Copy link

mooperd commented Dec 1, 2018

+1

Copy link
Contributor

@jeffwidman jeffwidman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clean up the commit history?

if sys.version_info >= (3, 7):
ret = None
else:
raise err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, you only need this to be raise and it will re-raise the most recent one

@@ -54,6 +54,9 @@ pushd servers
fi
echo
echo "Extracting kafka ${kafka} binaries"
if [ ! -d ../$kafka ]; then
mkdir ../$kafka
fi
Copy link
Contributor

@jeffwidman jeffwidman Dec 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like the .gitignore change, this feels like a distinct PR / commit which wouldn't happen if I merge by squashing

@@ -15,3 +15,4 @@ docs/_build
integration-test/
tests-env/
.pytest_cache/
venv/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense to me to add, but as a separate commit from the SSL fix.

However your commit history is a mess, so normally I'd merge this PR by squashing... but that would conflict with above...

@mooperd
Copy link

mooperd commented Dec 1, 2018

Hi,

With the following code:

from kafka import KafkaAdminClient

adminclient = KafkaAdminClient(
    bootstrap_servers="kafka-317b40d8-andrew-e213.aivencloud.com:18224",
    security_protocol="SSL",
    ssl_cafile="ca.pem",
    ssl_certfile="service.cert",
    ssl_keyfile="service.key",
)

adminclient.create_topics(['meow'], timeout_ms=None, validate_only=False)

I get an error:

Traceback (most recent call last):
  File "ensure-kafka-topic.py", line 10, in <module>
    ssl_keyfile="service.key",
  File "/Users/andrew/dev/aiven/kafka/admin/client.py", line 195, in __init__
    **self.config)
  File "/Users/andrew/dev/aiven/kafka/client_async.py", line 231, in __init__
    self.config['api_version'] = self.check_version(timeout=check_timeout)
  File "/Users/andrew/dev/aiven/kafka/client_async.py", line 857, in check_version
    version = conn.check_version(timeout=remaining, strict=strict, topics=list(self.config['bootstrap_topics_filter']))
  File "/Users/andrew/dev/aiven/kafka/conn.py", line 953, in check_version
    if not self.connect_blocking(timeout_at - time.time()):
  File "/Users/andrew/dev/aiven/kafka/conn.py", line 304, in connect_blocking
    self.connect()
  File "/Users/andrew/dev/aiven/kafka/conn.py", line 402, in connect
    if self._try_handshake():
  File "/Users/andrew/dev/aiven/kafka/conn.py", line 465, in _try_handshake
    self._sock.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 1112, in do_handshake
    self._check_connected()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 900, in _check_connected
    self.getpeername()
OSError: [Errno 57] Socket is not connected

Python 3.7.1 on OSX connecting to Aiven Kafka 2.0.1
System Version: macOS 10.13.5 (17F77)

Similarly, on linux:

Traceback (most recent call last):
  File "hit_kafka.py", line 10, in <module>
    ssl_keyfile="service.key",
  File "/hello/kafka/producer/kafka.py", line 372, in __init__
    **self.config)
  File "/hello/kafka/client_async.py", line 231, in __init__
    self.config['api_version'] = self.check_version(timeout=check_timeout)
  File "/hello/kafka/client_async.py", line 857, in check_version
    version = conn.check_version(timeout=remaining, strict=strict, topics=list(self.config['bootstrap_topics_filter']))
  File "/hello/kafka/conn.py", line 953, in check_version
    if not self.connect_blocking(timeout_at - time.time()):
  File "/hello/kafka/conn.py", line 304, in connect_blocking
    self.connect()
  File "/hello/kafka/conn.py", line 402, in connect
    if self._try_handshake():
  File "/hello/kafka/conn.py", line 465, in _try_handshake
    self._sock.do_handshake()
  File "/usr/local/lib/python3.7/ssl.py", line 1112, in do_handshake
    self._check_connected()
  File "/usr/local/lib/python3.7/ssl.py", line 900, in _check_connected
    self.getpeername()
OSError: [Errno 107] Transport endpoint is not connected

Python 3.7.1
Debian Stretch

@joagain
Copy link

joagain commented Dec 4, 2018

Hi,

I'm getting a similar (but not exactly the same) error as @mooperd 's when calling KafkaConsumer. beginning_offsets:

  File "/Users/myuser/myproject/virtualenv/lib/python3.7/site-packages/kafka/consumer/group.py", line 986, in beginning_offsets
    partitions, self.config['request_timeout_ms'])
  File "/Users/myuser/myproject/virtualenv/lib/python3.7/site-packages/kafka/consumer/fetcher.py", line 213, in beginning_offsets
    partitions, OffsetResetStrategy.EARLIEST, timeout_ms)
  File "/Users/myuser/myproject/virtualenv/lib/python3.7/site-packages/kafka/consumer/fetcher.py", line 221, in beginning_or_end_offset
    offsets = self._retrieve_offsets(timestamps, timeout_ms)
  File "/Users/myuser/myproject/virtualenv/lib/python3.7/site-packages/kafka/consumer/fetcher.py", line 279, in _retrieve_offsets
    self._client.poll(future=future, timeout_ms=remaining_ms)
  File "/Users/myuser/myproject/virtualenv/lib/python3.7/site-packages/kafka/client_async.py", line 559, in poll
    self._maybe_connect(node_id)
  File "/Users/myuser/myproject/virtualenv/lib/python3.7/site-packages/kafka/client_async.py", line 386, in _maybe_connect
    conn.connect()
  File "/Users/myuser/myproject/virtualenv/lib/python3.7/site-packages/kafka/conn.py", line 402, in connect
    if self._try_handshake():
  File "/Users/myuser/myproject/virtualenv/lib/python3.7/site-packages/kafka/conn.py", line 465, in _try_handshake
    self._sock.do_handshake()
  File "/usr/local/Cellar/python/3.7.1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 1112, in do_handshake
    self._check_connected()
  File "/usr/local/Cellar/python/3.7.1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 900, in _check_connected
    self.getpeername()
OSError: [Errno 57] Socket is not connected

Update: I was able to fix the issue above by catching the OSError that was thrown. My issue was that the socket wasn't connected the first time the client's poll happened, and the program just crashed. I'm catching the error to give some time to the polling loop.

    def _try_handshake(self):
        assert self.config['security_protocol'] in ('SSL', 'SASL_SSL')
        try:
            self._sock.do_handshake()
            return True
        # old ssl in python2.6 will swallow all SSLErrors here...
        except (SSLWantReadError, SSLWantWriteError, OSError): # FIX HERE
            pass
        except (SSLZeroReturnError, ConnectionError, SSLEOFError):
            log.warning('SSL connection closed by server during handshake.')
            self.close(Errors.KafkaConnectionError('SSL connection closed by server during handshake'))
        # Other SSLErrors will be raised to user

@seanthegeek
Copy link
Author

Superseded by PR #1669

@jeffwidman
Copy link
Contributor

@mooperd / @joagain I just merged #1669.

Please try the latest master and see if that fixes these issues... if not, please open a new issue. @joagain in particular, based on a quick glance I don't think you should need to hack around that error, I think we should be handling at a library level. Although that is only based on a quick glance, so I may be missing something.

@danjo133
Copy link
Contributor

danjo133 commented Jan 7, 2019

I did: pip install git+https://github.com/dpkp/kafka-python after #1669 was merged and I need to add except OSError as well, otherwise I get the same:
OSError: [Errno 57] Socket is not connected

If I add the OSError catch there, it works for me (OSX, python 3.7.0)

@jeffwidman
Copy link
Contributor

@danjo133 can you add this as a separate issue? Or better yet a new PR so that we can discuss the actual code change?

Commenting on old issues just tends to get lost in the noise...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants