changeset 441:a858267f7dea

improved surge protection: dont sleep, add total requests rate imported from: moin--main--1.5--patch-445
author Thomas Waldmann <tw@waldmann-edv.de>
date Wed, 15 Feb 2006 07:39:21 +0000
parents 0f07dcad6614
children 7f314352e723
files ChangeLog MoinMoin/multiconfig.py MoinMoin/request.py
diffstat 3 files changed, 40 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Feb 14 06:38:53 2006 +0000
+++ b/ChangeLog	Wed Feb 15 07:39:21 2006 +0000
@@ -2,6 +2,20 @@
 # arch-tag: automatic-ChangeLog--arch@arch.thinkmo.de--2003-archives/moin--main--1.5
 #
 
+2006-02-15 08:39:21 GMT	Thomas Waldmann <tw@waldmann-edv.de>	patch-445
+
+    Summary:
+      improved surge protection: dont sleep, add total requests rate
+    Revision:
+      moin--main--1.5--patch-445
+
+    improved surge protection: dont sleep, add total requests rate
+    
+
+    modified files:
+     ChangeLog MoinMoin/multiconfig.py MoinMoin/request.py
+
+
 2006-02-14 07:38:53 GMT	Thomas Waldmann <tw@waldmann-edv.de>	patch-444
 
     Summary:
--- a/MoinMoin/multiconfig.py	Tue Feb 14 06:38:53 2006 +0000
+++ b/MoinMoin/multiconfig.py	Wed Feb 15 07:39:21 2006 +0000
@@ -299,6 +299,7 @@
     
     surge_action_limits = { # allow max. <count> <action> requests per <dt> secs
         # action: (count, dt)
+        'all': (20, 30),
         'show': (20, 60),
         'recall': (5, 60),
         'raw': (20, 40),  # some people use this for css
--- a/MoinMoin/request.py	Tue Feb 14 06:38:53 2006 +0000
+++ b/MoinMoin/request.py	Wed Feb 15 07:39:21 2006 +0000
@@ -145,14 +145,10 @@
             self.user = self.get_user()
             
             if not self.query_string.startswith('action=xmlrpc'):
-                self.clock.start('botprot')
                 if not self.forbidden and self.isForbidden():
                     self.makeForbidden403()
-                self.clock.stop('botprot')
-                self.clock.start('surgeprot')
                 if not self.forbidden and self.surge_protect():
                     self.makeUnavailable503()
-                self.clock.stop('surgeprot')
 
             from MoinMoin import i18n
 
@@ -176,9 +172,9 @@
         """ check if someone requesting too much from us """
         validuser = self.user.valid
         current_id = validuser and self.user.name or self.remote_addr
-        current_action = self.form.get('action', ['show'])[0]
         if not validuser and current_id.startswith('127.'): # localnet
             return False
+        current_action = self.form.get('action', ['show'])[0]
         
         limits = self.cfg.surge_action_limits
         default_limit = self.cfg.surge_action_limits.get('default', (30, 60))
@@ -207,6 +203,19 @@
             events = surgedict.setdefault(current_id, copy.copy({}))
             timestamps = events.setdefault(current_action, copy.copy([]))
             surge_detected = len(timestamps) > maxnum
+
+            surge_indicator = surge_detected and "!" or ""
+            timestamps.append((now, surge_indicator))
+            if surge_detected:
+                if len(timestamps) < maxnum*2:
+                    timestamps.append((now + self.cfg.surge_lockout_time, surge_indicator)) # continue like that and get locked out
+        
+            current_action = 'all' # put a total limit on user's requests
+            maxnum, dt = limits.get(current_action, default_limit)
+            events = surgedict.setdefault(current_id, copy.copy({}))
+            timestamps = events.setdefault(current_action, copy.copy([]))
+            surge_detected = surge_detected or len(timestamps) > maxnum
+            
             surge_indicator = surge_detected and "!" or ""
             timestamps.append((now, surge_indicator))
             if surge_detected:
@@ -853,8 +862,13 @@
         if not forbidden and self.cfg.hosts_deny:
             ip = self.remote_addr
             for host in self.cfg.hosts_deny:
-                if ip == host or host[-1] == '.' and ip.startswith(host):
+                if host[-1] == '.' and ip.startswith(host):
                     forbidden = 1
+                    #self.log("hosts_deny (net): %s" % str(forbidden))
+                    break
+                if ip == host:
+                    forbidden = 1
+                    #self.log("hosts_deny (ip): %s" % str(forbidden))
                     break
         return forbidden
 
@@ -984,8 +998,11 @@
     def run(self):
         # Exit now if __init__ failed or request is forbidden
         if self.failed or self.forbidden:
-            if self.forbidden:
-                time.sleep(10) # let the sucker wait!
+            #Don't sleep()! Seems to bind too much resources, so twisted will
+            #run out of threads, files, whatever (with low CPU load) and stop
+            #serving requests.
+            #if self.forbidden:
+            #    time.sleep(10) # let the sucker wait!
             return self.finish()
 
         self.open_logs()