]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add client_socket_timeout option
authorStuart McLaren <stuart.mclaren@hp.com>
Fri, 5 Sep 2014 12:48:04 +0000 (12:48 +0000)
committerStuart McLaren <stuart.mclaren@hp.com>
Thu, 16 Oct 2014 09:53:17 +0000 (09:53 +0000)
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

Change-Id: If492810a2f10fa5954f8c8bb708b14be0b77fb90
Closes-bug: #1371022

cinder/tests/test_wsgi.py
cinder/wsgi.py
etc/cinder/cinder.conf.sample

index a267bb879e4affbf10e0157296f042919afc74e2..36c1e73b55308f2dd8270f2afc00bc981d1f01da 100644 (file)
 """Unit tests for `cinder.wsgi`."""
 
 import os.path
+import re
+import socket
 import tempfile
+import time
 import urllib2
 
 import mock
@@ -141,7 +144,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):
index cbd62e665554e74250149e0edee3485160858e03..5e433e72369d3c502a2161396251ff98f0e3b4cb 100644 (file)
@@ -79,6 +79,11 @@ eventlet_opts = [
                     "max_header_line may need to be increased when using "
                     "large tokens (typically those generated by the "
                     "Keystone v3 API with big service catalogs)."),
+    cfg.IntOpt('client_socket_timeout', default=900,
+               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
@@ -107,6 +112,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"
@@ -229,7 +235,8 @@ class Server(object):
             'site': self.app,
             'protocol': self._protocol,
             'custom_pool': self._pool,
-            'log': self._wsgi_logger
+            'log': self._wsgi_logger,
+            'socket_timeout': self.client_socket_timeout
         }
 
         self._server = eventlet.spawn(**wsgi_kwargs)
index 65976fb000b674fe823737597a6a5af5dca4874f..f54956fd0471256ab673e4a4db8a869f627f67bc 100644 (file)
 # with big service catalogs). (integer value)
 #max_header_line=16384
 
+# 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=900
+
 # Sets the value of TCP_KEEPALIVE (True/False) for each server
 # socket. (boolean value)
 #tcp_keepalive=true