Skip to content
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

NameError trying to use SSL with gevents on Python 3.3.3 or 2.7.6 and earlier #856

Closed
mjpieters opened this issue Sep 5, 2016 · 3 comments
Labels
PyVer: python3 Affects Python 3

Comments

@mjpieters
Copy link

mjpieters commented Sep 5, 2016

  • gevent version: 1.1.2
  • Python version: 3.3.3, 2.7.6
  • Operating System: Linux, OS X

Description:

Accessing an SSL website results in a NameError exception for SOL_SOCKET:

NameError: global name 'SOL_SOCKET' is not defined

What I've run:

from gevent import monkey; monkey.patch_all()
import gevent, requests
requests.get('https://haofly.net')

Full traceback

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.3/site-packages/requests/api.py", line 70, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/local/lib/python3.3/site-packages/requests/api.py", line 56, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python3.3/site-packages/requests/sessions.py", line 475, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.3/site-packages/requests/sessions.py", line 596, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.3/site-packages/requests/adapters.py", line 423, in send
    timeout=timeout
  File "/usr/local/lib/python3.3/site-packages/requests/packages/urllib3/connectionpool.py", line 595, in urlopen
      chunked=chunked)
  File "/usr/local/lib/python3.3/site-packages/requests/packages/urllib3/connectionpool.py", line 352, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.3/site-packages/requests/packages/urllib3/connectionpool.py", line 831, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.3/site-packages/requests/packages/urllib3/connection.py", line 289, in connect
    ssl_version=resolved_ssl_version)
  File "/usr/local/lib/python3.3/site-packages/requests/packages/urllib3/util/ssl_.py", line 308, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/local/lib/python3.3/site-packages/gevent/_ssl3.py", line 60, in wrap_socket
    _context=self)
  File "/usr/local/lib/python3.3/site-packages/gevent/_ssl3.py", line 143, in __init__
    if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
NameError: global name 'SOL_SOCKET' is not defined

Proposed fix

The SOL_SOCKET and SO_TYPE constants are defined on the socket module. They are only incidentally present in ssl for many but not all Python releases gevent supports; any release that includes a fix for Python issue 19422 includes a line:

from socket import SOL_SOCKET, SO_TYPE

Both these names would have to be imported from socket in _ssl3.py too if gevent is to support all 2.7 and 3.3 revisions. Future versions of Python may remove that name from ssl again, since it is not part of the ssl module public API.


This bug was originally reported on Stack Overflow by haofly.

@jamadden
Copy link
Member

jamadden commented Sep 6, 2016

Thank you for your report.

Python 3.3 is currently in "security-fix only" mode. The bugfix you mentioned was merged in 2013 and has been included in all bugfix and security-fix releases of Python 3.3 since 2014. Given 3.3's status and the difficulty of testing on such an old point-release that's long been superseded, it seems to me that a reasonable response is "update your Python version."

As far as 2.7 goes, gevent is tested on 2.7.8 and 2.7.9+ because there are two separate ssl implementations. The <=2.7.8 code does not reference these constants as far as I can see, so I don't see how this can apply to 2.7.6. The 2.7.9+ code does use these constants, but that SSL implementation should have the python bugfix, so again I don't see how this can apply to 2.7.9+.

Given that gevent works with and relies heavily on the actual stdlib implementation, I wouldn't consider this a bug in gevent; it would be more accurate to say that gevent only supports Python 3.3.4+ (the documentation can be adjusted accordingly). When future versions adjust the stdlib implementation, doubtless gevent will have to change in response, but it's hard to predict for sure what those changes will have to be.

@jamadden jamadden added the PyVer: python3 Affects Python 3 label Sep 6, 2016
@mjpieters
Copy link
Author

My point is more that using socket constants via their import into the ssl module is a source of bugs. In this specific case you get away with it for now and only older, less used releases are affected, but it's still wrong to rely on those constants being available from that location. :-)

@jamadden
Copy link
Member

jamadden commented Sep 6, 2016

I think I get your point, and I understand. But if you'll notice, _ssl3.py doesn't explicitly import any symbols from the stdlib. It---and more to the point, lots of gevent---simply relies on copying the existing globals from the stdlib modules. Do I like it? Not exactly. Does it make linters work extra hard? It absolutely does. But is that the way it works now? Sure is.

(Recent work has made this slightly more obvious, through the copy_globals function. There are around 10+ gevent modules that rely on this.)

hashbrowncipher pushed a commit to hashbrowncipher/gevent that referenced this issue Oct 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PyVer: python3 Affects Python 3
Projects
None yet
Development

No branches or pull requests

2 participants