python-engineio 4.12.2__tar.gz → 4.13.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.12.2/src/python_engineio.egg-info → python_engineio-4.13.0}/PKG-INFO +4 -2
- {python_engineio-4.12.2 → python_engineio-4.13.0}/docs/client.rst +7 -3
- {python_engineio-4.12.2 → python_engineio-4.13.0}/docs/server.rst +7 -3
- {python_engineio-4.12.2 → python_engineio-4.13.0}/pyproject.toml +11 -4
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_client.py +14 -6
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_drivers/aiohttp.py +9 -16
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_drivers/asgi.py +3 -3
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_drivers/tornado.py +2 -1
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_server.py +6 -5
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/base_server.py +4 -1
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/client.py +15 -3
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/server.py +2 -2
- {python_engineio-4.12.2 → python_engineio-4.13.0/src/python_engineio.egg-info}/PKG-INFO +4 -2
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/python_engineio.egg-info/requires.txt +3 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/async/test_aiohttp.py +19 -6
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/async/test_client.py +64 -66
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/async/test_server.py +26 -2
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/common/test_client.py +44 -49
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/common/test_server.py +25 -2
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tox.ini +2 -3
- {python_engineio-4.12.2 → python_engineio-4.13.0}/LICENSE +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/MANIFEST.in +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/README.md +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/docs/Makefile +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/docs/_static/README.md +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/docs/api.rst +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/docs/conf.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/docs/index.rst +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/docs/intro.rst +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/docs/make.bat +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/setup.cfg +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/__init__.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_drivers/__init__.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_drivers/_websocket_wsgi.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_drivers/eventlet.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_drivers/gevent.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_drivers/gevent_uwsgi.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_drivers/sanic.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_drivers/threading.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/async_socket.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/base_client.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/base_socket.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/exceptions.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/json.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/middleware.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/packet.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/payload.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/socket.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/engineio/static_files.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/python_engineio.egg-info/SOURCES.txt +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/python_engineio.egg-info/dependency_links.txt +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/python_engineio.egg-info/not-zip-safe +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/src/python_engineio.egg-info/top_level.txt +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/__init__.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/async/__init__.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/async/index.html +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/async/test_asgi.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/async/test_sanic.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/async/test_socket.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/async/test_tornado.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/common/__init__.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/common/index.html +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/common/test_middleware.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/common/test_packet.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/common/test_payload.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/common/test_socket.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/performance/README.md +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/performance/binary_b64_packet.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/performance/binary_packet.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/performance/json_packet.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/performance/payload.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/performance/run.sh +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/performance/server_receive.py +0 -0
- {python_engineio-4.12.2 → python_engineio-4.13.0}/tests/performance/text_packet.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-engineio
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.13.0
|
|
4
4
|
Summary: Engine.IO server and client for Python
|
|
5
5
|
Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -10,7 +10,7 @@ Classifier: Environment :: Web Environment
|
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
|
-
Requires-Python: >=3.
|
|
13
|
+
Requires-Python: >=3.8
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
16
|
Requires-Dist: simple-websocket>=0.10.0
|
|
@@ -19,6 +19,8 @@ Requires-Dist: requests>=2.21.0; extra == "client"
|
|
|
19
19
|
Requires-Dist: websocket-client>=0.54.0; extra == "client"
|
|
20
20
|
Provides-Extra: asyncio-client
|
|
21
21
|
Requires-Dist: aiohttp>=3.4; extra == "asyncio-client"
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: tox; extra == "dev"
|
|
22
24
|
Provides-Extra: docs
|
|
23
25
|
Requires-Dist: sphinx; extra == "docs"
|
|
24
26
|
Dynamic: license-file
|
|
@@ -199,9 +199,13 @@ terminal::
|
|
|
199
199
|
# asyncio
|
|
200
200
|
eio = engineio.AsyncClient(logger=True)
|
|
201
201
|
|
|
202
|
-
The ``logger`` argument
|
|
203
|
-
|
|
204
|
-
|
|
202
|
+
The ``logger`` argument controls logging behavior:
|
|
203
|
+
|
|
204
|
+
* ``True``: Enables log output to ``stderr`` at the ``INFO`` level.
|
|
205
|
+
* ``False``: Enables log output to ``stderr`` at the ``ERROR`` level. This is
|
|
206
|
+
the default.
|
|
207
|
+
* A ``logging.Logger`` instance: Uses the provided logger without additional
|
|
208
|
+
configuration.
|
|
205
209
|
|
|
206
210
|
Logging can help identify the cause of connection problems, unexpected
|
|
207
211
|
disconnections and other issues.
|
|
@@ -350,9 +350,13 @@ terminal::
|
|
|
350
350
|
# asyncio
|
|
351
351
|
eio = engineio.AsyncServer(logger=True)
|
|
352
352
|
|
|
353
|
-
The ``logger`` argument
|
|
354
|
-
|
|
355
|
-
|
|
353
|
+
The ``logger`` argument controls logging behavior:
|
|
354
|
+
|
|
355
|
+
* ``True``: Enables log output to ``stderr`` at the ``INFO`` level.
|
|
356
|
+
* ``False``: Enables log output to ``stderr`` at the ``ERROR`` level. This is
|
|
357
|
+
the default.
|
|
358
|
+
* A ``logging.Logger`` instance: Uses the provided logger without additional
|
|
359
|
+
configuration.
|
|
356
360
|
|
|
357
361
|
Logging can help identify the cause of connection problems, 400 responses,
|
|
358
362
|
bad performance and other issues.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-engineio"
|
|
3
|
-
version = "4.
|
|
3
|
+
version = "4.13.0"
|
|
4
4
|
license = {text = "MIT"}
|
|
5
5
|
authors = [{name = "Miguel Grinberg", email = "miguel.grinberg@gmail.com"}]
|
|
6
6
|
description = "Engine.IO server and client for Python"
|
|
@@ -10,7 +10,7 @@ classifiers = [
|
|
|
10
10
|
"Programming Language :: Python :: 3",
|
|
11
11
|
"Operating System :: OS Independent",
|
|
12
12
|
]
|
|
13
|
-
requires-python = ">=3.
|
|
13
|
+
requires-python = ">=3.8"
|
|
14
14
|
dependencies = ["simple-websocket >= 0.10.0"]
|
|
15
15
|
|
|
16
16
|
[project.readme]
|
|
@@ -26,8 +26,15 @@ client = [
|
|
|
26
26
|
"requests >= 2.21.0",
|
|
27
27
|
"websocket-client >= 0.54.0",
|
|
28
28
|
]
|
|
29
|
-
asyncio_client = [
|
|
30
|
-
|
|
29
|
+
asyncio_client = [
|
|
30
|
+
"aiohttp >= 3.4"
|
|
31
|
+
]
|
|
32
|
+
dev = [
|
|
33
|
+
"tox",
|
|
34
|
+
]
|
|
35
|
+
docs = [
|
|
36
|
+
"sphinx",
|
|
37
|
+
]
|
|
31
38
|
|
|
32
39
|
[tool.setuptools]
|
|
33
40
|
zip-safe = false
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
from http.cookies import SimpleCookie
|
|
3
|
+
import inspect
|
|
2
4
|
import signal
|
|
3
5
|
import ssl
|
|
4
6
|
import threading
|
|
@@ -214,6 +216,12 @@ class AsyncClient(base_client.BaseClient):
|
|
|
214
216
|
|
|
215
217
|
async def _reset(self):
|
|
216
218
|
super()._reset()
|
|
219
|
+
while True: # pragma: no cover
|
|
220
|
+
try:
|
|
221
|
+
self.queue.get_nowait()
|
|
222
|
+
self.queue.task_done()
|
|
223
|
+
except self.queue_empty:
|
|
224
|
+
break
|
|
217
225
|
if not self.external_http: # pragma: no cover
|
|
218
226
|
if self.http and not self.http.closed:
|
|
219
227
|
await self.http.close()
|
|
@@ -313,16 +321,16 @@ class AsyncClient(base_client.BaseClient):
|
|
|
313
321
|
|
|
314
322
|
# extract any new cookies passed in a header so that they can also be
|
|
315
323
|
# sent the the WebSocket route
|
|
316
|
-
cookies = {}
|
|
317
324
|
for header, value in headers.items():
|
|
318
325
|
if header.lower() == 'cookie':
|
|
319
|
-
|
|
320
|
-
|
|
326
|
+
ck = SimpleCookie(headers[header])
|
|
327
|
+
self.http.cookie_jar.update_cookies(
|
|
328
|
+
{k: m.value for k, m in ck.items()})
|
|
321
329
|
del headers[header]
|
|
322
330
|
break
|
|
323
|
-
self.http.cookie_jar.update_cookies(cookies)
|
|
324
331
|
|
|
325
|
-
extra_options = {
|
|
332
|
+
extra_options = {
|
|
333
|
+
'timeout': aiohttp.ClientWSTimeout(ws_close=self.request_timeout)}
|
|
326
334
|
if not self.ssl_verify:
|
|
327
335
|
ssl_context = ssl.create_default_context()
|
|
328
336
|
ssl_context.check_hostname = False
|
|
@@ -462,7 +470,7 @@ class AsyncClient(base_client.BaseClient):
|
|
|
462
470
|
run_async = kwargs.pop('run_async', False)
|
|
463
471
|
ret = None
|
|
464
472
|
if event in self.handlers:
|
|
465
|
-
if
|
|
473
|
+
if inspect.iscoroutinefunction(self.handlers[event]) is True:
|
|
466
474
|
if run_async:
|
|
467
475
|
task = self.start_background_task(self.handlers[event],
|
|
468
476
|
*args)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import inspect
|
|
2
2
|
import sys
|
|
3
|
-
from urllib.parse import urlsplit
|
|
4
3
|
|
|
5
4
|
from aiohttp.web import Response, WebSocketResponse
|
|
6
5
|
|
|
@@ -22,12 +21,8 @@ def translate_request(request):
|
|
|
22
21
|
"""This function takes the arguments passed to the request handler and
|
|
23
22
|
uses them to generate a WSGI compatible environ dictionary.
|
|
24
23
|
"""
|
|
25
|
-
message = request._message
|
|
26
|
-
payload = request._payload
|
|
27
|
-
|
|
28
|
-
uri_parts = urlsplit(message.path)
|
|
29
24
|
environ = {
|
|
30
|
-
'wsgi.input':
|
|
25
|
+
'wsgi.input': request.content,
|
|
31
26
|
'wsgi.errors': sys.stderr,
|
|
32
27
|
'wsgi.version': (1, 0),
|
|
33
28
|
'wsgi.async': True,
|
|
@@ -35,10 +30,10 @@ def translate_request(request):
|
|
|
35
30
|
'wsgi.multiprocess': False,
|
|
36
31
|
'wsgi.run_once': False,
|
|
37
32
|
'SERVER_SOFTWARE': 'aiohttp',
|
|
38
|
-
'REQUEST_METHOD':
|
|
39
|
-
'QUERY_STRING':
|
|
40
|
-
'RAW_URI':
|
|
41
|
-
'SERVER_PROTOCOL': 'HTTP
|
|
33
|
+
'REQUEST_METHOD': request.method,
|
|
34
|
+
'QUERY_STRING': request.query_string or '',
|
|
35
|
+
'RAW_URI': request.path_qs,
|
|
36
|
+
'SERVER_PROTOCOL': f'HTTP/{request.version[0]}.{request.version[1]}',
|
|
42
37
|
'REMOTE_ADDR': '127.0.0.1',
|
|
43
38
|
'REMOTE_PORT': '0',
|
|
44
39
|
'SERVER_NAME': 'aiohttp',
|
|
@@ -46,7 +41,7 @@ def translate_request(request):
|
|
|
46
41
|
'aiohttp.request': request
|
|
47
42
|
}
|
|
48
43
|
|
|
49
|
-
for hdr_name, hdr_value in
|
|
44
|
+
for hdr_name, hdr_value in request.headers.items():
|
|
50
45
|
hdr_name = hdr_name.upper()
|
|
51
46
|
if hdr_name == 'CONTENT-TYPE':
|
|
52
47
|
environ['CONTENT_TYPE'] = hdr_value
|
|
@@ -63,9 +58,7 @@ def translate_request(request):
|
|
|
63
58
|
|
|
64
59
|
environ['wsgi.url_scheme'] = environ.get('HTTP_X_FORWARDED_PROTO', 'http')
|
|
65
60
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
environ['PATH_INFO'] = path_info
|
|
61
|
+
environ['PATH_INFO'] = request.path
|
|
69
62
|
environ['SCRIPT_NAME'] = ''
|
|
70
63
|
|
|
71
64
|
return environ
|
|
@@ -105,7 +98,7 @@ class WebSocket: # pragma: no cover
|
|
|
105
98
|
f = self._sock.send_bytes
|
|
106
99
|
else:
|
|
107
100
|
f = self._sock.send_str
|
|
108
|
-
if
|
|
101
|
+
if inspect.iscoroutinefunction(f):
|
|
109
102
|
await f(message)
|
|
110
103
|
else:
|
|
111
104
|
f(message)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import inspect
|
|
1
2
|
import os
|
|
2
3
|
import sys
|
|
3
|
-
import asyncio
|
|
4
4
|
|
|
5
5
|
from engineio.static_files import get_static_file
|
|
6
6
|
|
|
@@ -102,7 +102,7 @@ class ASGIApp:
|
|
|
102
102
|
if self.on_startup:
|
|
103
103
|
try:
|
|
104
104
|
await self.on_startup() \
|
|
105
|
-
if
|
|
105
|
+
if inspect.iscoroutinefunction(self.on_startup) \
|
|
106
106
|
else self.on_startup()
|
|
107
107
|
except:
|
|
108
108
|
await send({'type': 'lifespan.startup.failed'})
|
|
@@ -112,7 +112,7 @@ class ASGIApp:
|
|
|
112
112
|
if self.on_shutdown:
|
|
113
113
|
try:
|
|
114
114
|
await self.on_shutdown() \
|
|
115
|
-
if
|
|
115
|
+
if inspect.iscoroutinefunction(self.on_shutdown) \
|
|
116
116
|
else self.on_shutdown()
|
|
117
117
|
except:
|
|
118
118
|
await send({'type': 'lifespan.shutdown.failed'})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import inspect
|
|
2
3
|
import sys
|
|
3
4
|
from urllib.parse import urlsplit
|
|
4
5
|
from .. import exceptions
|
|
@@ -24,7 +25,7 @@ def get_tornado_handler(engineio_server):
|
|
|
24
25
|
async def get(self, *args, **kwargs):
|
|
25
26
|
if self.request.headers.get('Upgrade', '').lower() == 'websocket':
|
|
26
27
|
ret = super().get(*args, **kwargs)
|
|
27
|
-
if
|
|
28
|
+
if inspect.iscoroutine(ret):
|
|
28
29
|
await ret
|
|
29
30
|
else:
|
|
30
31
|
await engineio_server.handle_request(self)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import inspect
|
|
2
3
|
import urllib
|
|
3
4
|
|
|
4
5
|
from . import base_server
|
|
@@ -56,8 +57,8 @@ class AsyncServer(base_server.BaseServer):
|
|
|
56
57
|
:param cors_allowed_origins: Origin or list of origins that are allowed to
|
|
57
58
|
connect to this server. Only the same origin
|
|
58
59
|
is allowed by default. Set this argument to
|
|
59
|
-
``'*'`` to allow all origins, or
|
|
60
|
-
disable CORS handling.
|
|
60
|
+
``'*'`` or ``['*']`` to allow all origins, or
|
|
61
|
+
to ``[]`` to disable CORS handling.
|
|
61
62
|
:param cors_credentials: Whether credentials (cookies, authentication) are
|
|
62
63
|
allowed in requests to this server.
|
|
63
64
|
:param logger: To enable logging set to ``True`` or pass a logger object to
|
|
@@ -212,7 +213,7 @@ class AsyncServer(base_server.BaseServer):
|
|
|
212
213
|
Note: this method is a coroutine.
|
|
213
214
|
"""
|
|
214
215
|
translate_request = self._async['translate_request']
|
|
215
|
-
if
|
|
216
|
+
if inspect.iscoroutinefunction(translate_request):
|
|
216
217
|
environ = await translate_request(*args, **kwargs)
|
|
217
218
|
else:
|
|
218
219
|
environ = translate_request(*args, **kwargs)
|
|
@@ -427,7 +428,7 @@ class AsyncServer(base_server.BaseServer):
|
|
|
427
428
|
async def _make_response(self, response_dict, environ):
|
|
428
429
|
cors_headers = self._cors_headers(environ)
|
|
429
430
|
make_response = self._async['make_response']
|
|
430
|
-
if
|
|
431
|
+
if inspect.iscoroutinefunction(make_response):
|
|
431
432
|
response = await make_response(
|
|
432
433
|
response_dict['status'],
|
|
433
434
|
response_dict['headers'] + cors_headers,
|
|
@@ -502,7 +503,7 @@ class AsyncServer(base_server.BaseServer):
|
|
|
502
503
|
run_async = kwargs.pop('run_async', False)
|
|
503
504
|
ret = None
|
|
504
505
|
if event in self.handlers:
|
|
505
|
-
if
|
|
506
|
+
if inspect.iscoroutinefunction(self.handlers[event]):
|
|
506
507
|
async def run_async_handler():
|
|
507
508
|
try:
|
|
508
509
|
try:
|
|
@@ -310,7 +310,10 @@ class BaseServer:
|
|
|
310
310
|
is_allowed = self.cors_allowed_origins(origin)
|
|
311
311
|
allowed_origins = [origin] if is_allowed else []
|
|
312
312
|
else:
|
|
313
|
-
|
|
313
|
+
if '*' in self.cors_allowed_origins:
|
|
314
|
+
allowed_origins = None
|
|
315
|
+
else:
|
|
316
|
+
allowed_origins = self.cors_allowed_origins
|
|
314
317
|
return allowed_origins
|
|
315
318
|
|
|
316
319
|
def _cors_headers(self, environ):
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
from base64 import b64encode
|
|
2
|
-
from
|
|
2
|
+
from http.cookies import SimpleCookie
|
|
3
3
|
import logging
|
|
4
4
|
import queue
|
|
5
5
|
import ssl
|
|
6
6
|
import threading
|
|
7
7
|
import time
|
|
8
8
|
import urllib
|
|
9
|
+
from engineio.json import JSONDecodeError
|
|
9
10
|
|
|
10
11
|
try:
|
|
11
12
|
import requests
|
|
@@ -173,6 +174,15 @@ class Client(base_client.BaseClient):
|
|
|
173
174
|
"""Create an event object."""
|
|
174
175
|
return threading.Event(*args, **kwargs)
|
|
175
176
|
|
|
177
|
+
def _reset(self):
|
|
178
|
+
super()._reset()
|
|
179
|
+
while True: # pragma: no cover
|
|
180
|
+
try:
|
|
181
|
+
self.queue.get_nowait()
|
|
182
|
+
self.queue.task_done()
|
|
183
|
+
except self.queue_empty:
|
|
184
|
+
break
|
|
185
|
+
|
|
176
186
|
def _connect_polling(self, url, headers, engineio_path):
|
|
177
187
|
"""Establish a long-polling connection to the Engine.IO server."""
|
|
178
188
|
if requests is None: # pragma: no cover
|
|
@@ -259,8 +269,10 @@ class Client(base_client.BaseClient):
|
|
|
259
269
|
extra_options = {}
|
|
260
270
|
if self.http:
|
|
261
271
|
# cookies
|
|
262
|
-
|
|
263
|
-
|
|
272
|
+
ck = SimpleCookie()
|
|
273
|
+
for cookie in self.http.cookies:
|
|
274
|
+
ck[cookie.name] = cookie.value
|
|
275
|
+
cookies = ck.output(header='', sep=';').strip()
|
|
264
276
|
for header, value in headers.items():
|
|
265
277
|
if header.lower() == 'cookie':
|
|
266
278
|
if cookies:
|
|
@@ -54,8 +54,8 @@ class Server(base_server.BaseServer):
|
|
|
54
54
|
:param cors_allowed_origins: Origin or list of origins that are allowed to
|
|
55
55
|
connect to this server. Only the same origin
|
|
56
56
|
is allowed by default. Set this argument to
|
|
57
|
-
``'*'`` to allow all origins, or
|
|
58
|
-
disable CORS handling.
|
|
57
|
+
``'*'`` or ``['*']`` to allow all origins, or
|
|
58
|
+
to ``[]`` to disable CORS handling.
|
|
59
59
|
:param cors_credentials: Whether credentials (cookies, authentication) are
|
|
60
60
|
allowed in requests to this server. The default
|
|
61
61
|
is ``True``.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-engineio
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.13.0
|
|
4
4
|
Summary: Engine.IO server and client for Python
|
|
5
5
|
Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -10,7 +10,7 @@ Classifier: Environment :: Web Environment
|
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
|
-
Requires-Python: >=3.
|
|
13
|
+
Requires-Python: >=3.8
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
16
|
Requires-Dist: simple-websocket>=0.10.0
|
|
@@ -19,6 +19,8 @@ Requires-Dist: requests>=2.21.0; extra == "client"
|
|
|
19
19
|
Requires-Dist: websocket-client>=0.54.0; extra == "client"
|
|
20
20
|
Provides-Extra: asyncio-client
|
|
21
21
|
Requires-Dist: aiohttp>=3.4; extra == "asyncio-client"
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: tox; extra == "dev"
|
|
22
24
|
Provides-Extra: docs
|
|
23
25
|
Requires-Dist: sphinx; extra == "docs"
|
|
24
26
|
Dynamic: license-file
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
from unittest import mock
|
|
2
2
|
|
|
3
|
+
import yarl
|
|
4
|
+
from aiohttp.web import Request
|
|
5
|
+
|
|
3
6
|
from engineio.async_drivers import aiohttp as async_aiohttp
|
|
4
7
|
|
|
5
8
|
|
|
@@ -12,18 +15,28 @@ class TestAiohttp:
|
|
|
12
15
|
app.router.add_post.assert_any_call('/foo', mock_server.handle_request)
|
|
13
16
|
|
|
14
17
|
def test_translate_request(self):
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
message = mock.MagicMock()
|
|
19
|
+
message.url = yarl.URL('https://example.com/foo/bar?baz=1')
|
|
20
|
+
message.method = 'PUT'
|
|
21
|
+
message.path = '/foo/bar?baz=1'
|
|
22
|
+
message.version = (1, 1)
|
|
23
|
+
message.headers = {
|
|
20
24
|
'a': 'b',
|
|
21
25
|
'c-c': 'd',
|
|
22
26
|
'c_c': 'e',
|
|
23
27
|
'content-type': 'application/json',
|
|
24
28
|
'content-length': 123,
|
|
25
29
|
}
|
|
26
|
-
|
|
30
|
+
|
|
31
|
+
request = Request(
|
|
32
|
+
message,
|
|
33
|
+
payload=b'hello world',
|
|
34
|
+
protocol=mock.MagicMock(),
|
|
35
|
+
payload_writer=mock.MagicMock(),
|
|
36
|
+
task=mock.MagicMock(),
|
|
37
|
+
loop=mock.MagicMock(),
|
|
38
|
+
)
|
|
39
|
+
|
|
27
40
|
environ = async_aiohttp.translate_request(request)
|
|
28
41
|
expected_environ = {
|
|
29
42
|
'REQUEST_METHOD': 'PUT',
|