Bläddra i källkod

Limit number of parallel connections

Unrud 9 år sedan
förälder
incheckning
83ea9da2b4
4 ändrade filer med 22 tillägg och 2 borttagningar
  1. 3 0
      config
  2. 16 2
      radicale/__init__.py
  3. 2 0
      radicale/__main__.py
  4. 1 0
      radicale/config.py

+ 3 - 0
config

@@ -24,6 +24,9 @@
 # File storing the PID in daemon mode
 #pid =
 
+# Max parallel connections
+#max_connections = 20
+
 # Max size of request body (bytes)
 #max_content_length = 10000000
 

+ 16 - 2
radicale/__init__.py

@@ -29,9 +29,11 @@ should have been included in this package.
 import os
 import pprint
 import base64
+import contextlib
 import socket
 import socketserver
 import ssl
+import threading
 import wsgiref.simple_server
 import re
 import zlib
@@ -57,6 +59,7 @@ class HTTPServer(wsgiref.simple_server.WSGIServer):
 
     # These class attributes must be set before creating instance
     client_timeout = None
+    max_connections = None
 
     def __init__(self, address, handler, bind_and_activate=True):
         """Create server."""
@@ -76,6 +79,13 @@ class HTTPServer(wsgiref.simple_server.WSGIServer):
             self.server_bind()
             self.server_activate()
 
+        if self.max_connections:
+            self.connections_guard = threading.BoundedSemaphore(
+                self.max_connections)
+        else:
+            # use dummy context manager
+            self.connections_guard = contextlib.suppress()
+
     def get_request(self):
         # Set timeout for client
         _socket, address = super().get_request()
@@ -106,11 +116,15 @@ class HTTPSServer(HTTPServer):
 
 
 class ThreadedHTTPServer(socketserver.ThreadingMixIn, HTTPServer):
-    pass
+    def process_request_thread(self, request, client_address):
+        with self.connections_guard:
+            return super().process_request_thread(request, client_address)
 
 
 class ThreadedHTTPSServer(socketserver.ThreadingMixIn, HTTPSServer):
-    pass
+    def process_request_thread(self, request, client_address):
+        with self.connections_guard:
+            return super().process_request_thread(request, client_address)
 
 
 class RequestHandler(wsgiref.simple_server.WSGIRequestHandler):

+ 2 - 0
radicale/__main__.py

@@ -171,6 +171,8 @@ def run():
     else:
         server_class = ThreadedHTTPServer
     server_class.client_timeout = configuration.getint("server", "timeout")
+    server_class.max_connections = configuration.getint("server",
+                                                        "max_connections")
 
     if not configuration.getboolean("server", "dns_lookup"):
         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",
         "daemon": "False",
         "pid": "",
+        "max_connections": "20",
         "max_content_length": "10000000",
         "timeout": "10",
         "ssl": "False",