Browse Source

Add timeout to integrated sever

Unrud 9 years ago
parent
commit
b55d2181ed
4 changed files with 21 additions and 2 deletions
  1. 3 0
      config
  2. 16 2
      radicale/__init__.py
  3. 1 0
      radicale/__main__.py
  4. 1 0
      radicale/config.py

+ 3 - 0
config

@@ -24,6 +24,9 @@
 # File storing the PID in daemon mode
 # File storing the PID in daemon mode
 #pid =
 #pid =
 
 
+# Socket timeout (seconds)
+#timeout = 10
+
 # SSL flag, enable HTTPS protocol
 # SSL flag, enable HTTPS protocol
 #ssl = False
 #ssl = False
 
 

+ 16 - 2
radicale/__init__.py

@@ -54,6 +54,10 @@ WELL_KNOWN_RE = re.compile(r"/\.well-known/(carddav|caldav)/?$")
 
 
 class HTTPServer(wsgiref.simple_server.WSGIServer):
 class HTTPServer(wsgiref.simple_server.WSGIServer):
     """HTTP server."""
     """HTTP server."""
+
+    # These class attributes must be set before creating instance
+    client_timeout = None
+
     def __init__(self, address, handler, bind_and_activate=True):
     def __init__(self, address, handler, bind_and_activate=True):
         """Create server."""
         """Create server."""
         ipv6 = ":" in address[0]
         ipv6 = ":" in address[0]
@@ -72,6 +76,13 @@ class HTTPServer(wsgiref.simple_server.WSGIServer):
             self.server_bind()
             self.server_bind()
             self.server_activate()
             self.server_activate()
 
 
+    def get_request(self):
+        # Set timeout for client
+        _socket, address = super().get_request()
+        if self.client_timeout:
+            _socket.settimeout(self.client_timeout)
+        return _socket, address
+
 
 
 class HTTPSServer(HTTPServer):
 class HTTPSServer(HTTPServer):
     """HTTPS server."""
     """HTTPS server."""
@@ -290,8 +301,11 @@ class Application:
         # Get content
         # Get content
         content_length = int(environ.get("CONTENT_LENGTH") or 0)
         content_length = int(environ.get("CONTENT_LENGTH") or 0)
         if content_length:
         if content_length:
-            content = self.decode(
-                environ["wsgi.input"].read(content_length), environ)
+            try:
+                content = self.decode(
+                    environ["wsgi.input"].read(content_length), environ)
+            except socket.timeout:
+                return response(client.REQUEST_TIMEOUT)
             self.logger.debug("Request content:\n%s" % content)
             self.logger.debug("Request content:\n%s" % content)
         else:
         else:
             content = None
             content = None

+ 1 - 0
radicale/__main__.py

@@ -170,6 +170,7 @@ def run():
                         name, filename, exception))
                         name, filename, exception))
     else:
     else:
         server_class = ThreadedHTTPServer
         server_class = ThreadedHTTPServer
+    server_class.client_timeout = configuration.getint("server", "timeout")
 
 
     if not configuration.getboolean("server", "dns_lookup"):
     if not configuration.getboolean("server", "dns_lookup"):
         RequestHandler.address_string = lambda self: self.client_address[0]
         RequestHandler.address_string = lambda self: self.client_address[0]

+ 1 - 0
radicale/config.py

@@ -34,6 +34,7 @@ INITIAL_CONFIG = {
         "hosts": "0.0.0.0:5232",
         "hosts": "0.0.0.0:5232",
         "daemon": "False",
         "daemon": "False",
         "pid": "",
         "pid": "",
+        "timeout": "10",
         "ssl": "False",
         "ssl": "False",
         "certificate": "/etc/apache2/ssl/server.crt",
         "certificate": "/etc/apache2/ssl/server.crt",
         "key": "/etc/apache2/ssl/server.key",
         "key": "/etc/apache2/ssl/server.key",