From b3c0df70c4b63dfc09d43cae33f48dbbfcc94b92 Mon Sep 17 00:00:00 2001 From: Ngai-Fung Yip Date: Mon, 22 Apr 2019 15:44:44 +0800 Subject: fix the compatible issue with gevent+dnspython --- websocket/_http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/websocket/_http.py b/websocket/_http.py index 5b9a26d..c642c28 100644 --- a/websocket/_http.py +++ b/websocket/_http.py @@ -140,7 +140,7 @@ def _get_addrinfo_list(hostname, port, is_secure, proxy): try: if not phost: addrinfo_list = socket.getaddrinfo( - hostname, port, 0, 0, socket.SOL_TCP) + hostname, port, 0, socket.SOCK_STREAM, socket.SOL_TCP) return addrinfo_list, False, None else: pport = pport and pport or 80 -- cgit v1.2.1 From 32c6d41bf0677b6c3147d144724831691eb7fd8a Mon Sep 17 00:00:00 2001 From: spacewander Date: Fri, 10 May 2019 18:22:21 +0800 Subject: Improve the readability of HTTP status codes. This commit also changes the type of 'SUPPORTED_REDIRECT_STATUSES' to 'tuple'. It seems that this change doesn't break anything. --- websocket/_handshake.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/websocket/_handshake.py b/websocket/_handshake.py index 809a8c9..a088bb0 100644 --- a/websocket/_handshake.py +++ b/websocket/_handshake.py @@ -55,7 +55,8 @@ else: # websocket supported version. VERSION = 13 -SUPPORTED_REDIRECT_STATUSES = [HTTPStatus.MOVED_PERMANENTLY, HTTPStatus.FOUND, HTTPStatus.SEE_OTHER] +SUPPORTED_REDIRECT_STATUSES = (HTTPStatus.MOVED_PERMANENTLY, HTTPStatus.FOUND, HTTPStatus.SEE_OTHER,) +SUCCESS_STATUSES = SUPPORTED_REDIRECT_STATUSES + (HTTPStatus.SWITCHING_PROTOCOLS,) CookieJar = SimpleCookieJar() @@ -154,7 +155,7 @@ def _get_handshake_headers(resource, host, port, options): return headers, key -def _get_resp_headers(sock, success_statuses=(101, 301, 302, 303)): +def _get_resp_headers(sock, success_statuses=SUCCESS_STATUSES): status, resp_headers, status_message = read_headers(sock) if status not in success_statuses: raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers) -- cgit v1.2.1 From 0598ef1a7a9d72670bf592439f1899412e790989 Mon Sep 17 00:00:00 2001 From: Damjan Stulic Date: Wed, 7 Aug 2019 15:26:16 -0700 Subject: added support for allowing users to change connection header --- websocket/_handshake.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/websocket/_handshake.py b/websocket/_handshake.py index 809a8c9..20b950b 100644 --- a/websocket/_handshake.py +++ b/websocket/_handshake.py @@ -95,14 +95,13 @@ def _pack_hostname(hostname): def _get_handshake_headers(resource, host, port, options): headers = [ "GET %s HTTP/1.1" % resource, - "Upgrade: websocket", - "Connection: Upgrade" + "Upgrade: websocket" ] if port == 80 or port == 443: hostport = _pack_hostname(host) else: hostport = "%s:%d" % (_pack_hostname(host), port) - + if "host" in options and options["host"] is not None: headers.append("Host: %s" % options["host"]) else: @@ -126,6 +125,11 @@ def _get_handshake_headers(resource, host, port, options): if not 'header' in options or 'Sec-WebSocket-Version' not in options['header']: headers.append("Sec-WebSocket-Version: %s" % VERSION) + if not 'connection' in options: + headers.append('Connection: upgrade') + else: + headers.append(options['connection']) + subprotocols = options.get("subprotocols") if subprotocols: headers.append("Sec-WebSocket-Protocol: %s" % ",".join(subprotocols)) -- cgit v1.2.1 From 72a06826ad5814e000b8cf4f09d5b745471e0326 Mon Sep 17 00:00:00 2001 From: Damjan Stulic Date: Wed, 7 Aug 2019 15:35:50 -0700 Subject: removed extra white space --- websocket/_handshake.py | 1 - 1 file changed, 1 deletion(-) diff --git a/websocket/_handshake.py b/websocket/_handshake.py index 20b950b..92b3f9b 100644 --- a/websocket/_handshake.py +++ b/websocket/_handshake.py @@ -101,7 +101,6 @@ def _get_handshake_headers(resource, host, port, options): hostport = _pack_hostname(host) else: hostport = "%s:%d" % (_pack_hostname(host), port) - if "host" in options and options["host"] is not None: headers.append("Host: %s" % options["host"]) else: -- cgit v1.2.1 From 58c05a9283b128372d31715a2d9a1046f9806af7 Mon Sep 17 00:00:00 2001 From: Damjan Stulic Date: Wed, 7 Aug 2019 16:09:28 -0700 Subject: updated if statement to include check against None --- websocket/_handshake.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/websocket/_handshake.py b/websocket/_handshake.py index 92b3f9b..3ff5147 100644 --- a/websocket/_handshake.py +++ b/websocket/_handshake.py @@ -124,7 +124,7 @@ def _get_handshake_headers(resource, host, port, options): if not 'header' in options or 'Sec-WebSocket-Version' not in options['header']: headers.append("Sec-WebSocket-Version: %s" % VERSION) - if not 'connection' in options: + if not 'connection' in options or options['connection'] is None: headers.append('Connection: upgrade') else: headers.append(options['connection']) -- cgit v1.2.1 From 6b69bc210e3a19ad39110906210044a6e8d9abf9 Mon Sep 17 00:00:00 2001 From: Mike D <5084545+devmonkey22@users.noreply.github.com> Date: Mon, 16 Sep 2019 08:36:12 -0400 Subject: Resolve issue opening socket to intranet on Windows 10 with no proxy settings but behind proxy Fix for #571. Always provide `socket.SOCK_STREAM` to `socket.getaddrinfo`. --- websocket/_http.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/websocket/_http.py b/websocket/_http.py index 5b9a26d..119077b 100644 --- a/websocket/_http.py +++ b/websocket/_http.py @@ -138,16 +138,15 @@ def _get_addrinfo_list(hostname, port, is_secure, proxy): phost, pport, pauth = get_proxy_info( hostname, is_secure, proxy.host, proxy.port, proxy.auth, proxy.no_proxy) try: + # when running on windows 10, getaddrinfo without socktype returns a socktype 0. + # This generates an error exception: `_on_error: exception Socket type must be stream or datagram, not 0` + # or `OSError: [Errno 22] Invalid argument` when creating socket. Force the socket type to SOCK_STREAM. if not phost: addrinfo_list = socket.getaddrinfo( - hostname, port, 0, 0, socket.SOL_TCP) + hostname, port, 0, socket.SOCK_STREAM, socket.SOL_TCP) return addrinfo_list, False, None else: pport = pport and pport or 80 - # when running on windows 10, the getaddrinfo used above - # returns a socktype 0. This generates an error exception: - #_on_error: exception Socket type must be stream or datagram, not 0 - # Force the socket type to SOCK_STREAM addrinfo_list = socket.getaddrinfo(phost, pport, 0, socket.SOCK_STREAM, socket.SOL_TCP) return addrinfo_list, True, pauth except socket.gaierror as e: -- cgit v1.2.1 From 9aa6a2698cf9bd5a5adfc45f99bb100bde60b057 Mon Sep 17 00:00:00 2001 From: Dmitry Mottl Date: Tue, 24 Sep 2019 16:25:08 +0300 Subject: Show compressed text messages in wsdump.py --- bin/wsdump.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/bin/wsdump.py b/bin/wsdump.py index bc07246..026e125 100755 --- a/bin/wsdump.py +++ b/bin/wsdump.py @@ -6,6 +6,8 @@ import sys import threading import time import ssl +import gzip +import zlib import six from six.moves.urllib.parse import urlparse @@ -162,10 +164,28 @@ def main(): msg = None if six.PY3 and opcode == websocket.ABNF.OPCODE_TEXT and isinstance(data, bytes): data = str(data, "utf-8") - if not args.verbose and opcode in OPCODE_DATA: - msg = data - elif args.verbose: + if isinstance(data, bytes) and len(data)>2 and data[:2] == b'\037\213': # gzip magick + try: + data = "[gzip] " + str(gzip.decompress(data), "utf-8") + except: + pass + elif isinstance(data, bytes): + try: + decomp = zlib.decompressobj( + -zlib.MAX_WBITS + ) + data = decomp.decompress(data) + data = "[zlib] " + str(data + decomp.flush(), "utf-8") + except: + pass + + if isinstance(data, bytes): + data = repr(data) + + if args.verbose: msg = "%s: %s" % (websocket.ABNF.OPCODE_MAP.get(opcode), data) + else: + msg = data if msg is not None: if args.timings: -- cgit v1.2.1 From 79ae7ad3fd2f45724abca76fba3668c9357095b4 Mon Sep 17 00:00:00 2001 From: Dmitry Mottl Date: Wed, 25 Sep 2019 14:48:36 +0300 Subject: Simplify zlib.decompress call --- bin/wsdump.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/bin/wsdump.py b/bin/wsdump.py index 026e125..5cdb8d8 100755 --- a/bin/wsdump.py +++ b/bin/wsdump.py @@ -171,11 +171,7 @@ def main(): pass elif isinstance(data, bytes): try: - decomp = zlib.decompressobj( - -zlib.MAX_WBITS - ) - data = decomp.decompress(data) - data = "[zlib] " + str(data + decomp.flush(), "utf-8") + data = "[zlib] " + str(zlib.decompress(data, -zlib.MAX_WBITS), "utf-8") except: pass -- cgit v1.2.1 From af502e5ae513203638f53a31cf64ec2d85835981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=A0?= Date: Fri, 4 Oct 2019 19:42:07 +0200 Subject: Create dummy `ssl` object --- websocket/_ssl_compat.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/websocket/_ssl_compat.py b/websocket/_ssl_compat.py index 5b3c413..96cd173 100644 --- a/websocket/_ssl_compat.py +++ b/websocket/_ssl_compat.py @@ -49,4 +49,6 @@ except ImportError: class SSLWantWriteError(Exception): pass + ssl = lambda: None + HAVE_SSL = False -- cgit v1.2.1 From f3d07c6c96d0cc3cee2c05e6895325e8bc640215 Mon Sep 17 00:00:00 2001 From: Lucas Hussey Date: Fri, 25 Oct 2019 00:40:11 -0400 Subject: Fixed typo Class name "SSLDispacther" had a typo, should be "SSLDispatcher". Fixed class definition, and instance creation (in create_dispatcher). --- websocket/_app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/websocket/_app.py b/websocket/_app.py index 81aa1fc..4e76e87 100644 --- a/websocket/_app.py +++ b/websocket/_app.py @@ -54,7 +54,7 @@ class Dispatcher: break check_callback() -class SSLDispacther: +class SSLDispatcher: def __init__(self, app, ping_timeout): self.app = app self.ping_timeout = ping_timeout @@ -314,7 +314,7 @@ class WebSocketApp(object): def create_dispatcher(self, ping_timeout): timeout = ping_timeout or 10 if self.sock.is_ssl(): - return SSLDispacther(self, timeout) + return SSLDispatcher(self, timeout) return Dispatcher(self, timeout) -- cgit v1.2.1 From 2f85766642fab2d5c0994429c8506afeafa24fa9 Mon Sep 17 00:00:00 2001 From: Yehiyam Livneh Date: Sun, 24 Nov 2019 17:14:00 +0200 Subject: avoid calling repr(data) if tracing is not enabled --- .gitignore | 2 ++ websocket/_core.py | 3 ++- websocket/_logging.py | 6 ++++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index ebf5448..f75aba2 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ dist .cache/ compliance/reports/ +.eggs +.vscode \ No newline at end of file diff --git a/websocket/_core.py b/websocket/_core.py index 0f914c2..418aafc 100644 --- a/websocket/_core.py +++ b/websocket/_core.py @@ -271,7 +271,8 @@ class WebSocket(object): frame.get_mask_key = self.get_mask_key data = frame.format() length = len(data) - trace("send: " + repr(data)) + if (isEnabledForTrace()): + trace("send: " + repr(data)) with self.lock: while data: diff --git a/websocket/_logging.py b/websocket/_logging.py index 70a6271..c947778 100644 --- a/websocket/_logging.py +++ b/websocket/_logging.py @@ -34,7 +34,7 @@ _logger.addHandler(NullHandler()) _traceEnabled = False __all__ = ["enableTrace", "dump", "error", "warning", "debug", "trace", - "isEnabledForError", "isEnabledForDebug"] + "isEnabledForError", "isEnabledForDebug", "isEnabledForTrace"] def enableTrace(traceable, handler = logging.StreamHandler()): @@ -49,7 +49,6 @@ def enableTrace(traceable, handler = logging.StreamHandler()): _logger.addHandler(handler) _logger.setLevel(logging.DEBUG) - def dump(title, message): if _traceEnabled: _logger.debug("--- " + title + " ---") @@ -80,3 +79,6 @@ def isEnabledForError(): def isEnabledForDebug(): return _logger.isEnabledFor(logging.DEBUG) + +def isEnabledForTrace(): + return _traceEnabled -- cgit v1.2.1 From aae7d973fff3bbb47f47253d2a68c982d2468a3d Mon Sep 17 00:00:00 2001 From: Oliver <20156451+olie304@users.noreply.github.com> Date: Thu, 28 Nov 2019 14:14:43 -0600 Subject: Fix for errors that occur when closing websocket https://github.com/websocket-client/websocket-client/issues/449 --- websocket/_app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/websocket/_app.py b/websocket/_app.py index 81aa1fc..cd88b94 100644 --- a/websocket/_app.py +++ b/websocket/_app.py @@ -46,7 +46,7 @@ class Dispatcher: self.ping_timeout = ping_timeout def read(self, sock, read_callback, check_callback): - while self.app.sock.connected: + while self.app.keep_running: r, w, e = select.select( (self.app.sock.sock, ), (), (), self.ping_timeout) if r: @@ -60,7 +60,7 @@ class SSLDispacther: self.ping_timeout = ping_timeout def read(self, sock, read_callback, check_callback): - while self.app.sock.connected: + while self.app.keep_running: r = self.select() if r: if not read_callback(): -- cgit v1.2.1 From 8753020d503da6018acc0c7f6218138be19a45e6 Mon Sep 17 00:00:00 2001 From: "truong.hua" Date: Mon, 2 Dec 2019 16:36:53 +0700 Subject: Fix getting 400 bad request with long proxy authorization string --- websocket/_http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/websocket/_http.py b/websocket/_http.py index 5b9a26d..7068c6c 100644 --- a/websocket/_http.py +++ b/websocket/_http.py @@ -276,7 +276,7 @@ def _tunnel(sock, host, port, auth): auth_str = auth[0] if auth[1]: auth_str += ":" + auth[1] - encoded_str = base64encode(auth_str.encode()).strip().decode() + encoded_str = base64encode(auth_str.encode()).strip().decode().replace('\n', '') connect_header += "Proxy-Authorization: Basic %s\r\n" % encoded_str connect_header += "\r\n" dump("request header", connect_header) -- cgit v1.2.1 From db3da3d6e7d2304bd8df85c43071a7d76d2aad27 Mon Sep 17 00:00:00 2001 From: Ting-Wei Lan Date: Wed, 4 Dec 2019 08:51:45 +0800 Subject: wsdump: Fix --headers option Since https://github.com/websocket-client/websocket-client/pull/506 changes the way that options['header'] is used, it breaks --headers option of wsdump command because wsdump command uses a map object instead of a list here, which can only be used once. Therefore, after the first use with 'not in' operator, it becomes empty and no headers specified by the user are sent. To fix it, simply convert the map object into a list, so it can be use multiple times. --- bin/wsdump.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/wsdump.py b/bin/wsdump.py index bc07246..557ace1 100755 --- a/bin/wsdump.py +++ b/bin/wsdump.py @@ -130,7 +130,7 @@ def main(): if args.nocert: opts = {"cert_reqs": ssl.CERT_NONE, "check_hostname": False} if args.headers: - options['header'] = map(str.strip, args.headers.split(',')) + options['header'] = list(map(str.strip, args.headers.split(','))) ws = websocket.create_connection(args.url, sslopt=opts, **options) if args.raw: console = NonInteractive() -- cgit v1.2.1 From 7fb88888743472067e601739c438d1f64972509f Mon Sep 17 00:00:00 2001 From: liris Date: Wed, 25 Dec 2019 21:00:56 +0900 Subject: start release 0.57.0 --- ChangeLog | 2 ++ websocket/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b691322..4924a93 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ ChangeLog ============ +- 0.57.0 + - 0.56.0 - Don't retry sockets with timeout set to 0(#536) diff --git a/websocket/__init__.py b/websocket/__init__.py index 15c74ce..605f76c 100644 --- a/websocket/__init__.py +++ b/websocket/__init__.py @@ -26,4 +26,4 @@ from ._exceptions import * from ._logging import * from ._socket import * -__version__ = "0.56.0" +__version__ = "0.57.0" -- cgit v1.2.1 From 14f6c9326dc907bea3cfdcf3e45f620200a2ae16 Mon Sep 17 00:00:00 2001 From: liris Date: Wed, 25 Dec 2019 21:06:21 +0900 Subject: Change Log --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 4924a93..d84d27c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,8 @@ ChangeLog ============ - 0.57.0 + - wsdump: Fix --headers option (#589) + - Fix getting 400 bad request with long proxy authorization string (#587) - 0.56.0 -- cgit v1.2.1