diff options
author | liris <liris.pp@gmail.com> | 2019-02-23 14:06:09 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-23 14:06:09 +0900 |
commit | 38b0481fccb9d1d50282fb72be8fb4124a6b9078 (patch) | |
tree | ae814f9cc631176543009541ca094c18780e0e47 /websocket | |
parent | 2c18d28f3596acfd269fa568fbf85ff9ca2b97fb (diff) | |
parent | bbab5ba15c87cfa11ef7c867a8273db06d88d1f7 (diff) | |
download | websocket-client-38b0481fccb9d1d50282fb72be8fb4124a6b9078.tar.gz |
Merge pull request #474 from ARMmbed/ssl-socket-fix
Diffstat (limited to 'websocket')
-rw-r--r-- | websocket/_socket.py | 38 | ||||
-rw-r--r-- | websocket/_ssl_compat.py | 10 | ||||
-rw-r--r-- | websocket/_utils.py | 7 |
3 files changed, 51 insertions, 4 deletions
diff --git a/websocket/_socket.py b/websocket/_socket.py index c84fcf9..d811c21 100644 --- a/websocket/_socket.py +++ b/websocket/_socket.py @@ -19,6 +19,8 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Boston, MA 02110-1335 USA """ +import errno +import select import socket import six @@ -77,8 +79,24 @@ def recv(sock, bufsize): if not sock: raise WebSocketConnectionClosedException("socket is already closed.") + def _recv(): + try: + return sock.recv(bufsize) + except SSLWantReadError: + pass + except socket.error as exc: + error_code = extract_error_code(exc) + if error_code is None: + raise + if error_code != errno.EAGAIN or error_code != errno.EWOULDBLOCK: + raise + + r, w, e = select.select((sock, ), (), (), sock.gettimeout()) + if r: + return sock.recv(bufsize) + try: - bytes_ = sock.recv(bufsize) + bytes_ = _recv() except socket.timeout as e: message = extract_err_message(e) raise WebSocketTimeoutException(message) @@ -113,8 +131,24 @@ def send(sock, data): if not sock: raise WebSocketConnectionClosedException("socket is already closed.") + def _send(): + try: + return sock.send(data) + except SSLWantWriteError: + pass + except socket.error as exc: + error_code = extract_error_code(exc) + if error_code is None: + raise + if error_code != errno.EAGAIN or error_code != errno.EWOULDBLOCK: + raise + + r, w, e = select.select((), (sock, ), (), sock.gettimeout()) + if w: + return sock.send(data) + try: - return sock.send(data) + return _send() except socket.timeout as e: message = extract_err_message(e) raise WebSocketTimeoutException(message) diff --git a/websocket/_ssl_compat.py b/websocket/_ssl_compat.py index 0304816..5b3c413 100644 --- a/websocket/_ssl_compat.py +++ b/websocket/_ssl_compat.py @@ -19,11 +19,13 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Boston, MA 02110-1335 USA """ -__all__ = ["HAVE_SSL", "ssl", "SSLError"] +__all__ = ["HAVE_SSL", "ssl", "SSLError", "SSLWantReadError", "SSLWantWriteError"] try: import ssl from ssl import SSLError + from ssl import SSLWantReadError + from ssl import SSLWantWriteError if hasattr(ssl, 'SSLContext') and hasattr(ssl.SSLContext, 'check_hostname'): HAVE_CONTEXT_CHECK_HOSTNAME = True else: @@ -41,4 +43,10 @@ except ImportError: class SSLError(Exception): pass + class SSLWantReadError(Exception): + pass + + class SSLWantWriteError(Exception): + pass + HAVE_SSL = False diff --git a/websocket/_utils.py b/websocket/_utils.py index 399fb89..8eddabf 100644 --- a/websocket/_utils.py +++ b/websocket/_utils.py @@ -21,7 +21,7 @@ Copyright (C) 2010 Hiroki Ohtani(liris) """ import six -__all__ = ["NoLock", "validate_utf8", "extract_err_message"] +__all__ = ["NoLock", "validate_utf8", "extract_err_message", "extract_error_code"] class NoLock(object): @@ -103,3 +103,8 @@ def extract_err_message(exception): return exception.args[0] else: return None + + +def extract_error_code(exception): + if exception.args and len(exception.args) > 1: + return exception.args[0] if isinstance(exception.args[0], int) else None |