Skip to content

Commit

Permalink
Always treat SSLError timeouts as socket timeouts (celery#247)
Browse files Browse the repository at this point in the history
Without specifically handling this case, the socket.timeout()
was not raised sometimes causing the connection to lock up.

In the case we hit the errno was None, so the previous if
condition did not apply.

Co-Authored-By: aojeagarcia <aojeagarcia@suse.com>
  • Loading branch information
2 people authored and matusvalo committed Jan 31, 2019
1 parent 457b3ba commit bf122a0
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
4 changes: 4 additions & 0 deletions amqp/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,10 @@ def _read(self, n, initial=False,
try:
s = recv(n - len(rbuf)) # see note above
except socket.error as exc:
# ssl.sock.read may cause a SSLerror without errno
# http://bugs.python.org/issue10272
if isinstance(exc, SSLError) and 'timed out' in str(exc):
raise socket.timeout()
# ssl.sock.read may cause ENOENT if the
# operation couldn't be performed (Issue celery#1414).
if exc.errno in _errnos:
Expand Down
18 changes: 17 additions & 1 deletion t/unit/test_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import struct

import pytest
from case import ANY, Mock, call, patch
from case import ANY, Mock, MagicMock, call, patch

from amqp import transport
from amqp.exceptions import UnexpectedFrame
Expand Down Expand Up @@ -653,6 +653,22 @@ def test_write_ValueError(self):
match=r'.*Socket closed.*'):
self.t._write('foo')

def test_read_timeout(self):
self.t.sock = Mock(name='SSLSocket')
self.t._quick_recv = Mock(name='recv', return_value='4')
self.t._quick_recv.side_effect = socket.timeout()
self.t._read_buffer = MagicMock(return_value='AA')
with pytest.raises(socket.timeout):
self.t._read(64)

def test_read_SSLError(self):
self.t.sock = Mock(name='SSLSocket')
self.t._quick_recv = Mock(name='recv', return_value='4')
self.t._quick_recv.side_effect = transport.SSLError('timed out')
self.t._read_buffer = MagicMock(return_value='AA')
with pytest.raises(socket.timeout):
self.t._read(64)


class test_TCPTransport:

Expand Down

0 comments on commit bf122a0

Please sign in to comment.