summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfranck cuny <franck@lumberjaph.net>2010-04-27 18:47:49 +0200
committerfranck cuny <franck@lumberjaph.net>2010-04-27 18:47:49 +0200
commit2ae3fd059b5aaf093c7fb26e674833b65008ad42 (patch)
treec62d4d46851bfff1db49a734e1fb315d90ce2e40
parenttests (diff)
downloadplack-middleware-throttle-2ae3fd059b5aaf093c7fb26e674833b65008ad42.tar.gz
change how path works, by default the whole application is throttled, but if path is specified, only this path will be throttled
-rw-r--r--lib/Plack/Middleware/Throttle.pm22
-rw-r--r--t/05_filter_path.t10
2 files changed, 19 insertions, 13 deletions
diff --git a/lib/Plack/Middleware/Throttle.pm b/lib/Plack/Middleware/Throttle.pm
index 3ef72a9..25b2aad 100644
--- a/lib/Plack/Middleware/Throttle.pm
+++ b/lib/Plack/Middleware/Throttle.pm
@@ -21,7 +21,7 @@ has white_list =>
( is => 'rw', isa => 'ArrayRef', predicate => 'has_white_list' );
has black_list =>
( is => 'rw', isa => 'ArrayRef', predicate => 'has_black_list' );
-has path => ( is => 'rw', isa => 'ArrayRef', predicate => 'has_path' );
+has path => ( is => 'rw', isa => 'RegexpRef', predicate => 'has_path' );
sub prepare_app {
my $self = shift;
@@ -45,8 +45,9 @@ sub call {
my $res = $self->app->($env);
- return $res if $self->path_is_not_throttled($env);
- return $res if $self->is_white_listed($env);
+ return $res unless $self->path_is_throttled($env);
+
+ return $res if $self->is_white_listed($env);
return $self->forbiden if $self->is_black_listed($env);
my $key = $self->cache_key($env);
@@ -94,12 +95,16 @@ sub is_black_listed {
return 0;
}
-sub path_is_not_throttled {
+sub path_is_throttled {
my ( $self, $env ) = @_;
+
return 0 if !$self->has_path;
+ my $path_match = $self->path;
my $path = $env->{PATH_INFO};
- if ( grep { $path =~ /$_/ } @{ $self->path } ) {
- return 1;
+
+ for ($path) {
+ my $matched = 'CODE' eq ref $path_match ? $path_match->($_) : $_ =~ $path_match;
+ $matched ? return 1 : return 0;
}
return 0;
}
@@ -155,7 +160,8 @@ Plack::Middleware::Throttle - A Plack Middleware for rate-limiting incoming HTTP
my $handler = builder {
enable "Throttle::Hourly",
max => 2,
- backend => Plack::Middleware::Throttle::Backend::Hash->new();
+ backend => Plack::Middleware::Throttle::Backend::Hash->new(),
+ path => qr{^/foo};
sub { [ '200', [ 'Content-Type' => 'text/html' ], ['hello world'] ] };
};
@@ -212,7 +218,7 @@ Key to prefix sessions entry in the cache.
=item B<path>
-List of regex for path exclusions.
+URL pattern or a callback to match request to throttle. If no path is specified, the whole application will be throttled.
=item B<white_list>
diff --git a/t/05_filter_path.t b/t/05_filter_path.t
index 73ec24b..1be3706 100644
--- a/t/05_filter_path.t
+++ b/t/05_filter_path.t
@@ -11,7 +11,7 @@ my $handler = builder {
enable "Throttle::Hourly",
max => 1,
backend => Plack::Middleware::Throttle::Backend::Hash->new(),
- path => [qr/^\/foo/];
+ path => qr{^/foo};
sub { [ '200', [ 'Content-Type' => 'text/html' ], ['hello world'] ] };
};
@@ -21,17 +21,17 @@ test_psgi
my $cb = shift;
{
for ( 1 .. 2 ) {
- my $req = GET "http://localhost/foo";
+ my $req = GET "http://localhost/bar";
my $res = $cb->($req);
is $res->content, 'hello world', 'content is valid';
ok !$res->header('X-RateLimit-Limit'), 'no header ratelimit';
}
- my $req = GET "http://localhost/bar";
+ my $req = GET "http://localhost/foo";
my $res = $cb->($req);
is $res->content, 'hello world', 'content is valid';
ok $res->header('X-RateLimit-Limit'), 'header ratelimit';
- my $req = GET "http://localhost/bar";
- my $res = $cb->($req);
+ $req = GET "http://localhost/foo";
+ $res = $cb->($req);
is $res->code, 503, 'rate limit exceeded';
}
};