Skip to content

Commit

Permalink
Update dependency websocket-client to v0.57.0 (#270)
Browse files Browse the repository at this point in the history
* Update dependency websocket-client to v0.57.0

* Install websocket-client version 0.57.0

Co-authored-by: Renovate Bot <renovatebot@gmail.com>
Co-authored-by: h3llrais3r <pooh_beer_1@hotmail.com>
  • Loading branch information
3 people committed Dec 26, 2019
1 parent 2d99413 commit 381fdd2
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 24 deletions.
217 changes: 217 additions & 0 deletions lib/bin/wsdump.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
#!c:\tools\python27\python.exe

import argparse
import code
import sys
import threading
import time
import ssl
import gzip
import zlib

import six
from six.moves.urllib.parse import urlparse

import websocket

try:
import readline
except ImportError:
pass


def get_encoding():
encoding = getattr(sys.stdin, "encoding", "")
if not encoding:
return "utf-8"
else:
return encoding.lower()


OPCODE_DATA = (websocket.ABNF.OPCODE_TEXT, websocket.ABNF.OPCODE_BINARY)
ENCODING = get_encoding()


class VAction(argparse.Action):

def __call__(self, parser, args, values, option_string=None):
if values is None:
values = "1"
try:
values = int(values)
except ValueError:
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",
help="websocket url. ex. ws://echo.websocket.org/")
parser.add_argument("-p", "--proxy",
help="proxy url. ex. http://127.0.0.1:8080")
parser.add_argument("-v", "--verbose", default=0, nargs='?', action=VAction,
dest="verbose",
help="set verbose mode. If set to 1, show opcode. "
"If set to 2, enable to trace websocket module")
parser.add_argument("-n", "--nocert", action='store_true',
help="Ignore invalid SSL cert")
parser.add_argument("-r", "--raw", action="store_true",
help="raw output")
parser.add_argument("-s", "--subprotocols", nargs='*',
help="Set subprotocols")
parser.add_argument("-o", "--origin",
help="Set origin")
parser.add_argument("--eof-wait", default=0, type=int,
help="wait time(second) after 'EOF' received.")
parser.add_argument("-t", "--text",
help="Send initial text")
parser.add_argument("--timings", action="store_true",
help="Print timings in seconds")
parser.add_argument("--headers",
help="Set custom headers. Use ',' as separator")

return parser.parse_args()


class RawInput:

def raw_input(self, prompt):
if six.PY3:
line = input(prompt)
else:
line = raw_input(prompt)

if ENCODING and ENCODING != "utf-8" and not isinstance(line, six.text_type):
line = line.decode(ENCODING).encode("utf-8")
elif isinstance(line, six.text_type):
line = line.encode("utf-8")

return line


class InteractiveConsole(RawInput, code.InteractiveConsole):

def write(self, data):
sys.stdout.write("\033[2K\033[E")
# sys.stdout.write("\n")
sys.stdout.write("\033[34m< " + data + "\033[39m")
sys.stdout.write("\n> ")
sys.stdout.flush()

def read(self):
return self.raw_input("> ")


class NonInteractive(RawInput):

def write(self, data):
sys.stdout.write(data)
sys.stdout.write("\n")
sys.stdout.flush()

def read(self):
return self.raw_input("")


def main():
start_time = time.time()
args = parse_args()
if args.verbose > 1:
websocket.enableTrace(True)
options = {}
if args.proxy:
p = urlparse(args.proxy)
options["http_proxy_host"] = p.hostname
options["http_proxy_port"] = p.port
if args.origin:
options["origin"] = args.origin
if args.subprotocols:
options["subprotocols"] = args.subprotocols
opts = {}
if args.nocert:
opts = {"cert_reqs": ssl.CERT_NONE, "check_hostname": False}
if args.headers:
options['header'] = list(map(str.strip, args.headers.split(',')))
ws = websocket.create_connection(args.url, sslopt=opts, **options)
if args.raw:
console = NonInteractive()
else:
console = InteractiveConsole()
print("Press Ctrl+C to quit")

def recv():
try:
frame = ws.recv_frame()
except websocket.WebSocketException:
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
elif frame.opcode == websocket.ABNF.OPCODE_CLOSE:
ws.send_close()
return frame.opcode, None
elif frame.opcode == websocket.ABNF.OPCODE_PING:
ws.pong(frame.data)
return frame.opcode, frame.data

return frame.opcode, frame.data

def recv_ws():
while True:
opcode, data = recv()
msg = None
if six.PY3 and opcode == websocket.ABNF.OPCODE_TEXT and isinstance(data, bytes):
data = str(data, "utf-8")
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:
data = "[zlib] " + str(zlib.decompress(data, -zlib.MAX_WBITS), "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:
console.write(str(time.time() - start_time) + ": " + msg)
else:
console.write(msg)

if opcode == websocket.ABNF.OPCODE_CLOSE:
break

thread = threading.Thread(target=recv_ws)
thread.daemon = True
thread.start()

if args.text:
ws.send(args.text)

while True:
try:
message = console.read()
ws.send(message)
except KeyboardInterrupt:
return
except EOFError:
time.sleep(args.eof_wait)
return


if __name__ == "__main__":
try:
main()
except Exception as e:
print(e)
2 changes: 1 addition & 1 deletion lib/websocket/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@
from ._logging import *
from ._socket import *

__version__ = "0.56.0"
__version__ = "0.57.0"
15 changes: 8 additions & 7 deletions lib/websocket/_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,25 @@

class Dispatcher:
def __init__(self, app, ping_timeout):
self.app = app
self.app = app
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:
if not read_callback():
break
check_callback()

class SSLDispacther:
class SSLDispatcher:
def __init__(self, app, ping_timeout):
self.app = app
self.app = app
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():
Expand All @@ -75,6 +75,7 @@ def select(self):
r, w, e = select.select((sock, ), (), (), self.ping_timeout)
return r


class WebSocketApp(object):
"""
Higher level of APIs are provided.
Expand Down Expand Up @@ -179,7 +180,7 @@ def run_forever(self, sockopt=None, sslopt=None,
http_no_proxy=None, http_proxy_auth=None,
skip_utf8_validation=False,
host=None, origin=None, dispatcher=None,
suppress_origin = False, proxy_type=None):
suppress_origin=False, proxy_type=None):
"""
run event loop for WebSocket framework.
This loop is infinite loop and is alive during websocket is available.
Expand Down Expand Up @@ -314,7 +315,7 @@ def check():
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)

Expand Down
3 changes: 2 additions & 1 deletion lib/websocket/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ def send_frame(self, frame):
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:
Expand Down
1 change: 1 addition & 0 deletions lib/websocket/_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ def __init__(self, message, status_code, status_message=None, resp_headers=None)
self.status_code = status_code
self.resp_headers = resp_headers


class WebSocketAddressException(WebSocketException):
"""
If the websocket address info cannot be found, this exception will be raised.
Expand Down
22 changes: 14 additions & 8 deletions lib/websocket/_handshake.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
from ._logging import *
from ._socket import *

if six.PY3:
if hasattr(six, 'PY3') and six.PY3:
from base64 import encodebytes as base64encode
else:
from base64 import encodestring as base64encode

if six.PY3:
if six.PY34:
if hasattr(six, 'PY3') and six.PY3:
if hasattr(six, 'PY34') and six.PY34:
from http import client as HTTPStatus
else:
from http import HTTPStatus
Expand All @@ -55,7 +55,8 @@ def compare_digest(s1, s2):
# 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()

Expand Down Expand Up @@ -85,6 +86,7 @@ def handshake(sock, hostname, port, resource, **options):

return handshake_response(status, resp, subproto)


def _pack_hostname(hostname):
# IPv6 address
if ':' in hostname:
Expand All @@ -95,14 +97,12 @@ 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:
Expand All @@ -126,6 +126,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 or options['connection'] is None:
headers.append('Connection: upgrade')
else:
headers.append(options['connection'])

subprotocols = options.get("subprotocols")
if subprotocols:
headers.append("Sec-WebSocket-Protocol: %s" % ",".join(subprotocols))
Expand Down Expand Up @@ -154,12 +159,13 @@ 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)
return status, resp_headers


_HEADERS_TO_CHECK = {
"upgrade": "websocket",
"connection": "upgrade",
Expand Down

0 comments on commit 381fdd2

Please sign in to comment.