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.
@@ -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('content-disposition:'):
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('sec-websocket-key')
52
- subprotocols = self.request.headers.get('sec-websocket-protocol')
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
- 'upgrade': 'websocket',
231
- 'connection': 'upgrade',
232
- 'sec-websocket-accept': base64.b64encode(hashlib.sha1(f'{self.websocket.key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11'.encode('utf-8')).digest()).decode('utf-8')
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['sec-websocket-protocol'] = subprotocol
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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: CheeseAPI
3
- Version: 2.0.8b5
3
+ Version: 2.0.8b6
4
4
  Summary: 一款web协程框架
5
5
  Project-URL: Source, https://github.com/CheeseUnknown/CheeseAPI
6
6
  Author-email: Cheese Unknown <cheese@cheese.ren>
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "CheeseAPI"
7
- version = "2.0.8-beta.5"
7
+ version = "2.0.8-beta.6"
8
8
  description = "一款web协程框架"
9
9
  readme = "README.md"
10
10
  license-files = { paths = [ "LICENSE" ] }
File without changes
File without changes
File without changes