wsgi: configurable socket_timeout
This commit is contained in:
@@ -540,7 +540,8 @@ class Server(BaseHTTPServer.HTTPServer):
|
|||||||
log_output=True,
|
log_output=True,
|
||||||
log_format=DEFAULT_LOG_FORMAT,
|
log_format=DEFAULT_LOG_FORMAT,
|
||||||
url_length_limit=MAX_REQUEST_LINE,
|
url_length_limit=MAX_REQUEST_LINE,
|
||||||
debug=True):
|
debug=True,
|
||||||
|
socket_timeout=None):
|
||||||
|
|
||||||
self.outstanding_requests = 0
|
self.outstanding_requests = 0
|
||||||
self.socket = socket
|
self.socket = socket
|
||||||
@@ -561,6 +562,7 @@ class Server(BaseHTTPServer.HTTPServer):
|
|||||||
self.log_format = log_format
|
self.log_format = log_format
|
||||||
self.url_length_limit = url_length_limit
|
self.url_length_limit = url_length_limit
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
|
self.socket_timeout = socket_timeout
|
||||||
|
|
||||||
def get_environ(self):
|
def get_environ(self):
|
||||||
d = {
|
d = {
|
||||||
@@ -623,7 +625,8 @@ def server(sock, site,
|
|||||||
log_output=True,
|
log_output=True,
|
||||||
log_format=DEFAULT_LOG_FORMAT,
|
log_format=DEFAULT_LOG_FORMAT,
|
||||||
url_length_limit=MAX_REQUEST_LINE,
|
url_length_limit=MAX_REQUEST_LINE,
|
||||||
debug=True):
|
debug=True,
|
||||||
|
socket_timeout=None):
|
||||||
"""Start up a WSGI server handling requests from the supplied server
|
"""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,
|
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*,
|
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 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 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 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(),
|
serv = Server(sock, sock.getsockname(),
|
||||||
site, log,
|
site, log,
|
||||||
@@ -657,7 +661,9 @@ def server(sock, site,
|
|||||||
log_output=log_output,
|
log_output=log_output,
|
||||||
log_format=log_format,
|
log_format=log_format,
|
||||||
url_length_limit=url_length_limit,
|
url_length_limit=url_length_limit,
|
||||||
debug=debug)
|
debug=debug,
|
||||||
|
socket_timeout=socket_timeout,
|
||||||
|
)
|
||||||
if server_event is not None:
|
if server_event is not None:
|
||||||
server_event.send(serv)
|
server_event.send(serv)
|
||||||
if max_size is None:
|
if max_size is None:
|
||||||
@@ -683,6 +689,7 @@ def server(sock, site,
|
|||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
client_socket = sock.accept()
|
client_socket = sock.accept()
|
||||||
|
client_socket[0].settimeout(serv.socket_timeout)
|
||||||
if debug:
|
if debug:
|
||||||
serv.log.write("(%s) accepted %r\n" % (
|
serv.log.write("(%s) accepted %r\n" % (
|
||||||
serv.pid, client_socket[1]))
|
serv.pid, client_socket[1]))
|
||||||
|
@@ -1201,6 +1201,17 @@ class TestHttpd(_TestBase):
|
|||||||
self.assertTrue("BOOM" in runlog)
|
self.assertTrue("BOOM" in runlog)
|
||||||
self.assertFalse("Traceback" 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):
|
def read_headers(sock):
|
||||||
fd = sock.makefile()
|
fd = sock.makefile()
|
||||||
|
Reference in New Issue
Block a user