diff --git a/config b/config index f3a3a46..ee28711 100644 --- a/config +++ b/config @@ -24,6 +24,9 @@ # File storing the PID in daemon mode #pid = +# Socket timeout (seconds) +#timeout = 10 + # SSL flag, enable HTTPS protocol #ssl = False diff --git a/radicale/__init__.py b/radicale/__init__.py index 8d36ee7..ba1994d 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -54,6 +54,10 @@ WELL_KNOWN_RE = re.compile(r"/\.well-known/(carddav|caldav)/?$") class HTTPServer(wsgiref.simple_server.WSGIServer): """HTTP server.""" + + # These class attributes must be set before creating instance + client_timeout = None + def __init__(self, address, handler, bind_and_activate=True): """Create server.""" ipv6 = ":" in address[0] @@ -72,6 +76,13 @@ class HTTPServer(wsgiref.simple_server.WSGIServer): self.server_bind() 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): """HTTPS server.""" @@ -290,8 +301,11 @@ class Application: # Get content content_length = int(environ.get("CONTENT_LENGTH") or 0) 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) else: content = None diff --git a/radicale/__main__.py b/radicale/__main__.py index cda628b..dc17905 100644 --- a/radicale/__main__.py +++ b/radicale/__main__.py @@ -170,6 +170,7 @@ def run(): name, filename, exception)) else: server_class = ThreadedHTTPServer + server_class.client_timeout = configuration.getint("server", "timeout") if not configuration.getboolean("server", "dns_lookup"): RequestHandler.address_string = lambda self: self.client_address[0] diff --git a/radicale/config.py b/radicale/config.py index 71a315b..7ec3d11 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -34,6 +34,7 @@ INITIAL_CONFIG = { "hosts": "0.0.0.0:5232", "daemon": "False", "pid": "", + "timeout": "10", "ssl": "False", "certificate": "/etc/apache2/ssl/server.crt", "key": "/etc/apache2/ssl/server.key",