latch-asgi 1.0.6.dev1__tar.gz → 1.0.6.dev3__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 (19) hide show
  1. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/PKG-INFO +1 -1
  2. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/context/websocket.py +12 -1
  3. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/server.py +7 -15
  4. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/pyproject.toml +1 -1
  5. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/COPYING +0 -0
  6. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/README.md +0 -0
  7. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/__init__.py +0 -0
  8. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/asgi_iface.py +0 -0
  9. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/auth.py +0 -0
  10. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/config.py +0 -0
  11. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/context/__init__.py +0 -0
  12. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/context/common.py +0 -0
  13. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/context/http.py +0 -0
  14. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/datadog_propagator.py +0 -0
  15. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/framework/__init__.py +0 -0
  16. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/framework/common.py +0 -0
  17. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/framework/http.py +0 -0
  18. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/framework/websocket.py +0 -0
  19. {latch_asgi-1.0.6.dev1 → latch_asgi-1.0.6.dev3}/latch_asgi/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: latch-asgi
3
- Version: 1.0.6.dev1
3
+ Version: 1.0.6.dev3
4
4
  Summary: ASGI python server
5
5
  Author-Email: Max Smolin <max@latch.bio>
6
6
  License: CC0-1.0
@@ -58,7 +58,18 @@ class Context(
58
58
  and "permessage-deflate" in offer.replace(" ", "").lower()
59
59
  and not _has_extensions_header(headers_out)
60
60
  ):
61
- headers_out["Sec-WebSocket-Extensions"] = "permessage-deflate"
61
+ # Minimal negotiation: if the client offered client_max_window_bits without a value,
62
+ # reply with a concrete value to satisfy browsers like Chrome.
63
+ offer_no_space = offer.replace(" ", "").lower()
64
+ if (
65
+ "client_max_window_bits" in offer_no_space
66
+ and "client_max_window_bits=" not in offer_no_space
67
+ ):
68
+ headers_out["Sec-WebSocket-Extensions"] = (
69
+ "permessage-deflate; client_max_window_bits=15"
70
+ )
71
+ else:
72
+ headers_out["Sec-WebSocket-Extensions"] = "permessage-deflate"
62
73
 
63
74
  await accept_connection(
64
75
  self.send, subprotocol=subprotocol, headers=headers_out or headers
@@ -222,13 +222,6 @@ class LatchASGIServer:
222
222
  s.set_attribute("http.route", scope["path"])
223
223
 
224
224
  close_reason: str | None = None
225
- close_already_sent: bool = False
226
-
227
- async def send_tracking(e):
228
- nonlocal close_already_sent
229
- if isinstance(e, dict) and e.get("type") == "websocket.close":
230
- close_already_sent = True
231
- await send(e)
232
225
  try:
233
226
  try:
234
227
  msg = await receive()
@@ -237,7 +230,7 @@ class LatchASGIServer:
237
230
  "ASGI protocol violation: missing websocket.connect event"
238
231
  )
239
232
 
240
- ctx = websocket.Context(scope, receive, send_tracking)
233
+ ctx = websocket.Context(scope, receive, send)
241
234
  close_reason = await handler(ctx)
242
235
  except WebsocketErrorResponse:
243
236
  raise
@@ -248,7 +241,7 @@ class LatchASGIServer:
248
241
  raise WebsocketInternalServerError("Internal Error") from e
249
242
  except WebsocketErrorResponse as e:
250
243
  await close_connection(
251
- send_tracking, status=e.status, reason=orjson.dumps({"error": e.data}).decode()
244
+ send, status=e.status, reason=orjson.dumps({"error": e.data}).decode()
252
245
  )
253
246
 
254
247
  if e.status != WebsocketStatus.server_error:
@@ -256,13 +249,12 @@ class LatchASGIServer:
256
249
 
257
250
  raise
258
251
  else:
259
- if not close_already_sent:
260
- if close_reason is None:
261
- close_reason = "Session complete"
252
+ if close_reason is None:
253
+ close_reason = "Session complete"
262
254
 
263
- await close_connection(
264
- send_tracking, status=WebsocketStatus.normal, reason=close_reason
265
- )
255
+ await close_connection(
256
+ send, status=WebsocketStatus.normal, reason=close_reason
257
+ )
266
258
 
267
259
  async def scope_http(
268
260
  self: Self,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "latch-asgi"
3
- version = "1.0.6.dev1"
3
+ version = "1.0.6.dev3"
4
4
  description = "ASGI python server"
5
5
  authors = [
6
6
  { name = "Max Smolin", email = "max@latch.bio" },
File without changes