Skip to content

Commit 3a1790b

Browse files
authored
Merge pull request datastax#989 from datastax/long-python_catch-ssl-errs
PYTHON-1024: fix catch ssl err catching
2 parents 2ace932 + 281ac3e commit 3a1790b

File tree

4 files changed

+36
-7
lines changed

4 files changed

+36
-7
lines changed

CHANGELOG.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
3.15.2
22
======
33

4+
Bug Fixes
5+
---------
6+
* Improve and fix socket error-catching code in nonblocking-socket reactors (PYTHON-1024)
7+
48
Other
59
-----
610
* Fix tests when RF is not maintained if we decomission a node (PYTHON-1017)

cassandra/io/asyncorereactor.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,10 +424,14 @@ def handle_read(self):
424424
break
425425
except socket.error as err:
426426
if ssl and isinstance(err, ssl.SSLError):
427-
if err.args[0] not in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE):
427+
if err.args[0] in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE):
428+
return
429+
else:
428430
self.defunct(err)
429431
return
430-
elif err.args[0] not in NONBLOCKING:
432+
elif err.args[0] in NONBLOCKING:
433+
return
434+
else:
431435
self.defunct(err)
432436
return
433437

cassandra/io/libevreactor.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,10 +344,14 @@ def handle_read(self, watcher, revents, errno=None):
344344
break
345345
except socket.error as err:
346346
if ssl and isinstance(err, ssl.SSLError):
347-
if err.args[0] not in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE):
347+
if err.args[0] in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE):
348+
return
349+
else:
348350
self.defunct(err)
349351
return
350-
elif err.args[0] not in NONBLOCKING:
352+
elif err.args[0] in NONBLOCKING:
353+
return
354+
else:
351355
self.defunct(err)
352356
return
353357

tests/unit/io/utils.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@
2525
from mock import Mock
2626

2727
import errno
28+
import logging
2829
import math
2930
import os
3031
from socket import error as socket_error
32+
import ssl
3133

3234
try:
3335
import unittest2 as unittest
@@ -37,6 +39,9 @@
3739
import time
3840

3941

42+
log = logging.getLogger(__name__)
43+
44+
4045
class TimerCallback(object):
4146

4247
invoked = False
@@ -247,26 +252,38 @@ def test_successful_connection(self):
247252
return c
248253

249254
def test_eagain_on_buffer_size(self):
255+
self._check_error_recovery_on_buffer_size(errno.EAGAIN)
256+
257+
def test_ewouldblock_on_buffer_size(self):
258+
self._check_error_recovery_on_buffer_size(errno.EWOULDBLOCK)
259+
260+
def test_sslwantread_on_buffer_size(self):
261+
self._check_error_recovery_on_buffer_size(ssl.SSL_ERROR_WANT_READ)
262+
263+
def test_sslwantwrite_on_buffer_size(self):
264+
self._check_error_recovery_on_buffer_size(ssl.SSL_ERROR_WANT_WRITE)
265+
266+
def _check_error_recovery_on_buffer_size(self, error_code):
250267
c = self.test_successful_connection()
251268

252269
header = six.b('\x00\x00\x00\x00') + int32_pack(20000)
253270
responses = [
254271
header + (six.b('a') * (4096 - len(header))),
255272
six.b('a') * 4096,
256-
socket_error(errno.EAGAIN),
273+
socket_error(error_code),
257274
six.b('a') * 100,
258-
socket_error(errno.EAGAIN)]
275+
socket_error(error_code)]
259276

260277
def side_effect(*args):
261278
response = responses.pop(0)
279+
log.debug('about to mock return {}'.format(response))
262280
if isinstance(response, socket_error):
263281
raise response
264282
else:
265283
return response
266284

267285
self.get_socket(c).recv.side_effect = side_effect
268286
c.handle_read(*self.null_handle_function_args)
269-
self.assertEqual(c._current_frame.end_pos, 20000 + len(header))
270287
# the EAGAIN prevents it from reading the last 100 bytes
271288
c._iobuf.seek(0, os.SEEK_END)
272289
pos = c._iobuf.tell()

0 commit comments

Comments
 (0)