Scille / parsec-cloud

Open source Dropbox-like file sharing with full client encryption !
https://parsec.cloud
Other
268 stars 40 forks source link

ASGI callable returned without completing response. #8438

Open sentry-io[bot] opened 20 hours ago

sentry-io[bot] commented 20 hours ago

Sentry Issue: PARSEC3-SERVER-P

ASGI callable returned without completing response.
vxgmichel commented 20 hours ago

Can be easily reproduced using this patch:

diff --git a/server/parsec/components/events.py b/server/parsec/components/events.py
index 7009a722b..62f383697 100644
--- a/server/parsec/components/events.py
+++ b/server/parsec/components/events.py
@@ -428,7 +428,14 @@ class BaseEventsComponent:
                 client_ctx=client_ctx, last_event_id=last_event_id, cancel_scope=cancel_scope
             )
             try:
-                yield outcome
+
+                async def cancel_later(cancel_scope: anyio.CancelScope):
+                    await anyio.sleep(10)
+                    cancel_scope.cancel()
+
+                async with anyio.create_task_group() as tg:
+                    tg.start_soon(cancel_later, cancel_scope)
+                    yield outcome
             finally:
                 if not isinstance(outcome, SseAPiEventsListenBadOutcome):
                     # It's vital to unregister the client here given the memory location of the
vxgmichel commented 20 hours ago

Can be easily fixed using this patch:

diff --git a/server/parsec/asgi/rpc.py b/server/parsec/asgi/rpc.py
index 9bffc2f24..9f6df6ee5 100644
--- a/server/parsec/asgi/rpc.py
+++ b/server/parsec/asgi/rpc.py
@@ -826,6 +826,7 @@ class StreamingResponseMiddleware(StreamingResponse):
         self.client_ctx.logger.info("SSE session start")
         try:
             await self._run_session(scope, receive, send)
+            await send({"type": "http.response.body", "body": b"", "more_body": False})
         except HTTPException as exc:
             self.client_ctx.logger.info(
                 "SSE session HTTP error",