python-engineio 4.9.1__tar.gz → 4.10.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_engineio-4.9.1/src/python_engineio.egg-info → python_engineio-4.10.0}/PKG-INFO +1 -1
- {python_engineio-4.9.1 → python_engineio-4.10.0}/pyproject.toml +1 -1
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_client.py +1 -1
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_drivers/asgi.py +7 -1
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_drivers/eventlet.py +1 -1
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_server.py +22 -12
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/client.py +1 -2
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/server.py +20 -14
- {python_engineio-4.9.1 → python_engineio-4.10.0/src/python_engineio.egg-info}/PKG-INFO +1 -1
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/python_engineio.egg-info/SOURCES.txt +0 -1
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/async/test_asgi.py +43 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/async/test_server.py +26 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/common/test_server.py +39 -1
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tox.ini +2 -2
- python_engineio-4.9.1/tests/common/test_async_eventlet.py +0 -29
- {python_engineio-4.9.1 → python_engineio-4.10.0}/LICENSE +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/MANIFEST.in +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/README.md +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/docs/Makefile +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/docs/_static/README.md +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/docs/api.rst +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/docs/client.rst +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/docs/conf.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/docs/index.rst +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/docs/intro.rst +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/docs/make.bat +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/docs/server.rst +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/setup.cfg +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/__init__.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_drivers/__init__.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_drivers/_websocket_wsgi.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_drivers/aiohttp.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_drivers/gevent.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_drivers/gevent_uwsgi.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_drivers/sanic.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_drivers/threading.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_drivers/tornado.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_socket.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/base_client.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/base_server.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/base_socket.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/exceptions.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/json.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/middleware.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/packet.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/payload.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/socket.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/static_files.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/python_engineio.egg-info/dependency_links.txt +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/python_engineio.egg-info/not-zip-safe +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/python_engineio.egg-info/requires.txt +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/src/python_engineio.egg-info/top_level.txt +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/__init__.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/async/__init__.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/async/index.html +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/async/test_aiohttp.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/async/test_client.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/async/test_sanic.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/async/test_socket.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/async/test_tornado.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/common/__init__.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/common/index.html +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/common/test_client.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/common/test_middleware.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/common/test_packet.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/common/test_payload.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/common/test_socket.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/performance/README.md +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/performance/binary_b64_packet.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/performance/binary_packet.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/performance/json_packet.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/performance/payload.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/performance/run.sh +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/performance/server_receive.py +0 -0
- {python_engineio-4.9.1 → python_engineio-4.10.0}/tests/performance/text_packet.py +0 -0
|
@@ -62,7 +62,7 @@ class AsyncClient(base_client.BaseClient):
|
|
|
62
62
|
:param http_session: an initialized ``aiohttp.ClientSession`` object to be
|
|
63
63
|
used when sending requests to the server. Use it if
|
|
64
64
|
you need to add special client options such as proxy
|
|
65
|
-
servers, SSL certificates, etc.
|
|
65
|
+
servers, SSL certificates, custom CA bundle, etc.
|
|
66
66
|
:param ssl_verify: ``True`` to verify SSL certificates, or ``False`` to
|
|
67
67
|
skip SSL certificate verification, allowing
|
|
68
68
|
connections to servers with self signed certificates.
|
|
@@ -63,7 +63,8 @@ class ASGIApp:
|
|
|
63
63
|
await self.lifespan(scope, receive, send)
|
|
64
64
|
elif scope['type'] in ['http', 'websocket'] and (
|
|
65
65
|
self.engineio_path is None
|
|
66
|
-
or scope['path'].startswith(
|
|
66
|
+
or self._ensure_trailing_slash(scope['path']).startswith(
|
|
67
|
+
self.engineio_path)):
|
|
67
68
|
await self.engineio_server.handle_request(scope, receive, send)
|
|
68
69
|
else:
|
|
69
70
|
static_file = get_static_file(scope['path'], self.static_files) \
|
|
@@ -127,6 +128,11 @@ class ASGIApp:
|
|
|
127
128
|
await send({'type': 'http.response.body',
|
|
128
129
|
'body': b'Not Found'})
|
|
129
130
|
|
|
131
|
+
def _ensure_trailing_slash(self, path):
|
|
132
|
+
if not path.endswith('/'):
|
|
133
|
+
path += '/'
|
|
134
|
+
return path
|
|
135
|
+
|
|
130
136
|
|
|
131
137
|
async def translate_request(scope, receive, send):
|
|
132
138
|
class AwaitablePayload(object): # pragma: no cover
|
|
@@ -70,6 +70,10 @@ class AsyncServer(base_server.BaseServer):
|
|
|
70
70
|
:param async_handlers: If set to ``True``, run message event handlers in
|
|
71
71
|
non-blocking threads. To run handlers synchronously,
|
|
72
72
|
set to ``False``. The default is ``True``.
|
|
73
|
+
:param monitor_clients: If set to ``True``, a background task will ensure
|
|
74
|
+
inactive clients are closed. Set to ``False`` to
|
|
75
|
+
disable the monitoring task (not recommended). The
|
|
76
|
+
default is ``True``.
|
|
73
77
|
:param transports: The list of allowed transports. Valid transports
|
|
74
78
|
are ``'polling'`` and ``'websocket'``. Defaults to
|
|
75
79
|
``['polling', 'websocket']``.
|
|
@@ -284,18 +288,24 @@ class AsyncServer(base_server.BaseServer):
|
|
|
284
288
|
r = self._bad_request('Invalid session ' + sid)
|
|
285
289
|
else:
|
|
286
290
|
socket = self._get_socket(sid)
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
291
|
+
if self.transport(sid) != transport:
|
|
292
|
+
self._log_error_once(
|
|
293
|
+
'Invalid transport for session ' + sid,
|
|
294
|
+
'bad-transport')
|
|
295
|
+
r = self._bad_request('Invalid transport')
|
|
296
|
+
else:
|
|
297
|
+
try:
|
|
298
|
+
packets = await socket.handle_get_request(environ)
|
|
299
|
+
if isinstance(packets, list):
|
|
300
|
+
r = self._ok(packets, jsonp_index=jsonp_index)
|
|
301
|
+
else:
|
|
302
|
+
r = packets
|
|
303
|
+
except exceptions.EngineIOError:
|
|
304
|
+
if sid in self.sockets: # pragma: no cover
|
|
305
|
+
await self.disconnect(sid)
|
|
306
|
+
r = self._bad_request()
|
|
307
|
+
if sid in self.sockets and self.sockets[sid].closed:
|
|
308
|
+
del self.sockets[sid]
|
|
299
309
|
elif method == 'POST':
|
|
300
310
|
if sid is None or sid not in self.sockets:
|
|
301
311
|
self._log_error_once('Invalid session ' + sid, 'bad-sid')
|
|
@@ -510,8 +510,7 @@ class Client(base_client.BaseClient):
|
|
|
510
510
|
except Exception as e: # pragma: no cover
|
|
511
511
|
if type(e) is OSError and e.errno == 9:
|
|
512
512
|
self.logger.info(
|
|
513
|
-
'WebSocket connection is closing, aborting'
|
|
514
|
-
str(e))
|
|
513
|
+
'WebSocket connection is closing, aborting')
|
|
515
514
|
else:
|
|
516
515
|
self.logger.info(
|
|
517
516
|
'Unexpected error receiving packet: "%s", aborting',
|
|
@@ -180,7 +180,7 @@ class Server(base_server.BaseServer):
|
|
|
180
180
|
if sid in self.sockets: # pragma: no cover
|
|
181
181
|
del self.sockets[sid]
|
|
182
182
|
else:
|
|
183
|
-
for client in self.sockets.values():
|
|
183
|
+
for client in self.sockets.copy().values():
|
|
184
184
|
client.close()
|
|
185
185
|
self.sockets = {}
|
|
186
186
|
|
|
@@ -270,19 +270,25 @@ class Server(base_server.BaseServer):
|
|
|
270
270
|
r = self._bad_request('Invalid session')
|
|
271
271
|
else:
|
|
272
272
|
socket = self._get_socket(sid)
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
273
|
+
if self.transport(sid) != transport:
|
|
274
|
+
self._log_error_once(
|
|
275
|
+
'Invalid transport for session ' + sid,
|
|
276
|
+
'bad-transport')
|
|
277
|
+
r = self._bad_request('Invalid transport')
|
|
278
|
+
else:
|
|
279
|
+
try:
|
|
280
|
+
packets = socket.handle_get_request(
|
|
281
|
+
environ, start_response)
|
|
282
|
+
if isinstance(packets, list):
|
|
283
|
+
r = self._ok(packets, jsonp_index=jsonp_index)
|
|
284
|
+
else:
|
|
285
|
+
r = packets
|
|
286
|
+
except exceptions.EngineIOError:
|
|
287
|
+
if sid in self.sockets: # pragma: no cover
|
|
288
|
+
self.disconnect(sid)
|
|
289
|
+
r = self._bad_request()
|
|
290
|
+
if sid in self.sockets and self.sockets[sid].closed:
|
|
291
|
+
del self.sockets[sid]
|
|
286
292
|
elif method == 'POST':
|
|
287
293
|
if sid is None or sid not in self.sockets:
|
|
288
294
|
self._log_error_once(
|
|
@@ -38,12 +38,55 @@ class AsgiTests(unittest.TestCase):
|
|
|
38
38
|
def test_engineio_routing(self):
|
|
39
39
|
mock_server = mock.MagicMock()
|
|
40
40
|
mock_server.handle_request = AsyncMock()
|
|
41
|
+
|
|
41
42
|
app = async_asgi.ASGIApp(mock_server)
|
|
42
43
|
scope = {'type': 'http', 'path': '/engine.io/'}
|
|
43
44
|
_run(app(scope, 'receive', 'send'))
|
|
44
45
|
mock_server.handle_request.mock.assert_called_once_with(
|
|
45
46
|
scope, 'receive', 'send'
|
|
46
47
|
)
|
|
48
|
+
mock_server.handle_request.mock.reset_mock()
|
|
49
|
+
scope = {'type': 'http', 'path': '/engine.io/'}
|
|
50
|
+
_run(app(scope, 'receive', 'send'))
|
|
51
|
+
mock_server.handle_request.mock.assert_called_once_with(
|
|
52
|
+
scope, 'receive', 'send'
|
|
53
|
+
)
|
|
54
|
+
mock_server.handle_request.mock.reset_mock()
|
|
55
|
+
scope = {'type': 'http', 'path': '/engine.iofoo/'}
|
|
56
|
+
_run(app(scope, 'receive', AsyncMock()))
|
|
57
|
+
mock_server.handle_request.mock.assert_not_called()
|
|
58
|
+
|
|
59
|
+
app = async_asgi.ASGIApp(mock_server, engineio_path=None)
|
|
60
|
+
mock_server.handle_request.mock.reset_mock()
|
|
61
|
+
scope = {'type': 'http', 'path': '/foo'}
|
|
62
|
+
_run(app(scope, 'receive', 'send'))
|
|
63
|
+
mock_server.handle_request.mock.assert_called_once_with(
|
|
64
|
+
scope, 'receive', 'send'
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
app = async_asgi.ASGIApp(mock_server, engineio_path='mysocket.io')
|
|
68
|
+
mock_server.handle_request.mock.reset_mock()
|
|
69
|
+
scope = {'type': 'http', 'path': '/mysocket.io'}
|
|
70
|
+
_run(app(scope, 'receive', 'send'))
|
|
71
|
+
mock_server.handle_request.mock.assert_called_once_with(
|
|
72
|
+
scope, 'receive', 'send'
|
|
73
|
+
)
|
|
74
|
+
mock_server.handle_request.mock.reset_mock()
|
|
75
|
+
scope = {'type': 'http', 'path': '/mysocket.io/'}
|
|
76
|
+
_run(app(scope, 'receive', 'send'))
|
|
77
|
+
mock_server.handle_request.mock.assert_called_once_with(
|
|
78
|
+
scope, 'receive', 'send'
|
|
79
|
+
)
|
|
80
|
+
mock_server.handle_request.mock.reset_mock()
|
|
81
|
+
scope = {'type': 'http', 'path': '/mysocket.io/foo'}
|
|
82
|
+
_run(app(scope, 'receive', 'send'))
|
|
83
|
+
mock_server.handle_request.mock.assert_called_once_with(
|
|
84
|
+
scope, 'receive', 'send'
|
|
85
|
+
)
|
|
86
|
+
mock_server.handle_request.mock.reset_mock()
|
|
87
|
+
scope = {'type': 'http', 'path': '/mysocket.iofoo'}
|
|
88
|
+
_run(app(scope, 'receive', AsyncMock()))
|
|
89
|
+
mock_server.handle_request.mock.assert_not_called()
|
|
47
90
|
|
|
48
91
|
def test_other_app_routing(self):
|
|
49
92
|
other_app = AsyncMock()
|
|
@@ -659,6 +659,32 @@ class TestAsyncServer(unittest.TestCase):
|
|
|
659
659
|
assert len(s.sockets) == 0
|
|
660
660
|
assert a._async['make_response'].call_args[0][0] == '400 BAD REQUEST'
|
|
661
661
|
|
|
662
|
+
@mock.patch('importlib.import_module')
|
|
663
|
+
def test_get_request_bad_websocket_transport(self, import_module):
|
|
664
|
+
a = self.get_async_mock(
|
|
665
|
+
{'REQUEST_METHOD': 'GET',
|
|
666
|
+
'QUERY_STRING': 'EIO=4&transport=websocket&sid=foo'}
|
|
667
|
+
)
|
|
668
|
+
import_module.side_effect = [a]
|
|
669
|
+
s = async_server.AsyncServer()
|
|
670
|
+
s.sockets['foo'] = mock_socket = self._get_mock_socket()
|
|
671
|
+
mock_socket.upgraded = False
|
|
672
|
+
_run(s.handle_request('request'))
|
|
673
|
+
assert a._async['make_response'].call_args[0][0] == '400 BAD REQUEST'
|
|
674
|
+
|
|
675
|
+
@mock.patch('importlib.import_module')
|
|
676
|
+
def test_get_request_bad_polling_transport(self, import_module):
|
|
677
|
+
a = self.get_async_mock(
|
|
678
|
+
{'REQUEST_METHOD': 'GET',
|
|
679
|
+
'QUERY_STRING': 'EIO=4&transport=polling&sid=foo'}
|
|
680
|
+
)
|
|
681
|
+
import_module.side_effect = [a]
|
|
682
|
+
s = async_server.AsyncServer()
|
|
683
|
+
s.sockets['foo'] = mock_socket = self._get_mock_socket()
|
|
684
|
+
mock_socket.upgraded = True
|
|
685
|
+
_run(s.handle_request('request'))
|
|
686
|
+
assert a._async['make_response'].call_args[0][0] == '400 BAD REQUEST'
|
|
687
|
+
|
|
662
688
|
@mock.patch('importlib.import_module')
|
|
663
689
|
def test_post_request_with_bad_sid(self, import_module):
|
|
664
690
|
a = self.get_async_mock(
|
|
@@ -111,6 +111,14 @@ class TestServer(unittest.TestCase):
|
|
|
111
111
|
del sys.modules['engineio.async_drivers.threading']
|
|
112
112
|
|
|
113
113
|
def test_async_mode_eventlet(self):
|
|
114
|
+
sys.modules['eventlet'] = mock.MagicMock()
|
|
115
|
+
sys.modules['eventlet'].green = mock.MagicMock()
|
|
116
|
+
sys.modules['eventlet.green'] = sys.modules['eventlet'].green
|
|
117
|
+
sys.modules['eventlet.green'].threading = mock.MagicMock()
|
|
118
|
+
sys.modules['eventlet.green.threading'] = \
|
|
119
|
+
sys.modules['eventlet.green'].threading
|
|
120
|
+
sys.modules['eventlet'].websocket = mock.MagicMock()
|
|
121
|
+
sys.modules['eventlet.websocket'] = sys.modules['eventlet'].websocket
|
|
114
122
|
s = server.Server(async_mode='eventlet')
|
|
115
123
|
assert s.async_mode == 'eventlet'
|
|
116
124
|
|
|
@@ -120,6 +128,11 @@ class TestServer(unittest.TestCase):
|
|
|
120
128
|
assert s._async['thread'] == async_eventlet.EventletThread
|
|
121
129
|
assert s._async['queue'] == queue.Queue
|
|
122
130
|
assert s._async['websocket'] == async_eventlet.WebSocketWSGI
|
|
131
|
+
del sys.modules['eventlet']
|
|
132
|
+
del sys.modules['eventlet.green']
|
|
133
|
+
del sys.modules['eventlet.green.threading']
|
|
134
|
+
del sys.modules['eventlet.websocket']
|
|
135
|
+
del sys.modules['engineio.async_drivers.eventlet']
|
|
123
136
|
|
|
124
137
|
@mock.patch('importlib.import_module', side_effect=_mock_import)
|
|
125
138
|
def test_async_mode_gevent_uwsgi(self, import_module):
|
|
@@ -228,7 +241,10 @@ class TestServer(unittest.TestCase):
|
|
|
228
241
|
with pytest.raises(ValueError):
|
|
229
242
|
server.Server(async_mode='foo')
|
|
230
243
|
|
|
231
|
-
@mock.patch(
|
|
244
|
+
@mock.patch(
|
|
245
|
+
'importlib.import_module',
|
|
246
|
+
side_effect=[_mock_async],
|
|
247
|
+
)
|
|
232
248
|
def test_async_mode_auto_eventlet(self, import_module):
|
|
233
249
|
s = server.Server()
|
|
234
250
|
assert s.async_mode == 'eventlet'
|
|
@@ -867,6 +883,28 @@ class TestServer(unittest.TestCase):
|
|
|
867
883
|
assert start_response.call_args[0][0] == '400 BAD REQUEST'
|
|
868
884
|
assert len(s.sockets) == 0
|
|
869
885
|
|
|
886
|
+
def test_get_request_bad_websocket_transport(self):
|
|
887
|
+
s = server.Server()
|
|
888
|
+
mock_socket = self._get_mock_socket()
|
|
889
|
+
mock_socket.upgraded = False
|
|
890
|
+
s.sockets['foo'] = mock_socket
|
|
891
|
+
environ = {'REQUEST_METHOD': 'GET',
|
|
892
|
+
'QUERY_STRING': 'EIO=4&transport=websocket&sid=foo'}
|
|
893
|
+
start_response = mock.MagicMock()
|
|
894
|
+
s.handle_request(environ, start_response)
|
|
895
|
+
assert start_response.call_args[0][0] == '400 BAD REQUEST'
|
|
896
|
+
|
|
897
|
+
def test_get_request_bad_polling_transport(self):
|
|
898
|
+
s = server.Server()
|
|
899
|
+
mock_socket = self._get_mock_socket()
|
|
900
|
+
mock_socket.upgraded = True
|
|
901
|
+
s.sockets['foo'] = mock_socket
|
|
902
|
+
environ = {'REQUEST_METHOD': 'GET',
|
|
903
|
+
'QUERY_STRING': 'EIO=4&transport=polling&sid=foo'}
|
|
904
|
+
start_response = mock.MagicMock()
|
|
905
|
+
s.handle_request(environ, start_response)
|
|
906
|
+
assert start_response.call_args[0][0] == '400 BAD REQUEST'
|
|
907
|
+
|
|
870
908
|
def test_post_request(self):
|
|
871
909
|
s = server.Server()
|
|
872
910
|
mock_socket = self._get_mock_socket()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[tox]
|
|
2
|
-
envlist=flake8,py38,py39,py310,py311,py312,pypy3,docs
|
|
2
|
+
envlist=flake8,py38,py39,py310,py311,py312,py313,pypy3,docs
|
|
3
3
|
skip_missing_interpreters=True
|
|
4
4
|
|
|
5
5
|
[gh-actions]
|
|
@@ -9,6 +9,7 @@ python =
|
|
|
9
9
|
3.10: py310
|
|
10
10
|
3.11: py311
|
|
11
11
|
3.12: py312
|
|
12
|
+
3.13: py313
|
|
12
13
|
pypy-3: pypy3
|
|
13
14
|
|
|
14
15
|
[testenv]
|
|
@@ -18,7 +19,6 @@ commands=
|
|
|
18
19
|
deps=
|
|
19
20
|
pytest
|
|
20
21
|
pytest-cov
|
|
21
|
-
eventlet
|
|
22
22
|
aiohttp
|
|
23
23
|
tornado
|
|
24
24
|
requests
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
import unittest
|
|
3
|
-
from unittest import mock
|
|
4
|
-
|
|
5
|
-
from engineio.async_drivers import eventlet as async_eventlet
|
|
6
|
-
import pytest
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class TestAsyncEventlet(unittest.TestCase):
|
|
10
|
-
def setUp(self):
|
|
11
|
-
logging.getLogger('engineio').setLevel(logging.NOTSET)
|
|
12
|
-
|
|
13
|
-
def test_bad_environ(self):
|
|
14
|
-
wsgi = async_eventlet.WebSocketWSGI(None, mock.MagicMock())
|
|
15
|
-
environ = {'foo': 'bar'}
|
|
16
|
-
start_response = 'bar'
|
|
17
|
-
with pytest.raises(RuntimeError):
|
|
18
|
-
wsgi(environ, start_response)
|
|
19
|
-
|
|
20
|
-
@mock.patch(
|
|
21
|
-
'engineio.async_drivers.eventlet._WebSocketWSGI.__call__',
|
|
22
|
-
return_value='data',
|
|
23
|
-
)
|
|
24
|
-
def test_wsgi_call(self, _WebSocketWSGI):
|
|
25
|
-
_WebSocketWSGI.__call__ = lambda e, s: 'data'
|
|
26
|
-
environ = {'eventlet.input': mock.MagicMock()}
|
|
27
|
-
start_response = 'bar'
|
|
28
|
-
wsgi = async_eventlet.WebSocketWSGI(None, mock.MagicMock())
|
|
29
|
-
assert wsgi(environ, start_response) == 'data'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_engineio-4.9.1 → python_engineio-4.10.0}/src/engineio/async_drivers/_websocket_wsgi.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_engineio-4.9.1 → python_engineio-4.10.0}/src/python_engineio.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|