mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-07 13:41:15 -07:00
Bump websocket-client from 1.2.3 to 1.3.2 (#1700)
* Bump websocket-client from 1.2.3 to 1.3.2 Bumps [websocket-client](https://github.com/websocket-client/websocket-client) from 1.2.3 to 1.3.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.2.3...v1.3.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.3.2 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:
parent
67baf9a260
commit
d510e0f600
22 changed files with 251 additions and 205 deletions
|
@ -2,7 +2,7 @@
|
||||||
__init__.py
|
__init__.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -23,4 +23,4 @@ from ._exceptions import *
|
||||||
from ._logging import *
|
from ._logging import *
|
||||||
from ._socket import *
|
from ._socket import *
|
||||||
|
|
||||||
__version__ = "1.2.3"
|
__version__ = "1.3.2"
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
"""
|
import array
|
||||||
|
import os
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
|
||||||
"""
|
from ._exceptions import *
|
||||||
|
from ._utils import validate_utf8
|
||||||
|
from threading import Lock
|
||||||
|
|
||||||
"""
|
"""
|
||||||
_abnf.py
|
_abnf.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -20,14 +25,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
import array
|
|
||||||
import os
|
|
||||||
import struct
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from ._exceptions import *
|
|
||||||
from ._utils import validate_utf8
|
|
||||||
from threading import Lock
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# If wsaccel is available, use compiled routines to mask data.
|
# If wsaccel is available, use compiled routines to mask data.
|
||||||
|
@ -79,6 +76,8 @@ STATUS_POLICY_VIOLATION = 1008
|
||||||
STATUS_MESSAGE_TOO_BIG = 1009
|
STATUS_MESSAGE_TOO_BIG = 1009
|
||||||
STATUS_INVALID_EXTENSION = 1010
|
STATUS_INVALID_EXTENSION = 1010
|
||||||
STATUS_UNEXPECTED_CONDITION = 1011
|
STATUS_UNEXPECTED_CONDITION = 1011
|
||||||
|
STATUS_SERVICE_RESTART = 1012
|
||||||
|
STATUS_TRY_AGAIN_LATER = 1013
|
||||||
STATUS_BAD_GATEWAY = 1014
|
STATUS_BAD_GATEWAY = 1014
|
||||||
STATUS_TLS_HANDSHAKE_ERROR = 1015
|
STATUS_TLS_HANDSHAKE_ERROR = 1015
|
||||||
|
|
||||||
|
@ -92,6 +91,8 @@ VALID_CLOSE_STATUS = (
|
||||||
STATUS_MESSAGE_TOO_BIG,
|
STATUS_MESSAGE_TOO_BIG,
|
||||||
STATUS_INVALID_EXTENSION,
|
STATUS_INVALID_EXTENSION,
|
||||||
STATUS_UNEXPECTED_CONDITION,
|
STATUS_UNEXPECTED_CONDITION,
|
||||||
|
STATUS_SERVICE_RESTART,
|
||||||
|
STATUS_TRY_AGAIN_LATER,
|
||||||
STATUS_BAD_GATEWAY,
|
STATUS_BAD_GATEWAY,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -146,7 +147,7 @@ class ABNF:
|
||||||
self.data = data
|
self.data = data
|
||||||
self.get_mask_key = os.urandom
|
self.get_mask_key = os.urandom
|
||||||
|
|
||||||
def validate(self, skip_utf8_validation=False):
|
def validate(self, skip_utf8_validation=False) -> None:
|
||||||
"""
|
"""
|
||||||
Validate the ABNF frame.
|
Validate the ABNF frame.
|
||||||
|
|
||||||
|
@ -174,13 +175,13 @@ class ABNF:
|
||||||
|
|
||||||
code = 256 * self.data[0] + self.data[1]
|
code = 256 * self.data[0] + self.data[1]
|
||||||
if not self._is_valid_close_status(code):
|
if not self._is_valid_close_status(code):
|
||||||
raise WebSocketProtocolException("Invalid close opcode.")
|
raise WebSocketProtocolException("Invalid close opcode %r", code)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _is_valid_close_status(code):
|
def _is_valid_close_status(code: int) -> bool:
|
||||||
return code in VALID_CLOSE_STATUS or (3000 <= code < 5000)
|
return code in VALID_CLOSE_STATUS or (3000 <= code < 5000)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self) -> str:
|
||||||
return "fin=" + str(self.fin) \
|
return "fin=" + str(self.fin) \
|
||||||
+ " opcode=" + str(self.opcode) \
|
+ " opcode=" + str(self.opcode) \
|
||||||
+ " data=" + str(self.data)
|
+ " data=" + str(self.data)
|
||||||
|
@ -206,7 +207,7 @@ class ABNF:
|
||||||
# mask must be set if send data from client
|
# mask must be set if send data from client
|
||||||
return ABNF(fin, 0, 0, 0, opcode, 1, data)
|
return ABNF(fin, 0, 0, 0, opcode, 1, data)
|
||||||
|
|
||||||
def format(self):
|
def format(self) -> bytes:
|
||||||
"""
|
"""
|
||||||
Format this object to string(byte array) to send data to server.
|
Format this object to string(byte array) to send data to server.
|
||||||
"""
|
"""
|
||||||
|
@ -251,9 +252,9 @@ class ABNF:
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
mask_key: <type>
|
mask_key: bytes or str
|
||||||
4 byte string.
|
4 byte mask.
|
||||||
data: <type>
|
data: bytes or str
|
||||||
data to mask/unmask.
|
data to mask/unmask.
|
||||||
"""
|
"""
|
||||||
if data is None:
|
if data is None:
|
||||||
|
@ -286,7 +287,7 @@ class frame_buffer:
|
||||||
self.length = None
|
self.length = None
|
||||||
self.mask = None
|
self.mask = None
|
||||||
|
|
||||||
def has_received_header(self):
|
def has_received_header(self) -> bool:
|
||||||
return self.header is None
|
return self.header is None
|
||||||
|
|
||||||
def recv_header(self):
|
def recv_header(self):
|
||||||
|
@ -308,7 +309,7 @@ class frame_buffer:
|
||||||
return False
|
return False
|
||||||
return self.header[frame_buffer._HEADER_MASK_INDEX]
|
return self.header[frame_buffer._HEADER_MASK_INDEX]
|
||||||
|
|
||||||
def has_received_length(self):
|
def has_received_length(self) -> bool:
|
||||||
return self.length is None
|
return self.length is None
|
||||||
|
|
||||||
def recv_length(self):
|
def recv_length(self):
|
||||||
|
@ -323,7 +324,7 @@ class frame_buffer:
|
||||||
else:
|
else:
|
||||||
self.length = length_bits
|
self.length = length_bits
|
||||||
|
|
||||||
def has_received_mask(self):
|
def has_received_mask(self) -> bool:
|
||||||
return self.mask is None
|
return self.mask is None
|
||||||
|
|
||||||
def recv_mask(self):
|
def recv_mask(self):
|
||||||
|
@ -360,7 +361,7 @@ class frame_buffer:
|
||||||
|
|
||||||
return frame
|
return frame
|
||||||
|
|
||||||
def recv_strict(self, bufsize):
|
def recv_strict(self, bufsize: int) -> bytes:
|
||||||
shortage = bufsize - sum(map(len, self.recv_buffer))
|
shortage = bufsize - sum(map(len, self.recv_buffer))
|
||||||
while shortage > 0:
|
while shortage > 0:
|
||||||
# Limit buffer size that we pass to socket.recv() to avoid
|
# Limit buffer size that we pass to socket.recv() to avoid
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
"""
|
import selectors
|
||||||
|
import sys
|
||||||
"""
|
import threading
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
from ._abnf import ABNF
|
||||||
|
from ._core import WebSocket, getdefaulttimeout
|
||||||
|
from ._exceptions import *
|
||||||
|
from . import _logging
|
||||||
|
|
||||||
"""
|
"""
|
||||||
_app.py
|
_app.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -20,16 +26,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
import selectors
|
|
||||||
import sys
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
import traceback
|
|
||||||
from ._abnf import ABNF
|
|
||||||
from ._core import WebSocket, getdefaulttimeout
|
|
||||||
from ._exceptions import *
|
|
||||||
from . import _logging
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["WebSocketApp"]
|
__all__ = ["WebSocketApp"]
|
||||||
|
|
||||||
|
@ -86,6 +82,20 @@ class SSLDispatcher:
|
||||||
return r[0][0]
|
return r[0][0]
|
||||||
|
|
||||||
|
|
||||||
|
class WrappedDispatcher:
|
||||||
|
"""
|
||||||
|
WrappedDispatcher
|
||||||
|
"""
|
||||||
|
def __init__(self, app, ping_timeout, dispatcher):
|
||||||
|
self.app = app
|
||||||
|
self.ping_timeout = ping_timeout
|
||||||
|
self.dispatcher = dispatcher
|
||||||
|
|
||||||
|
def read(self, sock, read_callback, check_callback):
|
||||||
|
self.dispatcher.read(sock, read_callback)
|
||||||
|
self.ping_timeout and self.dispatcher.timeout(self.ping_timeout, check_callback)
|
||||||
|
|
||||||
|
|
||||||
class WebSocketApp:
|
class WebSocketApp:
|
||||||
"""
|
"""
|
||||||
Higher level of APIs are provided. The interface is like JavaScript WebSocket object.
|
Higher level of APIs are provided. The interface is like JavaScript WebSocket object.
|
||||||
|
@ -97,7 +107,8 @@ class WebSocketApp:
|
||||||
on_cont_message=None,
|
on_cont_message=None,
|
||||||
keep_running=True, get_mask_key=None, cookie=None,
|
keep_running=True, get_mask_key=None, cookie=None,
|
||||||
subprotocols=None,
|
subprotocols=None,
|
||||||
on_data=None):
|
on_data=None,
|
||||||
|
socket=None):
|
||||||
"""
|
"""
|
||||||
WebSocketApp initialization
|
WebSocketApp initialization
|
||||||
|
|
||||||
|
@ -153,6 +164,8 @@ class WebSocketApp:
|
||||||
Cookie value.
|
Cookie value.
|
||||||
subprotocols: list
|
subprotocols: list
|
||||||
List of available sub protocols. Default is None.
|
List of available sub protocols. Default is None.
|
||||||
|
socket: socket
|
||||||
|
Pre-initialized stream socket.
|
||||||
"""
|
"""
|
||||||
self.url = url
|
self.url = url
|
||||||
self.header = header if header is not None else []
|
self.header = header if header is not None else []
|
||||||
|
@ -172,6 +185,7 @@ class WebSocketApp:
|
||||||
self.last_ping_tm = 0
|
self.last_ping_tm = 0
|
||||||
self.last_pong_tm = 0
|
self.last_pong_tm = 0
|
||||||
self.subprotocols = subprotocols
|
self.subprotocols = subprotocols
|
||||||
|
self.prepared_socket = socket
|
||||||
|
|
||||||
def send(self, data, opcode=ABNF.OPCODE_TEXT):
|
def send(self, data, opcode=ABNF.OPCODE_TEXT):
|
||||||
"""
|
"""
|
||||||
|
@ -258,7 +272,8 @@ class WebSocketApp:
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
teardown: bool
|
teardown: bool
|
||||||
False if caught KeyboardInterrupt, True if other exception was raised during a loop
|
False if the `WebSocketApp` is closed or caught KeyboardInterrupt,
|
||||||
|
True if any other exception was raised during a loop.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if ping_timeout is not None and ping_timeout <= 0:
|
if ping_timeout is not None and ping_timeout <= 0:
|
||||||
|
@ -315,9 +330,8 @@ class WebSocketApp:
|
||||||
http_proxy_port=http_proxy_port, http_no_proxy=http_no_proxy,
|
http_proxy_port=http_proxy_port, http_no_proxy=http_no_proxy,
|
||||||
http_proxy_auth=http_proxy_auth, subprotocols=self.subprotocols,
|
http_proxy_auth=http_proxy_auth, subprotocols=self.subprotocols,
|
||||||
host=host, origin=origin, suppress_origin=suppress_origin,
|
host=host, origin=origin, suppress_origin=suppress_origin,
|
||||||
proxy_type=proxy_type)
|
proxy_type=proxy_type, socket=self.prepared_socket)
|
||||||
if not dispatcher:
|
dispatcher = self.create_dispatcher(ping_timeout, dispatcher)
|
||||||
dispatcher = self.create_dispatcher(ping_timeout)
|
|
||||||
|
|
||||||
self._callback(self.on_open)
|
self._callback(self.on_open)
|
||||||
|
|
||||||
|
@ -367,6 +381,7 @@ class WebSocketApp:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
dispatcher.read(self.sock.sock, read, check)
|
dispatcher.read(self.sock.sock, read, check)
|
||||||
|
return False
|
||||||
except (Exception, KeyboardInterrupt, SystemExit) as e:
|
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):
|
||||||
|
@ -375,7 +390,9 @@ class WebSocketApp:
|
||||||
teardown()
|
teardown()
|
||||||
return not isinstance(e, KeyboardInterrupt)
|
return not isinstance(e, KeyboardInterrupt)
|
||||||
|
|
||||||
def create_dispatcher(self, ping_timeout):
|
def create_dispatcher(self, ping_timeout, dispatcher=None):
|
||||||
|
if dispatcher: # If custom dispatcher is set, use WrappedDispatcher
|
||||||
|
return WrappedDispatcher(self, ping_timeout, dispatcher)
|
||||||
timeout = ping_timeout or 10
|
timeout = ping_timeout or 10
|
||||||
if self.sock.is_ssl():
|
if self.sock.is_ssl():
|
||||||
return SSLDispatcher(self, timeout)
|
return SSLDispatcher(self, timeout)
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
"""
|
import http.cookies
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
_cookiejar.py
|
_cookiejar.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -20,7 +18,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
import http.cookies
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleCookieJar:
|
class SimpleCookieJar:
|
||||||
|
|
|
@ -1,27 +1,3 @@
|
||||||
"""
|
|
||||||
_core.py
|
|
||||||
====================================
|
|
||||||
WebSocket Python client
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
_core.py
|
|
||||||
websocket - WebSocket client library for Python
|
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
"""
|
|
||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
import threading
|
import threading
|
||||||
|
@ -37,6 +13,25 @@ from ._socket import *
|
||||||
from ._ssl_compat import *
|
from ._ssl_compat import *
|
||||||
from ._utils import *
|
from ._utils import *
|
||||||
|
|
||||||
|
"""
|
||||||
|
_core.py
|
||||||
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
"""
|
||||||
|
|
||||||
__all__ = ['WebSocket', 'create_connection']
|
__all__ = ['WebSocket', 'create_connection']
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,14 +245,14 @@ class WebSocket:
|
||||||
options.pop('socket', None))
|
options.pop('socket', None))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.handshake_response = handshake(self.sock, *addrs, **options)
|
self.handshake_response = handshake(self.sock, url, *addrs, **options)
|
||||||
for attempt in range(options.pop('redirect_limit', 3)):
|
for attempt in range(options.pop('redirect_limit', 3)):
|
||||||
if self.handshake_response.status in SUPPORTED_REDIRECT_STATUSES:
|
if self.handshake_response.status in SUPPORTED_REDIRECT_STATUSES:
|
||||||
url = self.handshake_response.headers['location']
|
url = self.handshake_response.headers['location']
|
||||||
self.sock.close()
|
self.sock.close()
|
||||||
self.sock, addrs = connect(url, self.sock_opt, proxy_info(**options),
|
self.sock, addrs = connect(url, self.sock_opt, proxy_info(**options),
|
||||||
options.pop('socket', None))
|
options.pop('socket', None))
|
||||||
self.handshake_response = handshake(self.sock, *addrs, **options)
|
self.handshake_response = handshake(self.sock, url, *addrs, **options)
|
||||||
self.connected = True
|
self.connected = True
|
||||||
except:
|
except:
|
||||||
if self.sock:
|
if self.sock:
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
"""
|
|
||||||
Define WebSocket exceptions
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
_exceptions.py
|
_exceptions.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
_handshake.py
|
_handshake.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -47,8 +47,8 @@ class handshake_response:
|
||||||
CookieJar.add(headers.get("set-cookie"))
|
CookieJar.add(headers.get("set-cookie"))
|
||||||
|
|
||||||
|
|
||||||
def handshake(sock, hostname, port, resource, **options):
|
def handshake(sock, url, hostname, port, resource, **options):
|
||||||
headers, key = _get_handshake_headers(resource, hostname, port, options)
|
headers, key = _get_handshake_headers(resource, url, hostname, port, options)
|
||||||
|
|
||||||
header_str = "\r\n".join(headers)
|
header_str = "\r\n".join(headers)
|
||||||
send(sock, header_str)
|
send(sock, header_str)
|
||||||
|
@ -72,7 +72,7 @@ def _pack_hostname(hostname):
|
||||||
return hostname
|
return hostname
|
||||||
|
|
||||||
|
|
||||||
def _get_handshake_headers(resource, host, port, options):
|
def _get_handshake_headers(resource, url, host, port, options):
|
||||||
headers = [
|
headers = [
|
||||||
"GET %s HTTP/1.1" % resource,
|
"GET %s HTTP/1.1" % resource,
|
||||||
"Upgrade: websocket"
|
"Upgrade: websocket"
|
||||||
|
@ -86,9 +86,14 @@ def _get_handshake_headers(resource, host, port, options):
|
||||||
else:
|
else:
|
||||||
headers.append("Host: %s" % hostport)
|
headers.append("Host: %s" % hostport)
|
||||||
|
|
||||||
|
# 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
|
||||||
|
scheme, url = url.split(":", 1)
|
||||||
if "suppress_origin" not in options or not options["suppress_origin"]:
|
if "suppress_origin" not in options or not options["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":
|
||||||
|
headers.append("Origin: https://%s" % hostport)
|
||||||
else:
|
else:
|
||||||
headers.append("Origin: http://%s" % hostport)
|
headers.append("Origin: http://%s" % hostport)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
_http.py
|
_http.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -186,12 +186,10 @@ def _open_socket(addrinfo_list, sockopt, timeout):
|
||||||
except socket.error as error:
|
except socket.error as error:
|
||||||
error.remote_ip = str(address[0])
|
error.remote_ip = str(address[0])
|
||||||
try:
|
try:
|
||||||
eConnRefused = (errno.ECONNREFUSED, errno.WSAECONNREFUSED)
|
eConnRefused = (errno.ECONNREFUSED, errno.WSAECONNREFUSED, errno.ENETUNREACH)
|
||||||
except:
|
except:
|
||||||
eConnRefused = (errno.ECONNREFUSED, )
|
eConnRefused = (errno.ECONNREFUSED, errno.ENETUNREACH)
|
||||||
if error.errno == errno.EINTR:
|
if error.errno in eConnRefused:
|
||||||
continue
|
|
||||||
elif error.errno in eConnRefused:
|
|
||||||
err = error
|
err = error
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
"""
|
import logging
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
_logging.py
|
_logging.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -20,7 +18,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
import logging
|
|
||||||
|
|
||||||
_logger = logging.getLogger('websocket')
|
_logger = logging.getLogger('websocket')
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
"""
|
import errno
|
||||||
|
import selectors
|
||||||
|
import socket
|
||||||
|
|
||||||
"""
|
from ._exceptions import *
|
||||||
|
from ._ssl_compat import *
|
||||||
|
from ._utils import *
|
||||||
|
|
||||||
"""
|
"""
|
||||||
_socket.py
|
_socket.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -20,13 +24,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
import errno
|
|
||||||
import selectors
|
|
||||||
import socket
|
|
||||||
|
|
||||||
from ._exceptions import *
|
|
||||||
from ._ssl_compat import *
|
|
||||||
from ._utils import *
|
|
||||||
|
|
||||||
DEFAULT_SOCKET_OPTION = [(socket.SOL_TCP, socket.TCP_NODELAY, 1)]
|
DEFAULT_SOCKET_OPTION = [(socket.SOL_TCP, socket.TCP_NODELAY, 1)]
|
||||||
if hasattr(socket, "SO_KEEPALIVE"):
|
if hasattr(socket, "SO_KEEPALIVE"):
|
||||||
|
@ -92,9 +89,7 @@ def recv(sock, bufsize):
|
||||||
pass
|
pass
|
||||||
except socket.error as exc:
|
except socket.error as exc:
|
||||||
error_code = extract_error_code(exc)
|
error_code = extract_error_code(exc)
|
||||||
if error_code is None:
|
if error_code != errno.EAGAIN and error_code != errno.EWOULDBLOCK:
|
||||||
raise
|
|
||||||
if error_code != errno.EAGAIN or error_code != errno.EWOULDBLOCK:
|
|
||||||
raise
|
raise
|
||||||
|
|
||||||
sel = selectors.DefaultSelector()
|
sel = selectors.DefaultSelector()
|
||||||
|
@ -111,6 +106,8 @@ def recv(sock, bufsize):
|
||||||
bytes_ = sock.recv(bufsize)
|
bytes_ = sock.recv(bufsize)
|
||||||
else:
|
else:
|
||||||
bytes_ = _recv()
|
bytes_ = _recv()
|
||||||
|
except TimeoutError:
|
||||||
|
raise WebSocketTimeoutException("Connection timed out")
|
||||||
except socket.timeout as e:
|
except socket.timeout as e:
|
||||||
message = extract_err_message(e)
|
message = extract_err_message(e)
|
||||||
raise WebSocketTimeoutException(message)
|
raise WebSocketTimeoutException(message)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
_ssl_compat.py
|
_ssl_compat.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
"""
|
import os
|
||||||
|
import socket
|
||||||
|
import struct
|
||||||
|
|
||||||
|
from urllib.parse import unquote, urlparse
|
||||||
|
|
||||||
"""
|
|
||||||
"""
|
"""
|
||||||
_url.py
|
_url.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -20,13 +23,6 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import socket
|
|
||||||
import struct
|
|
||||||
|
|
||||||
from urllib.parse import unquote, urlparse
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["parse_url", "get_proxy_info"]
|
__all__ = ["parse_url", "get_proxy_info"]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
_url.py
|
_url.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
wsdump.py
|
wsdump.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -64,7 +64,7 @@ class VAction(argparse.Action):
|
||||||
def parse_args():
|
def parse_args():
|
||||||
parser = argparse.ArgumentParser(description="WebSocket Simple Dump Tool")
|
parser = argparse.ArgumentParser(description="WebSocket Simple Dump Tool")
|
||||||
parser.add_argument("url", metavar="ws_url",
|
parser.add_argument("url", metavar="ws_url",
|
||||||
help="websocket url. ex. ws://echo.websocket.org/")
|
help="websocket url. ex. ws://echo.websocket.events/")
|
||||||
parser.add_argument("-p", "--proxy",
|
parser.add_argument("-p", "--proxy",
|
||||||
help="proxy url. ex. http://127.0.0.1:8080")
|
help="proxy url. ex. http://127.0.0.1:8080")
|
||||||
parser.add_argument("-v", "--verbose", default=0, nargs='?', action=VAction,
|
parser.add_argument("-v", "--verbose", default=0, nargs='?', action=VAction,
|
||||||
|
|
|
@ -3,5 +3,6 @@ Connection: Upgrade, Keep-Alive
|
||||||
Upgrade: WebSocket
|
Upgrade: WebSocket
|
||||||
Sec-WebSocket-Accept: Kxep+hNu9n51529fGidYu7a3wO0=
|
Sec-WebSocket-Accept: Kxep+hNu9n51529fGidYu7a3wO0=
|
||||||
Set-Cookie: Token=ABCDE
|
Set-Cookie: Token=ABCDE
|
||||||
|
Set-Cookie: Token=FGHIJ
|
||||||
some_header: something
|
some_header: something
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
import websocket as ws
|
||||||
|
from websocket._abnf import *
|
||||||
|
import unittest
|
||||||
|
|
||||||
"""
|
"""
|
||||||
test_abnf.py
|
test_abnf.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -19,10 +23,6 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import websocket as ws
|
|
||||||
from websocket._abnf import *
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
|
|
||||||
class ABNFTest(unittest.TestCase):
|
class ABNFTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
import threading
|
||||||
|
import websocket as ws
|
||||||
|
import ssl
|
||||||
|
import unittest
|
||||||
|
|
||||||
"""
|
"""
|
||||||
test_app.py
|
test_app.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -19,12 +26,6 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import os.path
|
|
||||||
import websocket as ws
|
|
||||||
import ssl
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
# Skip test to access the internet unless TEST_WITH_INTERNET == 1
|
# Skip test to access the internet unless TEST_WITH_INTERNET == 1
|
||||||
TEST_WITH_INTERNET = os.environ.get('TEST_WITH_INTERNET', '0') == '1'
|
TEST_WITH_INTERNET = os.environ.get('TEST_WITH_INTERNET', '0') == '1'
|
||||||
# Skip tests relying on local websockets server unless LOCAL_WS_SERVER_PORT != -1
|
# Skip tests relying on local websockets server unless LOCAL_WS_SERVER_PORT != -1
|
||||||
|
@ -45,11 +46,13 @@ class WebSocketAppTest(unittest.TestCase):
|
||||||
WebSocketAppTest.keep_running_open = WebSocketAppTest.NotSetYet()
|
WebSocketAppTest.keep_running_open = WebSocketAppTest.NotSetYet()
|
||||||
WebSocketAppTest.keep_running_close = WebSocketAppTest.NotSetYet()
|
WebSocketAppTest.keep_running_close = WebSocketAppTest.NotSetYet()
|
||||||
WebSocketAppTest.get_mask_key_id = WebSocketAppTest.NotSetYet()
|
WebSocketAppTest.get_mask_key_id = WebSocketAppTest.NotSetYet()
|
||||||
|
WebSocketAppTest.on_error_data = WebSocketAppTest.NotSetYet()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
WebSocketAppTest.keep_running_open = WebSocketAppTest.NotSetYet()
|
WebSocketAppTest.keep_running_open = WebSocketAppTest.NotSetYet()
|
||||||
WebSocketAppTest.keep_running_close = WebSocketAppTest.NotSetYet()
|
WebSocketAppTest.keep_running_close = WebSocketAppTest.NotSetYet()
|
||||||
WebSocketAppTest.get_mask_key_id = WebSocketAppTest.NotSetYet()
|
WebSocketAppTest.get_mask_key_id = WebSocketAppTest.NotSetYet()
|
||||||
|
WebSocketAppTest.on_error_data = WebSocketAppTest.NotSetYet()
|
||||||
|
|
||||||
@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 testKeepRunning(self):
|
def testKeepRunning(self):
|
||||||
|
@ -77,6 +80,54 @@ 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")
|
||||||
|
def testRunForeverDispatcher(self):
|
||||||
|
""" A WebSocketApp should keep running as long as its self.keep_running
|
||||||
|
is not False (in the boolean context).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def on_open(self, *args, **kwargs):
|
||||||
|
""" Send a message, receive, and send one more
|
||||||
|
"""
|
||||||
|
self.send("hello!")
|
||||||
|
self.recv()
|
||||||
|
self.send("goodbye!")
|
||||||
|
|
||||||
|
def on_message(wsapp, message):
|
||||||
|
print(message)
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
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")
|
||||||
|
|
||||||
|
@unittest.skipUnless(TEST_WITH_LOCAL_SERVER, "Tests using local websocket server are disabled")
|
||||||
|
def testRunForeverTeardownCleanExit(self):
|
||||||
|
""" The WebSocketApp.run_forever() method should return `False` when the application ends gracefully.
|
||||||
|
"""
|
||||||
|
app = ws.WebSocketApp('ws://127.0.0.1:' + LOCAL_WS_SERVER_PORT)
|
||||||
|
threading.Timer(interval=0.2, function=app.close).start()
|
||||||
|
teardown = app.run_forever()
|
||||||
|
self.assertEqual(teardown, False)
|
||||||
|
|
||||||
|
@unittest.skipUnless(TEST_WITH_LOCAL_SERVER, "Tests using local websocket server are disabled")
|
||||||
|
def testRunForeverTeardownExceptionalExit(self):
|
||||||
|
""" The WebSocketApp.run_forever() method should return `True` when the application ends with an exception.
|
||||||
|
It should also invoke the `on_error` callback before exiting.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def break_it():
|
||||||
|
# Deliberately break the WebSocketApp by closing the inner socket.
|
||||||
|
app.sock.close()
|
||||||
|
|
||||||
|
def on_error(_, err):
|
||||||
|
WebSocketAppTest.on_error_data = str(err)
|
||||||
|
|
||||||
|
app = ws.WebSocketApp('ws://127.0.0.1:' + LOCAL_WS_SERVER_PORT, on_error=on_error)
|
||||||
|
threading.Timer(interval=0.2, function=break_it).start()
|
||||||
|
teardown = app.run_forever(ping_timeout=0.1)
|
||||||
|
self.assertEqual(teardown, True)
|
||||||
|
self.assertTrue(len(WebSocketAppTest.on_error_data) > 0)
|
||||||
|
|
||||||
@unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
|
@unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
|
||||||
def testSockMaskKey(self):
|
def testSockMaskKey(self):
|
||||||
""" A WebSocketApp should forward the received mask_key function down
|
""" A WebSocketApp should forward the received mask_key function down
|
||||||
|
@ -86,7 +137,7 @@ class WebSocketAppTest(unittest.TestCase):
|
||||||
def my_mask_key_func():
|
def my_mask_key_func():
|
||||||
return "\x00\x00\x00\x00"
|
return "\x00\x00\x00\x00"
|
||||||
|
|
||||||
app = ws.WebSocketApp('wss://stream.meetup.com/2/rsvps', get_mask_key=my_mask_key_func)
|
app = ws.WebSocketApp('wss://api-pub.bitfinex.com/ws/1', get_mask_key=my_mask_key_func)
|
||||||
|
|
||||||
# if numpy is installed, this assertion fail
|
# if numpy is installed, this assertion fail
|
||||||
# Note: We can't use 'is' for comparing the functions directly, need to use 'id'.
|
# Note: We can't use 'is' for comparing the functions directly, need to use 'id'.
|
||||||
|
@ -136,7 +187,7 @@ class WebSocketAppTest(unittest.TestCase):
|
||||||
def testOpcodeBinary(self):
|
def testOpcodeBinary(self):
|
||||||
""" Test WebSocketApp binary opcode
|
""" Test WebSocketApp binary opcode
|
||||||
"""
|
"""
|
||||||
|
# The lack of wss:// in the URL below is on purpose
|
||||||
app = ws.WebSocketApp('streaming.vn.teslamotors.com/streaming/')
|
app = ws.WebSocketApp('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")
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
"""
|
import unittest
|
||||||
|
from websocket._cookiejar import SimpleCookieJar
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
test_cookiejar.py
|
test_cookiejar.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -20,8 +19,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
import unittest
|
|
||||||
from websocket._cookiejar import SimpleCookieJar
|
|
||||||
|
|
||||||
|
|
||||||
class CookieJarTest(unittest.TestCase):
|
class CookieJarTest(unittest.TestCase):
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
import websocket as ws
|
||||||
|
from websocket._http import proxy_info, read_headers, _start_proxied_socket, _tunnel, _get_addrinfo_list, connect
|
||||||
|
import unittest
|
||||||
|
import ssl
|
||||||
|
import websocket
|
||||||
|
import socket
|
||||||
|
|
||||||
"""
|
"""
|
||||||
test_http.py
|
test_http.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -19,15 +28,6 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import os.path
|
|
||||||
import websocket as ws
|
|
||||||
from websocket._http import proxy_info, read_headers, _start_proxied_socket, _tunnel, _get_addrinfo_list, connect
|
|
||||||
import unittest
|
|
||||||
import ssl
|
|
||||||
import websocket
|
|
||||||
import socket
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from python_socks._errors import ProxyError, ProxyTimeoutError, ProxyConnectionError
|
from python_socks._errors import ProxyError, ProxyTimeoutError, ProxyConnectionError
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
from websocket._url import get_proxy_info, parse_url, _is_address_in_network, _is_no_proxy_host
|
||||||
|
|
||||||
"""
|
"""
|
||||||
test_url.py
|
test_url.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -19,10 +23,6 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import unittest
|
|
||||||
from websocket._url import get_proxy_info, parse_url, _is_address_in_network, _is_no_proxy_host
|
|
||||||
|
|
||||||
|
|
||||||
class UrlTest(unittest.TestCase):
|
class UrlTest(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -209,73 +209,73 @@ class ProxyInfoTest(unittest.TestCase):
|
||||||
del os.environ["no_proxy"]
|
del os.environ["no_proxy"]
|
||||||
|
|
||||||
def testProxyFromArgs(self):
|
def testProxyFromArgs(self):
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", False, proxy_host="localhost"), ("localhost", 0, None))
|
self.assertEqual(get_proxy_info("echo.websocket.events", False, proxy_host="localhost"), ("localhost", 0, None))
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", False, proxy_host="localhost", proxy_port=3128),
|
self.assertEqual(get_proxy_info("echo.websocket.events", False, proxy_host="localhost", proxy_port=3128),
|
||||||
("localhost", 3128, None))
|
("localhost", 3128, None))
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", True, proxy_host="localhost"), ("localhost", 0, None))
|
self.assertEqual(get_proxy_info("echo.websocket.events", True, proxy_host="localhost"), ("localhost", 0, None))
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", True, proxy_host="localhost", proxy_port=3128),
|
self.assertEqual(get_proxy_info("echo.websocket.events", True, proxy_host="localhost", proxy_port=3128),
|
||||||
("localhost", 3128, None))
|
("localhost", 3128, None))
|
||||||
|
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", False, proxy_host="localhost", proxy_auth=("a", "b")),
|
self.assertEqual(get_proxy_info("echo.websocket.events", False, proxy_host="localhost", proxy_auth=("a", "b")),
|
||||||
("localhost", 0, ("a", "b")))
|
("localhost", 0, ("a", "b")))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
get_proxy_info("echo.websocket.org", False, proxy_host="localhost", proxy_port=3128, proxy_auth=("a", "b")),
|
get_proxy_info("echo.websocket.events", False, proxy_host="localhost", proxy_port=3128, proxy_auth=("a", "b")),
|
||||||
("localhost", 3128, ("a", "b")))
|
("localhost", 3128, ("a", "b")))
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", True, proxy_host="localhost", proxy_auth=("a", "b")),
|
self.assertEqual(get_proxy_info("echo.websocket.events", True, proxy_host="localhost", proxy_auth=("a", "b")),
|
||||||
("localhost", 0, ("a", "b")))
|
("localhost", 0, ("a", "b")))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
get_proxy_info("echo.websocket.org", True, proxy_host="localhost", proxy_port=3128, proxy_auth=("a", "b")),
|
get_proxy_info("echo.websocket.events", True, proxy_host="localhost", proxy_port=3128, proxy_auth=("a", "b")),
|
||||||
("localhost", 3128, ("a", "b")))
|
("localhost", 3128, ("a", "b")))
|
||||||
|
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", True, proxy_host="localhost", proxy_port=3128,
|
self.assertEqual(get_proxy_info("echo.websocket.events", True, proxy_host="localhost", proxy_port=3128,
|
||||||
no_proxy=["example.com"], proxy_auth=("a", "b")),
|
no_proxy=["example.com"], proxy_auth=("a", "b")),
|
||||||
("localhost", 3128, ("a", "b")))
|
("localhost", 3128, ("a", "b")))
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", True, proxy_host="localhost", proxy_port=3128,
|
self.assertEqual(get_proxy_info("echo.websocket.events", True, proxy_host="localhost", proxy_port=3128,
|
||||||
no_proxy=["echo.websocket.org"], proxy_auth=("a", "b")),
|
no_proxy=["echo.websocket.events"], proxy_auth=("a", "b")),
|
||||||
(None, 0, None))
|
(None, 0, None))
|
||||||
|
|
||||||
def testProxyFromEnv(self):
|
def testProxyFromEnv(self):
|
||||||
os.environ["http_proxy"] = "http://localhost/"
|
os.environ["http_proxy"] = "http://localhost/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", None, None))
|
self.assertEqual(get_proxy_info("echo.websocket.events", False), ("localhost", None, None))
|
||||||
os.environ["http_proxy"] = "http://localhost:3128/"
|
os.environ["http_proxy"] = "http://localhost:3128/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", 3128, None))
|
self.assertEqual(get_proxy_info("echo.websocket.events", False), ("localhost", 3128, None))
|
||||||
|
|
||||||
os.environ["http_proxy"] = "http://localhost/"
|
os.environ["http_proxy"] = "http://localhost/"
|
||||||
os.environ["https_proxy"] = "http://localhost2/"
|
os.environ["https_proxy"] = "http://localhost2/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", None, None))
|
self.assertEqual(get_proxy_info("echo.websocket.events", False), ("localhost", None, None))
|
||||||
os.environ["http_proxy"] = "http://localhost:3128/"
|
os.environ["http_proxy"] = "http://localhost:3128/"
|
||||||
os.environ["https_proxy"] = "http://localhost2:3128/"
|
os.environ["https_proxy"] = "http://localhost2:3128/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", 3128, None))
|
self.assertEqual(get_proxy_info("echo.websocket.events", False), ("localhost", 3128, None))
|
||||||
|
|
||||||
os.environ["http_proxy"] = "http://localhost/"
|
os.environ["http_proxy"] = "http://localhost/"
|
||||||
os.environ["https_proxy"] = "http://localhost2/"
|
os.environ["https_proxy"] = "http://localhost2/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", True), ("localhost2", None, None))
|
self.assertEqual(get_proxy_info("echo.websocket.events", True), ("localhost2", None, None))
|
||||||
os.environ["http_proxy"] = "http://localhost:3128/"
|
os.environ["http_proxy"] = "http://localhost:3128/"
|
||||||
os.environ["https_proxy"] = "http://localhost2:3128/"
|
os.environ["https_proxy"] = "http://localhost2:3128/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", True), ("localhost2", 3128, None))
|
self.assertEqual(get_proxy_info("echo.websocket.events", True), ("localhost2", 3128, None))
|
||||||
|
|
||||||
os.environ["http_proxy"] = "http://a:b@localhost/"
|
os.environ["http_proxy"] = "http://a:b@localhost/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", None, ("a", "b")))
|
self.assertEqual(get_proxy_info("echo.websocket.events", False), ("localhost", None, ("a", "b")))
|
||||||
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
|
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", 3128, ("a", "b")))
|
self.assertEqual(get_proxy_info("echo.websocket.events", False), ("localhost", 3128, ("a", "b")))
|
||||||
|
|
||||||
os.environ["http_proxy"] = "http://a:b@localhost/"
|
os.environ["http_proxy"] = "http://a:b@localhost/"
|
||||||
os.environ["https_proxy"] = "http://a:b@localhost2/"
|
os.environ["https_proxy"] = "http://a:b@localhost2/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", None, ("a", "b")))
|
self.assertEqual(get_proxy_info("echo.websocket.events", False), ("localhost", None, ("a", "b")))
|
||||||
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
|
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
|
||||||
os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
|
os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", 3128, ("a", "b")))
|
self.assertEqual(get_proxy_info("echo.websocket.events", False), ("localhost", 3128, ("a", "b")))
|
||||||
|
|
||||||
os.environ["http_proxy"] = "http://a:b@localhost/"
|
os.environ["http_proxy"] = "http://a:b@localhost/"
|
||||||
os.environ["https_proxy"] = "http://a:b@localhost2/"
|
os.environ["https_proxy"] = "http://a:b@localhost2/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", True), ("localhost2", None, ("a", "b")))
|
self.assertEqual(get_proxy_info("echo.websocket.events", True), ("localhost2", None, ("a", "b")))
|
||||||
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
|
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
|
||||||
os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
|
os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", True), ("localhost2", 3128, ("a", "b")))
|
self.assertEqual(get_proxy_info("echo.websocket.events", True), ("localhost2", 3128, ("a", "b")))
|
||||||
|
|
||||||
os.environ["http_proxy"] = "http://john%40example.com:P%40SSWORD@localhost:3128/"
|
os.environ["http_proxy"] = "http://john%40example.com:P%40SSWORD@localhost:3128/"
|
||||||
os.environ["https_proxy"] = "http://john%40example.com:P%40SSWORD@localhost2:3128/"
|
os.environ["https_proxy"] = "http://john%40example.com:P%40SSWORD@localhost2:3128/"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", True), ("localhost2", 3128, ("john@example.com", "P@SSWORD")))
|
self.assertEqual(get_proxy_info("echo.websocket.events", True), ("localhost2", 3128, ("john@example.com", "P@SSWORD")))
|
||||||
|
|
||||||
os.environ["http_proxy"] = "http://a:b@localhost/"
|
os.environ["http_proxy"] = "http://a:b@localhost/"
|
||||||
os.environ["https_proxy"] = "http://a:b@localhost2/"
|
os.environ["https_proxy"] = "http://a:b@localhost2/"
|
||||||
|
@ -283,12 +283,12 @@ class ProxyInfoTest(unittest.TestCase):
|
||||||
self.assertEqual(get_proxy_info("example.1.com", True), ("localhost2", None, ("a", "b")))
|
self.assertEqual(get_proxy_info("example.1.com", True), ("localhost2", None, ("a", "b")))
|
||||||
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
|
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
|
||||||
os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
|
os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
|
||||||
os.environ["no_proxy"] = "example1.com,example2.com, echo.websocket.org"
|
os.environ["no_proxy"] = "example1.com,example2.com, echo.websocket.events"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", True), (None, 0, None))
|
self.assertEqual(get_proxy_info("echo.websocket.events", True), (None, 0, None))
|
||||||
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
|
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
|
||||||
os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
|
os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
|
||||||
os.environ["no_proxy"] = "example1.com,example2.com, .websocket.org"
|
os.environ["no_proxy"] = "example1.com,example2.com, .websocket.events"
|
||||||
self.assertEqual(get_proxy_info("echo.websocket.org", True), (None, 0, None))
|
self.assertEqual(get_proxy_info("echo.websocket.events", True), (None, 0, None))
|
||||||
|
|
||||||
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
|
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
|
||||||
os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
|
os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
|
||||||
|
|
|
@ -1,14 +1,21 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
"""
|
import os
|
||||||
|
import os.path
|
||||||
"""
|
import socket
|
||||||
|
import websocket as ws
|
||||||
|
import unittest
|
||||||
|
from websocket._handshake import _create_sec_websocket_key, \
|
||||||
|
_validate as _validate_header
|
||||||
|
from websocket._http import read_headers
|
||||||
|
from websocket._utils import validate_utf8
|
||||||
|
from base64 import decodebytes as base64decode
|
||||||
|
|
||||||
"""
|
"""
|
||||||
test_websocket.py
|
test_websocket.py
|
||||||
websocket - WebSocket client library for Python
|
websocket - WebSocket client library for Python
|
||||||
|
|
||||||
Copyright 2021 engn33r
|
Copyright 2022 engn33r
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -23,18 +30,6 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import os.path
|
|
||||||
import socket
|
|
||||||
import websocket as ws
|
|
||||||
from websocket._handshake import _create_sec_websocket_key, \
|
|
||||||
_validate as _validate_header
|
|
||||||
from websocket._http import read_headers
|
|
||||||
from websocket._utils import validate_utf8
|
|
||||||
from base64 import decodebytes as base64decode
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import ssl
|
import ssl
|
||||||
from ssl import SSLError
|
from ssl import SSLError
|
||||||
|
@ -201,14 +196,16 @@ class WebSocketTest(unittest.TestCase):
|
||||||
@unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
|
@unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
|
||||||
def testIter(self):
|
def testIter(self):
|
||||||
count = 2
|
count = 2
|
||||||
for _ in ws.create_connection('wss://stream.meetup.com/2/rsvps'):
|
s = ws.create_connection('wss://api.bitfinex.com/ws/2')
|
||||||
|
s.send('{"event": "subscribe", "channel": "ticker"}')
|
||||||
|
for _ in s:
|
||||||
count -= 1
|
count -= 1
|
||||||
if count == 0:
|
if count == 0:
|
||||||
break
|
break
|
||||||
|
|
||||||
@unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
|
@unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
|
||||||
def testNext(self):
|
def testNext(self):
|
||||||
sock = ws.create_connection('wss://stream.meetup.com/2/rsvps')
|
sock = ws.create_connection('wss://api.bitfinex.com/ws/2')
|
||||||
self.assertEqual(str, type(next(sock)))
|
self.assertEqual(str, type(next(sock)))
|
||||||
|
|
||||||
def testInternalRecvStrict(self):
|
def testInternalRecvStrict(self):
|
||||||
|
@ -383,6 +380,7 @@ class WebSocketTest(unittest.TestCase):
|
||||||
s = ws.create_connection("ws://127.0.0.1:" + LOCAL_WS_SERVER_PORT,
|
s = ws.create_connection("ws://127.0.0.1:" + LOCAL_WS_SERVER_PORT,
|
||||||
headers={"User-Agent": "PythonWebsocketClient"})
|
headers={"User-Agent": "PythonWebsocketClient"})
|
||||||
self.assertNotEqual(s, None)
|
self.assertNotEqual(s, None)
|
||||||
|
self.assertEqual(s.getsubprotocol(), None)
|
||||||
s.send("Hello, World")
|
s.send("Hello, World")
|
||||||
result = s.recv()
|
result = s.recv()
|
||||||
self.assertEqual(result, "Hello, World")
|
self.assertEqual(result, "Hello, World")
|
||||||
|
|
|
@ -47,7 +47,7 @@ tzdata==2022.1
|
||||||
tzlocal==4.2
|
tzlocal==4.2
|
||||||
urllib3==1.26.9
|
urllib3==1.26.9
|
||||||
webencodings==0.5.1
|
webencodings==0.5.1
|
||||||
websocket-client==1.2.3
|
websocket-client==1.3.2
|
||||||
xmltodict==0.12.0
|
xmltodict==0.12.0
|
||||||
zipp==3.8.0
|
zipp==3.8.0
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue