Skip to content

PYTHON-2443 Fix TypeError when pyOpenSSL socket has timeout of None #526

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 1 commit into from

Conversation

kimvais
Copy link

@kimvais kimvais commented Nov 27, 2020

Fix for crash with the following stack trace when socket.getdefaulttimeout() is None

Traceback (most recent call last):
  File "<REDACTED>/manage.py", line 39, in <module>
    execute_from_command_line(sys.argv)
  File "<REDACTED>/dist-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "<REDACTED>/dist-packages/django/core/management/__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "<REDACTED>/dist-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "<REDACTED>/dist-packages/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "<REDACTED>.py", line 365, in handle
    sources += <REDACTED>.objects.filter(**query)[:limit]
  File "<REDACTED>/dist-packages/mongoengine/queryset/manager.py", line 37, in __get__
    queryset = queryset_class(owner, owner._get_collection())
  File "<REDACTED>/dist-packages/mongoengine/document.py", line 211, in _get_collection
    db = cls._get_db()
  File "<REDACTED>/dist-packages/mongoengine/document.py", line 189, in _get_db
    return get_db(cls._meta.get("db_alias", DEFAULT_CONNECTION_NAME))
  File "<REDACTED>/dist-packages/mongoengine/connection.py", line 369, in get_db
    conn_settings["username"], conn_settings["password"], **auth_kwargs
  File "<REDACTED>/dist-packages/pymongo/database.py", line 1495, in authenticate
    connect=True)
  File "<REDACTED>/dist-packages/pymongo/mongo_client.py", line 780, in _cache_credentials
    with server.get_socket(all_credentials) as sock_info:
  File "<REDACTED>/contextlib.py", line 17, in __enter__
    return self.gen.next()
  File "<REDACTED>/dist-packages/pymongo/pool.py", line 1225, in get_socket
    sock_info = self._get_socket(all_credentials)
  File "<REDACTED>/dist-packages/pymongo/pool.py", line 1275, in _get_socket
    sock_info = self.connect(all_credentials)
  File "<REDACTED>/dist-packages/pymongo/pool.py", line 1193, in connect
    sock_info.ismaster(all_credentials)
  File "<REDACTED>/dist-packages/pymongo/pool.py", line 546, in ismaster
    return self._ismaster(None, None, None, all_credentials)
  File "<REDACTED>/dist-packages/pymongo/pool.py", line 580, in _ismaster
    exhaust_allowed=awaitable)
  File "<REDACTED>/dist-packages/pymongo/pool.py", line 699, in command
    self._raise_connection_failure(error)
  File "<REDACTED>/dist-packages/pymongo/pool.py", line 694, in command
    exhaust_allowed=exhaust_allowed)
  File "<REDACTED>/dist-packages/pymongo/network.py", line 150, in command
    reply = receive_message(sock_info, request_id)
  File "<REDACTED>/dist-packages/pymongo/network.py", line 196, in receive_message    _receive_data_on_socket(sock_info, 16, deadline))
  File "<REDACTED>/dist-packages/pymongo/network.py", line 266, in _receive_data_on_socket
    chunk = sock_info.sock.recv(length)
  File "<REDACTED>/dist-packages/pymongo/pyopenssl_context.py", line 120, in recv
    return self._call(super(_sslConn, self).recv, *args, **kwargs)
  File "<REDACTED>/dist-packages/pymongo/pyopenssl_context.py", line 110, in _call    self, True, True, timeout)
  File "<REDACTED>/dist-packages/pymongo/socket_checker.py", line 60, in select
    res = self._poller.poll(timeout * 1000)
TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'

@ShaneHarvey ShaneHarvey changed the title Fix a crash when SSL socket has timeout of None. PYTHON-2443 Fix TypeError when pyOpenSSL socket has timeout of None Nov 30, 2020
Copy link
Member

@ShaneHarvey ShaneHarvey left a comment

Choose a reason for hiding this comment

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

Thank you for fixing this issue!

@@ -57,7 +57,9 @@ def select(self, sock, read=False, write=False, timeout=0):
try:
# poll() timeout is in milliseconds. select()
# timeout is in seconds.
res = self._poller.poll(timeout * 1000)
# socket.getdefaulttimeout() can return None
timeout_ = timeout * 1000 if timeout is not None else None
Copy link
Member

Choose a reason for hiding this comment

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

Suggest reversing the if/else to shorten the line to <80 chars:

timeout_ = None if timeout is None else timeout * 1000

@@ -57,7 +57,9 @@ def select(self, sock, read=False, write=False, timeout=0):
try:
Copy link
Member

Choose a reason for hiding this comment

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

Can you please update this method's docstring to say:

        """Select for reads or writes with a timeout in seconds (or None).

@ShaneHarvey
Copy link
Member

Thanks @kimvais, your fix will be merged in #527 (where I've added a test case).

@ShaneHarvey ShaneHarvey closed this Dec 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tracked-in-jira Ticket filed in Mongo's Jira system
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants