summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eventlet/wsgi.py13
-rw-r--r--tests/wsgi_test.py11
2 files changed, 21 insertions, 3 deletions
diff --git a/eventlet/wsgi.py b/eventlet/wsgi.py
index 59186e5..1a99b78 100644
--- a/eventlet/wsgi.py
+++ b/eventlet/wsgi.py
@@ -540,7 +540,8 @@ class Server(BaseHTTPServer.HTTPServer):
log_output=True,
log_format=DEFAULT_LOG_FORMAT,
url_length_limit=MAX_REQUEST_LINE,
- debug=True):
+ debug=True,
+ socket_timeout=None):
self.outstanding_requests = 0
self.socket = socket
@@ -561,6 +562,7 @@ class Server(BaseHTTPServer.HTTPServer):
self.log_format = log_format
self.url_length_limit = url_length_limit
self.debug = debug
+ self.socket_timeout = socket_timeout
def get_environ(self):
d = {
@@ -623,7 +625,8 @@ def server(sock, site,
log_output=True,
log_format=DEFAULT_LOG_FORMAT,
url_length_limit=MAX_REQUEST_LINE,
- debug=True):
+ debug=True,
+ socket_timeout=None):
"""Start up a WSGI server handling requests from the supplied server
socket. This function loops forever. The *sock* object will be closed after server exits,
but the underlying file descriptor will remain open, so if you have a dup() of *sock*,
@@ -645,6 +648,7 @@ def server(sock, site,
:param log_format: A python format string that is used as the template to generate log lines. The following values can be formatted into it: client_ip, date_time, request_line, status_code, body_length, wall_seconds. The default is a good example of how to use it.
:param url_length_limit: A maximum allowed length of the request url. If exceeded, 414 error is returned.
:param debug: True if the server should send exception tracebacks to the clients on 500 errors. If False, the server will respond with empty bodies.
+ :param socket_timeout: Timeout for client connections' socket operations. Default None means wait forever.
"""
serv = Server(sock, sock.getsockname(),
site, log,
@@ -657,7 +661,9 @@ def server(sock, site,
log_output=log_output,
log_format=log_format,
url_length_limit=url_length_limit,
- debug=debug)
+ debug=debug,
+ socket_timeout=socket_timeout,
+ )
if server_event is not None:
server_event.send(serv)
if max_size is None:
@@ -683,6 +689,7 @@ def server(sock, site,
while True:
try:
client_socket = sock.accept()
+ client_socket[0].settimeout(serv.socket_timeout)
if debug:
serv.log.write("(%s) accepted %r\n" % (
serv.pid, client_socket[1]))
diff --git a/tests/wsgi_test.py b/tests/wsgi_test.py
index 3bbbd2f..0e10de7 100644
--- a/tests/wsgi_test.py
+++ b/tests/wsgi_test.py
@@ -1201,6 +1201,17 @@ class TestHttpd(_TestBase):
self.assertTrue("BOOM" in runlog)
self.assertFalse("Traceback" in runlog)
+ def test_server_socket_timeout(self):
+ self.spawn_server(socket_timeout=0.1)
+ sock = eventlet.connect(('localhost', self.port))
+ sock.send('GET / HTTP/1.1\r\n')
+ eventlet.sleep(0.1)
+ try:
+ read_http(sock)
+ assert False, 'Expected ConnectionClosed exception'
+ except ConnectionClosed:
+ pass
+
def read_headers(sock):
fd = sock.makefile()