-
Notifications
You must be signed in to change notification settings - Fork 939
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
EOF occurred in violation of protocol #719
Comments
I've seen this as well, although the error seems sporadic (I don't see it on all SSL requests). |
Yes, I agree with you, it does not occur for all SSL requests. I can reproduce this error by refreshing page, which is making socket connection, very quickly. I guess, in this case requests does not complete, consequently error occurs. I tackle this problem by placing nginx server as a proxy to receive ssl requests. |
Upgraded from |
@maryokhin What version of Python are you on? Do you experience this issue in rc2? What Python/gevent versions are others experiencing this on? The sporadic nature of this makes it difficult to debug. A self-contained failing testcase would be very helpful. |
@jamadden Python 3.5 + rc1 passes, rc2 & rc3 fails. Tested on whatever Ubuntu version Travis uses. |
@maryokhin Tested how? Is it separable? |
@jamadden: It was a Travis build running a Docker container of Django 1.9.1 on gunicorn 19.4.5 using a Python 3.5 interpreter 😬 I understand that's not very reproducible or useful, but rc1 works under the same conditions and rc2/rc3 doesn't, I upgraded/downgraded back and fourth. |
Thanks, that is helpful, especially because you see this on Python 3, because the only change to the SSL module for Python 3 between rc1 and rc2 was in the exceptions that get raised on timeouts. This traded one loop for another apparently equivalent loop, whose only apparent difference is that it properly respects the total timeout. Posting the traceback you get on Python 3 might also be helpful. |
Sure. I'm guessing this happens as soon as the first SSL request is made:
|
The error in The handshake process is also entirely in C and bypasses the Python timeout issue that was changed, so the I'm having difficulties reproducing the |
Continuing on the The Python-level Looking more closely at the implementation of
Let's consider branch (1) for now (as a catch-all, branch (2) is not that helpful), and because we're probably trying to write, based on the location of the error. The only place I can find that puts the IO object into the "special" state is part of the handshake process. Either it needs a So that leaves us with the certificate case during a handshake (which I think can be re-negotiated at almost any time?), or "any unknown error" (specifically, we didn't need to read or write or explicitly do an cert lookup---that's checked after the read/write cases---and the socket isn't being closed). I haven't been able to reproduce this using either a Python server or the openssl s_server, sending data of various sizes from small to very large under OS X or a recent Ubuntu. Is anyone else able to reproduce this reliably? @maryokhin can you still reproduce it (perhaps it was a transient SNS issue)? Can you reproduce it outside of the travis environment, or hitting a different availability zone? Other thoughts? |
Not sure of this is helpful, but I've dealt with open SSL a bit. The most common way (in my experience) you get the "eof in violation of protocol" message is when the client fails to send an SSL shutdown, but just closes the socket when communication is complete. There is an option "suppress_ragged_eofs" |
From SSL module docs:
|
Thanks. But as the quoted docs note, that parameter defaults to True, and I don't see anywhere in the |
In the stdlib (and in gevent's modified copy of it), |
Nuts. Were you able to reproduce the error in 61c6a5a? (If so I can grab a packet capture.) |
Sadly I have not been able to reproduce the error with that code or numerous variations in it, including using an OpenSSL server, various data sizes and timeouts, etc. |
I've seen this happen "around" high level APIs by failing to call shutdown() on the underlying SSL structure. Basically, imagine a test script that uses urllib / httplib to send some HTTP request, then immediately exits. Not only is this a problem for SSL, I believe in TCP cases the request may also have data loss. (I guess HTTP insulates from having to understand this somewhat since it follows a model where client controls connection set up and tear down, and also initiates all requests.) I've never looked too closely at the standard library ssl module before, but that looks kind of bad: https://hg.python.org/cpython/file/2.7/Lib/ssl.py#l789 to ensure against data loss every SSL socket should have SSL_shutdown called on it before sockets are closed. (https://www.openssl.org/docs/manmaster/ssl/SSL_shutdown.html). But it looks like standard library only does this in the case that unwrap() is called. So, that may be what the original reporter was doing. (I've left a line comment on the test commit -- I can try reproducing later today maybe.) |
Hmm.... wait maybe not, because the stack trace had that in the middle of do_handshake, so this must be something different, |
I think the original |
The following two code snippets trigger the bug every time with Python 3.5. Tested on Ubuntu 15.10 (amd64). Buggy code using send
Buggy code using sendall with timeout
|
Unsurprisingly, the monkey patching is unnecessary. It works in the same way if gevent.socket and gevent.ssl are used directly. |
When looking at Python 3.5's |
Thanks, that was the missing piece! I'm adding test cases and fixes to gevent now. Note that
|
This problem still persists.
While using Celery + Gevent + RabbitMQ I have placed a lot of logs. The interesting thing is that code inside this task finishes but gevent worker itself hangs and does not send success results to RabbitMQ. |
I have the same celery + Gevent + RabbitMQ problem, do you fix the problem? |
I am trying to run a socket server with ssl support. For this purpose I am usung flask-socketio which uses gevent behind. I think flask-socketio has nothing to do with ssl options, it is just passing to ssl configurations to gevent init.
Socket server with ssl support was possible, but after re-installing all the pip packages, I started to get the following error.
is there any solution?
The text was updated successfully, but these errors were encountered: