Bump websocket-client from 1.3.2 to 1.4.2 (#1886)

* Bump websocket-client from 1.3.2 to 1.4.2

Bumps [websocket-client](https://github.com/websocket-client/websocket-client) from 1.3.2 to 1.4.2.
- [Release notes](https://github.com/websocket-client/websocket-client/releases)
- [Changelog](https://github.com/websocket-client/websocket-client/blob/master/ChangeLog)
- [Commits](https://github.com/websocket-client/websocket-client/compare/v1.3.2...v1.4.2)

---
updated-dependencies:
- dependency-name: websocket-client
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update websocket-client==1.4.2

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com>

[skip ci]
This commit is contained in:
dependabot[bot] 2022-11-12 17:29:02 -08:00 committed by GitHub
parent a5ccc9a1a3
commit 3af08f0d07
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 177 additions and 101 deletions

View file

@ -17,10 +17,10 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
""" """
from ._abnf import * from ._abnf import *
from ._app import WebSocketApp from ._app import WebSocketApp, setReconnect
from ._core import * from ._core import *
from ._exceptions import * from ._exceptions import *
from ._logging import * from ._logging import *
from ._socket import * from ._socket import *
__version__ = "1.3.2" __version__ = "1.4.2"

View file

@ -1,9 +1,11 @@
import inspect
import selectors import selectors
import sys import sys
import threading import threading
import time import time
import traceback import traceback
from ._abnf import ABNF from ._abnf import ABNF
from ._url import parse_url
from ._core import WebSocket, getdefaulttimeout from ._core import WebSocket, getdefaulttimeout
from ._exceptions import * from ._exceptions import *
from . import _logging from . import _logging
@ -29,15 +31,40 @@ limitations under the License.
__all__ = ["WebSocketApp"] __all__ = ["WebSocketApp"]
RECONNECT = 0
class Dispatcher:
def setReconnect(reconnectInterval):
global RECONNECT
RECONNECT = reconnectInterval
class DispatcherBase:
""" """
Dispatcher DispatcherBase
""" """
def __init__(self, app, ping_timeout): def __init__(self, app, ping_timeout):
self.app = app self.app = app
self.ping_timeout = ping_timeout self.ping_timeout = ping_timeout
def timeout(self, seconds, callback):
time.sleep(seconds)
callback()
def reconnect(self, seconds, reconnector):
try:
while True:
_logging.info("reconnect() - retrying in %s seconds [%s frames in stack]" % (seconds, len(inspect.stack())))
time.sleep(seconds)
reconnector(reconnecting=True)
except KeyboardInterrupt as e:
_logging.info("User exited %s" % (e,))
class Dispatcher(DispatcherBase):
"""
Dispatcher
"""
def read(self, sock, read_callback, check_callback): def read(self, sock, read_callback, check_callback):
while self.app.keep_running: while self.app.keep_running:
sel = selectors.DefaultSelector() sel = selectors.DefaultSelector()
@ -51,14 +78,10 @@ class Dispatcher:
sel.close() sel.close()
class SSLDispatcher: class SSLDispatcher(DispatcherBase):
""" """
SSLDispatcher SSLDispatcher
""" """
def __init__(self, app, ping_timeout):
self.app = app
self.ping_timeout = ping_timeout
def read(self, sock, read_callback, check_callback): def read(self, sock, read_callback, check_callback):
while self.app.keep_running: while self.app.keep_running:
r = self.select() r = self.select()
@ -90,10 +113,17 @@ class WrappedDispatcher:
self.app = app self.app = app
self.ping_timeout = ping_timeout self.ping_timeout = ping_timeout
self.dispatcher = dispatcher self.dispatcher = dispatcher
dispatcher.signal(2, dispatcher.abort) # keyboard interrupt
def read(self, sock, read_callback, check_callback): def read(self, sock, read_callback, check_callback):
self.dispatcher.read(sock, read_callback) self.dispatcher.read(sock, read_callback)
self.ping_timeout and self.dispatcher.timeout(self.ping_timeout, check_callback) self.ping_timeout and self.timeout(self.ping_timeout, check_callback)
def timeout(self, seconds, callback):
self.dispatcher.timeout(seconds, callback)
def reconnect(self, seconds, reconnector):
self.timeout(seconds, reconnector)
class WebSocketApp: class WebSocketApp:
@ -186,6 +216,7 @@ class WebSocketApp:
self.last_pong_tm = 0 self.last_pong_tm = 0
self.subprotocols = subprotocols self.subprotocols = subprotocols
self.prepared_socket = socket self.prepared_socket = socket
self.has_errored = False
def send(self, data, opcode=ABNF.OPCODE_TEXT): def send(self, data, opcode=ABNF.OPCODE_TEXT):
""" """
@ -228,9 +259,10 @@ class WebSocketApp:
ping_payload="", ping_payload="",
http_proxy_host=None, http_proxy_port=None, http_proxy_host=None, http_proxy_port=None,
http_no_proxy=None, http_proxy_auth=None, http_no_proxy=None, http_proxy_auth=None,
http_proxy_timeout=None,
skip_utf8_validation=False, skip_utf8_validation=False,
host=None, origin=None, dispatcher=None, host=None, origin=None, dispatcher=None,
suppress_origin=False, proxy_type=None): suppress_origin=False, proxy_type=None, reconnect=None):
""" """
Run event loop for WebSocket framework. Run event loop for WebSocket framework.
@ -258,6 +290,10 @@ class WebSocketApp:
HTTP proxy port. If not set, set to 80. HTTP proxy port. If not set, set to 80.
http_no_proxy: list http_no_proxy: list
Whitelisted host names that don't use the proxy. Whitelisted host names that don't use the proxy.
http_proxy_timeout: int or float
HTTP proxy timeout, default is 60 sec as per python-socks.
http_proxy_auth: tuple
HTTP proxy auth information. tuple of username and password. Default is None.
skip_utf8_validation: bool skip_utf8_validation: bool
skip utf8 validation. skip utf8 validation.
host: str host: str
@ -268,6 +304,10 @@ class WebSocketApp:
customize reading data from socket. customize reading data from socket.
suppress_origin: bool suppress_origin: bool
suppress outputting origin header. suppress outputting origin header.
proxy_type: str
type of proxy from: http, socks4, socks4a, socks5, socks5h
reconnect: int
delay interval when reconnecting
Returns Returns
------- -------
@ -276,6 +316,9 @@ class WebSocketApp:
True if any other exception was raised during a loop. True if any other exception was raised during a loop.
""" """
if reconnect is None:
reconnect = RECONNECT
if ping_timeout is not None and ping_timeout <= 0: if ping_timeout is not None and ping_timeout <= 0:
raise WebSocketException("Ensure ping_timeout > 0") raise WebSocketException("Ensure ping_timeout > 0")
if ping_interval is not None and ping_interval < 0: if ping_interval is not None and ping_interval < 0:
@ -317,84 +360,105 @@ class WebSocketApp:
# Finally call the callback AFTER all teardown is complete # Finally call the callback AFTER all teardown is complete
self._callback(self.on_close, close_status_code, close_reason) self._callback(self.on_close, close_status_code, close_reason)
try: def setSock(reconnecting=False):
self.sock = WebSocket( self.sock = WebSocket(
self.get_mask_key, sockopt=sockopt, sslopt=sslopt, self.get_mask_key, sockopt=sockopt, sslopt=sslopt,
fire_cont_frame=self.on_cont_message is not None, fire_cont_frame=self.on_cont_message is not None,
skip_utf8_validation=skip_utf8_validation, skip_utf8_validation=skip_utf8_validation,
enable_multithread=True) enable_multithread=True)
self.sock.settimeout(getdefaulttimeout()) self.sock.settimeout(getdefaulttimeout())
self.sock.connect( try:
self.url, header=self.header, cookie=self.cookie, self.sock.connect(
http_proxy_host=http_proxy_host, self.url, header=self.header, cookie=self.cookie,
http_proxy_port=http_proxy_port, http_no_proxy=http_no_proxy, http_proxy_host=http_proxy_host,
http_proxy_auth=http_proxy_auth, subprotocols=self.subprotocols, http_proxy_port=http_proxy_port, http_no_proxy=http_no_proxy,
host=host, origin=origin, suppress_origin=suppress_origin, http_proxy_auth=http_proxy_auth, http_proxy_timeout=http_proxy_timeout,
proxy_type=proxy_type, socket=self.prepared_socket) subprotocols=self.subprotocols,
dispatcher = self.create_dispatcher(ping_timeout, dispatcher) host=host, origin=origin, suppress_origin=suppress_origin,
proxy_type=proxy_type, socket=self.prepared_socket)
self._callback(self.on_open) self._callback(self.on_open)
if ping_interval: _logging.warning("websocket connected")
event = threading.Event() dispatcher.read(self.sock.sock, read, check)
thread = threading.Thread( except (WebSocketConnectionClosedException, ConnectionRefusedError, KeyboardInterrupt, SystemExit, Exception) as e:
target=self._send_ping, args=(ping_interval, event, ping_payload)) _logging.error("%s - %s" % (e, reconnect and "reconnecting" or "goodbye"))
thread.daemon = True reconnecting or handleDisconnect(e)
thread.start()
def read(): def read():
if not self.keep_running: if not self.keep_running:
return teardown() return teardown()
try:
op_code, frame = self.sock.recv_data_frame(True) op_code, frame = self.sock.recv_data_frame(True)
if op_code == ABNF.OPCODE_CLOSE: except (WebSocketConnectionClosedException, KeyboardInterrupt) as e:
return teardown(frame) if custom_dispatcher:
elif op_code == ABNF.OPCODE_PING: return handleDisconnect(e)
self._callback(self.on_ping, frame.data)
elif op_code == ABNF.OPCODE_PONG:
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, frame.data,
frame.opcode, frame.fin)
self._callback(self.on_cont_message,
frame.data, frame.fin)
else: else:
data = frame.data raise e
if op_code == ABNF.OPCODE_TEXT: if op_code == ABNF.OPCODE_CLOSE:
data = data.decode("utf-8") return teardown(frame)
self._callback(self.on_data, data, frame.opcode, True) elif op_code == ABNF.OPCODE_PING:
self._callback(self.on_message, data) self._callback(self.on_ping, frame.data)
elif op_code == ABNF.OPCODE_PONG:
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, frame.data,
frame.opcode, frame.fin)
self._callback(self.on_cont_message,
frame.data, frame.fin)
else:
data = frame.data
if op_code == ABNF.OPCODE_TEXT:
data = data.decode("utf-8")
self._callback(self.on_data, data, frame.opcode, True)
self._callback(self.on_message, data)
return True return True
def check(): def check():
if (ping_timeout): if (ping_timeout):
has_timeout_expired = time.time() - self.last_ping_tm > ping_timeout has_timeout_expired = time.time() - self.last_ping_tm > ping_timeout
has_pong_not_arrived_after_last_ping = self.last_pong_tm - self.last_ping_tm < 0 has_pong_not_arrived_after_last_ping = self.last_pong_tm - self.last_ping_tm < 0
has_pong_arrived_too_late = self.last_pong_tm - self.last_ping_tm > ping_timeout has_pong_arrived_too_late = self.last_pong_tm - self.last_ping_tm > ping_timeout
if (self.last_ping_tm and if (self.last_ping_tm and
has_timeout_expired and has_timeout_expired and
(has_pong_not_arrived_after_last_ping or has_pong_arrived_too_late)): (has_pong_not_arrived_after_last_ping or has_pong_arrived_too_late)):
raise WebSocketTimeoutException("ping/pong timed out") raise WebSocketTimeoutException("ping/pong timed out")
return True return True
dispatcher.read(self.sock.sock, read, check) def handleDisconnect(e):
return False self.has_errored = True
except (Exception, KeyboardInterrupt, SystemExit) as e:
self._callback(self.on_error, e) self._callback(self.on_error, e)
if isinstance(e, SystemExit): if isinstance(e, SystemExit):
# propagate SystemExit further # propagate SystemExit further
raise raise
teardown() if reconnect and not isinstance(e, KeyboardInterrupt):
return not isinstance(e, KeyboardInterrupt) _logging.info("websocket disconnected (retrying in %s seconds) [%s frames in stack]" % (reconnect, len(inspect.stack())))
dispatcher.reconnect(reconnect, setSock)
else:
teardown()
def create_dispatcher(self, ping_timeout, dispatcher=None): custom_dispatcher = bool(dispatcher)
dispatcher = self.create_dispatcher(ping_timeout, dispatcher, parse_url(self.url)[3])
if ping_interval:
event = threading.Event()
thread = threading.Thread(
target=self._send_ping, args=(ping_interval, event, ping_payload))
thread.daemon = True
thread.start()
setSock()
return self.has_errored
def create_dispatcher(self, ping_timeout, dispatcher=None, is_ssl=False):
if dispatcher: # If custom dispatcher is set, use WrappedDispatcher if dispatcher: # If custom dispatcher is set, use WrappedDispatcher
return WrappedDispatcher(self, ping_timeout, dispatcher) return WrappedDispatcher(self, ping_timeout, dispatcher)
timeout = ping_timeout or 10 timeout = ping_timeout or 10
if self.sock.is_ssl(): if is_ssl:
return SSLDispatcher(self, timeout) return SSLDispatcher(self, timeout)
return Dispatcher(self, timeout) return Dispatcher(self, timeout)

View file

@ -46,8 +46,11 @@ class WebSocket:
>>> import websocket >>> import websocket
>>> ws = websocket.WebSocket() >>> ws = websocket.WebSocket()
>>> ws.connect("ws://echo.websocket.org") >>> ws.connect("ws://echo.websocket.events")
>>> ws.recv()
'echo.websocket.events sponsored by Lob.com'
>>> ws.send("Hello, Server") >>> ws.send("Hello, Server")
19
>>> ws.recv() >>> ws.recv()
'Hello, Server' 'Hello, Server'
>>> ws.close() >>> ws.close()
@ -203,7 +206,7 @@ class WebSocket:
If you set "header" list object, you can set your own custom header. If you set "header" list object, you can set your own custom header.
>>> ws = WebSocket() >>> ws = WebSocket()
>>> ws.connect("ws://echo.websocket.org/", >>> ws.connect("ws://echo.websocket.events",
... header=["User-Agent: MyProgram", ... header=["User-Agent: MyProgram",
... "x-custom: header"]) ... "x-custom: header"])
@ -233,6 +236,8 @@ class WebSocket:
Whitelisted host names that don't use the proxy. Whitelisted host names that don't use the proxy.
http_proxy_auth: tuple http_proxy_auth: tuple
HTTP proxy auth information. Tuple of username and password. Default is None. HTTP proxy auth information. Tuple of username and password. Default is None.
http_proxy_timeout: int or float
HTTP proxy timeout, default is 60 sec as per python-socks.
redirect_limit: int redirect_limit: int
Number of redirects to follow. Number of redirects to follow.
subprotocols: list subprotocols: list
@ -281,7 +286,7 @@ class WebSocket:
""" """
Send the data frame. Send the data frame.
>>> ws = create_connection("ws://echo.websocket.org/") >>> ws = create_connection("ws://echo.websocket.events")
>>> frame = ABNF.create_frame("Hello", ABNF.OPCODE_TEXT) >>> frame = ABNF.create_frame("Hello", ABNF.OPCODE_TEXT)
>>> ws.send_frame(frame) >>> ws.send_frame(frame)
>>> cont_frame = ABNF.create_frame("My name is ", ABNF.OPCODE_CONT, 0) >>> cont_frame = ABNF.create_frame("My name is ", ABNF.OPCODE_CONT, 0)
@ -541,7 +546,7 @@ def create_connection(url, timeout=None, class_=WebSocket, **options):
You can customize using 'options'. You can customize using 'options'.
If you set "header" list object, you can set your own custom header. If you set "header" list object, you can set your own custom header.
>>> conn = create_connection("ws://echo.websocket.org/", >>> conn = create_connection("ws://echo.websocket.events",
... header=["User-Agent: MyProgram", ... header=["User-Agent: MyProgram",
... "x-custom: header"]) ... "x-custom: header"])
@ -572,6 +577,8 @@ def create_connection(url, timeout=None, class_=WebSocket, **options):
Whitelisted host names that don't use the proxy. Whitelisted host names that don't use the proxy.
http_proxy_auth: tuple http_proxy_auth: tuple
HTTP proxy auth information. tuple of username and password. Default is None. HTTP proxy auth information. tuple of username and password. Default is None.
http_proxy_timeout: int or float
HTTP proxy timeout, default is 60 sec as per python-socks.
enable_multithread: bool enable_multithread: bool
Enable lock for multithread. Enable lock for multithread.
redirect_limit: int redirect_limit: int

View file

@ -81,7 +81,7 @@ def _get_handshake_headers(resource, url, host, port, options):
hostport = _pack_hostname(host) hostport = _pack_hostname(host)
else: else:
hostport = "%s:%d" % (_pack_hostname(host), port) hostport = "%s:%d" % (_pack_hostname(host), port)
if "host" in options and options["host"] is not None: if options.get("host"):
headers.append("Host: %s" % options["host"]) headers.append("Host: %s" % options["host"])
else: else:
headers.append("Host: %s" % hostport) headers.append("Host: %s" % hostport)
@ -89,7 +89,7 @@ def _get_handshake_headers(resource, url, host, port, options):
# scheme indicates whether http or https is used in Origin # scheme indicates whether http or https is used in Origin
# The same approach is used in parse_url of _url.py to set default port # The same approach is used in parse_url of _url.py to set default port
scheme, url = url.split(":", 1) scheme, url = url.split(":", 1)
if "suppress_origin" not in options or not options["suppress_origin"]: if not options.get("suppress_origin"):
if "origin" in options and options["origin"] is not None: if "origin" in options and options["origin"] is not None:
headers.append("Origin: %s" % options["origin"]) headers.append("Origin: %s" % options["origin"])
elif scheme == "wss": elif scheme == "wss":
@ -100,16 +100,15 @@ def _get_handshake_headers(resource, url, host, port, options):
key = _create_sec_websocket_key() key = _create_sec_websocket_key()
# Append Sec-WebSocket-Key & Sec-WebSocket-Version if not manually specified # Append Sec-WebSocket-Key & Sec-WebSocket-Version if not manually specified
if 'header' not in options or 'Sec-WebSocket-Key' not in options['header']: if not options.get('header') or 'Sec-WebSocket-Key' not in options['header']:
key = _create_sec_websocket_key()
headers.append("Sec-WebSocket-Key: %s" % key) headers.append("Sec-WebSocket-Key: %s" % key)
else: else:
key = options['header']['Sec-WebSocket-Key'] key = options['header']['Sec-WebSocket-Key']
if 'header' not in options or 'Sec-WebSocket-Version' not in options['header']: if not options.get('header') or 'Sec-WebSocket-Version' not in options['header']:
headers.append("Sec-WebSocket-Version: %s" % VERSION) headers.append("Sec-WebSocket-Version: %s" % VERSION)
if 'connection' not in options or options['connection'] is None: if not options.get('connection'):
headers.append('Connection: Upgrade') headers.append('Connection: Upgrade')
else: else:
headers.append(options['connection']) headers.append(options['connection'])
@ -118,8 +117,8 @@ def _get_handshake_headers(resource, url, host, port, options):
if subprotocols: if subprotocols:
headers.append("Sec-WebSocket-Protocol: %s" % ",".join(subprotocols)) headers.append("Sec-WebSocket-Protocol: %s" % ",".join(subprotocols))
if "header" in options: header = options.get("header")
header = options["header"] if header:
if isinstance(header, dict): if isinstance(header, dict):
header = [ header = [
": ".join([k, v]) ": ".join([k, v])

View file

@ -23,7 +23,7 @@ import sys
from ._exceptions import * from ._exceptions import *
from ._logging import * from ._logging import *
from ._socket import* from ._socket import *
from ._ssl_compat import * from ._ssl_compat import *
from ._url import * from ._url import *
@ -59,7 +59,7 @@ class proxy_info:
self.no_proxy = options.get("http_no_proxy", None) self.no_proxy = options.get("http_no_proxy", None)
self.proxy_protocol = options.get("proxy_type", "http") self.proxy_protocol = options.get("proxy_type", "http")
# Note: If timeout not specified, default python-socks timeout is 60 seconds # Note: If timeout not specified, default python-socks timeout is 60 seconds
self.proxy_timeout = options.get("timeout", None) self.proxy_timeout = options.get("http_proxy_timeout", None)
if self.proxy_protocol not in ['http', 'socks4', 'socks4a', 'socks5', 'socks5h']: if self.proxy_protocol not in ['http', 'socks4', 'socks4a', 'socks5', 'socks5h']:
raise ProxyError("Only http, socks4, socks5 proxy protocols are supported") raise ProxyError("Only http, socks4, socks5 proxy protocols are supported")
else: else:
@ -114,22 +114,22 @@ def connect(url, options, proxy, socket):
if proxy.proxy_host and not socket and not (proxy.proxy_protocol == "http"): if proxy.proxy_host and not socket and not (proxy.proxy_protocol == "http"):
return _start_proxied_socket(url, options, proxy) return _start_proxied_socket(url, options, proxy)
hostname, port, resource, is_secure = parse_url(url) hostname, port_from_url, resource, is_secure = parse_url(url)
if socket: if socket:
return socket, (hostname, port, resource) return socket, (hostname, port_from_url, resource)
addrinfo_list, need_tunnel, auth = _get_addrinfo_list( addrinfo_list, need_tunnel, auth = _get_addrinfo_list(
hostname, port, is_secure, proxy) hostname, port_from_url, is_secure, proxy)
if not addrinfo_list: if not addrinfo_list:
raise WebSocketException( raise WebSocketException(
"Host not found.: " + hostname + ":" + str(port)) "Host not found.: " + hostname + ":" + str(port_from_url))
sock = None sock = None
try: try:
sock = _open_socket(addrinfo_list, options.sockopt, options.timeout) sock = _open_socket(addrinfo_list, options.sockopt, options.timeout)
if need_tunnel: if need_tunnel:
sock = _tunnel(sock, hostname, port, auth) sock = _tunnel(sock, hostname, port_from_url, auth)
if is_secure: if is_secure:
if HAVE_SSL: if HAVE_SSL:
@ -137,7 +137,7 @@ def connect(url, options, proxy, socket):
else: else:
raise WebSocketException("SSL not available.") raise WebSocketException("SSL not available.")
return sock, (hostname, port, resource) return sock, (hostname, port_from_url, resource)
except: except:
if sock: if sock:
sock.close() sock.close()
@ -184,17 +184,16 @@ def _open_socket(addrinfo_list, sockopt, timeout):
try: try:
sock.connect(address) sock.connect(address)
except socket.error as error: except socket.error as error:
sock.close()
error.remote_ip = str(address[0]) error.remote_ip = str(address[0])
try: try:
eConnRefused = (errno.ECONNREFUSED, errno.WSAECONNREFUSED, errno.ENETUNREACH) eConnRefused = (errno.ECONNREFUSED, errno.WSAECONNREFUSED, errno.ENETUNREACH)
except: except AttributeError:
eConnRefused = (errno.ECONNREFUSED, errno.ENETUNREACH) eConnRefused = (errno.ECONNREFUSED, errno.ENETUNREACH)
if error.errno in eConnRefused: if error.errno in eConnRefused:
err = error err = error
continue continue
else: else:
if sock:
sock.close()
raise error raise error
else: else:
break break

View file

@ -35,7 +35,7 @@ __all__ = ["enableTrace", "dump", "error", "warning", "debug", "trace",
"isEnabledForError", "isEnabledForDebug", "isEnabledForTrace"] "isEnabledForError", "isEnabledForDebug", "isEnabledForTrace"]
def enableTrace(traceable, handler=logging.StreamHandler()): def enableTrace(traceable, handler=logging.StreamHandler(), level="DEBUG"):
""" """
Turn on/off the traceability. Turn on/off the traceability.
@ -48,7 +48,7 @@ def enableTrace(traceable, handler=logging.StreamHandler()):
_traceEnabled = traceable _traceEnabled = traceable
if traceable: if traceable:
_logger.addHandler(handler) _logger.addHandler(handler)
_logger.setLevel(logging.DEBUG) _logger.setLevel(getattr(logging, level))
def dump(title, message): def dump(title, message):
@ -70,6 +70,10 @@ def debug(msg):
_logger.debug(msg) _logger.debug(msg)
def info(msg):
_logger.info(msg)
def trace(msg): def trace(msg):
if _traceEnabled: if _traceEnabled:
_logger.debug(msg) _logger.debug(msg)

View file

@ -80,7 +80,8 @@ class WebSocketAppTest(unittest.TestCase):
app = ws.WebSocketApp('ws://127.0.0.1:' + LOCAL_WS_SERVER_PORT, on_open=on_open, on_close=on_close, on_message=on_message) app = ws.WebSocketApp('ws://127.0.0.1:' + LOCAL_WS_SERVER_PORT, on_open=on_open, on_close=on_close, on_message=on_message)
app.run_forever() app.run_forever()
@unittest.skipUnless(TEST_WITH_LOCAL_SERVER, "Tests using local websocket server are disabled") # @unittest.skipUnless(TEST_WITH_LOCAL_SERVER, "Tests using local websocket server are disabled")
@unittest.skipUnless(False, "Test disabled for now (requires rel)")
def testRunForeverDispatcher(self): def testRunForeverDispatcher(self):
""" A WebSocketApp should keep running as long as its self.keep_running """ A WebSocketApp should keep running as long as its self.keep_running
is not False (in the boolean context). is not False (in the boolean context).
@ -98,7 +99,9 @@ class WebSocketAppTest(unittest.TestCase):
self.close() self.close()
app = ws.WebSocketApp('ws://127.0.0.1:' + LOCAL_WS_SERVER_PORT, on_open=on_open, on_message=on_message) app = ws.WebSocketApp('ws://127.0.0.1:' + LOCAL_WS_SERVER_PORT, on_open=on_open, on_message=on_message)
app.run_forever(dispatcher="Dispatcher") app.run_forever(dispatcher="Dispatcher") # doesn't work
# app.run_forever(dispatcher=rel) # would work
# rel.dispatch()
@unittest.skipUnless(TEST_WITH_LOCAL_SERVER, "Tests using local websocket server are disabled") @unittest.skipUnless(TEST_WITH_LOCAL_SERVER, "Tests using local websocket server are disabled")
def testRunForeverTeardownCleanExit(self): def testRunForeverTeardownCleanExit(self):
@ -188,7 +191,7 @@ class WebSocketAppTest(unittest.TestCase):
""" Test WebSocketApp binary opcode """ Test WebSocketApp binary opcode
""" """
# The lack of wss:// in the URL below is on purpose # The lack of wss:// in the URL below is on purpose
app = ws.WebSocketApp('streaming.vn.teslamotors.com/streaming/') app = ws.WebSocketApp('wss://streaming.vn.teslamotors.com/streaming/')
app.run_forever(ping_interval=2, ping_timeout=1, ping_payload="Ping payload") app.run_forever(ping_interval=2, ping_timeout=1, ping_payload="Ping payload")
@unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled") @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")

View file

@ -105,15 +105,15 @@ class HttpTest(unittest.TestCase):
if ws._http.HAVE_PYTHON_SOCKS: if ws._http.HAVE_PYTHON_SOCKS:
# Need this check, otherwise case where python_socks is not installed triggers # Need this check, otherwise case where python_socks is not installed triggers
# websocket._exceptions.WebSocketException: Python Socks is needed for SOCKS proxying but is not available # websocket._exceptions.WebSocketException: Python Socks is needed for SOCKS proxying but is not available
self.assertRaises((ProxyTimeoutError, OSError), _start_proxied_socket, "wss://example.com", OptsList(), proxy_info(http_proxy_host="example.com", http_proxy_port="8080", proxy_type="socks4", timeout=1)) self.assertRaises((ProxyTimeoutError, OSError), _start_proxied_socket, "wss://example.com", OptsList(), proxy_info(http_proxy_host="example.com", http_proxy_port="8080", proxy_type="socks4", http_proxy_timeout=1))
self.assertRaises((ProxyTimeoutError, OSError), _start_proxied_socket, "wss://example.com", OptsList(), proxy_info(http_proxy_host="example.com", http_proxy_port="8080", proxy_type="socks4a", timeout=1)) self.assertRaises((ProxyTimeoutError, OSError), _start_proxied_socket, "wss://example.com", OptsList(), proxy_info(http_proxy_host="example.com", http_proxy_port="8080", proxy_type="socks4a", http_proxy_timeout=1))
self.assertRaises((ProxyTimeoutError, OSError), _start_proxied_socket, "wss://example.com", OptsList(), proxy_info(http_proxy_host="example.com", http_proxy_port="8080", proxy_type="socks5", timeout=1)) self.assertRaises((ProxyTimeoutError, OSError), _start_proxied_socket, "wss://example.com", OptsList(), proxy_info(http_proxy_host="example.com", http_proxy_port="8080", proxy_type="socks5", http_proxy_timeout=1))
self.assertRaises((ProxyTimeoutError, OSError), _start_proxied_socket, "wss://example.com", OptsList(), proxy_info(http_proxy_host="example.com", http_proxy_port="8080", proxy_type="socks5h", timeout=1)) self.assertRaises((ProxyTimeoutError, OSError), _start_proxied_socket, "wss://example.com", OptsList(), proxy_info(http_proxy_host="example.com", http_proxy_port="8080", proxy_type="socks5h", http_proxy_timeout=1))
self.assertRaises(ProxyConnectionError, connect, "wss://example.com", OptsList(), proxy_info(http_proxy_host="127.0.0.1", http_proxy_port=9999, proxy_type="socks4", timeout=1), None) self.assertRaises(ProxyConnectionError, connect, "wss://example.com", OptsList(), proxy_info(http_proxy_host="127.0.0.1", http_proxy_port=9999, proxy_type="socks4", http_proxy_timeout=1), None)
self.assertRaises(TypeError, _get_addrinfo_list, None, 80, True, proxy_info(http_proxy_host="127.0.0.1", http_proxy_port="9999", proxy_type="http")) self.assertRaises(TypeError, _get_addrinfo_list, None, 80, True, proxy_info(http_proxy_host="127.0.0.1", http_proxy_port="9999", proxy_type="http"))
self.assertRaises(TypeError, _get_addrinfo_list, None, 80, True, proxy_info(http_proxy_host="127.0.0.1", http_proxy_port="9999", proxy_type="http")) self.assertRaises(TypeError, _get_addrinfo_list, None, 80, True, proxy_info(http_proxy_host="127.0.0.1", http_proxy_port="9999", proxy_type="http"))
self.assertRaises(socket.timeout, connect, "wss://google.com", OptsList(), proxy_info(http_proxy_host="8.8.8.8", http_proxy_port=9999, proxy_type="http", timeout=1), None) self.assertRaises(socket.timeout, connect, "wss://google.com", OptsList(), proxy_info(http_proxy_host="8.8.8.8", http_proxy_port=9999, proxy_type="http", http_proxy_timeout=1), None)
self.assertEqual( self.assertEqual(
connect("wss://google.com", OptsList(), proxy_info(http_proxy_host="8.8.8.8", http_proxy_port=8080, proxy_type="http"), True), connect("wss://google.com", OptsList(), proxy_info(http_proxy_host="8.8.8.8", http_proxy_port=8080, proxy_type="http"), True),
(True, ("google.com", 443, "/"))) (True, ("google.com", 443, "/")))

View file

@ -432,7 +432,7 @@ class HandshakeTest(unittest.TestCase):
self.assertRaises(ws._exceptions.WebSocketBadStatusException, self.assertRaises(ws._exceptions.WebSocketBadStatusException,
websock3.connect, "wss://api.bitfinex.com/ws/2", cookie="chocolate", websock3.connect, "wss://api.bitfinex.com/ws/2", cookie="chocolate",
origin="testing_websockets.com", origin="testing_websockets.com",
host="echo.websocket.org/websocket-client-test", host="echo.websocket.events/websocket-client-test",
subprotocols=["testproto"], subprotocols=["testproto"],
connection="Upgrade", connection="Upgrade",
header={"CustomHeader1":"123", header={"CustomHeader1":"123",

View file

@ -47,7 +47,7 @@ tzdata==2022.6
tzlocal==4.2 tzlocal==4.2
urllib3==1.26.12 urllib3==1.26.12
webencodings==0.5.1 webencodings==0.5.1
websocket-client==1.3.2 websocket-client==1.4.2
xmltodict==0.13.0 xmltodict==0.13.0
zipp==3.10.0 zipp==3.10.0