diff options
| author | Sergey Shepelev <temotor@gmail.com> | 2016-06-01 21:28:02 +0500 |
|---|---|---|
| committer | Sergey Shepelev <temotor@gmail.com> | 2016-06-01 21:28:02 +0500 |
| commit | 4b54ca96665aff3eb9b3efa09b4bebc51c65913f (patch) | |
| tree | 53701584ced2dba5159ecbc33b88113d544893c5 | |
| parent | 41bbe278d6ab1eaf52e4d7af3a01a4053fc6e2b1 (diff) | |
| download | eventlet-issue-320.tar.gz | |
wsgi: chunked timeout should close connection immediatelyissue-320
| -rw-r--r-- | eventlet/wsgi.py | 7 | ||||
| -rw-r--r-- | tests/__init__.py | 9 | ||||
| -rw-r--r-- | tests/wsgi_test.py | 24 | ||||
| -rw-r--r-- | tox.ini | 1 |
4 files changed, 41 insertions, 0 deletions
diff --git a/eventlet/wsgi.py b/eventlet/wsgi.py index 9d02d12..4ca6ac9 100644 --- a/eventlet/wsgi.py +++ b/eventlet/wsgi.py @@ -319,6 +319,7 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler): "of type %s" % type(conn)) def handle_one_request(self): + print('wsgi: socket: {0}'.format(repr(self.connection.fileno()))) if self.server.max_http_version: self.protocol_version = self.server.max_http_version @@ -630,10 +631,15 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler): try: BaseHTTPServer.BaseHTTPRequestHandler.finish(self) except socket.error as e: + print('wsgi.finish error:', str(e)) # Broken pipe, connection reset by peer if support.get_errno(e) not in BROKEN_SOCK: raise + # finally: + # pass + print('wsgi.finish shutdown') greenio.shutdown_safe(self.connection) + print('wsgi.finish close') self.connection.close() def handle_expect_100(self): @@ -718,6 +724,7 @@ class Server(BaseHTTPServer.HTTPServer): try: proto.__init__(sock, address, self) except socket.timeout: + print('socket.timeout') # Expected exceptions are not exceptional sock.close() # similar to logging "accepted" in server() diff --git a/tests/__init__.py b/tests/__init__.py index 62bae83..3665811 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -21,6 +21,7 @@ import unittest import warnings from nose.plugins.skip import SkipTest +import psutil import eventlet from eventlet import tpool @@ -346,5 +347,13 @@ def run_isolated(path, prefix='tests/isolated/', env=None, args=None): assert ok, 'Expected single line "pass" in stdout' +def get_sockets(filters=None): + xs = psutil.Process().connections(kind='all') + print('get_sockets: {0}'.format(xs)) + if filters: + xs = [c for c in xs if all(getattr(c, f) == filters[f] for f in filters)] + return xs + + certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt') private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key') diff --git a/tests/wsgi_test.py b/tests/wsgi_test.py index 3d2f11f..f6d9935 100644 --- a/tests/wsgi_test.py +++ b/tests/wsgi_test.py @@ -1527,6 +1527,30 @@ class TestHttpd(_TestBase): assert result.status == 'HTTP/1.1 200 OK' assert result.body == b'Host: localhost\nx-ANY_k: one\nx-ANY_k: two' + def test_chunked_timeout(self): + def app(env, start_response): + start_response('200 OK', [('Content-Type', 'text/plain')]) + line = b'a' * (1 << 20) + for _ in range(10): + yield line + eventlet.sleep(0.1) + + self.spawn_server(site=app, socket_timeout=0.1) + sock = eventlet.connect(self.server_addr) + print('client socket: {0}'.format(sock.fileno())) + sock.sendall(b'GET / HTTP/1.1\r\nHost: localhost\r\n\r\n') + status, headers = read_headers(sock) + assert headers['transfer-encoding'] == 'chunked' + ss = tests.get_sockets(filters={'status': 'ESTABLISHED'}) + assert len(ss) == 2, repr(ss) + + sock.recv(1) + eventlet.sleep(0.2) + recvall(sock) + ss = tests.get_sockets(filters={'status': 'ESTABLISHED'}) + assert len(ss) == 0, repr(ss) + sock.close() + def read_headers(sock): fd = sock.makefile('rb') @@ -43,6 +43,7 @@ basepython = pypy: pypy deps = nose==1.3.1 + psutil==4.2.0 setuptools==5.4.1 py{26,27}: subprocess32==3.2.7 py27-dns: dnspython==1.12.0 |
