python-engineio 4.12.1__tar.gz → 4.12.3__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.
Files changed (74) hide show
  1. {python_engineio-4.12.1/src/python_engineio.egg-info → python_engineio-4.12.3}/PKG-INFO +1 -1
  2. {python_engineio-4.12.1 → python_engineio-4.12.3}/pyproject.toml +1 -1
  3. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_client.py +16 -7
  4. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_drivers/asgi.py +2 -2
  5. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_server.py +2 -2
  6. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/base_client.py +12 -1
  7. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/base_server.py +4 -1
  8. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/client.py +18 -6
  9. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/server.py +2 -2
  10. {python_engineio-4.12.1 → python_engineio-4.12.3/src/python_engineio.egg-info}/PKG-INFO +1 -1
  11. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/async/test_client.py +48 -66
  12. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/async/test_server.py +26 -2
  13. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/common/test_client.py +47 -51
  14. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/common/test_server.py +25 -2
  15. {python_engineio-4.12.1 → python_engineio-4.12.3}/LICENSE +0 -0
  16. {python_engineio-4.12.1 → python_engineio-4.12.3}/MANIFEST.in +0 -0
  17. {python_engineio-4.12.1 → python_engineio-4.12.3}/README.md +0 -0
  18. {python_engineio-4.12.1 → python_engineio-4.12.3}/docs/Makefile +0 -0
  19. {python_engineio-4.12.1 → python_engineio-4.12.3}/docs/_static/README.md +0 -0
  20. {python_engineio-4.12.1 → python_engineio-4.12.3}/docs/api.rst +0 -0
  21. {python_engineio-4.12.1 → python_engineio-4.12.3}/docs/client.rst +0 -0
  22. {python_engineio-4.12.1 → python_engineio-4.12.3}/docs/conf.py +0 -0
  23. {python_engineio-4.12.1 → python_engineio-4.12.3}/docs/index.rst +0 -0
  24. {python_engineio-4.12.1 → python_engineio-4.12.3}/docs/intro.rst +0 -0
  25. {python_engineio-4.12.1 → python_engineio-4.12.3}/docs/make.bat +0 -0
  26. {python_engineio-4.12.1 → python_engineio-4.12.3}/docs/server.rst +0 -0
  27. {python_engineio-4.12.1 → python_engineio-4.12.3}/setup.cfg +0 -0
  28. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/__init__.py +0 -0
  29. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_drivers/__init__.py +0 -0
  30. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_drivers/_websocket_wsgi.py +0 -0
  31. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_drivers/aiohttp.py +0 -0
  32. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_drivers/eventlet.py +0 -0
  33. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_drivers/gevent.py +0 -0
  34. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_drivers/gevent_uwsgi.py +0 -0
  35. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_drivers/sanic.py +0 -0
  36. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_drivers/threading.py +0 -0
  37. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_drivers/tornado.py +0 -0
  38. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/async_socket.py +0 -0
  39. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/base_socket.py +0 -0
  40. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/exceptions.py +0 -0
  41. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/json.py +0 -0
  42. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/middleware.py +0 -0
  43. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/packet.py +0 -0
  44. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/payload.py +0 -0
  45. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/socket.py +0 -0
  46. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/engineio/static_files.py +0 -0
  47. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/python_engineio.egg-info/SOURCES.txt +0 -0
  48. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/python_engineio.egg-info/dependency_links.txt +0 -0
  49. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/python_engineio.egg-info/not-zip-safe +0 -0
  50. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/python_engineio.egg-info/requires.txt +0 -0
  51. {python_engineio-4.12.1 → python_engineio-4.12.3}/src/python_engineio.egg-info/top_level.txt +0 -0
  52. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/__init__.py +0 -0
  53. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/async/__init__.py +0 -0
  54. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/async/index.html +0 -0
  55. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/async/test_aiohttp.py +0 -0
  56. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/async/test_asgi.py +0 -0
  57. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/async/test_sanic.py +0 -0
  58. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/async/test_socket.py +0 -0
  59. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/async/test_tornado.py +0 -0
  60. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/common/__init__.py +0 -0
  61. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/common/index.html +0 -0
  62. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/common/test_middleware.py +0 -0
  63. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/common/test_packet.py +0 -0
  64. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/common/test_payload.py +0 -0
  65. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/common/test_socket.py +0 -0
  66. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/performance/README.md +0 -0
  67. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/performance/binary_b64_packet.py +0 -0
  68. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/performance/binary_packet.py +0 -0
  69. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/performance/json_packet.py +0 -0
  70. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/performance/payload.py +0 -0
  71. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/performance/run.sh +0 -0
  72. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/performance/server_receive.py +0 -0
  73. {python_engineio-4.12.1 → python_engineio-4.12.3}/tests/performance/text_packet.py +0 -0
  74. {python_engineio-4.12.1 → python_engineio-4.12.3}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-engineio
3
- Version: 4.12.1
3
+ Version: 4.12.3
4
4
  Summary: Engine.IO server and client for Python
5
5
  Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "python-engineio"
3
- version = "4.12.1"
3
+ version = "4.12.3"
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"
@@ -126,7 +126,6 @@ class AsyncClient(base_client.BaseClient):
126
126
  if not transports:
127
127
  raise ValueError('No valid transports provided')
128
128
  self.transports = transports or valid_transports
129
- self.queue = self.create_queue()
130
129
  return await getattr(self, '_connect_' + self.transports[0])(
131
130
  url, headers or {}, engineio_path)
132
131
 
@@ -199,11 +198,15 @@ class AsyncClient(base_client.BaseClient):
199
198
  """
200
199
  return await asyncio.sleep(seconds)
201
200
 
202
- def create_queue(self):
201
+ def create_queue(self, *args, **kwargs):
203
202
  """Create a queue object."""
204
- q = asyncio.Queue()
205
- q.Empty = asyncio.QueueEmpty
206
- return q
203
+ return asyncio.Queue(*args, **kwargs)
204
+
205
+ def get_queue_empty_exception(self):
206
+ """Return the queue empty exception raised by queues created by the
207
+ ``create_queue()`` method.
208
+ """
209
+ return asyncio.QueueEmpty
207
210
 
208
211
  def create_event(self):
209
212
  """Create an event object."""
@@ -211,6 +214,12 @@ class AsyncClient(base_client.BaseClient):
211
214
 
212
215
  async def _reset(self):
213
216
  super()._reset()
217
+ while True: # pragma: no cover
218
+ try:
219
+ self.queue.get_nowait()
220
+ self.queue.task_done()
221
+ except self.queue_empty:
222
+ break
214
223
  if not self.external_http: # pragma: no cover
215
224
  if self.http and not self.http.closed:
216
225
  await self.http.close()
@@ -624,7 +633,7 @@ class AsyncClient(base_client.BaseClient):
624
633
  packets = None
625
634
  try:
626
635
  packets = [await asyncio.wait_for(self.queue.get(), timeout)]
627
- except (self.queue.Empty, asyncio.TimeoutError):
636
+ except (self.queue_empty, asyncio.TimeoutError):
628
637
  self.logger.error('packet queue is empty, aborting')
629
638
  break
630
639
  except asyncio.CancelledError: # pragma: no cover
@@ -636,7 +645,7 @@ class AsyncClient(base_client.BaseClient):
636
645
  while True:
637
646
  try:
638
647
  packets.append(self.queue.get_nowait())
639
- except self.queue.Empty:
648
+ except self.queue_empty:
640
649
  break
641
650
  if packets[-1] is None:
642
651
  packets = packets[:-1]
@@ -280,9 +280,9 @@ class WebSocket: # pragma: no cover
280
280
  event = await self.asgi_receive()
281
281
  if event['type'] != 'websocket.receive':
282
282
  raise OSError()
283
- if 'bytes' in event:
283
+ if event.get('bytes', None) is not None:
284
284
  return event['bytes']
285
- elif 'text' in event:
285
+ elif event.get('text', None) is not None:
286
286
  return event['text']
287
287
  else: # pragma: no cover
288
288
  raise OSError()
@@ -56,8 +56,8 @@ class AsyncServer(base_server.BaseServer):
56
56
  :param cors_allowed_origins: Origin or list of origins that are allowed to
57
57
  connect to this server. Only the same origin
58
58
  is allowed by default. Set this argument to
59
- ``'*'`` to allow all origins, or to ``[]`` to
60
- disable CORS handling.
59
+ ``'*'`` or ``['*']`` to allow all origins, or
60
+ to ``[]`` to disable CORS handling.
61
61
  :param cors_credentials: Whether credentials (cookies, authentication) are
62
62
  allowed in requests to this server.
63
63
  :param logger: To enable logging set to ``True`` or pass a logger object to
@@ -61,7 +61,8 @@ class BaseClient:
61
61
  self.ws = None
62
62
  self.read_loop_task = None
63
63
  self.write_loop_task = None
64
- self.queue = None
64
+ self.queue = self.create_queue()
65
+ self.queue_empty = self.get_queue_empty_exception()
65
66
  self.state = 'disconnected'
66
67
  self.ssl_verify = ssl_verify
67
68
  self.websocket_extra_options = websocket_extra_options or {}
@@ -156,3 +157,13 @@ class BaseClient:
156
157
  if not self.timestamp_requests:
157
158
  return ''
158
159
  return '&t=' + str(time.time())
160
+
161
+ def create_queue(self, *args, **kwargs): # pragma: no cover
162
+ """Create a queue object."""
163
+ raise NotImplementedError('must be implemented in a subclass')
164
+
165
+ def get_queue_empty_exception(self): # pragma: no cover
166
+ """Return the queue empty exception raised by queues created by the
167
+ ``create_queue()`` method.
168
+ """
169
+ raise NotImplementedError('must be implemented in a subclass')
@@ -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
- allowed_origins = self.cors_allowed_origins
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):
@@ -91,7 +91,6 @@ class Client(base_client.BaseClient):
91
91
  if not transports:
92
92
  raise ValueError('No valid transports provided')
93
93
  self.transports = transports or valid_transports
94
- self.queue = self.create_queue()
95
94
  return getattr(self, '_connect_' + self.transports[0])(
96
95
  url, headers or {}, engineio_path)
97
96
 
@@ -162,14 +161,27 @@ class Client(base_client.BaseClient):
162
161
 
163
162
  def create_queue(self, *args, **kwargs):
164
163
  """Create a queue object."""
165
- q = queue.Queue(*args, **kwargs)
166
- q.Empty = queue.Empty
167
- return q
164
+ return queue.Queue(*args, **kwargs)
165
+
166
+ def get_queue_empty_exception(self):
167
+ """Return the queue empty exception raised by queues created by the
168
+ ``create_queue()`` method.
169
+ """
170
+ return queue.Empty
168
171
 
169
172
  def create_event(self, *args, **kwargs):
170
173
  """Create an event object."""
171
174
  return threading.Event(*args, **kwargs)
172
175
 
176
+ def _reset(self):
177
+ super()._reset()
178
+ while True: # pragma: no cover
179
+ try:
180
+ self.queue.get_nowait()
181
+ self.queue.task_done()
182
+ except self.queue_empty:
183
+ break
184
+
173
185
  def _connect_polling(self, url, headers, engineio_path):
174
186
  """Establish a long-polling connection to the Engine.IO server."""
175
187
  if requests is None: # pragma: no cover
@@ -566,7 +578,7 @@ class Client(base_client.BaseClient):
566
578
  packets = None
567
579
  try:
568
580
  packets = [self.queue.get(timeout=timeout)]
569
- except self.queue.Empty:
581
+ except self.queue_empty:
570
582
  self.logger.error('packet queue is empty, aborting')
571
583
  break
572
584
  if packets == [None]:
@@ -576,7 +588,7 @@ class Client(base_client.BaseClient):
576
588
  while True:
577
589
  try:
578
590
  packets.append(self.queue.get(block=False))
579
- except self.queue.Empty:
591
+ except self.queue_empty:
580
592
  break
581
593
  if packets[-1] is None:
582
594
  packets = packets[:-1]
@@ -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 to ``[]`` to
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.12.1
3
+ Version: 4.12.3
4
4
  Summary: Engine.IO server and client for Python
5
5
  Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
6
6
  License: MIT
@@ -16,6 +16,14 @@ from engineio import payload
16
16
 
17
17
 
18
18
  class TestAsyncClient:
19
+ def mock_queue(self, client):
20
+ client.queue = mock.MagicMock()
21
+ client.queue_empty = RuntimeError
22
+ client.queue.get_nowait.side_effect = client.queue_empty
23
+ client.queue.get = mock.AsyncMock()
24
+ client.queue.put = mock.AsyncMock()
25
+ client.queue.join = mock.AsyncMock()
26
+
19
27
  async def test_is_asyncio_based(self):
20
28
  c = async_client.AsyncClient()
21
29
  assert c.is_asyncio_based()
@@ -143,9 +151,7 @@ class TestAsyncClient:
143
151
  base_client.connected_clients.append(c)
144
152
  c.state = 'connected'
145
153
  c.current_transport = 'polling'
146
- c.queue = mock.MagicMock()
147
- c.queue.put = mock.AsyncMock()
148
- c.queue.join = mock.AsyncMock()
154
+ self.mock_queue(c)
149
155
  c.read_loop_task = mock.AsyncMock()()
150
156
  c.ws = mock.MagicMock()
151
157
  c.ws.close = mock.AsyncMock()
@@ -162,9 +168,7 @@ class TestAsyncClient:
162
168
  base_client.connected_clients.append(c)
163
169
  c.state = 'connected'
164
170
  c.current_transport = 'websocket'
165
- c.queue = mock.MagicMock()
166
- c.queue.put = mock.AsyncMock()
167
- c.queue.join = mock.AsyncMock()
171
+ self.mock_queue(c)
168
172
  c.read_loop_task = mock.AsyncMock()()
169
173
  c.ws = mock.MagicMock()
170
174
  c.ws.close = mock.AsyncMock()
@@ -181,9 +185,7 @@ class TestAsyncClient:
181
185
  base_client.connected_clients.append(c)
182
186
  c.state = 'connected'
183
187
  c.current_transport = 'polling'
184
- c.queue = mock.MagicMock()
185
- c.queue.put = mock.AsyncMock()
186
- c.queue.join = mock.AsyncMock()
188
+ self.mock_queue(c)
187
189
  c.read_loop_task = mock.AsyncMock()()
188
190
  c.ws = mock.MagicMock()
189
191
  c.ws.close = mock.AsyncMock()
@@ -197,9 +199,7 @@ class TestAsyncClient:
197
199
  base_client.connected_clients.append(c)
198
200
  c.state = 'connected'
199
201
  c.current_transport = 'websocket'
200
- c.queue = mock.MagicMock()
201
- c.queue.put = mock.AsyncMock()
202
- c.queue.join = mock.AsyncMock()
202
+ self.mock_queue(c)
203
203
  c.read_loop_task = mock.AsyncMock()()
204
204
  c.ws = mock.MagicMock()
205
205
  c.ws.close = mock.AsyncMock()
@@ -225,7 +225,7 @@ class TestAsyncClient:
225
225
  async def test_create_queue(self):
226
226
  c = async_client.AsyncClient()
227
227
  q = c.create_queue()
228
- with pytest.raises(q.Empty):
228
+ with pytest.raises(c.queue_empty):
229
229
  q.get_nowait()
230
230
 
231
231
  async def test_create_event(self):
@@ -1014,8 +1014,7 @@ class TestAsyncClient:
1014
1014
  c.ping_timeout = 5
1015
1015
  c.state = 'connected'
1016
1016
  c.base_url = 'http://foo'
1017
- c.queue = mock.MagicMock()
1018
- c.queue.put = mock.AsyncMock()
1017
+ self.mock_queue(c)
1019
1018
  c._send_request = mock.AsyncMock(return_value=None)
1020
1019
  c._trigger_event = mock.AsyncMock()
1021
1020
  c.write_loop_task = mock.AsyncMock()()
@@ -1036,8 +1035,7 @@ class TestAsyncClient:
1036
1035
  c.ping_timeout = 5
1037
1036
  c.state = 'connected'
1038
1037
  c.base_url = 'http://foo'
1039
- c.queue = mock.MagicMock()
1040
- c.queue.put = mock.AsyncMock()
1038
+ self.mock_queue(c)
1041
1039
  c._send_request = mock.AsyncMock()
1042
1040
  c._send_request.return_value.status = 400
1043
1041
  c.write_loop_task = mock.AsyncMock()()
@@ -1055,8 +1053,7 @@ class TestAsyncClient:
1055
1053
  c.ping_timeout = 60
1056
1054
  c.state = 'connected'
1057
1055
  c.base_url = 'http://foo'
1058
- c.queue = mock.MagicMock()
1059
- c.queue.put = mock.AsyncMock()
1056
+ self.mock_queue(c)
1060
1057
  c._send_request = mock.AsyncMock()
1061
1058
  c._send_request.return_value.status = 200
1062
1059
  c._send_request.return_value.read = mock.AsyncMock(return_value=b'foo')
@@ -1074,8 +1071,7 @@ class TestAsyncClient:
1074
1071
  c.ping_timeout = 5
1075
1072
  c.state = 'connected'
1076
1073
  c.base_url = 'http://foo'
1077
- c.queue = mock.MagicMock()
1078
- c.queue.put = mock.AsyncMock()
1074
+ self.mock_queue(c)
1079
1075
  c._send_request = mock.AsyncMock()
1080
1076
  c._send_request.side_effect = [
1081
1077
  mock.MagicMock(
@@ -1114,8 +1110,7 @@ class TestAsyncClient:
1114
1110
  c.ping_timeout = 2
1115
1111
  c.base_url = 'ws://foo'
1116
1112
  c.state = 'connected'
1117
- c.queue = mock.MagicMock()
1118
- c.queue.put = mock.AsyncMock()
1113
+ self.mock_queue(c)
1119
1114
  c.ws = mock.MagicMock()
1120
1115
  c.ws.receive = mock.AsyncMock(side_effect=asyncio.TimeoutError())
1121
1116
  c.write_loop_task = mock.AsyncMock()()
@@ -1129,8 +1124,7 @@ class TestAsyncClient:
1129
1124
  c.ping_timeout = 2
1130
1125
  c.base_url = 'ws://foo'
1131
1126
  c.state = 'connected'
1132
- c.queue = mock.MagicMock()
1133
- c.queue.put = mock.AsyncMock()
1127
+ self.mock_queue(c)
1134
1128
  c.ws = mock.MagicMock()
1135
1129
  c.ws.receive = mock.AsyncMock(
1136
1130
  side_effect=aiohttp.client_exceptions.ServerDisconnectedError()
@@ -1146,8 +1140,7 @@ class TestAsyncClient:
1146
1140
  c.ping_timeout = 2
1147
1141
  c.base_url = 'ws://foo'
1148
1142
  c.state = 'connected'
1149
- c.queue = mock.MagicMock()
1150
- c.queue.put = mock.AsyncMock()
1143
+ self.mock_queue(c)
1151
1144
  c.ws = mock.MagicMock()
1152
1145
  c.ws.receive = mock.AsyncMock(side_effect=ValueError)
1153
1146
  c.write_loop_task = mock.AsyncMock()()
@@ -1161,8 +1154,7 @@ class TestAsyncClient:
1161
1154
  c.ping_timeout = 2
1162
1155
  c.base_url = 'ws://foo'
1163
1156
  c.state = 'connected'
1164
- c.queue = mock.MagicMock()
1165
- c.queue.put = mock.AsyncMock()
1157
+ self.mock_queue(c)
1166
1158
  c.ws = mock.MagicMock()
1167
1159
  c.ws.receive = mock.AsyncMock(
1168
1160
  side_effect=[
@@ -1188,7 +1180,7 @@ class TestAsyncClient:
1188
1180
  c.state = 'connected'
1189
1181
  c.ping_interval = 1
1190
1182
  c.ping_timeout = 2
1191
- c.queue = mock.MagicMock()
1183
+ self.mock_queue(c)
1192
1184
  c.queue.get = mock.AsyncMock(return_value=None)
1193
1185
  await c._write_loop()
1194
1186
  c.queue.task_done.assert_called_once_with()
@@ -1199,9 +1191,8 @@ class TestAsyncClient:
1199
1191
  c.state = 'connected'
1200
1192
  c.ping_interval = 1
1201
1193
  c.ping_timeout = 2
1202
- c.queue = mock.MagicMock()
1203
- c.queue.Empty = RuntimeError
1204
- c.queue.get = mock.AsyncMock(side_effect=RuntimeError)
1194
+ self.mock_queue(c)
1195
+ c.queue.get = mock.AsyncMock(side_effect=c.queue_empty)
1205
1196
  await c._write_loop()
1206
1197
  c.queue.get.assert_awaited_once_with()
1207
1198
 
@@ -1212,15 +1203,14 @@ class TestAsyncClient:
1212
1203
  c.ping_interval = 1
1213
1204
  c.ping_timeout = 2
1214
1205
  c.current_transport = 'polling'
1215
- c.queue = mock.MagicMock()
1216
- c.queue.Empty = RuntimeError
1206
+ self.mock_queue(c)
1217
1207
  c.queue.get = mock.AsyncMock(
1218
1208
  side_effect=[
1219
1209
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1220
- RuntimeError,
1210
+ c.queue_empty,
1221
1211
  ]
1222
1212
  )
1223
- c.queue.get_nowait = mock.MagicMock(side_effect=RuntimeError)
1213
+ c.queue.get_nowait = mock.MagicMock(side_effect=c.queue_empty)
1224
1214
  c._send_request = mock.AsyncMock()
1225
1215
  c._send_request.return_value.status = 200
1226
1216
  await c._write_loop()
@@ -1243,19 +1233,18 @@ class TestAsyncClient:
1243
1233
  c.ping_interval = 1
1244
1234
  c.ping_timeout = 2
1245
1235
  c.current_transport = 'polling'
1246
- c.queue = mock.MagicMock()
1247
- c.queue.Empty = RuntimeError
1236
+ self.mock_queue(c)
1248
1237
  c.queue.get = mock.AsyncMock(
1249
1238
  side_effect=[
1250
1239
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1251
- RuntimeError,
1240
+ c.queue_empty,
1252
1241
  ]
1253
1242
  )
1254
1243
  c.queue.get_nowait = mock.MagicMock(
1255
1244
  side_effect=[
1256
1245
  packet.Packet(packet.PING),
1257
1246
  packet.Packet(packet.NOOP),
1258
- RuntimeError,
1247
+ c.queue_empty,
1259
1248
  ]
1260
1249
  )
1261
1250
  c._send_request = mock.AsyncMock()
@@ -1284,12 +1273,11 @@ class TestAsyncClient:
1284
1273
  c.ping_interval = 1
1285
1274
  c.ping_timeout = 2
1286
1275
  c.current_transport = 'polling'
1287
- c.queue = mock.MagicMock()
1288
- c.queue.Empty = RuntimeError
1276
+ self.mock_queue(c)
1289
1277
  c.queue.get = mock.AsyncMock(
1290
1278
  side_effect=[
1291
1279
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1292
- RuntimeError,
1280
+ c.queue_empty,
1293
1281
  ]
1294
1282
  )
1295
1283
  c.queue.get_nowait = mock.MagicMock(
@@ -1321,12 +1309,11 @@ class TestAsyncClient:
1321
1309
  c.ping_interval = 1
1322
1310
  c.ping_timeout = 2
1323
1311
  c.current_transport = 'polling'
1324
- c.queue = mock.MagicMock()
1325
- c.queue.Empty = RuntimeError
1312
+ self.mock_queue(c)
1326
1313
  c.queue.get = mock.AsyncMock(
1327
1314
  side_effect=[packet.Packet(packet.MESSAGE, {'foo': 'bar'})]
1328
1315
  )
1329
- c.queue.get_nowait = mock.MagicMock(side_effect=[RuntimeError])
1316
+ c.queue.get_nowait = mock.MagicMock(side_effect=[c.queue_empty])
1330
1317
  c._send_request = mock.AsyncMock(return_value=None)
1331
1318
  await c._write_loop()
1332
1319
  assert c.queue.task_done.call_count == 1
@@ -1349,12 +1336,11 @@ class TestAsyncClient:
1349
1336
  c.ping_interval = 1
1350
1337
  c.ping_timeout = 2
1351
1338
  c.current_transport = 'polling'
1352
- c.queue = mock.MagicMock()
1353
- c.queue.Empty = RuntimeError
1339
+ self.mock_queue(c)
1354
1340
  c.queue.get = mock.AsyncMock(
1355
1341
  side_effect=[packet.Packet(packet.MESSAGE, {'foo': 'bar'})]
1356
1342
  )
1357
- c.queue.get_nowait = mock.MagicMock(side_effect=[RuntimeError])
1343
+ c.queue.get_nowait = mock.MagicMock(side_effect=[c.queue_empty])
1358
1344
  c._send_request = mock.AsyncMock()
1359
1345
  c._send_request.return_value.status = 500
1360
1346
  await c._write_loop()
@@ -1378,15 +1364,14 @@ class TestAsyncClient:
1378
1364
  c.ping_interval = 1
1379
1365
  c.ping_timeout = 2
1380
1366
  c.current_transport = 'websocket'
1381
- c.queue = mock.MagicMock()
1382
- c.queue.Empty = RuntimeError
1367
+ self.mock_queue(c)
1383
1368
  c.queue.get = mock.AsyncMock(
1384
1369
  side_effect=[
1385
1370
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1386
- RuntimeError,
1371
+ c.queue_empty,
1387
1372
  ]
1388
1373
  )
1389
- c.queue.get_nowait = mock.MagicMock(side_effect=[RuntimeError])
1374
+ c.queue.get_nowait = mock.MagicMock(side_effect=[c.queue_empty])
1390
1375
  c.ws = mock.MagicMock()
1391
1376
  c.ws.send_str = mock.AsyncMock()
1392
1377
  await c._write_loop()
@@ -1400,19 +1385,18 @@ class TestAsyncClient:
1400
1385
  c.ping_interval = 1
1401
1386
  c.ping_timeout = 2
1402
1387
  c.current_transport = 'websocket'
1403
- c.queue = mock.MagicMock()
1404
- c.queue.Empty = RuntimeError
1388
+ self.mock_queue(c)
1405
1389
  c.queue.get = mock.AsyncMock(
1406
1390
  side_effect=[
1407
1391
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1408
- RuntimeError,
1392
+ c.queue_empty,
1409
1393
  ]
1410
1394
  )
1411
1395
  c.queue.get_nowait = mock.MagicMock(
1412
1396
  side_effect=[
1413
1397
  packet.Packet(packet.PING),
1414
1398
  packet.Packet(packet.NOOP),
1415
- RuntimeError,
1399
+ c.queue_empty,
1416
1400
  ]
1417
1401
  )
1418
1402
  c.ws = mock.MagicMock()
@@ -1430,12 +1414,11 @@ class TestAsyncClient:
1430
1414
  c.ping_interval = 1
1431
1415
  c.ping_timeout = 2
1432
1416
  c.current_transport = 'websocket'
1433
- c.queue = mock.MagicMock()
1434
- c.queue.Empty = RuntimeError
1417
+ self.mock_queue(c)
1435
1418
  c.queue.get = mock.AsyncMock(
1436
- side_effect=[packet.Packet(packet.MESSAGE, b'foo'), RuntimeError]
1419
+ side_effect=[packet.Packet(packet.MESSAGE, b'foo'), c.queue_empty]
1437
1420
  )
1438
- c.queue.get_nowait = mock.MagicMock(side_effect=[RuntimeError])
1421
+ c.queue.get_nowait = mock.MagicMock(side_effect=[c.queue_empty])
1439
1422
  c.ws = mock.MagicMock()
1440
1423
  c.ws.send_bytes = mock.AsyncMock()
1441
1424
  await c._write_loop()
@@ -1449,15 +1432,14 @@ class TestAsyncClient:
1449
1432
  c.ping_interval = 1
1450
1433
  c.ping_timeout = 2
1451
1434
  c.current_transport = 'websocket'
1452
- c.queue = mock.MagicMock()
1453
- c.queue.Empty = RuntimeError
1435
+ self.mock_queue(c)
1454
1436
  c.queue.get = mock.AsyncMock(
1455
1437
  side_effect=[
1456
1438
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1457
- RuntimeError,
1439
+ c.queue_empty,
1458
1440
  ]
1459
1441
  )
1460
- c.queue.get_nowait = mock.MagicMock(side_effect=[RuntimeError])
1442
+ c.queue.get_nowait = mock.MagicMock(side_effect=[c.queue_empty])
1461
1443
  c.ws = mock.MagicMock()
1462
1444
  c.ws.send_str = mock.AsyncMock(
1463
1445
  side_effect=aiohttp.client_exceptions.ServerDisconnectedError()
@@ -454,7 +454,7 @@ class TestAsyncServer:
454
454
  assert ('Access-Control-Allow-Origin', '*') not in headers
455
455
 
456
456
  @mock.patch('importlib.import_module')
457
- async def test_connect_cors_all_origins(self, import_module):
457
+ async def test_connect_str_cors_all_origins(self, import_module):
458
458
  a = self.get_async_mock(
459
459
  {'REQUEST_METHOD': 'GET', 'QUERY_STRING': '', 'HTTP_ORIGIN': 'foo'}
460
460
  )
@@ -466,6 +466,19 @@ class TestAsyncServer:
466
466
  assert ('Access-Control-Allow-Origin', 'foo') in headers
467
467
  assert ('Access-Control-Allow-Credentials', 'true') in headers
468
468
 
469
+ @mock.patch('importlib.import_module')
470
+ async def test_connect_list_cors_all_origins(self, import_module):
471
+ a = self.get_async_mock(
472
+ {'REQUEST_METHOD': 'GET', 'QUERY_STRING': '', 'HTTP_ORIGIN': 'foo'}
473
+ )
474
+ import_module.side_effect = [a]
475
+ s = async_server.AsyncServer(cors_allowed_origins=['*'])
476
+ await s.handle_request('request')
477
+ assert a._async['make_response'].call_args[0][0] == '200 OK'
478
+ headers = a._async['make_response'].call_args[0][1]
479
+ assert ('Access-Control-Allow-Origin', 'foo') in headers
480
+ assert ('Access-Control-Allow-Credentials', 'true') in headers
481
+
469
482
  @mock.patch('importlib.import_module')
470
483
  async def test_connect_cors_one_origin(self, import_module):
471
484
  a = self.get_async_mock(
@@ -564,7 +577,7 @@ class TestAsyncServer:
564
577
  assert header[0] != 'Access-Control-Allow-Origin'
565
578
 
566
579
  @mock.patch('importlib.import_module')
567
- async def test_connect_cors_all_no_origin(self, import_module):
580
+ async def test_connect_str_cors_all_no_origin(self, import_module):
568
581
  a = self.get_async_mock({'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''})
569
582
  import_module.side_effect = [a]
570
583
  s = async_server.AsyncServer(cors_allowed_origins='*')
@@ -574,6 +587,17 @@ class TestAsyncServer:
574
587
  for header in headers:
575
588
  assert header[0] != 'Access-Control-Allow-Origin'
576
589
 
590
+ @mock.patch('importlib.import_module')
591
+ async def test_connect_list_cors_all_no_origin(self, import_module):
592
+ a = self.get_async_mock({'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''})
593
+ import_module.side_effect = [a]
594
+ s = async_server.AsyncServer(cors_allowed_origins=['*'])
595
+ await s.handle_request('request')
596
+ assert a._async['make_response'].call_args[0][0] == '200 OK'
597
+ headers = a._async['make_response'].call_args[0][1]
598
+ for header in headers:
599
+ assert header[0] != 'Access-Control-Allow-Origin'
600
+
577
601
  @mock.patch('importlib.import_module')
578
602
  async def test_connect_cors_disabled_no_origin(self, import_module):
579
603
  a = self.get_async_mock({'REQUEST_METHOD': 'GET', 'QUERY_STRING': ''})
@@ -15,6 +15,11 @@ from engineio import payload
15
15
 
16
16
 
17
17
  class TestClient:
18
+ def mock_queue(self, client):
19
+ client.queue = mock.MagicMock()
20
+ client.queue_empty = RuntimeError
21
+ client.queue.get_nowait.side_effect = client.queue_empty
22
+
18
23
  def test_is_asyncio_based(self):
19
24
  c = client.Client()
20
25
  assert not c.is_asyncio_based()
@@ -33,10 +38,11 @@ class TestClient:
33
38
  'ws',
34
39
  'read_loop_task',
35
40
  'write_loop_task',
36
- 'queue',
37
41
  ]:
38
42
  assert getattr(c, attr) is None, attr + ' is not None'
39
43
  assert c.state == 'disconnected'
44
+ assert c.queue.__class__.__name__ == 'Queue'
45
+ assert c.queue_empty.__name__ == 'Empty'
40
46
 
41
47
  def test_custom_json(self):
42
48
  client.Client()
@@ -208,7 +214,7 @@ class TestClient:
208
214
  base_client.connected_clients.append(c)
209
215
  c.state = 'connected'
210
216
  c.current_transport = 'polling'
211
- c.queue = mock.MagicMock()
217
+ self.mock_queue(c)
212
218
  c.read_loop_task = mock.MagicMock()
213
219
  c.ws = mock.MagicMock()
214
220
  c._trigger_event = mock.MagicMock()
@@ -224,7 +230,7 @@ class TestClient:
224
230
  base_client.connected_clients.append(c)
225
231
  c.state = 'connected'
226
232
  c.current_transport = 'websocket'
227
- c.queue = mock.MagicMock()
233
+ self.mock_queue(c)
228
234
  c.read_loop_task = mock.MagicMock()
229
235
  c.ws = mock.MagicMock()
230
236
  c._trigger_event = mock.MagicMock()
@@ -240,7 +246,7 @@ class TestClient:
240
246
  base_client.connected_clients.append(c)
241
247
  c.state = 'connected'
242
248
  c.current_transport = 'polling'
243
- c.queue = mock.MagicMock()
249
+ self.mock_queue(c)
244
250
  c.read_loop_task = mock.MagicMock()
245
251
  c.ws = mock.MagicMock()
246
252
  c.disconnect(abort=True)
@@ -254,7 +260,7 @@ class TestClient:
254
260
  base_client.connected_clients.append(c)
255
261
  c.state = 'connected'
256
262
  c.current_transport = 'websocket'
257
- c.queue = mock.MagicMock()
263
+ self.mock_queue(c)
258
264
  c.read_loop_task = mock.MagicMock()
259
265
  c.ws = mock.MagicMock()
260
266
  c.disconnect(abort=True)
@@ -289,7 +295,7 @@ class TestClient:
289
295
  def test_create_queue(self):
290
296
  c = client.Client()
291
297
  q = c.create_queue()
292
- with pytest.raises(q.Empty):
298
+ with pytest.raises(c.queue_empty):
293
299
  q.get(timeout=0.01)
294
300
 
295
301
  def test_create_event(self):
@@ -1331,7 +1337,7 @@ class TestClient:
1331
1337
  c.ping_timeout = 5
1332
1338
  c.state = 'connected'
1333
1339
  c.base_url = 'http://foo'
1334
- c.queue = mock.MagicMock()
1340
+ self.mock_queue(c)
1335
1341
  c._send_request = mock.MagicMock(return_value=None)
1336
1342
  c._trigger_event = mock.MagicMock()
1337
1343
  c.write_loop_task = mock.MagicMock()
@@ -1352,7 +1358,7 @@ class TestClient:
1352
1358
  c.ping_timeout = 5
1353
1359
  c.state = 'connected'
1354
1360
  c.base_url = 'http://foo'
1355
- c.queue = mock.MagicMock()
1361
+ self.mock_queue(c)
1356
1362
  c._send_request = mock.MagicMock()
1357
1363
  c._send_request.return_value.status_code = 400
1358
1364
  c.write_loop_task = mock.MagicMock()
@@ -1371,7 +1377,7 @@ class TestClient:
1371
1377
  c.ping_timeout = 60
1372
1378
  c.state = 'connected'
1373
1379
  c.base_url = 'http://foo'
1374
- c.queue = mock.MagicMock()
1380
+ self.mock_queue(c)
1375
1381
  c._send_request = mock.MagicMock()
1376
1382
  c._send_request.return_value.status_code = 200
1377
1383
  c._send_request.return_value.content = b'foo'
@@ -1390,7 +1396,7 @@ class TestClient:
1390
1396
  c.ping_timeout = 5
1391
1397
  c.state = 'connected'
1392
1398
  c.base_url = 'http://foo'
1393
- c.queue = mock.MagicMock()
1399
+ self.mock_queue(c)
1394
1400
  c._send_request = mock.MagicMock()
1395
1401
  c._send_request.side_effect = [
1396
1402
  mock.MagicMock(
@@ -1424,7 +1430,7 @@ class TestClient:
1424
1430
  def test_read_loop_websocket_timeout(self):
1425
1431
  c = client.Client()
1426
1432
  c.state = 'connected'
1427
- c.queue = mock.MagicMock()
1433
+ self.mock_queue(c)
1428
1434
  c.ws = mock.MagicMock()
1429
1435
  c.ws.recv.side_effect = websocket.WebSocketTimeoutException
1430
1436
  c.write_loop_task = mock.MagicMock()
@@ -1436,7 +1442,7 @@ class TestClient:
1436
1442
  def test_read_loop_websocket_no_response(self):
1437
1443
  c = client.Client()
1438
1444
  c.state = 'connected'
1439
- c.queue = mock.MagicMock()
1445
+ self.mock_queue(c)
1440
1446
  c.ws = mock.MagicMock()
1441
1447
  c.ws.recv.side_effect = websocket.WebSocketConnectionClosedException
1442
1448
  c.write_loop_task = mock.MagicMock()
@@ -1448,7 +1454,7 @@ class TestClient:
1448
1454
  def test_read_loop_websocket_unexpected_error(self):
1449
1455
  c = client.Client()
1450
1456
  c.state = 'connected'
1451
- c.queue = mock.MagicMock()
1457
+ self.mock_queue(c)
1452
1458
  c.ws = mock.MagicMock()
1453
1459
  c.ws.recv.side_effect = ValueError
1454
1460
  c.write_loop_task = mock.MagicMock()
@@ -1462,7 +1468,7 @@ class TestClient:
1462
1468
  c.ping_interval = 1
1463
1469
  c.ping_timeout = 2
1464
1470
  c.state = 'connected'
1465
- c.queue = mock.MagicMock()
1471
+ self.mock_queue(c)
1466
1472
  c.ws = mock.MagicMock()
1467
1473
  c.ws.recv.side_effect = [
1468
1474
  packet.Packet(packet.PING).encode(),
@@ -1487,7 +1493,7 @@ class TestClient:
1487
1493
  c.state = 'connected'
1488
1494
  c.ping_interval = 1
1489
1495
  c.ping_timeout = 2
1490
- c.queue = mock.MagicMock()
1496
+ self.mock_queue(c)
1491
1497
  c.queue.get.return_value = None
1492
1498
  c._write_loop()
1493
1499
  c.queue.task_done.assert_called_once_with()
@@ -1498,9 +1504,8 @@ class TestClient:
1498
1504
  c.state = 'connected'
1499
1505
  c.ping_interval = 1
1500
1506
  c.ping_timeout = 2
1501
- c.queue = mock.MagicMock()
1502
- c.queue.Empty = RuntimeError
1503
- c.queue.get.side_effect = RuntimeError
1507
+ self.mock_queue(c)
1508
+ c.queue.get.side_effect = c.queue_empty
1504
1509
  c._write_loop()
1505
1510
  c.queue.get.assert_called_once_with(timeout=7)
1506
1511
 
@@ -1511,12 +1516,11 @@ class TestClient:
1511
1516
  c.ping_interval = 1
1512
1517
  c.ping_timeout = 2
1513
1518
  c.current_transport = 'polling'
1514
- c.queue = mock.MagicMock()
1515
- c.queue.Empty = RuntimeError
1519
+ self.mock_queue(c)
1516
1520
  c.queue.get.side_effect = [
1517
1521
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1518
- RuntimeError,
1519
- RuntimeError,
1522
+ c.queue_empty,
1523
+ c.queue_empty,
1520
1524
  ]
1521
1525
  c._send_request = mock.MagicMock()
1522
1526
  c._send_request.return_value.status_code = 200
@@ -1540,14 +1544,13 @@ class TestClient:
1540
1544
  c.ping_interval = 1
1541
1545
  c.ping_timeout = 2
1542
1546
  c.current_transport = 'polling'
1543
- c.queue = mock.MagicMock()
1544
- c.queue.Empty = RuntimeError
1547
+ self.mock_queue(c)
1545
1548
  c.queue.get.side_effect = [
1546
1549
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1547
1550
  packet.Packet(packet.PING),
1548
1551
  packet.Packet(packet.NOOP),
1549
- RuntimeError,
1550
- RuntimeError,
1552
+ c.queue_empty,
1553
+ c.queue_empty,
1551
1554
  ]
1552
1555
  c._send_request = mock.MagicMock()
1553
1556
  c._send_request.return_value.status_code = 200
@@ -1575,13 +1578,12 @@ class TestClient:
1575
1578
  c.ping_interval = 1
1576
1579
  c.ping_timeout = 2
1577
1580
  c.current_transport = 'polling'
1578
- c.queue = mock.MagicMock()
1579
- c.queue.Empty = RuntimeError
1581
+ self.mock_queue(c)
1580
1582
  c.queue.get.side_effect = [
1581
1583
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1582
1584
  packet.Packet(packet.PING),
1583
1585
  None,
1584
- RuntimeError,
1586
+ c.queue_empty,
1585
1587
  ]
1586
1588
  c._send_request = mock.MagicMock()
1587
1589
  c._send_request.return_value.status_code = 200
@@ -1609,11 +1611,10 @@ class TestClient:
1609
1611
  c.ping_interval = 1
1610
1612
  c.ping_timeout = 2
1611
1613
  c.current_transport = 'polling'
1612
- c.queue = mock.MagicMock()
1613
- c.queue.Empty = RuntimeError
1614
+ self.mock_queue(c)
1614
1615
  c.queue.get.side_effect = [
1615
1616
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1616
- RuntimeError,
1617
+ c.queue_empty,
1617
1618
  ]
1618
1619
  c._send_request = mock.MagicMock()
1619
1620
  c._send_request.return_value = None
@@ -1638,11 +1639,10 @@ class TestClient:
1638
1639
  c.ping_interval = 1
1639
1640
  c.ping_timeout = 2
1640
1641
  c.current_transport = 'polling'
1641
- c.queue = mock.MagicMock()
1642
- c.queue.Empty = RuntimeError
1642
+ self.mock_queue(c)
1643
1643
  c.queue.get.side_effect = [
1644
1644
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1645
- RuntimeError,
1645
+ c.queue_empty,
1646
1646
  ]
1647
1647
  c._send_request = mock.MagicMock()
1648
1648
  c._send_request.return_value.status_code = 500
@@ -1667,12 +1667,11 @@ class TestClient:
1667
1667
  c.ping_interval = 1
1668
1668
  c.ping_timeout = 2
1669
1669
  c.current_transport = 'websocket'
1670
- c.queue = mock.MagicMock()
1671
- c.queue.Empty = RuntimeError
1670
+ self.mock_queue(c)
1672
1671
  c.queue.get.side_effect = [
1673
1672
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1674
- RuntimeError,
1675
- RuntimeError,
1673
+ c.queue_empty,
1674
+ c.queue_empty,
1676
1675
  ]
1677
1676
  c.ws = mock.MagicMock()
1678
1677
  c._write_loop()
@@ -1687,14 +1686,13 @@ class TestClient:
1687
1686
  c.ping_interval = 1
1688
1687
  c.ping_timeout = 2
1689
1688
  c.current_transport = 'websocket'
1690
- c.queue = mock.MagicMock()
1691
- c.queue.Empty = RuntimeError
1689
+ self.mock_queue(c)
1692
1690
  c.queue.get.side_effect = [
1693
1691
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1694
1692
  packet.Packet(packet.PING),
1695
1693
  packet.Packet(packet.NOOP),
1696
- RuntimeError,
1697
- RuntimeError,
1694
+ c.queue_empty,
1695
+ c.queue_empty,
1698
1696
  ]
1699
1697
  c.ws = mock.MagicMock()
1700
1698
  c._write_loop()
@@ -1711,12 +1709,11 @@ class TestClient:
1711
1709
  c.ping_interval = 1
1712
1710
  c.ping_timeout = 2
1713
1711
  c.current_transport = 'websocket'
1714
- c.queue = mock.MagicMock()
1715
- c.queue.Empty = RuntimeError
1712
+ self.mock_queue(c)
1716
1713
  c.queue.get.side_effect = [
1717
1714
  packet.Packet(packet.MESSAGE, b'foo'),
1718
- RuntimeError,
1719
- RuntimeError,
1715
+ c.queue_empty,
1716
+ c.queue_empty,
1720
1717
  ]
1721
1718
  c.ws = mock.MagicMock()
1722
1719
  c._write_loop()
@@ -1731,12 +1728,11 @@ class TestClient:
1731
1728
  c.ping_interval = 1
1732
1729
  c.ping_timeout = 2
1733
1730
  c.current_transport = 'websocket'
1734
- c.queue = mock.MagicMock()
1735
- c.queue.Empty = RuntimeError
1731
+ self.mock_queue(c)
1736
1732
  c.queue.get.side_effect = [
1737
1733
  packet.Packet(packet.MESSAGE, {'foo': 'bar'}),
1738
- RuntimeError,
1739
- RuntimeError,
1734
+ c.queue_empty,
1735
+ c.queue_empty,
1740
1736
  ]
1741
1737
  c.ws = mock.MagicMock()
1742
1738
  c.ws.send.side_effect = websocket.WebSocketConnectionClosedException
@@ -615,7 +615,7 @@ class TestServer:
615
615
  assert ('Access-Control-Allow-Origin', 'c') not in headers
616
616
  assert ('Access-Control-Allow-Origin', '*') not in headers
617
617
 
618
- def test_connect_cors_headers_all_origins(self):
618
+ def test_connect_str_cors_headers_all_origins(self):
619
619
  s = server.Server(cors_allowed_origins='*')
620
620
  environ = {
621
621
  'REQUEST_METHOD': 'GET',
@@ -629,6 +629,20 @@ class TestServer:
629
629
  assert ('Access-Control-Allow-Origin', 'foo') in headers
630
630
  assert ('Access-Control-Allow-Credentials', 'true') in headers
631
631
 
632
+ def test_connect_list_cors_headers_all_origins(self):
633
+ s = server.Server(cors_allowed_origins=['*'])
634
+ environ = {
635
+ 'REQUEST_METHOD': 'GET',
636
+ 'QUERY_STRING': 'EIO=4',
637
+ 'HTTP_ORIGIN': 'foo',
638
+ }
639
+ start_response = mock.MagicMock()
640
+ s.handle_request(environ, start_response)
641
+ assert start_response.call_args[0][0] == '200 OK'
642
+ headers = start_response.call_args[0][1]
643
+ assert ('Access-Control-Allow-Origin', 'foo') in headers
644
+ assert ('Access-Control-Allow-Credentials', 'true') in headers
645
+
632
646
  def test_connect_cors_headers_one_origin(self):
633
647
  s = server.Server(cors_allowed_origins='a')
634
648
  environ = {
@@ -762,7 +776,7 @@ class TestServer:
762
776
  for header in headers:
763
777
  assert header[0] != 'Access-Control-Allow-Origin'
764
778
 
765
- def test_connect_cors_all_no_origin(self):
779
+ def test_connect_str_cors_all_no_origin(self):
766
780
  s = server.Server(cors_allowed_origins='*')
767
781
  environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'EIO=4'}
768
782
  start_response = mock.MagicMock()
@@ -771,6 +785,15 @@ class TestServer:
771
785
  for header in headers:
772
786
  assert header[0] != 'Access-Control-Allow-Origin'
773
787
 
788
+ def test_connect_list_cors_all_no_origin(self):
789
+ s = server.Server(cors_allowed_origins=['*'])
790
+ environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'EIO=4'}
791
+ start_response = mock.MagicMock()
792
+ s.handle_request(environ, start_response)
793
+ headers = start_response.call_args[0][1]
794
+ for header in headers:
795
+ assert header[0] != 'Access-Control-Allow-Origin'
796
+
774
797
  def test_connect_cors_disabled_no_origin(self):
775
798
  s = server.Server(cors_allowed_origins=[])
776
799
  environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'EIO=4'}