|
13 | 13 |
|
14 | 14 | log = logging.getLogger(__name__) |
15 | 15 |
|
| 16 | +# Errno values that indicate the remote peer has disconnected. |
| 17 | +_PEER_DISCONNECT_ERRNOS = frozenset(( |
| 18 | + errno.ENOTCONN, errno.ESHUTDOWN, |
| 19 | + errno.ECONNRESET, errno.ECONNABORTED, |
| 20 | +)) |
| 21 | + |
| 22 | +# Windows winerror codes for the same conditions: |
| 23 | +# 10053 = WSAECONNABORTED, 10054 = WSAECONNRESET |
| 24 | +_PEER_DISCONNECT_WINERRORS = frozenset((10053, 10054)) |
| 25 | + |
| 26 | + |
| 27 | +def _is_peer_disconnect(err): |
| 28 | + """Return True if *err* indicates the remote peer closed the connection.""" |
| 29 | + return (isinstance(err, ConnectionError) |
| 30 | + or getattr(err, 'winerror', None) in _PEER_DISCONNECT_WINERRORS |
| 31 | + or getattr(err, 'errno', None) in _PEER_DISCONNECT_ERRNOS) |
| 32 | + |
16 | 33 |
|
17 | 34 | # This module uses ``yield from`` and ``@asyncio.coroutine`` over ``await`` and |
18 | 35 | # ``async def`` for pre-Python-3.5 compatibility, so keep in mind that the |
@@ -229,21 +246,7 @@ async def handle_write(self): |
229 | 246 | if next_msg: |
230 | 247 | await self._loop.sock_sendall(self._socket, next_msg) |
231 | 248 | except socket.error as err: |
232 | | - # Peer disconnected — do a clean close instead of defunct. |
233 | | - # Use ConnectionError (parent of BrokenPipeError, |
234 | | - # ConnectionResetError, ConnectionAbortedError) plus a |
235 | | - # winerror check for Windows IOCP which may raise plain |
236 | | - # OSError with winerror=10054 (WSAECONNRESET) or |
237 | | - # 10053 (WSAECONNABORTED). |
238 | | - # Also check errno for ENOTCONN/ESHUTDOWN/ECONNRESET |
239 | | - # which macOS raises as plain OSError (not ConnectionError). |
240 | | - _peer_errnos = ( |
241 | | - errno.ENOTCONN, errno.ESHUTDOWN, |
242 | | - errno.ECONNRESET, errno.ECONNABORTED, |
243 | | - ) |
244 | | - if (isinstance(err, ConnectionError) |
245 | | - or getattr(err, 'winerror', None) in (10053, 10054) |
246 | | - or getattr(err, 'errno', None) in _peer_errnos): |
| 249 | + if _is_peer_disconnect(err): |
247 | 250 | log.debug("Connection %s closed by peer during write: %s", |
248 | 251 | self, err) |
249 | 252 | self.close() |
|
0 commit comments