From e8cc458f9dbb7333f04e76822a46011aaff85a45 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:00:28 +0100 Subject: [PATCH 01/25] test_websocket: [Cleanup] Correct typo --- websocket/tests/test_websocket.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/websocket/tests/test_websocket.py b/websocket/tests/test_websocket.py index 4573bf7..3408eef 100644 --- a/websocket/tests/test_websocket.py +++ b/websocket/tests/test_websocket.py @@ -43,7 +43,7 @@ TEST_WITH_INTERNET = os.environ.get('TEST_WITH_INTERNET', '0') == '1' # Skip Secure WebSocket test. TEST_SECURE_WS = True -TRACABLE = False +TRACEABLE = False def create_mask_key(n): @@ -86,7 +86,7 @@ class HeaderSockMock(SockMock): class WebSocketTest(unittest.TestCase): def setUp(self): - ws.enableTrace(TRACABLE) + ws.enableTrace(TRACEABLE) def tearDown(self): pass @@ -479,7 +479,7 @@ class WebSocketAppTest(unittest.TestCase): """ def setUp(self): - ws.enableTrace(TRACABLE) + ws.enableTrace(TRACEABLE) WebSocketAppTest.keep_running_open = WebSocketAppTest.NotSetYet() WebSocketAppTest.keep_running_close = WebSocketAppTest.NotSetYet() From 4875da67a050989109e9111b1c5323db1ccfbe3f Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:01:32 +0100 Subject: [PATCH 02/25] test_websocket: [Cleanup] Remove unused imports --- websocket/tests/test_websocket.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/websocket/tests/test_websocket.py b/websocket/tests/test_websocket.py index 3408eef..49cd3d4 100644 --- a/websocket/tests/test_websocket.py +++ b/websocket/tests/test_websocket.py @@ -7,7 +7,6 @@ sys.path[0:0] = [""] import os import os.path -import base64 import socket try: from ssl import SSLError @@ -21,7 +20,6 @@ if sys.version_info[0] == 2 and sys.version_info[1] < 7: else: import unittest -import uuid if six.PY3: from base64 import decodebytes as base64decode From 2e0067117d526390249a84778f50af67dac00963 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:17:04 +0100 Subject: [PATCH 03/25] wsdump, _abnf, _http: Compare to `None` using `in` --- bin/wsdump.py | 2 +- websocket/_abnf.py | 4 ++-- websocket/_http.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/wsdump.py b/bin/wsdump.py index c2fb49f..ea6bbb2 100755 --- a/bin/wsdump.py +++ b/bin/wsdump.py @@ -28,7 +28,7 @@ ENCODING = get_encoding() class VAction(argparse.Action): def __call__(self, parser, args, values, option_string=None): - if values==None: + if values is None: values = "1" try: values = int(values) diff --git a/websocket/_abnf.py b/websocket/_abnf.py index 2c7c4ab..912672a 100644 --- a/websocket/_abnf.py +++ b/websocket/_abnf.py @@ -116,7 +116,7 @@ class ABNF(object): self.rsv3 = rsv3 self.opcode = opcode self.mask = mask - if data == None: + if data is None: data = "" self.data = data self.get_mask_key = os.urandom @@ -224,7 +224,7 @@ class ABNF(object): data: data to mask/unmask. """ - if data == None: + if data is None: data = "" if isinstance(mask_key, six.text_type): diff --git a/websocket/_http.py b/websocket/_http.py index 63f3f83..8fae73f 100644 --- a/websocket/_http.py +++ b/websocket/_http.py @@ -161,7 +161,7 @@ def _ssl_socket(sock, user_sslopt, hostname): certPath = os.path.join( os.path.dirname(__file__), "cacert.pem") - if os.path.isfile(certPath) and user_sslopt.get('ca_certs', None) == None: + if os.path.isfile(certPath) and user_sslopt.get('ca_certs', None) is None: sslopt['ca_certs'] = certPath check_hostname = sslopt["cert_reqs"] != ssl.CERT_NONE and sslopt.pop('check_hostname', True) From 3f9e8bf9fb9811dfab9f40d96c2d800362c0be67 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:19:41 +0100 Subject: [PATCH 04/25] _app: Don't use mutable default argument value --- websocket/_app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/websocket/_app.py b/websocket/_app.py index af67080..215bff1 100644 --- a/websocket/_app.py +++ b/websocket/_app.py @@ -43,7 +43,7 @@ class WebSocketApp(object): Higher level of APIs are provided. The interface is like JavaScript WebSocket object. """ - def __init__(self, url, header=[], + def __init__(self, url, header=None, on_open=None, on_message=None, on_error=None, on_close=None, on_ping=None, on_pong=None, on_cont_message=None, @@ -87,7 +87,7 @@ class WebSocketApp(object): subprotocols: array of available sub protocols. default is None. """ self.url = url - self.header = header + self.header = header if header is not None else [] self.cookie = cookie self.on_open = on_open self.on_message = on_message From a49a3c22df8b4cb7cca8de8a8967b7e841f2fa8f Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:21:48 +0100 Subject: [PATCH 05/25] _handshake._get_handshake_headers: Use list literal --- websocket/_handshake.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/websocket/_handshake.py b/websocket/_handshake.py index 146ea58..f795d89 100644 --- a/websocket/_handshake.py +++ b/websocket/_handshake.py @@ -73,10 +73,11 @@ def handshake(sock, hostname, port, resource, **options): def _get_handshake_headers(resource, host, port, options): - headers = [] - headers.append("GET %s HTTP/1.1" % resource) - headers.append("Upgrade: websocket") - headers.append("Connection: Upgrade") + headers = [ + "GET %s HTTP/1.1" % resource, + "Upgrade: websocket", + "Connection: Upgrade" + ] if port == 80: hostport = host else: From f0f3cc129ba3a8192ab15666fcbf73f686fd9d51 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:22:53 +0100 Subject: [PATCH 06/25] _abnf.ABNF._is_valid_close_status: Make method static --- websocket/_abnf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/websocket/_abnf.py b/websocket/_abnf.py index 912672a..5b91310 100644 --- a/websocket/_abnf.py +++ b/websocket/_abnf.py @@ -148,7 +148,8 @@ class ABNF(object): if not self._is_valid_close_status(code): raise WebSocketProtocolException("Invalid close opcode.") - def _is_valid_close_status(self, code): + @staticmethod + def _is_valid_close_status(code): return code in VALID_CLOSE_STATUS or (3000 <= code <5000) def __str__(self): From 669096e87492b37f3f5bee404355f3851d41448c Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:25:59 +0100 Subject: [PATCH 07/25] wsdump, _core, _url, _utils: Remove redundant parentheses --- bin/wsdump.py | 18 +++++++++--------- websocket/_core.py | 6 +++--- websocket/_url.py | 2 +- websocket/_utils.py | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/bin/wsdump.py b/bin/wsdump.py index ea6bbb2..d395419 100755 --- a/bin/wsdump.py +++ b/bin/wsdump.py @@ -63,7 +63,7 @@ def parse_args(): return parser.parse_args() -class RawInput(): +class RawInput: def raw_input(self, prompt): if six.PY3: line = input(prompt) @@ -103,16 +103,16 @@ def main(): if args.verbose > 1: websocket.enableTrace(True) options = {} - if (args.proxy): + if args.proxy: p = urlparse(args.proxy) options["http_proxy_host"] = p.hostname options["http_proxy_port"] = p.port - if (args.origin): + if args.origin: options["origin"] = args.origin - if (args.subprotocols): + if args.subprotocols: options["subprotocols"] = args.subprotocols opts = {} - if (args.nocert): + if args.nocert: opts = { "cert_reqs": websocket.ssl.CERT_NONE, "check_hostname": False } ws = websocket.create_connection(args.url, sslopt=opts, **options) if args.raw: @@ -125,14 +125,14 @@ def main(): try: frame = ws.recv_frame() except websocket.WebSocketException: - return (websocket.ABNF.OPCODE_CLOSE, None) + return websocket.ABNF.OPCODE_CLOSE, None if not frame: raise websocket.WebSocketException("Not a valid frame %s" % frame) elif frame.opcode in OPCODE_DATA: - return (frame.opcode, frame.data) + return frame.opcode, frame.data elif frame.opcode == websocket.ABNF.OPCODE_CLOSE: ws.send_close() - return (frame.opcode, None) + return frame.opcode, None elif frame.opcode == websocket.ABNF.OPCODE_PING: ws.pong(frame.data) return frame.opcode, frame.data @@ -152,7 +152,7 @@ def main(): msg = "%s: %s" % (websocket.ABNF.OPCODE_MAP.get(opcode), data) if msg is not None: - if (args.timings): + if args.timings: console.write(str(time.time() - start_time) + ": " + msg) else: console.write(msg) diff --git a/websocket/_core.py b/websocket/_core.py index 13f7593..7527dbf 100644 --- a/websocket/_core.py +++ b/websocket/_core.py @@ -339,17 +339,17 @@ class WebSocket(object): elif frame.opcode == ABNF.OPCODE_CLOSE: self.send_close() - return (frame.opcode, frame) + return frame.opcode, frame elif frame.opcode == ABNF.OPCODE_PING: if len(frame.data) < 126: self.pong(frame.data) else: raise WebSocketProtocolException("Ping message is too long") if control_frame: - return (frame.opcode, frame) + return frame.opcode, frame elif frame.opcode == ABNF.OPCODE_PONG: if control_frame: - return (frame.opcode, frame) + return frame.opcode, frame def recv_frame(self): """ diff --git a/websocket/_url.py b/websocket/_url.py index dfd2c4b..9d705fd 100644 --- a/websocket/_url.py +++ b/websocket/_url.py @@ -66,7 +66,7 @@ def parse_url(url): if parsed.query: resource += "?" + parsed.query - return (hostname, port, resource, is_secure) + return hostname, port, resource, is_secure DEFAULT_NO_PROXY_HOST = ["localhost", "127.0.0.1"] diff --git a/websocket/_utils.py b/websocket/_utils.py index 58f6950..91be861 100644 --- a/websocket/_utils.py +++ b/websocket/_utils.py @@ -69,7 +69,7 @@ except ImportError: def _decode(state, codep, ch): tp = _UTF8D[ch] - codep = (ch & 0x3f ) | (codep << 6) if (state != _UTF8_ACCEPT) else (0xff >> tp) & (ch) + codep = (ch & 0x3f ) | (codep << 6) if (state != _UTF8_ACCEPT) else (0xff >> tp) & ch state = _UTF8D[256 + state + tp] return state, codep; From 17cfffbff1f89966a6c4057b3f62876c35e91b4d Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:28:41 +0100 Subject: [PATCH 08/25] _abnf, _socket: Don't override builtins --- websocket/_abnf.py | 6 +++--- websocket/_socket.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/websocket/_abnf.py b/websocket/_abnf.py index 5b91310..7c88328 100644 --- a/websocket/_abnf.py +++ b/websocket/_abnf.py @@ -344,9 +344,9 @@ class frame_buffer(object): # reads is limited by socket buffer and is relatively small, # yet passing large numbers repeatedly causes lots of large # buffers allocated and then shrunk, which results in fragmentation. - bytes = self.recv(min(16384, shortage)) - self.recv_buffer.append(bytes) - shortage -= len(bytes) + bytes_ = self.recv(min(16384, shortage)) + self.recv_buffer.append(bytes_) + shortage -= len(bytes_) unified = six.b("").join(self.recv_buffer) diff --git a/websocket/_socket.py b/websocket/_socket.py index b2aaa55..63e001c 100644 --- a/websocket/_socket.py +++ b/websocket/_socket.py @@ -74,7 +74,7 @@ def recv(sock, bufsize): raise WebSocketConnectionClosedException("socket is already closed.") try: - bytes = sock.recv(bufsize) + bytes_ = sock.recv(bufsize) except socket.timeout as e: message = extract_err_message(e) raise WebSocketTimeoutException(message) @@ -85,10 +85,10 @@ def recv(sock, bufsize): else: raise - if not bytes: + if not bytes_: raise WebSocketConnectionClosedException("Connection is already closed.") - return bytes + return bytes_ def recv_line(sock): From 32728cb8d12fb842e5141723fd0621277d8eab67 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:29:55 +0100 Subject: [PATCH 09/25] _utils.NoLock.__exit__: Use standard parameter names In any case, `type` is a builtin. --- websocket/_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/websocket/_utils.py b/websocket/_utils.py index 91be861..f431702 100644 --- a/websocket/_utils.py +++ b/websocket/_utils.py @@ -28,7 +28,7 @@ class NoLock(object): def __enter__(self): pass - def __exit__(self, type, value, traceback): + def __exit__(self, exc_type, exc_value, traceback): pass try: From e033f2bd0af1f591eebc2a91555576b8c58d7652 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:32:46 +0100 Subject: [PATCH 10/25] wsdump: Only catch relevant exceptions --- bin/wsdump.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/wsdump.py b/bin/wsdump.py index d395419..88a6638 100755 --- a/bin/wsdump.py +++ b/bin/wsdump.py @@ -10,7 +10,7 @@ import websocket from six.moves.urllib.parse import urlparse try: import readline -except: +except ImportError: pass From 75bfea0833cdf125c167c58475898487b32da1c1 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:33:24 +0100 Subject: [PATCH 11/25] _core.WebSocket.shutdown: Triple-quote docstring --- websocket/_core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/websocket/_core.py b/websocket/_core.py index 7527dbf..f63fc5c 100644 --- a/websocket/_core.py +++ b/websocket/_core.py @@ -415,7 +415,7 @@ class WebSocket(object): self.sock.shutdown(socket.SHUT_RDWR) def shutdown(self): - "close socket, immediately." + """close socket, immediately.""" if self.sock: self.sock.close() self.sock = None From 3b73be8736cb9d38db2fb429d24633c60b4be15f Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:33:49 +0100 Subject: [PATCH 12/25] _utils: Remove unnecessary trailing semicolon --- websocket/_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/websocket/_utils.py b/websocket/_utils.py index f431702..71d0e00 100644 --- a/websocket/_utils.py +++ b/websocket/_utils.py @@ -72,7 +72,7 @@ except ImportError: codep = (ch & 0x3f ) | (codep << 6) if (state != _UTF8_ACCEPT) else (0xff >> tp) & ch state = _UTF8D[256 + state + tp] - return state, codep; + return state, codep def _validate_utf8(utfbytes): state = _UTF8_ACCEPT From 6d3c23e5da41313c81767b634a6fbd961a5ce9d4 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:38:07 +0100 Subject: [PATCH 13/25] test_websocket: Remove unnecessary backslashes --- websocket/tests/test_websocket.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/websocket/tests/test_websocket.py b/websocket/tests/test_websocket.py index 49cd3d4..39d68c1 100644 --- a/websocket/tests/test_websocket.py +++ b/websocket/tests/test_websocket.py @@ -372,10 +372,10 @@ class WebSocketTest(unittest.TestCase): sock = ws.WebSocket() s = sock.sock = SockMock() # OPCODE=TEXT, FIN=0, MSG="Once more unto the breach, " - s.add_packet(six.b("\x01\x9babcd.\x0c\x00\x01A\x0f\x0c\x16\x04B\x16\n\x15" \ + s.add_packet(six.b("\x01\x9babcd.\x0c\x00\x01A\x0f\x0c\x16\x04B\x16\n\x15" "\rC\x10\t\x07C\x06\x13\x07\x02\x07\tNC")) # OPCODE=CONT, FIN=0, MSG="dear friends, " - s.add_packet(six.b("\x00\x8eabcd\x05\x07\x02\x16A\x04\x11\r\x04\x0c\x07" \ + s.add_packet(six.b("\x00\x8eabcd\x05\x07\x02\x16A\x04\x11\r\x04\x0c\x07" "\x17MB")) # OPCODE=CONT, FIN=1, MSG="once more" s.add_packet(six.b("\x80\x89abcd\x0e\x0c\x00\x01A\x0f\x0c\x16\x04")) @@ -395,7 +395,7 @@ class WebSocketTest(unittest.TestCase): # OPCODE=PING, FIN=1, MSG="Please PONG this" s.add_packet(six.b("\x89\x90abcd1\x0e\x06\x05\x12\x07C4.,$D\x15\n\n\x17")) # OPCODE=CONT, FIN=1, MSG="of a good thing" - s.add_packet(six.b("\x80\x8fabcd\x0e\x04C\x05A\x05\x0c\x0b\x05B\x17\x0c" \ + s.add_packet(six.b("\x80\x8fabcd\x0e\x04C\x05A\x05\x0c\x0b\x05B\x17\x0c" "\x08\x0c\x04")) data = sock.recv() self.assertEqual(data, "Too much of a good thing") From c47b0af0ae0e299b522bf139a0e1d9ddaac24a9f Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:42:44 +0100 Subject: [PATCH 14/25] _core, _handshake: Remove unused imports --- websocket/_core.py | 4 ---- websocket/_handshake.py | 3 --- 2 files changed, 7 deletions(-) diff --git a/websocket/_core.py b/websocket/_core.py index f63fc5c..eef7b26 100644 --- a/websocket/_core.py +++ b/websocket/_core.py @@ -30,19 +30,15 @@ if six.PY3: else: from base64 import encodestring as base64encode -import struct import threading # websocket modules -from ._exceptions import * from ._abnf import * from ._socket import * from ._utils import * -from ._url import * from ._logging import * from ._http import * from ._handshake import * -from ._ssl_compat import * """ websocket python client. diff --git a/websocket/_handshake.py b/websocket/_handshake.py index f795d89..67b16e4 100644 --- a/websocket/_handshake.py +++ b/websocket/_handshake.py @@ -26,14 +26,11 @@ if six.PY3: else: from base64 import encodestring as base64encode -import uuid import hashlib import hmac import os -import sys from ._logging import * -from ._url import * from ._socket import* from ._http import * from ._exceptions import * From 3b757ac3e2fddde7db2622a161aaeae36d916ec3 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:51:34 +0100 Subject: [PATCH 15/25] ChangeLog, _abnf, _logging: Corect typos --- ChangeLog | 4 ++-- websocket/_abnf.py | 4 ++-- websocket/_logging.py | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index c3141fc..d5b9592 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,7 @@ ChangeLog ============ - 0.37.0 - - fixed fialer that `websocket.create_connection` does not accept `origin` as a parameter (#246 ) + - fixed failure that `websocket.create_connection` does not accept `origin` as a parameter (#246 ) - 0.36.0 - added support for using custom connection class (#235) @@ -90,7 +90,7 @@ ChangeLog - 0.24.0 - Supporting http-basic auth in WebSocketApp (#143) - - fix failer of test.testInternalRecvStrict(#141) + - fix failure of test.testInternalRecvStrict(#141) - skip utf8 validation by skip_utf8_validation argument (#137) - WebsocketProxyException will be raised if we got error about proxy.(#138) diff --git a/websocket/_abnf.py b/websocket/_abnf.py index 7c88328..5f6c206 100644 --- a/websocket/_abnf.py +++ b/websocket/_abnf.py @@ -240,7 +240,7 @@ class ABNF(object): class frame_buffer(object): _HEADER_MASK_INDEX = 5 - _HEADER_LENGHT_INDEX = 6 + _HEADER_LENGTH_INDEX = 6 def __init__(self, recv_fn, skip_utf8_validation): self.recv = recv_fn @@ -290,7 +290,7 @@ class frame_buffer(object): return self.length is None def recv_length(self): - bits = self.header[frame_buffer._HEADER_LENGHT_INDEX] + bits = self.header[frame_buffer._HEADER_LENGTH_INDEX] length_bits = bits & 0x7f if length_bits == 0x7e: v = self.recv_strict(2) diff --git a/websocket/_logging.py b/websocket/_logging.py index a77d999..321e24a 100644 --- a/websocket/_logging.py +++ b/websocket/_logging.py @@ -29,15 +29,15 @@ __all__ = ["enableTrace", "dump", "error", "debug", "trace", "isEnabledForError", "isEnabledForDebug"] -def enableTrace(tracable): +def enableTrace(traceable): """ - turn on/off the tracability. + turn on/off the traceability. - tracable: boolean value. if set True, tracability is enabled. + traceable: boolean value. if set True, traceability is enabled. """ global _traceEnabled - _traceEnabled = tracable - if tracable: + _traceEnabled = traceable + if traceable: if not _logger.handlers: _logger.addHandler(logging.StreamHandler()) _logger.setLevel(logging.DEBUG) From a9cfa61dc31bfd0622dd9be02cee69bbc9e071ce Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:51:59 +0100 Subject: [PATCH 16/25] _core, test_websocket: Remove unused locals --- websocket/_core.py | 2 +- websocket/tests/test_websocket.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/websocket/_core.py b/websocket/_core.py index eef7b26..81b3166 100644 --- a/websocket/_core.py +++ b/websocket/_core.py @@ -79,7 +79,7 @@ class WebSocket(object): def __init__(self, get_mask_key=None, sockopt=None, sslopt=None, fire_cont_frame=False, enable_multithread=False, - skip_utf8_validation=False, **options): + skip_utf8_validation=False, **_): """ Initialize WebSocket object. """ diff --git a/websocket/tests/test_websocket.py b/websocket/tests/test_websocket.py index 39d68c1..20de24c 100644 --- a/websocket/tests/test_websocket.py +++ b/websocket/tests/test_websocket.py @@ -44,7 +44,7 @@ TEST_SECURE_WS = True TRACEABLE = False -def create_mask_key(n): +def create_mask_key(_): return "abcd" @@ -261,7 +261,7 @@ class WebSocketTest(unittest.TestCase): @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled") def testIter(self): count = 2 - for rsvp in ws.create_connection('ws://stream.meetup.com/2/rsvps'): + for _ in ws.create_connection('ws://stream.meetup.com/2/rsvps'): count -= 1 if count == 0: break @@ -280,7 +280,7 @@ class WebSocketTest(unittest.TestCase): # s.add_packet(SSLError("The read operation timed out")) s.add_packet(six.b("baz")) with self.assertRaises(ws.WebSocketTimeoutException): - data = sock.frame_buffer.recv_strict(9) + sock.frame_buffer.recv_strict(9) # if six.PY2: # with self.assertRaises(ws.WebSocketTimeoutException): # data = sock._recv_strict(9) @@ -290,7 +290,7 @@ class WebSocketTest(unittest.TestCase): data = sock.frame_buffer.recv_strict(9) self.assertEqual(data, six.b("foobarbaz")) with self.assertRaises(ws.WebSocketConnectionClosedException): - data = sock.frame_buffer.recv_strict(1) + sock.frame_buffer.recv_strict(1) def testRecvTimeout(self): sock = ws.WebSocket() @@ -301,13 +301,13 @@ class WebSocketTest(unittest.TestCase): s.add_packet(socket.timeout()) s.add_packet(six.b("\x4e\x43\x33\x0e\x10\x0f\x00\x40")) with self.assertRaises(ws.WebSocketTimeoutException): - data = sock.recv() + sock.recv() with self.assertRaises(ws.WebSocketTimeoutException): - data = sock.recv() + sock.recv() data = sock.recv() self.assertEqual(data, "Hello, World!") with self.assertRaises(ws.WebSocketConnectionClosedException): - data = sock.recv() + sock.recv() def testRecvWithSimpleFragmentation(self): sock = ws.WebSocket() From d58e5b1490657f7277c3d237521d637adbf887e3 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 11:57:41 +0100 Subject: [PATCH 17/25] test_fuzzingclient.py: Indent with spaces --- compliance/test_fuzzingclient.py | 44 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/compliance/test_fuzzingclient.py b/compliance/test_fuzzingclient.py index 8235dfb..58c5ea6 100644 --- a/compliance/test_fuzzingclient.py +++ b/compliance/test_fuzzingclient.py @@ -19,28 +19,28 @@ ws.close() for case in range(1, count+1): - url = SERVER + '/runCase?case={0}&agent={1}'.format(case, AGENT) - status = websocket.STATUS_NORMAL - try: - ws = websocket.create_connection(url) - while True: - opcode, msg = ws.recv_data() - if opcode == websocket.ABNF.OPCODE_TEXT: - msg.decode("utf-8") - if opcode in (websocket.ABNF.OPCODE_TEXT, websocket.ABNF.OPCODE_BINARY): - ws.send(msg, opcode) - except UnicodeDecodeError: - # this case is ok. - status = websocket.STATUS_PROTOCOL_ERROR - except websocket.WebSocketProtocolException: - status = websocket.STATUS_PROTOCOL_ERROR - except websocket.WebSocketPayloadException: - status = websocket.STATUS_INVALID_PAYLOAD - except Exception as e: - # status = websocket.STATUS_PROTOCOL_ERROR - print(traceback.format_exc()) - finally: - ws.close(status) + url = SERVER + '/runCase?case={0}&agent={1}'.format(case, AGENT) + status = websocket.STATUS_NORMAL + try: + ws = websocket.create_connection(url) + while True: + opcode, msg = ws.recv_data() + if opcode == websocket.ABNF.OPCODE_TEXT: + msg.decode("utf-8") + if opcode in (websocket.ABNF.OPCODE_TEXT, websocket.ABNF.OPCODE_BINARY): + ws.send(msg, opcode) + except UnicodeDecodeError: + # this case is ok. + status = websocket.STATUS_PROTOCOL_ERROR + except websocket.WebSocketProtocolException: + status = websocket.STATUS_PROTOCOL_ERROR + except websocket.WebSocketPayloadException: + status = websocket.STATUS_INVALID_PAYLOAD + except Exception as e: + # status = websocket.STATUS_PROTOCOL_ERROR + print(traceback.format_exc()) + finally: + ws.close(status) print("Ran {} test cases.".format(case)) url = SERVER + '/updateReports?agent={0}'.format(AGENT) From 9ebe59b5d7768b250ec517908cbc6cdabfe85707 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 12:08:03 +0100 Subject: [PATCH 18/25] _abnf, _app, _http, _url: [PEP 8] Fix indents --- websocket/_abnf.py | 6 +++--- websocket/_app.py | 17 +++++++++-------- websocket/_handshake.py | 2 +- websocket/_http.py | 4 ++-- websocket/_url.py | 5 +++-- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/websocket/_abnf.py b/websocket/_abnf.py index 5f6c206..476bd4d 100644 --- a/websocket/_abnf.py +++ b/websocket/_abnf.py @@ -68,7 +68,7 @@ VALID_CLOSE_STATUS = ( STATUS_MESSAGE_TOO_BIG, STATUS_INVALID_EXTENSION, STATUS_UNEXPECTED_CONDITION, - ) +) class ABNF(object): """ @@ -87,7 +87,7 @@ class ABNF(object): # available operation code value tuple OPCODES = (OPCODE_CONT, OPCODE_TEXT, OPCODE_BINARY, OPCODE_CLOSE, - OPCODE_PING, OPCODE_PONG) + OPCODE_PING, OPCODE_PONG) # opcode human readable string OPCODE_MAP = { @@ -97,7 +97,7 @@ class ABNF(object): OPCODE_CLOSE: "close", OPCODE_PING: "ping", OPCODE_PONG: "pong" - } + } # data length threshold. LENGTH_7 = 0x7e diff --git a/websocket/_app.py b/websocket/_app.py index 215bff1..891a97e 100644 --- a/websocket/_app.py +++ b/websocket/_app.py @@ -168,16 +168,16 @@ class WebSocketApp(object): close_frame = None try: - self.sock = WebSocket(self.get_mask_key, - sockopt=sockopt, sslopt=sslopt, + self.sock = WebSocket( + self.get_mask_key, sockopt=sockopt, sslopt=sslopt, fire_cont_frame=self.on_cont_message and True or False, skip_utf8_validation=skip_utf8_validation) self.sock.settimeout(getdefaulttimeout()) - self.sock.connect(self.url, header=self.header, cookie=self.cookie, + self.sock.connect( + self.url, header=self.header, cookie=self.cookie, http_proxy_host=http_proxy_host, - http_proxy_port=http_proxy_port, - http_no_proxy=http_no_proxy, http_proxy_auth=http_proxy_auth, - subprotocols=self.subprotocols, + http_proxy_port=http_proxy_port, http_no_proxy=http_no_proxy, + http_proxy_auth=http_proxy_auth, subprotocols=self.subprotocols, host=host, origin=origin) self._callback(self.on_open) @@ -227,8 +227,9 @@ class WebSocketApp(object): thread.join() self.keep_running = False self.sock.close() - self._callback(self.on_close, - *self._get_close_args(close_frame.data if close_frame else None)) + close_args = self._get_close_args( + close_frame.data if close_frame else None) + self._callback(self.on_close, *close_args) self.sock = None def _get_close_args(self, data): diff --git a/websocket/_handshake.py b/websocket/_handshake.py index 67b16e4..cfc228d 100644 --- a/websocket/_handshake.py +++ b/websocket/_handshake.py @@ -124,7 +124,7 @@ def _get_resp_headers(sock, success_status=101): _HEADERS_TO_CHECK = { "upgrade": "websocket", "connection": "upgrade", - } +} def _validate(headers, key, subprotocols): diff --git a/websocket/_http.py b/websocket/_http.py index 8fae73f..14a5c7e 100644 --- a/websocket/_http.py +++ b/websocket/_http.py @@ -82,8 +82,8 @@ def connect(url, options, proxy, socket): 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) + phost, pport, pauth = get_proxy_info( + hostname, is_secure, proxy.host, proxy.port, proxy.auth, proxy.no_proxy) if not phost: addrinfo_list = socket.getaddrinfo(hostname, port, 0, 0, socket.SOL_TCP) return addrinfo_list, False, None diff --git a/websocket/_url.py b/websocket/_url.py index 9d705fd..7299e5c 100644 --- a/websocket/_url.py +++ b/websocket/_url.py @@ -82,8 +82,9 @@ def _is_no_proxy_host(hostname, no_proxy): return hostname in no_proxy -def get_proxy_info(hostname, is_secure, - proxy_host=None, proxy_port=0, proxy_auth=None, no_proxy=None): +def get_proxy_info( + hostname, is_secure, proxy_host=None, proxy_port=0, proxy_auth=None, + no_proxy=None): """ try to retrieve proxy host and port from environment if not provided in options. From 953d46928030705057f16c7e1a3420cd666e9b34 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 12:11:07 +0100 Subject: [PATCH 19/25] wsdump, examples, setup, _abnf, _http, _utils: [PEP 8] Fix spacing --- bin/wsdump.py | 5 +++-- examples/echoapp_client.py | 6 +++--- setup.py | 4 ++-- websocket/_abnf.py | 16 ++++++++-------- websocket/_app.py | 2 +- websocket/_http.py | 6 +++--- websocket/_utils.py | 2 +- 7 files changed, 21 insertions(+), 20 deletions(-) diff --git a/bin/wsdump.py b/bin/wsdump.py index 88a6638..d85e4fc 100755 --- a/bin/wsdump.py +++ b/bin/wsdump.py @@ -33,9 +33,10 @@ class VAction(argparse.Action): try: values = int(values) except ValueError: - values = values.count("v")+1 + values = values.count("v") + 1 setattr(args, self.dest, values) + def parse_args(): parser = argparse.ArgumentParser(description="WebSocket Simple Dump Tool") parser.add_argument("url", metavar="ws_url", @@ -113,7 +114,7 @@ def main(): options["subprotocols"] = args.subprotocols opts = {} if args.nocert: - opts = { "cert_reqs": websocket.ssl.CERT_NONE, "check_hostname": False } + opts = {"cert_reqs": websocket.ssl.CERT_NONE, "check_hostname": False} ws = websocket.create_connection(args.url, sslopt=opts, **options) if args.raw: console = NonInteractive() diff --git a/examples/echoapp_client.py b/examples/echoapp_client.py index 48850b9..8689379 100644 --- a/examples/echoapp_client.py +++ b/examples/echoapp_client.py @@ -41,8 +41,8 @@ if __name__ == "__main__": else: host = sys.argv[1] ws = websocket.WebSocketApp(host, - on_message = on_message, - on_error = on_error, - on_close = on_close) + on_message=on_message, + on_error=on_error, + on_close=on_close) ws.on_open = on_open ws.run_forever() diff --git a/setup.py b/setup.py index 13778d7..c0d1654 100644 --- a/setup.py +++ b/setup.py @@ -2,12 +2,12 @@ from setuptools import setup import sys VERSION = "0.37.0" -NAME="websocket_client" +NAME = "websocket_client" install_requires = ["six"] tests_require = [] if sys.version_info[0] == 2: - if sys.version_info[1] < 7 or (sys.version_info[1] == 7 and sys.version_info[2]< 9): + if sys.version_info[1] < 7 or (sys.version_info[1] == 7 and sys.version_info[2] < 9): install_requires.append('backports.ssl_match_hostname') if sys.version_info[1] < 7: tests_require.append('unittest2==0.8.0') diff --git a/websocket/_abnf.py b/websocket/_abnf.py index 476bd4d..ed10470 100644 --- a/websocket/_abnf.py +++ b/websocket/_abnf.py @@ -78,12 +78,12 @@ class ABNF(object): """ # operation code values. - OPCODE_CONT = 0x0 - OPCODE_TEXT = 0x1 + OPCODE_CONT = 0x0 + OPCODE_TEXT = 0x1 OPCODE_BINARY = 0x2 - OPCODE_CLOSE = 0x8 - OPCODE_PING = 0x9 - OPCODE_PONG = 0xa + OPCODE_CLOSE = 0x8 + OPCODE_PING = 0x9 + OPCODE_PONG = 0xa # available operation code value tuple OPCODES = (OPCODE_CONT, OPCODE_TEXT, OPCODE_BINARY, OPCODE_CLOSE, @@ -100,7 +100,7 @@ class ABNF(object): } # data length threshold. - LENGTH_7 = 0x7e + LENGTH_7 = 0x7e LENGTH_16 = 1 << 16 LENGTH_63 = 1 << 63 @@ -150,7 +150,7 @@ class ABNF(object): @staticmethod def _is_valid_close_status(code): - return code in VALID_CLOSE_STATUS or (3000 <= code <5000) + return code in VALID_CLOSE_STATUS or (3000 <= code < 5000) def __str__(self): return "fin=" + str(self.fin) \ @@ -256,7 +256,7 @@ class frame_buffer(object): self.mask = None def has_received_header(self): - return self.header is None + return self.header is None def recv_header(self): header = self.recv_strict(2) diff --git a/websocket/_app.py b/websocket/_app.py index 891a97e..180a1fc 100644 --- a/websocket/_app.py +++ b/websocket/_app.py @@ -245,7 +245,7 @@ class WebSocketApp(object): return [] if data and len(data) >= 2: - code = 256*six.byte2int(data[0:1]) + six.byte2int(data[1:2]) + code = 256 * six.byte2int(data[0:1]) + six.byte2int(data[1:2]) reason = data[2:].decode('utf-8') return [code, reason] diff --git a/websocket/_http.py b/websocket/_http.py index 14a5c7e..b99c264 100644 --- a/websocket/_http.py +++ b/websocket/_http.py @@ -44,7 +44,7 @@ class proxy_info(object): self.host = options.get("http_proxy_host", None) if self.host: self.port = options.get("http_proxy_port", 0) - self.auth = options.get("http_proxy_auth", None) + self.auth = options.get("http_proxy_auth", None) self.no_proxy = options.get("http_no_proxy", None) else: self.port = 0 @@ -143,8 +143,8 @@ def _wrap_sni_socket(sock, sslopt, hostname, check_hostname): context.check_hostname = check_hostname if 'ciphers' in sslopt: context.set_ciphers(sslopt['ciphers']) - if 'cert_chain' in sslopt : - certfile,keyfile,password = sslopt['cert_chain'] + if 'cert_chain' in sslopt: + certfile, keyfile, password = sslopt['cert_chain'] context.load_cert_chain(certfile, keyfile, password) return context.wrap_socket( diff --git a/websocket/_utils.py b/websocket/_utils.py index 71d0e00..a7dd65c 100644 --- a/websocket/_utils.py +++ b/websocket/_utils.py @@ -69,7 +69,7 @@ except ImportError: def _decode(state, codep, ch): tp = _UTF8D[ch] - codep = (ch & 0x3f ) | (codep << 6) if (state != _UTF8_ACCEPT) else (0xff >> tp) & ch + codep = (ch & 0x3f) | (codep << 6) if (state != _UTF8_ACCEPT) else (0xff >> tp) & ch state = _UTF8D[256 + state + tp] return state, codep From f1975aa38092f65c6276066e5e72161eb0369539 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 12:15:16 +0100 Subject: [PATCH 20/25] echoapp_client: [PEP 8] Add space before comment --- examples/echoapp_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/echoapp_client.py b/examples/echoapp_client.py index 8689379..c15b35f 100644 --- a/examples/echoapp_client.py +++ b/examples/echoapp_client.py @@ -1,7 +1,7 @@ import websocket try: import thread -except ImportError: #TODO use Threading instead of _thread in python3 +except ImportError: # TODO use Threading instead of _thread in python3 import _thread as thread import time import sys From c5afde8d771833a8e9f4b3be85b817bc9c3dbfcb Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 12:18:57 +0100 Subject: [PATCH 21/25] wsdump, websocket.*: [PEP 8] Use conventional vertical spacing --- bin/wsdump.py | 9 ++++++++- websocket/_abnf.py | 4 +++- websocket/_app.py | 1 + websocket/_exceptions.py | 2 ++ websocket/_handshake.py | 1 + websocket/_http.py | 9 +++++++-- websocket/_socket.py | 3 +++ websocket/_utils.py | 4 ++++ 8 files changed, 29 insertions(+), 4 deletions(-) diff --git a/bin/wsdump.py b/bin/wsdump.py index d85e4fc..0478070 100755 --- a/bin/wsdump.py +++ b/bin/wsdump.py @@ -27,6 +27,7 @@ ENCODING = get_encoding() class VAction(argparse.Action): + def __call__(self, parser, args, values, option_string=None): if values is None: values = "1" @@ -64,7 +65,9 @@ def parse_args(): return parser.parse_args() + class RawInput: + def raw_input(self, prompt): if six.PY3: line = input(prompt) @@ -78,7 +81,9 @@ class RawInput: return line + class InteractiveConsole(RawInput, code.InteractiveConsole): + def write(self, data): sys.stdout.write("\033[2K\033[E") # sys.stdout.write("\n") @@ -89,7 +94,9 @@ class InteractiveConsole(RawInput, code.InteractiveConsole): def read(self): return self.raw_input("> ") + class NonInteractive(RawInput): + def write(self, data): sys.stdout.write(data) sys.stdout.write("\n") @@ -98,6 +105,7 @@ class NonInteractive(RawInput): def read(self): return self.raw_input("") + def main(): start_time = time.time() args = parse_args() @@ -140,7 +148,6 @@ def main(): return frame.opcode, frame.data - def recv_ws(): while True: opcode, data = recv() diff --git a/websocket/_abnf.py b/websocket/_abnf.py index ed10470..6e7b85f 100644 --- a/websocket/_abnf.py +++ b/websocket/_abnf.py @@ -70,6 +70,7 @@ VALID_CLOSE_STATUS = ( STATUS_UNEXPECTED_CONDITION, ) + class ABNF(object): """ ABNF frame class. @@ -238,6 +239,7 @@ class ABNF(object): _d = array.array("B", data) return _mask(_m, _d) + class frame_buffer(object): _HEADER_MASK_INDEX = 5 _HEADER_LENGTH_INDEX = 6 @@ -285,7 +287,6 @@ class frame_buffer(object): return False return self.header[frame_buffer._HEADER_MASK_INDEX] - def has_received_length(self): return self.length is None @@ -359,6 +360,7 @@ class frame_buffer(object): class continuous_frame(object): + def __init__(self, fire_cont_frame, skip_utf8_validation): self.fire_cont_frame = fire_cont_frame self.skip_utf8_validation = skip_utf8_validation diff --git a/websocket/_app.py b/websocket/_app.py index 180a1fc..9954ee6 100644 --- a/websocket/_app.py +++ b/websocket/_app.py @@ -43,6 +43,7 @@ class WebSocketApp(object): Higher level of APIs are provided. The interface is like JavaScript WebSocket object. """ + def __init__(self, url, header=None, on_open=None, on_message=None, on_error=None, on_close=None, on_ping=None, on_pong=None, diff --git a/websocket/_exceptions.py b/websocket/_exceptions.py index 7b3e508..bf5c4ab 100644 --- a/websocket/_exceptions.py +++ b/websocket/_exceptions.py @@ -25,6 +25,7 @@ Copyright (C) 2010 Hiroki Ohtani(liris) define websocket exceptions """ + class WebSocketException(Exception): """ websocket exception class. @@ -72,6 +73,7 @@ class WebSocketBadStatusException(WebSocketException): """ WebSocketBadStatusException will be raised when we get bad handshake status code. """ + def __init__(self, message, status_code): super(WebSocketBadStatusException, self).__init__(message % status_code) self.status_code = status_code diff --git a/websocket/_handshake.py b/websocket/_handshake.py index cfc228d..cba48ec 100644 --- a/websocket/_handshake.py +++ b/websocket/_handshake.py @@ -48,6 +48,7 @@ VERSION = 13 class handshake_response(object): + def __init__(self, status, headers, subprotocol): self.status = status self.headers = headers diff --git a/websocket/_http.py b/websocket/_http.py index b99c264..c57a310 100644 --- a/websocket/_http.py +++ b/websocket/_http.py @@ -39,7 +39,9 @@ from ._ssl_compat import * __all__ = ["proxy_info", "connect", "read_headers"] + class proxy_info(object): + def __init__(self, **options): self.host = options.get("http_proxy_host", None) if self.host: @@ -51,6 +53,7 @@ class proxy_info(object): self.auth = None self.no_proxy = None + def connect(url, options, proxy, socket): hostname, port, resource, is_secure = parse_url(url) @@ -158,7 +161,7 @@ def _wrap_sni_socket(sock, sslopt, hostname, check_hostname): def _ssl_socket(sock, user_sslopt, hostname): sslopt = dict(cert_reqs=ssl.CERT_REQUIRED) sslopt.update(user_sslopt) - + certPath = os.path.join( os.path.dirname(__file__), "cacert.pem") if os.path.isfile(certPath) and user_sslopt.get('ca_certs', None) is None: @@ -176,6 +179,7 @@ def _ssl_socket(sock, user_sslopt, hostname): return sock + def _tunnel(sock, host, port, auth): debug("Connecting proxy...") connect_header = "CONNECT %s:%d HTTP/1.0\r\n" % (host, port) @@ -199,9 +203,10 @@ def _tunnel(sock, host, port, auth): if status != 200: raise WebSocketProxyException( "failed CONNECT via proxy status: %r" % status) - + return sock + def read_headers(sock): status = None headers = {} diff --git a/websocket/_socket.py b/websocket/_socket.py index 63e001c..7055ae7 100644 --- a/websocket/_socket.py +++ b/websocket/_socket.py @@ -42,7 +42,9 @@ _default_timeout = None __all__ = ["DEFAULT_SOCKET_OPTION", "sock_opt", "setdefaulttimeout", "getdefaulttimeout", "recv", "recv_line", "send"] + class sock_opt(object): + def __init__(self, sockopt, sslopt): if sockopt is None: sockopt = [] @@ -52,6 +54,7 @@ class sock_opt(object): self.sslopt = sslopt self.timeout = None + def setdefaulttimeout(timeout): """ Set the global timeout setting to connect. diff --git a/websocket/_utils.py b/websocket/_utils.py index a7dd65c..c8bcd22 100644 --- a/websocket/_utils.py +++ b/websocket/_utils.py @@ -24,7 +24,9 @@ import six __all__ = ["NoLock", "validate_utf8", "extract_err_message"] + class NoLock(object): + def __enter__(self): pass @@ -86,6 +88,7 @@ except ImportError: return True + def validate_utf8(utfbytes): """ validate utf8 byte string. @@ -94,6 +97,7 @@ def validate_utf8(utfbytes): """ return _validate_utf8(utfbytes) + def extract_err_message(exception): if exception.args: return exception.args[0] From 9f138c94e71458172cd90dec49ce1d1163895c4f Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 12:21:25 +0100 Subject: [PATCH 22/25] websocket.*: [PEP 8] Use conventional line-length limit Line length is set to 80 characters; tests are excluded. --- websocket/_abnf.py | 13 ++++++++----- websocket/_app.py | 15 ++++++++++----- websocket/_core.py | 12 ++++++++---- websocket/_exceptions.py | 3 ++- websocket/_http.py | 12 ++++++++---- websocket/_socket.py | 3 ++- websocket/_utils.py | 3 ++- 7 files changed, 40 insertions(+), 21 deletions(-) diff --git a/websocket/_abnf.py b/websocket/_abnf.py index 6e7b85f..87503ce 100644 --- a/websocket/_abnf.py +++ b/websocket/_abnf.py @@ -145,7 +145,8 @@ class ABNF(object): if l > 2 and not skip_utf8_validation and not validate_utf8(self.data[2:]): raise WebSocketProtocolException("Invalid close frame.") - code = 256*six.byte2int(self.data[0:1]) + six.byte2int(self.data[1:2]) + code = 256 * \ + six.byte2int(self.data[0:1]) + six.byte2int(self.data[1:2]) if not self._is_valid_close_status(code): raise WebSocketProtocolException("Invalid close opcode.") @@ -155,8 +156,8 @@ class ABNF(object): def __str__(self): return "fin=" + str(self.fin) \ - + " opcode=" + str(self.opcode) \ - + " data=" + str(self.data) + + " opcode=" + str(self.opcode) \ + + " data=" + str(self.data) @staticmethod def create_frame(data, opcode, fin=1): @@ -344,7 +345,8 @@ class frame_buffer(object): # fragmenting the heap -- the number of bytes recv() actually # reads is limited by socket buffer and is relatively small, # yet passing large numbers repeatedly causes lots of large - # buffers allocated and then shrunk, which results in fragmentation. + # buffers allocated and then shrunk, which results in + # fragmentation. bytes_ = self.recv(min(16384, shortage)) self.recv_buffer.append(bytes_) shortage -= len(bytes_) @@ -392,6 +394,7 @@ class continuous_frame(object): self.cont_data = None frame.data = data[1] if not self.fire_cont_frame and data[0] == ABNF.OPCODE_TEXT and not self.skip_utf8_validation and not validate_utf8(frame.data): - raise WebSocketPayloadException("cannot decode: " + repr(frame.data)) + raise WebSocketPayloadException( + "cannot decode: " + repr(frame.data)) return [data[0], frame] diff --git a/websocket/_app.py b/websocket/_app.py index 9954ee6..5096aef 100644 --- a/websocket/_app.py +++ b/websocket/_app.py @@ -114,7 +114,8 @@ class WebSocketApp(object): """ if not self.sock or self.sock.send(data, opcode) == 0: - raise WebSocketConnectionClosedException("Connection is already closed.") + raise WebSocketConnectionClosedException( + "Connection is already closed.") def close(self): """ @@ -184,12 +185,14 @@ class WebSocketApp(object): if ping_interval: event = threading.Event() - thread = threading.Thread(target=self._send_ping, args=(ping_interval, event)) + thread = threading.Thread( + target=self._send_ping, args=(ping_interval, event)) thread.setDaemon(True) thread.start() while self.sock.connected: - r, w, e = select.select((self.sock.sock, ), (), (), ping_timeout) + r, w, e = select.select( + (self.sock.sock, ), (), (), ping_timeout) if not self.keep_running: break @@ -204,8 +207,10 @@ class WebSocketApp(object): self.last_pong_tm = time.time() self._callback(self.on_pong, frame.data) elif op_code == ABNF.OPCODE_CONT and self.on_cont_message: - self._callback(self.on_data, data, frame.opcode, frame.fin) - self._callback(self.on_cont_message, frame.data, frame.fin) + self._callback(self.on_data, data, + frame.opcode, frame.fin) + self._callback(self.on_cont_message, + frame.data, frame.fin) else: data = frame.data if six.PY3 and frame.opcode == ABNF.OPCODE_TEXT: diff --git a/websocket/_core.py b/websocket/_core.py index 81b3166..e0be9f2 100644 --- a/websocket/_core.py +++ b/websocket/_core.py @@ -91,7 +91,8 @@ class WebSocket(object): self.get_mask_key = get_mask_key # These buffer over the build-up of a single frame. self.frame_buffer = frame_buffer(self._recv, skip_utf8_validation) - self.cont_frame = continuous_frame(fire_cont_frame, skip_utf8_validation) + self.cont_frame = continuous_frame( + fire_cont_frame, skip_utf8_validation) if enable_multithread: self.lock = threading.Lock() @@ -325,7 +326,8 @@ class WebSocket(object): if not frame: # handle error: # 'NoneType' object has no attribute 'opcode' - raise WebSocketProtocolException("Not a valid frame %s" % frame) + raise WebSocketProtocolException( + "Not a valid frame %s" % frame) elif frame.opcode in (ABNF.OPCODE_TEXT, ABNF.OPCODE_BINARY, ABNF.OPCODE_CONT): self.cont_frame.validate(frame) self.cont_frame.add(frame) @@ -340,7 +342,8 @@ class WebSocket(object): if len(frame.data) < 126: self.pong(frame.data) else: - raise WebSocketProtocolException("Ping message is too long") + raise WebSocketProtocolException( + "Ping message is too long") if control_frame: return frame.opcode, frame elif frame.opcode == ABNF.OPCODE_PONG: @@ -385,7 +388,8 @@ class WebSocket(object): try: self.connected = False - self.send(struct.pack('!H', status) + reason, ABNF.OPCODE_CLOSE) + self.send(struct.pack('!H', status) + + reason, ABNF.OPCODE_CLOSE) sock_timeout = self.sock.gettimeout() self.sock.settimeout(timeout) try: diff --git a/websocket/_exceptions.py b/websocket/_exceptions.py index bf5c4ab..9d1a3bc 100644 --- a/websocket/_exceptions.py +++ b/websocket/_exceptions.py @@ -75,5 +75,6 @@ class WebSocketBadStatusException(WebSocketException): """ def __init__(self, message, status_code): - super(WebSocketBadStatusException, self).__init__(message % status_code) + super(WebSocketBadStatusException, self).__init__( + message % status_code) self.status_code = status_code diff --git a/websocket/_http.py b/websocket/_http.py index c57a310..4f9c3e3 100644 --- a/websocket/_http.py +++ b/websocket/_http.py @@ -60,7 +60,8 @@ def connect(url, options, proxy, socket): if socket: return socket, (hostname, port, resource) - addrinfo_list, need_tunnel, auth = _get_addrinfo_list(hostname, port, is_secure, proxy) + addrinfo_list, need_tunnel, auth = _get_addrinfo_list( + hostname, port, is_secure, proxy) if not addrinfo_list: raise WebSocketException( "Host not found.: " + hostname + ":" + str(port)) @@ -88,7 +89,8 @@ 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) if not phost: - addrinfo_list = socket.getaddrinfo(hostname, port, 0, 0, socket.SOL_TCP) + addrinfo_list = socket.getaddrinfo( + hostname, port, 0, 0, socket.SOL_TCP) return addrinfo_list, False, None else: pport = pport and pport or 80 @@ -140,7 +142,8 @@ def _wrap_sni_socket(sock, sslopt, hostname, check_hostname): sslopt.get('keyfile', None), sslopt.get('password', None), ) - # see https://github.com/liris/websocket-client/commit/b96a2e8fa765753e82eea531adb19716b52ca3ca#commitcomment-10803153 + # see + # https://github.com/liris/websocket-client/commit/b96a2e8fa765753e82eea531adb19716b52ca3ca#commitcomment-10803153 context.verify_mode = sslopt['cert_reqs'] if HAVE_CONTEXT_CHECK_HOSTNAME: context.check_hostname = check_hostname @@ -166,7 +169,8 @@ def _ssl_socket(sock, user_sslopt, hostname): os.path.dirname(__file__), "cacert.pem") if os.path.isfile(certPath) and user_sslopt.get('ca_certs', None) is None: sslopt['ca_certs'] = certPath - check_hostname = sslopt["cert_reqs"] != ssl.CERT_NONE and sslopt.pop('check_hostname', True) + check_hostname = sslopt["cert_reqs"] != ssl.CERT_NONE and sslopt.pop( + 'check_hostname', True) if _can_use_sni(): sock = _wrap_sni_socket(sock, sslopt, hostname, check_hostname) diff --git a/websocket/_socket.py b/websocket/_socket.py index 7055ae7..f2bc4f1 100644 --- a/websocket/_socket.py +++ b/websocket/_socket.py @@ -89,7 +89,8 @@ def recv(sock, bufsize): raise if not bytes_: - raise WebSocketConnectionClosedException("Connection is already closed.") + raise WebSocketConnectionClosedException( + "Connection is already closed.") return bytes_ diff --git a/websocket/_utils.py b/websocket/_utils.py index c8bcd22..0c939f8 100644 --- a/websocket/_utils.py +++ b/websocket/_utils.py @@ -71,7 +71,8 @@ except ImportError: def _decode(state, codep, ch): tp = _UTF8D[ch] - codep = (ch & 0x3f) | (codep << 6) if (state != _UTF8_ACCEPT) else (0xff >> tp) & ch + codep = (ch & 0x3f) | (codep << 6) if ( + state != _UTF8_ACCEPT) else (0xff >> tp) & ch state = _UTF8D[256 + state + tp] return state, codep From 525fcfc0fb8099eae1ad92b44e14f5ca9b27780e Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Wed, 27 Apr 2016 15:00:56 +0100 Subject: [PATCH 23/25] wsdump, test_fuzzingclient, websocket.*, test_websocket: Organise imports Previously, because of the multiple instances of `from foo import *`, names were imported from modules that had themselves imported them, instead of from the place of definition. This commit therefore does the following: - Declares `__all__` in every module that imports anything, so that `from foo import *` is sane. - Sorts the imports based on conventions, similar to the output of `isort`. - Places all conditional imports after unconditional imports, except where that isn't valid. - Imports local names from the modules where they are defined, except when importing the package itself. --- bin/wsdump.py | 7 ++++-- compliance/test_fuzzingclient.py | 6 +---- websocket/__init__.py | 5 ++++- websocket/_abnf.py | 22 ++++++++++++++++-- websocket/_app.py | 7 +++--- websocket/_core.py | 20 ++++++++--------- websocket/_handshake.py | 20 ++++++++--------- websocket/_http.py | 18 +++++++-------- websocket/_logging.py | 1 - websocket/_socket.py | 4 ++-- websocket/_ssl_compat.py | 1 - websocket/_url.py | 2 +- websocket/_utils.py | 1 - websocket/tests/test_websocket.py | 37 +++++++++++++++---------------- 14 files changed, 83 insertions(+), 68 deletions(-) diff --git a/bin/wsdump.py b/bin/wsdump.py index 0478070..5af00ac 100755 --- a/bin/wsdump.py +++ b/bin/wsdump.py @@ -2,12 +2,15 @@ import argparse import code -import six import sys import threading import time -import websocket + +import six from six.moves.urllib.parse import urlparse + +import websocket + try: import readline except ImportError: diff --git a/compliance/test_fuzzingclient.py b/compliance/test_fuzzingclient.py index 58c5ea6..f4b0ff1 100644 --- a/compliance/test_fuzzingclient.py +++ b/compliance/test_fuzzingclient.py @@ -1,13 +1,9 @@ #!/usr/bin/env python -import websocket import json import traceback -import six - - - +import websocket SERVER = 'ws://127.0.0.1:8642' AGENT = 'py-websockets-client' diff --git a/websocket/__init__.py b/websocket/__init__.py index a895023..9b2cef5 100644 --- a/websocket/__init__.py +++ b/websocket/__init__.py @@ -19,7 +19,10 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Boston, MA 02110-1335 USA """ -from ._core import * from ._app import WebSocketApp +from ._core import * +from ._exceptions import * +from ._logging import * +from ._socket import * __version__ = "0.37.0" diff --git a/websocket/_abnf.py b/websocket/_abnf.py index 87503ce..fca07e6 100644 --- a/websocket/_abnf.py +++ b/websocket/_abnf.py @@ -19,10 +19,12 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Boston, MA 02110-1335 USA """ -import six import array -import struct import os +import struct + +import six + from ._exceptions import * from ._utils import validate_utf8 @@ -44,6 +46,22 @@ except ImportError: else: return _d.tostring() +__all__ = [ + 'ABNF', 'continuous_frame', 'frame_buffer', + 'STATUS_NORMAL', + 'STATUS_GOING_AWAY', + 'STATUS_PROTOCOL_ERROR', + 'STATUS_UNSUPPORTED_DATA_TYPE', + 'STATUS_STATUS_NOT_AVAILABLE', + 'STATUS_ABNORMAL_CLOSED', + 'STATUS_INVALID_PAYLOAD', + 'STATUS_POLICY_VIOLATION', + 'STATUS_MESSAGE_TOO_BIG', + 'STATUS_INVALID_EXTENSION', + 'STATUS_UNEXPECTED_CONDITION', + 'STATUS_TLS_HANDSHAKE_ERROR', +] + # closing frame status codes. STATUS_NORMAL = 1000 STATUS_GOING_AWAY = 1001 diff --git a/websocket/_app.py b/websocket/_app.py index 5096aef..3ea942d 100644 --- a/websocket/_app.py +++ b/websocket/_app.py @@ -23,17 +23,18 @@ Copyright (C) 2010 Hiroki Ohtani(liris) """ WebSocketApp provides higher level APIs. """ +import select +import sys import threading import time import traceback -import sys -import select + import six +from ._abnf import ABNF from ._core import WebSocket, getdefaulttimeout from ._exceptions import * from ._logging import * -from ._abnf import ABNF __all__ = ["WebSocketApp"] diff --git a/websocket/_core.py b/websocket/_core.py index e0be9f2..adcdb6b 100644 --- a/websocket/_core.py +++ b/websocket/_core.py @@ -21,24 +21,22 @@ Copyright (C) 2010 Hiroki Ohtani(liris) """ from __future__ import print_function +import socket +import struct +import threading import six -import socket - -if six.PY3: - from base64 import encodebytes as base64encode -else: - from base64 import encodestring as base64encode - -import threading # websocket modules from ._abnf import * +from ._exceptions import * +from ._handshake import * +from ._http import * +from ._logging import * from ._socket import * from ._utils import * -from ._logging import * -from ._http import * -from ._handshake import * + +__all__ = ['WebSocket', 'create_connection'] """ websocket python client. diff --git a/websocket/_handshake.py b/websocket/_handshake.py index cba48ec..73c9e7f 100644 --- a/websocket/_handshake.py +++ b/websocket/_handshake.py @@ -19,21 +19,21 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Boston, MA 02110-1335 USA """ - -import six -if six.PY3: - from base64 import encodebytes as base64encode -else: - from base64 import encodestring as base64encode - import hashlib import hmac import os -from ._logging import * -from ._socket import* -from ._http import * +import six + from ._exceptions import * +from ._http import * +from ._logging import * +from ._socket import * + +if six.PY3: + from base64 import encodebytes as base64encode +else: + from base64 import encodestring as base64encode __all__ = ["handshake_response", "handshake"] diff --git a/websocket/_http.py b/websocket/_http.py index 4f9c3e3..88f313a 100644 --- a/websocket/_http.py +++ b/websocket/_http.py @@ -19,24 +19,24 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Boston, MA 02110-1335 USA """ - -import six -import socket import errno import os +import socket import sys +import six + +from ._exceptions import * +from ._logging import * +from ._socket import* +from ._ssl_compat import * +from ._url import * + if six.PY3: from base64 import encodebytes as base64encode else: from base64 import encodestring as base64encode -from ._logging import * -from ._url import * -from ._socket import* -from ._exceptions import * -from ._ssl_compat import * - __all__ = ["proxy_info", "connect", "read_headers"] diff --git a/websocket/_logging.py b/websocket/_logging.py index 321e24a..d440bf7 100644 --- a/websocket/_logging.py +++ b/websocket/_logging.py @@ -19,7 +19,6 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Boston, MA 02110-1335 USA """ - import logging _logger = logging.getLogger('websocket') diff --git a/websocket/_socket.py b/websocket/_socket.py index f2bc4f1..e2e1dd2 100644 --- a/websocket/_socket.py +++ b/websocket/_socket.py @@ -19,13 +19,13 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Boston, MA 02110-1335 USA """ - import socket + import six from ._exceptions import * -from ._utils import * from ._ssl_compat import * +from ._utils import * DEFAULT_SOCKET_OPTION = [(socket.SOL_TCP, socket.TCP_NODELAY, 1)] if hasattr(socket, "SO_KEEPALIVE"): diff --git a/websocket/_ssl_compat.py b/websocket/_ssl_compat.py index d41ca79..0304816 100644 --- a/websocket/_ssl_compat.py +++ b/websocket/_ssl_compat.py @@ -19,7 +19,6 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Boston, MA 02110-1335 USA """ - __all__ = ["HAVE_SSL", "ssl", "SSLError"] try: diff --git a/websocket/_url.py b/websocket/_url.py index 7299e5c..11216b6 100644 --- a/websocket/_url.py +++ b/websocket/_url.py @@ -19,9 +19,9 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Boston, MA 02110-1335 USA """ +import os from six.moves.urllib.parse import urlparse -import os __all__ = ["parse_url", "get_proxy_info"] diff --git a/websocket/_utils.py b/websocket/_utils.py index 0c939f8..399fb89 100644 --- a/websocket/_utils.py +++ b/websocket/_utils.py @@ -19,7 +19,6 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Boston, MA 02110-1335 USA """ - import six __all__ = ["NoLock", "validate_utf8", "extract_err_message"] diff --git a/websocket/tests/test_websocket.py b/websocket/tests/test_websocket.py index 20de24c..d2170ae 100644 --- a/websocket/tests/test_websocket.py +++ b/websocket/tests/test_websocket.py @@ -1,40 +1,39 @@ # -*- coding: utf-8 -*- # -import six import sys sys.path[0:0] = [""] import os import os.path import socket -try: - from ssl import SSLError -except ImportError: - # dummy class of SSLError for ssl none-support environment. - class SSLError(Exception): - pass -if sys.version_info[0] == 2 and sys.version_info[1] < 7: - import unittest2 as unittest -else: - import unittest +import six +# websocket-client +import websocket as ws +from websocket._handshake import _create_sec_websocket_key, \ + _validate as _validate_header +from websocket._http import read_headers +from websocket._url import get_proxy_info, parse_url +from websocket._utils import validate_utf8 if six.PY3: from base64 import decodebytes as base64decode else: from base64 import decodestring as base64decode +if sys.version_info[0] == 2 and sys.version_info[1] < 7: + import unittest2 as unittest +else: + import unittest -# websocket-client -import websocket as ws -from websocket._handshake import _create_sec_websocket_key -from websocket._url import parse_url, get_proxy_info -from websocket._utils import validate_utf8 -from websocket._handshake import _validate as _validate_header -from websocket._http import read_headers - +try: + from ssl import SSLError +except ImportError: + # dummy class of SSLError for ssl none-support environment. + class SSLError(Exception): + pass # Skip test to access the internet. TEST_WITH_INTERNET = os.environ.get('TEST_WITH_INTERNET', '0') == '1' From 88805d04254125b96e79d9e8c93938d314373b35 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Thu, 28 Apr 2016 11:37:41 +0100 Subject: [PATCH 24/25] fixup! wsdump, test_fuzzingclient, websocket.*, test_websocket: Organise imports --- websocket/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/websocket/__init__.py b/websocket/__init__.py index 9b2cef5..644bb75 100644 --- a/websocket/__init__.py +++ b/websocket/__init__.py @@ -19,6 +19,7 @@ Copyright (C) 2010 Hiroki Ohtani(liris) Boston, MA 02110-1335 USA """ +from ._abnf import * from ._app import WebSocketApp from ._core import * from ._exceptions import * From 01b88d38dac85501a136f6a78a61ca26b531f640 Mon Sep 17 00:00:00 2001 From: Allan Lewis Date: Thu, 28 Apr 2016 13:58:54 +0100 Subject: [PATCH 25/25] fixup! websocket.*: [PEP 8] Use conventional line-length limit --- websocket/_abnf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/websocket/_abnf.py b/websocket/_abnf.py index fca07e6..5b1a82d 100644 --- a/websocket/_abnf.py +++ b/websocket/_abnf.py @@ -390,7 +390,8 @@ class continuous_frame(object): def validate(self, frame): if not self.recving_frames and frame.opcode == ABNF.OPCODE_CONT: raise WebSocketProtocolException("Illegal frame") - if self.recving_frames and frame.opcode in (ABNF.OPCODE_TEXT, ABNF.OPCODE_BINARY): + if self.recving_frames and \ + frame.opcode in (ABNF.OPCODE_TEXT, ABNF.OPCODE_BINARY): raise WebSocketProtocolException("Illegal frame") def add(self, frame):