File 0001-websocket-fd-leak-when-client-did-not-close-connecti.patch of Package python-eventlet
From 6423df121a01dbafe2a796f281be69038e751de6 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)
---
eventlet/websocket.py | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/eventlet/websocket.py b/eventlet/websocket.py
index 1fdb3bf..5c9eec7 100644
--- a/eventlet/websocket.py
+++ b/eventlet/websocket.py
@@ -285,6 +285,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')
@@ -388,9 +394,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):
@@ -666,6 +677,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