CheeseAPI 2.0.8b5__tar.gz → 2.0.8b6__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.
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/request.py +1 -1
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/websocket.py +24 -7
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/PKG-INFO +1 -1
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/pyproject.toml +1 -1
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/.gitignore +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/__init__.py +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/app.py +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/cors.py +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/file.py +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/printer.py +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/response.py +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/route.py +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/scheduler.py +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/signal.py +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/static.py +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/CheeseAPI/validator.py +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/LICENSE +0 -0
- {cheeseapi-2.0.8b5 → cheeseapi-2.0.8b6}/README.md +0 -0
|
@@ -267,7 +267,7 @@ class RequestProxy:
|
|
|
267
267
|
name = None
|
|
268
268
|
filename = None
|
|
269
269
|
for line in headers.decode().strip().split('\r\n'):
|
|
270
|
-
if line.startswith('
|
|
270
|
+
if line.startswith('Content-Disposition:'):
|
|
271
271
|
name_match = re.search(r'name="([^"]*)"', line)
|
|
272
272
|
if name_match:
|
|
273
273
|
name = name_match.group(1)
|
|
@@ -48,8 +48,8 @@ class Websocket:
|
|
|
48
48
|
self._request: 'Request' = request
|
|
49
49
|
|
|
50
50
|
self._proxy: 'WebsocketProxy' = request._proxy.app.WebsocketProxy_Class(request._proxy.app, self)
|
|
51
|
-
self._key: str = self.request.headers.get('
|
|
52
|
-
subprotocols = self.request.headers.get('
|
|
51
|
+
self._key: str = self.request.headers.get('Sec-WebSocket-Key')
|
|
52
|
+
subprotocols = self.request.headers.get('Sec-WebSocket-Protocol')
|
|
53
53
|
self._subprotocols: list[str] | None = subprotocols.strip().split(',') if subprotocols else None
|
|
54
54
|
self._subprotocol: str | None = None
|
|
55
55
|
self.response: Response | None = None
|
|
@@ -109,6 +109,8 @@ class Websocket:
|
|
|
109
109
|
close = DualMethod(_static_close, _instance_close)
|
|
110
110
|
|
|
111
111
|
class WebsocketProxy:
|
|
112
|
+
_sync_tasks: dict[str, asyncio.Task] = {}
|
|
113
|
+
|
|
112
114
|
@staticmethod
|
|
113
115
|
def _static_send(path: str, data: bytes | list | str | dict, *, websocket_key_or_keys: str | list[str] | None = None):
|
|
114
116
|
if static.websocket_sync_servers is not None:
|
|
@@ -227,15 +229,15 @@ class WebsocketProxy:
|
|
|
227
229
|
|
|
228
230
|
async def get_response(self) -> Response:
|
|
229
231
|
headers = {
|
|
230
|
-
'
|
|
231
|
-
'
|
|
232
|
-
'
|
|
232
|
+
'Upgrade': 'websocket',
|
|
233
|
+
'Connection': 'Upgrade',
|
|
234
|
+
'Sec-WebSocket-Accept': base64.b64encode(hashlib.sha1(f'{self.websocket.key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11'.encode('utf-8')).digest()).decode('utf-8')
|
|
233
235
|
}
|
|
234
236
|
if self.websocket.subprotocols:
|
|
235
237
|
subprotocol = await self.websocket.on_subprotocol(self.websocket.subprotocols)
|
|
236
238
|
if subprotocol:
|
|
237
239
|
self.websocket._subprotocol = subprotocol
|
|
238
|
-
headers['
|
|
240
|
+
headers['Sec-WebSocket-Protocol'] = subprotocol
|
|
239
241
|
response = self.app.ResponseProxy_Class(self.app, Response(status = 101, headers = headers)).response
|
|
240
242
|
response._proxy.websocket = self.websocket
|
|
241
243
|
return response
|
|
@@ -244,7 +246,7 @@ class WebsocketProxy:
|
|
|
244
246
|
Websocket.connectors.setdefault(self.websocket.request.path, []).append(self.websocket)
|
|
245
247
|
if self.app.sync_server_url and self.websocket.request.path not in static.websocket_sync_server:
|
|
246
248
|
static.websocket_sync_server[self.websocket.request.path] = redis.asyncio.Redis.from_url(self.app.sync_server_url, socket_timeout = self.app.sync_server_timeout, socket_connect_timeout = self.app.sync_server_timeout)
|
|
247
|
-
asyncio.create_task(self.sync_server_running())
|
|
249
|
+
WebsocketProxy._sync_tasks[self.websocket.request.path] = asyncio.create_task(self.sync_server_running())
|
|
248
250
|
|
|
249
251
|
loop = asyncio.get_running_loop()
|
|
250
252
|
self.reader = asyncio.StreamReader()
|
|
@@ -259,10 +261,18 @@ class WebsocketProxy:
|
|
|
259
261
|
await self.websocket.on_connect()
|
|
260
262
|
|
|
261
263
|
async def sync_server_running(self):
|
|
264
|
+
pubsub = None
|
|
262
265
|
try:
|
|
263
266
|
if self.app.sync_server_url.startswith('redis'):
|
|
264
267
|
while True:
|
|
265
268
|
try:
|
|
269
|
+
if pubsub is not None:
|
|
270
|
+
try:
|
|
271
|
+
await pubsub.aclose()
|
|
272
|
+
except Exception:
|
|
273
|
+
pass
|
|
274
|
+
pubsub = None
|
|
275
|
+
|
|
266
276
|
pubsub = redis.asyncio.from_url(self.app.sync_server_url, socket_timeout = None, socket_connect_timeout = None).pubsub()
|
|
267
277
|
await pubsub.subscribe(self.websocket.request.path)
|
|
268
278
|
async for message in pubsub.listen():
|
|
@@ -302,6 +312,13 @@ class WebsocketProxy:
|
|
|
302
312
|
await asyncio.sleep(self.app.sync_server_timeout)
|
|
303
313
|
except (KeyboardInterrupt, SystemExit, asyncio.CancelledError):
|
|
304
314
|
...
|
|
315
|
+
finally:
|
|
316
|
+
WebsocketProxy._sync_tasks.pop(self.websocket.request.path, None)
|
|
317
|
+
if pubsub is not None:
|
|
318
|
+
try:
|
|
319
|
+
await pubsub.aclose()
|
|
320
|
+
except Exception:
|
|
321
|
+
pass
|
|
305
322
|
|
|
306
323
|
async def message(self):
|
|
307
324
|
while True:
|
|
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
|