The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

CGI::Application::Plugin::Throttle - Rate-Limiting for CGI::Application-based applications, using Redis for persistence.

SYNOPSIS

  use CGI::Application::Plugin::Throttle;


  # Your application
  sub setup {
    ...

    # Create a redis handle
    my $redis = Redis->new();

    # Configure throttling
    $self->throttle()->configure( redis => $redis,
                                  prefix => "REDIS:KEY:PREFIX",
                                  limit => 100,
                                  period => 60,
                                  exceeded => "slow_down_champ" );

DESCRIPTION

This module allows you to enforce a throttle on incoming requests to your application, based upon the remote IP address.

This module stores a count of accesses in a Redis key-store, and once hits from a particular source exceeed the specified threshold the user will be redirected to the run-mode you've specified.

POTENTIAL ISSUES / CONCERNS

Users who share IP addresses, because they are behind a common-gateway for example, will all suffer if the threshold is too low. We attempt to mitigate this by building the key using a combination of the remote IP address, and the remote user-agent.

This module will apply to all run-modes, because it seems likely that this is the most common case. If you have a preference for some modes to be excluded please do contact the author.

METHODS

import

Force the throttle method into the caller's namespace, and configure the prerun hook which is used by CGI::Application.

new

Constructor.

This method is used internally, and not expected to be invoked externally.

The defaults are setup here, although they can be overridden in the "configure" method.

throttle

Gain access to the throttle object.

_get_redis_key

Build and return the Redis key to use for this particular remote request.

The key is built from the prefix string set in "configure" method, along with:

The remote IP address of the client.
The remote HTTP Basic-Auth username of the client.
The remote User-Agent

count

Return the number of times the remote client has hit a run mode, along with the maximum allowed visits:

      sub your_run_mode
      {
          my ($self) = (@_);

          my( $count, $max ) = $self->throttle()->count();
          return( "$count visits seen - maximum is $max." );
      }

throttle_callback

This method is invoked by CGI::Application, as a hook.

The method is responsible for determining whether the remote client which triggered the current request has exceeded their request threshold.

If the client has made too many requests their intended run-mode will be changed to to redirect them.

configure

This method is what the user will invoke to configure the throttle-limits.

It is expected that within the users CGI::Application setup method there will be code similar to this:

    sub setup {
        my $self = shift;

        my $r = Redis->new();

        $self->throttle()->configure( %args )
    }

The arguments hash contains the following known keys:

redis

A Redis handle object.

limit

The maximum number of requests that the remote client may make, in the given period of time.

period

The period of time which requests are summed for. The period is specified in seconds and if more than limit requests are sent then the client will be redirected.

prefix

This module uses Redis to store the counts of client requests. Redis is a key-value store, and each key used by this module is given a prefix to avoid collisions. You may specify your prefix here.

exceeded

The run_mode to redirect the client to, when their request-count has exceeded the specified limit.

AUTHOR

Steve Kemp <steve@steve.org.uk>

COPYRIGHT AND LICENSE

Copyright (C) 2014 Steve Kemp <steve@steve.org.uk>.

This library is free software. You can modify and or distribute it under the same terms as Perl itself.