summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Shepelev <temotor@gmail.com>2018-03-29 20:38:09 +0300
committerSergey Shepelev <temotor@gmail.com>2020-08-19 15:15:07 +0300
commite51cc71304128be9b78f7b60f4c694928c411500 (patch)
treec03d06f389b13a7bddf0e9586a50ecde819ede0a
parentd9ae8bcaad9cca522d1a716f76a8b8e6a6c11e0c (diff)
downloadeventlet-474-websocket-fd-leak.tar.gz
-rw-r--r--tests/websocket_new_test.py29
-rw-r--r--tests/wsgi_test.py20
2 files changed, 47 insertions, 2 deletions
diff --git a/tests/websocket_new_test.py b/tests/websocket_new_test.py
index 5f98025..b061deb 100644
--- a/tests/websocket_new_test.py
+++ b/tests/websocket_new_test.py
@@ -1,6 +1,7 @@
import errno
-import struct
+import os
import re
+import struct
import eventlet
from eventlet import event
@@ -230,6 +231,30 @@ class TestWebSocket(tests.wsgi_test._TestBase):
done_with_request.wait()
assert not error_detected[0]
+ def test_client_timeout_fd_leak(self):
+ connect = '\r\n'.join((
+ 'GET /echo HTTP/1.1',
+ 'Upgrade: websocket',
+ 'Connection: Upgrade',
+ 'Host: ' + self.server_netloc,
+ 'Origin: http://' + self.server_netloc,
+ 'Sec-WebSocket-Version: 13',
+ 'Sec-WebSocket-Key: d9MXuOzlVQ0h+qRllvSCIg==',
+ '\r\n',
+ )).encode()
+ self.spawn_server(socket_timeout=0.5)
+ sock = eventlet.connect(self.server_addr)
+ sock.sendall(connect)
+ established = sock.recv(1024)
+ assert established.startswith(b'HTTP/1.1 101 ')
+ assert len(self.server_fds) == 1
+ fd = self.server_fds[0]
+ error = sock.recv(1024)
+ assert error == b'\x88\x17\x03\xf3Internal Server Error'
+ closed = sock.recv(1)
+ assert closed == b''
+ print(os.fstat(fd))
+
class TestWebSocketWithCompression(tests.wsgi_test._TestBase):
TEST_TIMEOUT = 5
@@ -255,7 +280,7 @@ class TestWebSocketWithCompression(tests.wsgi_test._TestBase):
'Upgrade: websocket',
'Connection: Upgrade',
'Sec-WebSocket-Accept: ywSyWXCPNsDxLrQdQrn5RFNRfBU=',
- 'Sec-WebSocket-Extensions: (.+)'
+ 'Sec-WebSocket-Extensions: (.+)',
'\r\n',
])))
diff --git a/tests/wsgi_test.py b/tests/wsgi_test.py
index 9ff9cef..15ec2cb 100644
--- a/tests/wsgi_test.py
+++ b/tests/wsgi_test.py
@@ -2,6 +2,7 @@
import cgi
import collections
import errno
+import functools
import os
import shutil
import signal
@@ -223,6 +224,7 @@ class _TestBase(tests.LimitedTestCase):
self.site = Site()
self.killer = None
self.set_site()
+ self.server_fds = []
self.spawn_server()
def tearDown(self):
@@ -236,6 +238,7 @@ class _TestBase(tests.LimitedTestCase):
Sets `self.server_addr` to (host, port) tuple suitable for `socket.connect`.
"""
+ self.server_fds[:] = []
self.logfile = six.StringIO()
new_kwargs = dict(max_size=128,
log=self.logfile,
@@ -245,6 +248,19 @@ class _TestBase(tests.LimitedTestCase):
if 'sock' not in new_kwargs:
new_kwargs['sock'] = eventlet.listen(('localhost', 0))
+ def wrap_accept(sock):
+ original = sock.accept
+
+ @functools.wraps(original)
+ def wrapped(*a, **kw):
+ t = original(*a, **kw)
+ self.server_fds.append(t[0].fileno())
+ return t
+
+ sock.accept = wrapped
+
+ wrap_accept(new_kwargs['sock'])
+
self.server_addr = new_kwargs['sock'].getsockname()
self.spawn_thread(wsgi.server, **new_kwargs)
@@ -263,6 +279,10 @@ class _TestBase(tests.LimitedTestCase):
def set_site(self):
raise NotImplementedError
+ @property
+ def server_netloc(self):
+ return '{a[0]}:{a[1]}'.format(a=self.server_addr)
+
class TestHttpd(_TestBase):
def set_site(self):