Skip to content

Commit

Permalink
Ensure websocket transport is closed when client does not close it
Browse files Browse the repository at this point in the history
fixes #8184
  • Loading branch information
bdraco committed Mar 1, 2024
1 parent 6c3122f commit b792d82
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions aiohttp/web_ws.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ async def close(
return True

if self._closing:
self._close_transport()
return True

reader = self._reader
Expand All @@ -440,9 +441,18 @@ async def close(
self._exception = asyncio.TimeoutError()
return True

def _set_closing(self, code: WSCloseCode) -> None:
"""Set the close code and mark the connection as closing."""
self._closing = True
self._close_code = code

def _set_code_close_transport(self, code: WSCloseCode) -> None:
"""Set the close code and close the transport."""
self._close_code = code
self._close_transport()

def _close_transport(self) -> None:
"""Close the transport."""
if self._req is not None and self._req.transport is not None:
self._req.transport.close()

Expand Down Expand Up @@ -487,14 +497,12 @@ async def receive(self, timeout: Optional[float] = None) -> WSMessage:
return WSMessage(WSMsgType.ERROR, exc, None)
except Exception as exc:
self._exception = exc
self._closing = True
self._close_code = WSCloseCode.ABNORMAL_CLOSURE
self._set_closing(WSCloseCode.ABNORMAL_CLOSURE)

Check warning on line 500 in aiohttp/web_ws.py

View check run for this annotation

Codecov / codecov/patch

aiohttp/web_ws.py#L500

Added line #L500 was not covered by tests
await self.close()
return WSMessage(WSMsgType.ERROR, exc, None)

if msg.type == WSMsgType.CLOSE:
self._closing = True
self._close_code = msg.data
self._set_closing(msg.data)
# Could be closed while awaiting reader.
if not self._closed and self._autoclose: # type: ignore[redundant-expr]
# The client is likely going to close the
Expand All @@ -503,7 +511,7 @@ async def receive(self, timeout: Optional[float] = None) -> WSMessage:
# likely result writing to a broken pipe.
await self.close(drain=False)
elif msg.type == WSMsgType.CLOSING:
self._closing = True
self._set_closing(WSCloseCode.OK)
elif msg.type == WSMsgType.PING and self._autoping:
await self.pong(msg.data)
continue
Expand Down

0 comments on commit b792d82

Please sign in to comment.