python-engineio 4.14.0__py3-none-any.whl → 4.15.1__py3-none-any.whl
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.
- engineio/async_client.py +18 -6
- engineio/async_server.py +38 -13
- engineio/async_socket.py +2 -2
- engineio/base_client.py +8 -2
- engineio/client.py +8 -1
- engineio/server.py +38 -13
- engineio/socket.py +2 -2
- engineio/static_files.py +2 -0
- {python_engineio-4.14.0.dist-info → python_engineio-4.15.1.dist-info}/METADATA +8 -7
- {python_engineio-4.14.0.dist-info → python_engineio-4.15.1.dist-info}/RECORD +13 -13
- {python_engineio-4.14.0.dist-info → python_engineio-4.15.1.dist-info}/WHEEL +1 -1
- {python_engineio-4.14.0.dist-info → python_engineio-4.15.1.dist-info}/licenses/LICENSE +0 -0
- {python_engineio-4.14.0.dist-info → python_engineio-4.15.1.dist-info}/top_level.txt +0 -0
engineio/async_client.py
CHANGED
|
@@ -226,6 +226,7 @@ class AsyncClient(base_client.BaseClient):
|
|
|
226
226
|
if not self.external_http: # pragma: no cover
|
|
227
227
|
if self.http and not self.http.closed:
|
|
228
228
|
await self.http.close()
|
|
229
|
+
self.http = None
|
|
229
230
|
|
|
230
231
|
def __del__(self): # pragma: no cover
|
|
231
232
|
# try to close the aiohttp session if it is still open
|
|
@@ -323,8 +324,13 @@ class AsyncClient(base_client.BaseClient):
|
|
|
323
324
|
self.logger.info(
|
|
324
325
|
'Attempting WebSocket connection to ' + websocket_url)
|
|
325
326
|
|
|
326
|
-
if self.http is None or self.http.closed:
|
|
327
|
-
self.
|
|
327
|
+
if self.http is None or self.http.closed:
|
|
328
|
+
if self.http_factory:
|
|
329
|
+
self.http = self.http_factory()
|
|
330
|
+
if inspect.iscoroutine(self.http):
|
|
331
|
+
self.http = await self.http
|
|
332
|
+
else:
|
|
333
|
+
self.http = aiohttp.ClientSession()
|
|
328
334
|
|
|
329
335
|
# extract any new cookies passed in a header so that they can also be
|
|
330
336
|
# sent the the WebSocket route
|
|
@@ -458,12 +464,17 @@ class AsyncClient(base_client.BaseClient):
|
|
|
458
464
|
|
|
459
465
|
async def _send_request(
|
|
460
466
|
self, method, url, headers=None, body=None,
|
|
461
|
-
timeout=None):
|
|
467
|
+
timeout=None):
|
|
462
468
|
if self.http is None or self.http.closed:
|
|
463
|
-
self.
|
|
469
|
+
if self.http_factory:
|
|
470
|
+
self.http = self.http_factory()
|
|
471
|
+
if inspect.iscoroutine(self.http):
|
|
472
|
+
self.http = await self.http
|
|
473
|
+
else:
|
|
474
|
+
self.http = aiohttp.ClientSession()
|
|
464
475
|
http_method = getattr(self.http, method.lower())
|
|
465
476
|
|
|
466
|
-
try:
|
|
477
|
+
try: # pragma: no cover
|
|
467
478
|
if not self.ssl_verify:
|
|
468
479
|
return await http_method(
|
|
469
480
|
url, headers=headers, data=body,
|
|
@@ -473,7 +484,8 @@ class AsyncClient(base_client.BaseClient):
|
|
|
473
484
|
url, headers=headers, data=body,
|
|
474
485
|
timeout=aiohttp.ClientTimeout(total=timeout))
|
|
475
486
|
|
|
476
|
-
except (aiohttp.ClientError, asyncio.TimeoutError)
|
|
487
|
+
except (aiohttp.ClientError, asyncio.TimeoutError) \
|
|
488
|
+
as exc: # pragma: no cover
|
|
477
489
|
self.logger.info('HTTP %s request to %s failed with error %s.',
|
|
478
490
|
method, url, exc)
|
|
479
491
|
return str(exc)
|
engineio/async_server.py
CHANGED
|
@@ -298,7 +298,19 @@ class AsyncServer(base_server.BaseServer):
|
|
|
298
298
|
self._log_error_once(f'{e} {sid}', 'bad-sid')
|
|
299
299
|
r = self._bad_request(f'{e} {sid}')
|
|
300
300
|
else:
|
|
301
|
-
if
|
|
301
|
+
if not socket.connected:
|
|
302
|
+
# cannot accept requests before connecting
|
|
303
|
+
self._log_error_once(
|
|
304
|
+
f'Socket for session {sid} is not connected',
|
|
305
|
+
'not-connected')
|
|
306
|
+
r = self._bad_request('Not connected')
|
|
307
|
+
elif socket.upgraded:
|
|
308
|
+
# cannot accept HTTP requests once upgraded
|
|
309
|
+
self._log_error_once(
|
|
310
|
+
f'Unexpected HTTP request for session {sid}',
|
|
311
|
+
'unexpected-http')
|
|
312
|
+
r = self._bad_request('Unexpected HTTP request')
|
|
313
|
+
elif transport != 'polling' and \
|
|
302
314
|
transport != upgrade_header:
|
|
303
315
|
self._log_error_once(
|
|
304
316
|
f'Invalid transport for session {sid}',
|
|
@@ -326,18 +338,31 @@ class AsyncServer(base_server.BaseServer):
|
|
|
326
338
|
r = self._bad_request(f'Invalid session {sid}')
|
|
327
339
|
else:
|
|
328
340
|
socket = self._get_socket(sid)
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
+
if not socket.connected:
|
|
342
|
+
# cannot accept requests before connecting
|
|
343
|
+
self._log_error_once(
|
|
344
|
+
f'Socket for session {sid} is not connected',
|
|
345
|
+
'not-connected')
|
|
346
|
+
r = self._bad_request('Not connected')
|
|
347
|
+
elif not socket.upgraded:
|
|
348
|
+
try:
|
|
349
|
+
await socket.handle_post_request(environ)
|
|
350
|
+
r = self._ok(jsonp_index=jsonp_index)
|
|
351
|
+
except exceptions.EngineIOError:
|
|
352
|
+
if sid in self.sockets: # pragma: no cover
|
|
353
|
+
await self.disconnect(sid)
|
|
354
|
+
r = self._bad_request()
|
|
355
|
+
except: # pragma: no cover
|
|
356
|
+
# for any other unexpected errors, we log the error
|
|
357
|
+
# and keep going
|
|
358
|
+
self.logger.exception('post request handler error')
|
|
359
|
+
r = self._ok(jsonp_index=jsonp_index)
|
|
360
|
+
else:
|
|
361
|
+
# cannot accept HTTP requests once upgraded
|
|
362
|
+
self._log_error_once(
|
|
363
|
+
f'Unexpected HTTP request for session {sid}',
|
|
364
|
+
'unexpected-http')
|
|
365
|
+
r = self._bad_request('Unexpected HTTP request')
|
|
341
366
|
elif method == 'OPTIONS':
|
|
342
367
|
r = self._ok()
|
|
343
368
|
else:
|
engineio/async_socket.py
CHANGED
|
@@ -56,8 +56,8 @@ class AsyncSocket(base_socket.BaseSocket):
|
|
|
56
56
|
"""Make sure the client is still sending pings."""
|
|
57
57
|
if self.closed:
|
|
58
58
|
raise exceptions.SocketIsClosedError()
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
last_ping = self.last_ping
|
|
60
|
+
if last_ping and time.time() - last_ping > self.server.ping_timeout:
|
|
61
61
|
self.server.logger.info('%s: Client is gone, closing socket',
|
|
62
62
|
self.sid)
|
|
63
63
|
# Passing abort=False here will cause close() to write a
|
engineio/base_client.py
CHANGED
|
@@ -55,8 +55,14 @@ class BaseClient:
|
|
|
55
55
|
self.upgrades = None
|
|
56
56
|
self.ping_interval = None
|
|
57
57
|
self.ping_timeout = None
|
|
58
|
-
self.http =
|
|
59
|
-
self.
|
|
58
|
+
self.http = None
|
|
59
|
+
self.http_factory = None
|
|
60
|
+
if http_session is not None:
|
|
61
|
+
if callable(http_session):
|
|
62
|
+
self.http_factory = http_session
|
|
63
|
+
else:
|
|
64
|
+
self.http = http_session
|
|
65
|
+
self.external_http = self.http is not None
|
|
60
66
|
self.handle_sigint = handle_sigint
|
|
61
67
|
self.ws = None
|
|
62
68
|
self.read_loop_task = None
|
engineio/client.py
CHANGED
|
@@ -183,6 +183,8 @@ class Client(base_client.BaseClient):
|
|
|
183
183
|
self.queue.task_done()
|
|
184
184
|
except self.queue_empty:
|
|
185
185
|
break
|
|
186
|
+
if not self.external_http: # pragma: no cover
|
|
187
|
+
self.http = None
|
|
186
188
|
|
|
187
189
|
def _connect_polling(self, url, headers, engineio_path):
|
|
188
190
|
"""Establish a long-polling connection to the Engine.IO server."""
|
|
@@ -274,6 +276,8 @@ class Client(base_client.BaseClient):
|
|
|
274
276
|
# so that they are preserved when connecting to the WebSocket route
|
|
275
277
|
cookies = None
|
|
276
278
|
extra_options = {}
|
|
279
|
+
if self.http is None and self.http_factory:
|
|
280
|
+
self.http = self.http_factory()
|
|
277
281
|
if self.http:
|
|
278
282
|
# cookies
|
|
279
283
|
ck = SimpleCookie()
|
|
@@ -458,7 +462,10 @@ class Client(base_client.BaseClient):
|
|
|
458
462
|
self, method, url, headers=None, body=None,
|
|
459
463
|
timeout=None): # pragma: no cover
|
|
460
464
|
if self.http is None:
|
|
461
|
-
self.
|
|
465
|
+
if self.http_factory:
|
|
466
|
+
self.http = self.http_factory()
|
|
467
|
+
else:
|
|
468
|
+
self.http = requests.Session()
|
|
462
469
|
if not self.ssl_verify:
|
|
463
470
|
self.http.verify = False
|
|
464
471
|
try:
|
engineio/server.py
CHANGED
|
@@ -276,7 +276,19 @@ class Server(base_server.BaseServer):
|
|
|
276
276
|
self._log_error_once(f'{e} {sid}', 'bad-sid')
|
|
277
277
|
r = self._bad_request(f'{e} {sid}')
|
|
278
278
|
else:
|
|
279
|
-
if
|
|
279
|
+
if not socket.connected:
|
|
280
|
+
# cannot accept requests before connecting
|
|
281
|
+
self._log_error_once(
|
|
282
|
+
f'Socket for session {sid} is not connected',
|
|
283
|
+
'not-connected')
|
|
284
|
+
r = self._bad_request('Not connected')
|
|
285
|
+
elif socket.upgraded:
|
|
286
|
+
# cannot accept HTTP requests once upgraded
|
|
287
|
+
self._log_error_once(
|
|
288
|
+
f'Unexpected HTTP request for session {sid}',
|
|
289
|
+
'unexpected-http')
|
|
290
|
+
r = self._bad_request('Unexpected HTTP request')
|
|
291
|
+
elif transport != 'polling' and \
|
|
280
292
|
transport != upgrade_header:
|
|
281
293
|
self._log_error_once(
|
|
282
294
|
f'Invalid transport for session {sid}',
|
|
@@ -304,18 +316,31 @@ class Server(base_server.BaseServer):
|
|
|
304
316
|
r = self._bad_request(f'Invalid session {sid}')
|
|
305
317
|
else:
|
|
306
318
|
socket = self._get_socket(sid)
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
+
if not socket.connected:
|
|
320
|
+
# cannot accept requests before connecting
|
|
321
|
+
self._log_error_once(
|
|
322
|
+
f'Socket for session {sid} is not connected',
|
|
323
|
+
'not-connected')
|
|
324
|
+
r = self._bad_request('Not connected')
|
|
325
|
+
elif not socket.upgraded:
|
|
326
|
+
try:
|
|
327
|
+
socket.handle_post_request(environ)
|
|
328
|
+
r = self._ok(jsonp_index=jsonp_index)
|
|
329
|
+
except exceptions.EngineIOError:
|
|
330
|
+
if sid in self.sockets: # pragma: no cover
|
|
331
|
+
self.disconnect(sid)
|
|
332
|
+
r = self._bad_request()
|
|
333
|
+
except: # pragma: no cover
|
|
334
|
+
# for any other unexpected errors, we log the error
|
|
335
|
+
# and keep going
|
|
336
|
+
self.logger.exception('post request handler error')
|
|
337
|
+
r = self._ok(jsonp_index=jsonp_index)
|
|
338
|
+
else:
|
|
339
|
+
# cannot accept HTTP requests once upgraded
|
|
340
|
+
self._log_error_once(
|
|
341
|
+
f'Unexpected HTTP request for session {sid}',
|
|
342
|
+
'unexpected-http')
|
|
343
|
+
r = self._bad_request('Unexpected HTTP request')
|
|
319
344
|
elif method == 'OPTIONS':
|
|
320
345
|
r = self._ok()
|
|
321
346
|
else:
|
engineio/socket.py
CHANGED
|
@@ -57,8 +57,8 @@ class Socket(base_socket.BaseSocket):
|
|
|
57
57
|
"""Make sure the client is still responding to pings."""
|
|
58
58
|
if self.closed:
|
|
59
59
|
raise exceptions.SocketIsClosedError()
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
last_ping = self.last_ping
|
|
61
|
+
if last_ping and time.time() - last_ping > self.server.ping_timeout:
|
|
62
62
|
self.server.logger.info('%s: Client is gone, closing socket',
|
|
63
63
|
self.sid)
|
|
64
64
|
# Passing abort=False here will cause close() to write a
|
engineio/static_files.py
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-engineio
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.15.1
|
|
4
4
|
Summary: Engine.IO server and client for Python
|
|
5
5
|
Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
|
|
6
|
-
License: MIT
|
|
7
|
-
Project-URL:
|
|
8
|
-
Project-URL:
|
|
9
|
-
Project-URL:
|
|
10
|
-
Project-URL:
|
|
11
|
-
Project-URL:
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://code.miguelgrinberg.com/miguelgrinberg/python-engineio
|
|
8
|
+
Project-URL: Documentation, https://python-engineio.readthedocs.io/
|
|
9
|
+
Project-URL: Source Code, https://code.miguelgrinberg.com/miguelgrinberg/python-engineio
|
|
10
|
+
Project-URL: Issue Tracker, https://code.miguelgrinberg.com/miguelgrinberg/python-engineio/issues
|
|
11
|
+
Project-URL: Changelog, https://code.miguelgrinberg.com/miguelgrinberg/python-engineio/src/branch/main/CHANGES.md
|
|
12
|
+
Project-URL: Funding, https://code.miguelgrinberg.com/miguelgrinberg/python-engineio#sponsor-this-project
|
|
12
13
|
Classifier: Environment :: Web Environment
|
|
13
14
|
Classifier: Intended Audience :: Developers
|
|
14
15
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
engineio/__init__.py,sha256=0R2PY1EXu3sicP7mkA0_QxEVGRlFlgvsxfhByqREE1A,481
|
|
2
|
-
engineio/async_client.py,sha256=
|
|
3
|
-
engineio/async_server.py,sha256=
|
|
4
|
-
engineio/async_socket.py,sha256=
|
|
5
|
-
engineio/base_client.py,sha256=
|
|
2
|
+
engineio/async_client.py,sha256=QIeN6WREOpPOXGk_c4z0HFuUZ-krcb0VNRJdYn3TptE,30996
|
|
3
|
+
engineio/async_server.py,sha256=j9nYtucVXquHvodl0GC_mws6E606JFuImEvtV7TbhEU,29008
|
|
4
|
+
engineio/async_socket.py,sha256=qZYv0BagtaxQvrKK3fwrI4cgf3ShtIRLKdjwxw43WdQ,10834
|
|
5
|
+
engineio/base_client.py,sha256=75L-ydpGSedVLph46aLiwpf8DNPhdgmbkXxH-nSso4E,6033
|
|
6
6
|
engineio/base_server.py,sha256=tTCqc65Vzf-0Be1uunt1FuGxPOvcpOUCxnT5V2mZCWo,14763
|
|
7
7
|
engineio/base_socket.py,sha256=PWiJC1msNo-0ctlP3JAwWsngKvnYM-ZjS6B6zzfu-eM,420
|
|
8
|
-
engineio/client.py,sha256=
|
|
8
|
+
engineio/client.py,sha256=_pboeKZil8q8kWvQcxYe6Jdu_5IfT5iNpjIDLtbXWUs,29539
|
|
9
9
|
engineio/exceptions.py,sha256=FyuMb5qhX9CUYP3fEoe1m-faU96ApdQTSbblaaoo8LA,292
|
|
10
10
|
engineio/json.py,sha256=SG5FTojqd1ix6u0dKXJsZVqqdYioZLO4S2GPL7BKl3U,405
|
|
11
11
|
engineio/middleware.py,sha256=5NKBXz-ftuFErUB_V9IDvRHaSOsjhtW-NnuJtquB1nc,3750
|
|
12
12
|
engineio/packet.py,sha256=YO3gmeKUoKyIsUq2e1z7Zifr5PGeS3gnaCeqR7wj5hQ,3198
|
|
13
13
|
engineio/payload.py,sha256=GIWu0Vnay4WNZlDxHqVgP34tKTBXX58OArJ-mO5zD3E,1539
|
|
14
|
-
engineio/server.py,sha256=
|
|
15
|
-
engineio/socket.py,sha256=
|
|
16
|
-
engineio/static_files.py,sha256=
|
|
14
|
+
engineio/server.py,sha256=hl7UrTFp6gJT-SCtvJMh9CdUSHr3RqNk5-Hav5sIDH8,24534
|
|
15
|
+
engineio/socket.py,sha256=1xCvZpaoqnud2HNJEs5FXOjOlycjNG5RtSgnHEv8yoE,10461
|
|
16
|
+
engineio/static_files.py,sha256=5h_SMrTbBITg9mYPswe2voA2u3tj9aXz_PuS4OLALj8,2112
|
|
17
17
|
engineio/async_drivers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
18
|
engineio/async_drivers/_websocket_wsgi.py,sha256=8kutiYG0syg3rFeqzMU3Pm-QQwaUx0F9EUUaOfKwPAU,1026
|
|
19
19
|
engineio/async_drivers/aiohttp.py,sha256=SOU9KOoru_OzxLioSKCYNIZQZLoyf-oxw6-bXc6-_L8,3697
|
|
@@ -24,8 +24,8 @@ engineio/async_drivers/gevent_uwsgi.py,sha256=m6ay5dov9FDQl0fbeiKeE-Orh5LiF6zLlY
|
|
|
24
24
|
engineio/async_drivers/sanic.py,sha256=GYX8YWR1GbRm-GkMTAQkfkWbY12MOT1IV2DzH0Xx8Ns,4495
|
|
25
25
|
engineio/async_drivers/threading.py,sha256=ywmG59d4H6OHZjKarBN97-9BHEsRxFEz9YN-E9QAu_I,463
|
|
26
26
|
engineio/async_drivers/tornado.py,sha256=v9uuGk8_HS6DjhoEKXfjHpki1FnydN4wi7eyBMsUTJA,5908
|
|
27
|
-
python_engineio-4.
|
|
28
|
-
python_engineio-4.
|
|
29
|
-
python_engineio-4.
|
|
30
|
-
python_engineio-4.
|
|
31
|
-
python_engineio-4.
|
|
27
|
+
python_engineio-4.15.1.dist-info/licenses/LICENSE,sha256=yel9Pbwfu82094CLKCzWRtuIev9PUxP-a76NTDFAWpw,1082
|
|
28
|
+
python_engineio-4.15.1.dist-info/METADATA,sha256=OUrDPraYcxJjKEZ4L87sn22DnY2pqcSPHximPyUyQvo,2634
|
|
29
|
+
python_engineio-4.15.1.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
30
|
+
python_engineio-4.15.1.dist-info/top_level.txt,sha256=u8PmNisCZLwRYcWrNLe9wutQ2tt4zNi8IH362c-HWuA,9
|
|
31
|
+
python_engineio-4.15.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|