Add client_socket_timeout option

Add a parameter to take advantage of the new(ish) eventlet socket timeout
behaviour.  Allows closing idle client connections after a period of
time, eg:

$ time nc localhost 8776
real    1m0.063s

Setting 'client_socket_timeout = 0' means do not timeout.

DocImpact:
Added client_socket_timeout option (default=0).

Conflicts:
        cinder/wsgi.py
        etc/cinder/cinder.conf.sample

Note: This patch is not 1:1 cherry-pick, I have changed the default value
of client_socket_timeout to 0.

Change-Id: If492810a2f10fa5954f8c8bb708b14be0b77fb90
Closes-bug: #1361360
Closes-bug: #1371022
(cherry picked from commit 08bfa77aec)
This commit is contained in:
Stuart McLaren 2014-09-05 12:48:04 +00:00 committed by abhishekkekane
parent aacfe1ba81
commit f88dc8495f
3 changed files with 51 additions and 1 deletions

View File

@ -17,7 +17,10 @@
"""Unit tests for `cinder.wsgi`."""
import os.path
import re
import socket
import tempfile
import time
import urllib2
import mock
@ -151,7 +154,41 @@ class TestWSGIServer(test.TestCase):
response = open_no_proxy('http://127.0.0.1:%d/' % server.port)
self.assertEqual(greetings, response.read())
server.stop()
def test_client_socket_timeout(self):
CONF.set_default("client_socket_timeout", 0.1)
greetings = 'Hello, World!!!'
def hello_world(env, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return [greetings]
server = cinder.wsgi.Server("test_app", hello_world,
host="127.0.0.1", port=0)
server.start()
s = socket.socket()
s.connect(("127.0.0.1", server.port))
fd = s.makefile('rw')
fd.write(b'GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
fd.flush()
buf = fd.read()
self.assertTrue(re.search(greetings, buf))
s2 = socket.socket()
s2.connect(("127.0.0.1", server.port))
time.sleep(0.2)
fd = s2.makefile('rw')
fd.write(b'GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
fd.flush()
buf = fd.read()
# connection is closed so we get nothing from the server
self.assertFalse(buf)
server.stop()
def test_app_using_ssl(self):

View File

@ -84,6 +84,11 @@ eventlet_opts = [
help='If False, closes the client socket connection '
'explicitly. Setting it to True to maintain backward '
'compatibility. Recommended setting is set it to False.'),
cfg.IntOpt('client_socket_timeout', default=0,
help="Timeout for client connections\' socket operations. "
"If an incoming connection is idle for this number of "
"seconds it will be closed. A value of \'0\' means "
"wait forever."),
]
CONF = cfg.CONF
@ -112,6 +117,7 @@ class Server(object):
"""
# Allow operators to customize http requests max header line size.
eventlet.wsgi.MAX_HEADER_LINE = CONF.max_header_line
self.client_socket_timeout = CONF.client_socket_timeout or None
self.name = name
self.app = app
self._host = host or "0.0.0.0"
@ -235,7 +241,8 @@ class Server(object):
'protocol': self._protocol,
'custom_pool': self._pool,
'log': self._wsgi_logger,
'keepalive': CONF.wsgi_keep_alive
'keepalive': CONF.wsgi_keep_alive,
'socket_timeout': self.client_socket_timeout
}
self._server = eventlet.spawn(**wsgi_kwargs)

View File

@ -311,6 +311,12 @@
# Recommended setting is set it to False. (boolean value)
#wsgi_keep_alive=true
# Timeout for client connections' socket operations. If an
# incoming connection is idle for this number of seconds it
# will be closed. A value of '0' means wait forever. (integer
# value)
#client_socket_timeout=0
# Sets the value of TCP_KEEPALIVE (True/False) for each server
# socket. (boolean value)
#tcp_keepalive=true