Closed
Description
Describe the bug
WebSocketResponse
(web_ws.py
) inherits fromStreamResponse
(web_response.py
).WebSocketResponse
overridesprepare
with apre_start
andpost_start
, which setsself._writer
to aWebSocketWriter
.WebSocketResponse
does not override theprepared
property fromStreamResponse
prepared
property checks ifself._payload_writer is not None
To Reproduce
wsock = web.WebSocketResponse()
try:
# Bug can happen when this job times out during `WebSocketResponse `calling `super().prepare()`
# and `StreamResponse` is inside `await self._start` and client connection is dropped but OS didn't notice
async with async_timeout(10):
await wsock.prepare()
except asyncio.TimeoutError:
if wsock.prepared:
# This raises because `close()` checks if `self._writer` is not None,
# which is set inside `StreamResponse._post_start`
await wsock.close()
Expected behavior
If wsock.prepared
returns True
, it should be safe to close the connection.
Logs/tracebacks
File "server/api.py", line 264, in handle
await wsock.close()
File "aiohttp/web_ws.py", line 329, in close
raise RuntimeError("Call .prepare() first")
### Python Version
```console
$ python --version
3.9
aiohttp Version
$ python -m pip show aiohttp
3.7.4.post0
multidict Version
$ python -m pip show multidict
5.1.0
yarl Version
$ python -m pip show yarl
1.6.3
OS
Debian
Related component
Server
Additional context
No response
Code of Conduct
- I agree to follow the aio-libs Code of Conduct