r30638 - in /scripts/KGB: debian/changelog server/KGB server/kgb.conf.sample

tincho at users.alioth.debian.org tincho at users.alioth.debian.org
Fri Feb 13 08:21:51 UTC 2009


Author: tincho
Date: Fri Feb 13 08:21:44 2009
New Revision: 30638

URL: http://svn.debian.org/wsvn/?sc=1&rev=30638
Log:
server/KGB, server/kgb.conf.sample: support for rate limiting the SOAP
interface (only global limits, not per client).

Modified:
    scripts/KGB/debian/changelog
    scripts/KGB/server/KGB
    scripts/KGB/server/kgb.conf.sample

Modified: scripts/KGB/debian/changelog
URL: http://svn.debian.org/wsvn/scripts/KGB/debian/changelog?rev=30638&op=diff
==============================================================================
--- scripts/KGB/debian/changelog (original)
+++ scripts/KGB/debian/changelog Fri Feb 13 08:21:44 2009
@@ -25,5 +25,7 @@
     forcefully die when POE gets silly.
   * server/KGB, server/kgb.conf.sample: now the bot answers when addressed on a
     channel.
+  * server/KGB, server/kgb.conf.sample: support for rate limiting the SOAP
+    interface (only global limits, not per client).
 
  -- Damyan Ivanov <dmn at debian.org>  Mon, 28 Jul 2008 14:44:04 +0300

Modified: scripts/KGB/server/KGB
URL: http://svn.debian.org/wsvn/scripts/KGB/server/KGB?rev=30638&op=diff
==============================================================================
--- scripts/KGB/server/KGB (original)
+++ scripts/KGB/server/KGB Fri Feb 13 08:21:44 2009
@@ -39,6 +39,75 @@
 =back
 
 =cut
+
+# Included source from Schedule::RateLimiter -- until packaged
+
+package Schedule::RateLimiter;
+use 5.006;
+use strict;
+use warnings;
+use Time::HiRes;
+
+our $VERSION = 0.01;
+
+sub new {
+    my $proto = shift;
+    my $class = ref($proto) || $proto;
+
+    my %args = @_;
+
+    die "Missing 'seconds' argument" unless defined( $args{seconds} );
+
+    if ( $args{seconds} =~ /[^-\d\.]/ ) {
+        die "'seconds' argument must be numeric";
+    }
+
+    my $iterations = $args{iterations} || 1;
+
+    if ( $iterations =~ /[^-\d\.]/ ) {
+        die "'iterations' argument must be numeric";
+    }
+
+    if ( int($iterations) != $iterations ) {
+        die "'iterations' argument must be integer";
+    }
+
+    die "'iterations' argument must be positive" if $iterations < 0;
+
+    my @list;
+    $#list = $iterations -1;
+
+    bless { 
+        current     => 0,
+        list        => \@list,
+        iterations  => $iterations,
+        seconds     => $args{seconds},
+        block       => ( exists($args{block}) ) ? $args{block} : 1,
+    }, $proto;
+}
+
+sub event {
+    my $self = shift;
+    my %args = @_;
+
+    my $t = Time::HiRes::time();
+
+    my $last = $self->{list}[$self->{current}] || 0;
+    my $block = exists( $args{block} ) ? $args{block} : $self->{block};
+
+    if ( ($t - $last) < $self->{seconds} ) {
+        return 0 unless $block;
+        Time::HiRes::sleep($self->{seconds} - ($t - $last));
+    }
+
+    $self->{list}[$self->{current}] = $t;
+
+    $self->{current} = ($self->{current}+1) % $self->{iterations};
+
+    return 1;
+}
+# End of included module
+
 package KGB;
 
 use strict;
@@ -86,6 +155,20 @@
     $conf->{soap}{service_name} ||= "KGB";
     $conf->{soap}{server_port}  ||= 9999;
     $conf->{soap}{server_addr}  ||= "127.0.0.1";
+
+    if($conf->{soap}{max_requests_per_minute}) {
+        my $rate = delete $conf->{soap}{max_requests_per_minute};
+        my $burst = delete $conf->{soap}{max_requests_burst} || 1;
+        if($rate !~ /^(?:\d+|\d*\.\d+)$/ or ($rate + 0 < 0)) {
+            die "Invalid value for config key: max_requests_per_minute";
+        }
+        $conf->{soap}{rate} = new Schedule::RateLimiter(
+            iterations => $burst,
+            seconds => ($rate * 60 * $burst),
+            block => 0
+        );
+    }
+
     $conf->{min_protocol_ver}     = 1 unless(defined $conf->{min_protocol_ver});
     $conf->{smart_answers}      ||= [ "My master told me to not respond." ];
  
@@ -403,6 +486,12 @@
             "Protocol version $proto_ver not welcomed");
         print $KGB::out "Protocol version $proto_ver rejected\n" if(
             $KGB::config->{debug});
+        return;
+    }
+    if($KGB::config->{soap}{rate} and not $KGB::config->{soap}{rate}->event()) {
+        $kernel->post(SOAPServer => 'FAULT', $response, 'Client.Slowdown',
+            "Server is overworked");
+        print $KGB::out "Rate limit enforced\n" if($KGB::config->{debug});
         return;
     }
     if($proto_ver == 0) {

Modified: scripts/KGB/server/kgb.conf.sample
URL: http://svn.debian.org/wsvn/scripts/KGB/server/kgb.conf.sample?rev=30638&op=diff
==============================================================================
--- scripts/KGB/server/kgb.conf.sample (original)
+++ scripts/KGB/server/kgb.conf.sample Fri Feb 13 08:21:44 2009
@@ -4,6 +4,8 @@
   server_addr: 127.0.0.1
   server_port: 9999
   service_name: KGB
+  max_requests_per_minute: 2.5
+  max_requests_burst: 5
 repositories:
   # just a name to identify it
   foo:




More information about the Pkg-perl-cvs-commits mailing list