File 0001-websocket-fd-leak-when-client-did-not-close-connecti.patch of Package python-eventlet
From 8c2d68130ac888bdc5f0f0d27012ee3082f5c2f8 Mon Sep 17 00:00:00 2001
From: Konstantin Enchant <sirkonst@gmail.com>
Date: Thu, 16 Nov 2017 17:06:28 +0300
Subject: [PATCH 1/2] websocket: fd leak when client did not close connection
properly
https://github.com/eventlet/eventlet/pull/450
(cherry picked from commit d5008744da40942e1726e1fa5dda5180179f1a4f)
(cherry picked from commit 6423df121a01dbafe2a796f281be69038e751de6)
---
eventlet/websocket.py | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/eventlet/websocket.py b/eventlet/websocket.py
index 9321956..70850d7 100644
--- a/eventlet/websocket.py
+++ b/eventlet/websocket.py
@@ -274,6 +274,12 @@ class WebSocket(object):
:param environ: The wsgi environment
:param version: The WebSocket spec version to follow (default is 76)
"""
+ self.log = environ.get('wsgi.errors', sys.stderr)
+ self.log_context = 'server={shost}/{spath} client={caddr}:{cport}'.format(
+ shost=environ.get('HTTP_HOST'),
+ spath=environ.get('SCRIPT_NAME', '') + environ.get('PATH_INFO', ''),
+ caddr=environ.get('REMOTE_ADDR'), cport=environ.get('REMOTE_PORT'),
+ )
self.socket = sock
self.origin = environ.get('HTTP_ORIGIN')
self.protocol = environ.get('HTTP_WEBSOCKET_PROTOCOL')
@@ -377,9 +383,14 @@ class WebSocket(object):
def close(self):
"""Forcibly close the websocket; generally it is preferable to
return from the handler method."""
- self._send_closing_frame()
- self.socket.shutdown(True)
- self.socket.close()
+ try:
+ self._send_closing_frame(True)
+ self.socket.shutdown(True)
+ except SocketError as e:
+ if e.errno != errno.ENOTCONN:
+ self.log.write('{ctx} socket shutdown error: {e}'.format(ctx=self.log_context, e=e))
+ finally:
+ self.socket.close()
class ConnectionClosedError(Exception):
@@ -655,6 +666,11 @@ class RFC6455WebSocket(WebSocket):
def close(self, close_data=None):
"""Forcibly close the websocket; generally it is preferable to
return from the handler method."""
- self._send_closing_frame(close_data=close_data)
- self.socket.shutdown(socket.SHUT_WR)
- self.socket.close()
+ try:
+ self._send_closing_frame(close_data=close_data, ignore_send_errors=True)
+ self.socket.shutdown(socket.SHUT_WR)
+ except SocketError as e:
+ if e.errno != errno.ENOTCONN:
+ self.log.write('{ctx} socket shutdown error: {e}'.format(ctx=self.log_context, e=e))
+ finally:
+ self.socket.close()
--
2.25.1