diff options
| author | Sergey Shepelev <temotor@gmail.com> | 2018-03-29 20:38:09 +0300 |
|---|---|---|
| committer | Sergey Shepelev <temotor@gmail.com> | 2020-08-19 15:15:07 +0300 |
| commit | e51cc71304128be9b78f7b60f4c694928c411500 (patch) | |
| tree | c03d06f389b13a7bddf0e9586a50ecde819ede0a | |
| parent | d9ae8bcaad9cca522d1a716f76a8b8e6a6c11e0c (diff) | |
| download | eventlet-474-websocket-fd-leak.tar.gz | |
| -rw-r--r-- | tests/websocket_new_test.py | 29 | ||||
| -rw-r--r-- | tests/wsgi_test.py | 20 |
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): |
