diff options
author | Andy McCurdy <andy@andymccurdy.com> | 2019-07-30 15:14:32 -0700 |
---|---|---|
committer | Andy McCurdy <andy@andymccurdy.com> | 2019-07-30 15:14:32 -0700 |
commit | 885ce770856a1ee5ebc51d7c5390c88fb62bc93e (patch) | |
tree | ea1f83c8382f289f96cdf7007c891d2835ff0699 /redis/connection.py | |
parent | 6b6e394ccb7199cb5e0d2e8192dc904aa0a8b347 (diff) | |
download | redis-py-885ce770856a1ee5ebc51d7c5390c88fb62bc93e.tar.gz |
version 3.3.4, more specifically identify nonblocking read errors
versions 3.3.1, 3.3.2 and 3.3.3 could potentially hide ConnectionErrors
on Python 2.7. This change accurately identifies errors by both
exception class and errno to determine whether a nonblocking socket can
be read
Diffstat (limited to 'redis/connection.py')
-rwxr-xr-x | redis/connection.py | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/redis/connection.py b/redis/connection.py index e753bcb..8b87ead 100755 --- a/redis/connection.py +++ b/redis/connection.py @@ -34,17 +34,18 @@ try: except ImportError: ssl_available = False -if ssl_available and hasattr(ssl, 'SSLWantReadError'): - # note that when using nonblocking sockets over ssl, the ssl module - # in python > 2.7.9 raises its own exceptions rather than BlockingIOError - blocking_exceptions = ( - BlockingIOError, - ssl.SSLWantReadError, - ssl.SSLWantWriteError - ) -else: - blocking_exceptions = (BlockingIOError,) +NONBLOCKING_EXCEPTION_ERROR_NUMBERS = { + BlockingIOError: 35, +} + +if ssl_available: + if hasattr(ssl, 'SSLWantReadError'): + NONBLOCKING_EXCEPTION_ERROR_NUMBERS[ssl.SSLWantReadError] = 2 + NONBLOCKING_EXCEPTION_ERROR_NUMBERS[ssl.SSLWantWriteError] = 2 + else: + NONBLOCKING_EXCEPTION_ERROR_NUMBERS[ssl.SSLError] = 2 +NONBLOCKING_EXCEPTIONS = tuple(NONBLOCKING_EXCEPTION_ERROR_NUMBERS.keys()) if HIREDIS_AVAILABLE: import hiredis @@ -180,12 +181,13 @@ class SocketBuffer(object): if length is not None and length > marker: continue return True - except blocking_exceptions as ex: + except NONBLOCKING_EXCEPTIONS as ex: # if we're in nonblocking mode and the recv raises a # blocking error, simply return False indicating that # there's no data to be read. otherwise raise the # original exception. - if raise_on_timeout: + allowed_errno = NONBLOCKING_EXCEPTION_ERROR_NUMBERS[ex.__class__] + if raise_on_timeout or ex.errno != allowed_errno: raise return False except socket.timeout: @@ -409,12 +411,13 @@ class HiredisParser(BaseParser): # data was read from the socket and added to the buffer. # return True to indicate that data was read. return True - except blocking_exceptions as ex: + except NONBLOCKING_EXCEPTIONS as ex: # if we're in nonblocking mode and the recv raises a # blocking error, simply return False indicating that # there's no data to be read. otherwise raise the # original exception. - if raise_on_timeout: + allowed_errno = NONBLOCKING_EXCEPTION_ERROR_NUMBERS[ex.__class__] + if raise_on_timeout or ex.errno != allowed_errno: raise return False except socket.timeout: |