Skip to content

Commit afd8c33

Browse files
authored
Handle OSError on shutdown & TimeoutError on recv (#974)
* Expect `TimeoutError` during `recv` * Expect `OSError` during socket shutdown, can happen if other end has already closed the socket
1 parent 05a8ff9 commit afd8c33

File tree

4 files changed

+16
-3
lines changed

4 files changed

+16
-3
lines changed

proxy/core/base/tcp_server.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,11 @@ async def handle_writables(self, writables: Writables) -> bool:
109109
async def handle_readables(self, readables: Readables) -> bool:
110110
teardown = False
111111
if self.work.connection.fileno() in readables:
112-
data = self.work.recv(self.flags.client_recvbuf_size)
112+
try:
113+
data = self.work.recv(self.flags.client_recvbuf_size)
114+
except TimeoutError:
115+
logger.info('Client recv timeout error')
116+
return True
113117
if data is None:
114118
logger.debug(
115119
'Connection closed by client {0}'.format(

proxy/core/base/tcp_upstream.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ async def read_from_descriptors(self, r: Readables) -> bool:
8181
else:
8282
# Tear down because upstream proxy closed the connection
8383
return True
84+
except TimeoutError:
85+
logger.info('Upstream recv timeout error')
86+
return True
8487
except ssl.SSLWantReadError:
8588
logger.info('Upstream SSLWantReadError, will retry')
8689
return False

proxy/core/connection/pool.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,10 @@ def _remove(self, fileno: int) -> None:
174174
"""Remove a connection by descriptor from the internal data structure."""
175175
conn = self.connections[fileno]
176176
logger.debug('Removing conn#{0} from pool'.format(id(conn)))
177-
conn.connection.shutdown(socket.SHUT_WR)
177+
try:
178+
conn.connection.shutdown(socket.SHUT_WR)
179+
except OSError:
180+
pass
178181
conn.close()
179182
self.pools[conn.addr].remove(conn)
180183
del self.connections[fileno]

proxy/http/websocket/client.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,8 @@ def run(self) -> None:
115115
finally:
116116
if not self.closed:
117117
self.selector.unregister(self.sock)
118-
self.sock.shutdown(socket.SHUT_WR)
118+
try:
119+
self.sock.shutdown(socket.SHUT_WR)
120+
except OSError:
121+
pass
119122
self.sock.close()

0 commit comments

Comments
 (0)